CS50xの課題をやっている - Week1〜4

 42のPiscineに向けて何かC言語を書く機会を増やさないとなと思っていたのだが、以前どこかで(たぶん𝕏Twitterで)見たCS50xというのを思いだした。見てみたところ、講義はYoutubeで配信されているだけで、見たかどうかのチェックはないようだ。少なくとも見たかどうかに関係なく、課題だけできる。のでやってみることにした。2022年分の日本語訳が https://cs50.jp/ にあるがネタは毎年同じようだ。
 GitHubアカウントがあれば、すぐ始められる。
 専用のIDE、というかブラウザー版VSCodeが用意されている(要GitHubアカウント)。

 ところで、この講座のコードを提出するときには「学術的な誠実さ」というものを守るよう求められる(提出時に"Keeping in mind the course's policy on academic honesty, are you sure you want to submit these files (yes/no)? "と聞かれる)ので、ここに回答そのものを書くのはネタバレが過ぎるだろう。だから書かないが、問題文を適当にまとめると、

  • 最初のWeek0の課題はScratch(というCではない言語)だったので飛ばした。

  • Week1: hello、mario-more('#'で階段を描画)、credit (Luhn’s Algorithm実装)

  • Week2: scrabble (文字列、配列の練習)、readability(文字列の分割)、caesar(シーザーの暗号。文字コードの操作)またはsubstitution(換字式暗号。文字列の文字の置換)と、数が多いので意外と重い

  • Week3: sort(複数のソートプログラムのバイナリーと複数のデータがあって、実行時間のくせからどれがselection sort、bubble sort、merge sortか当てる)、plurality(投票。文字列で候補者名が入力されるので文字列比較)、runoff(3位まで指定する投票。簡単版)をやって、ここまでで結構重かったので、tideman(3位まで指定する投票。めんどくさい版)はやってない

  • Week4: バイナリーファイルを扱う週。1個目、2個目はWAVとBMPにフィルターかける。3個目は大きいファイルから特定のシグネチャーを見つける。

    • WAVとBMPの課題はすでに入出力が書いてあって楽だったが、最後のやつは空のmain()関数が置いてあるだけだったので、直前の課題からコピペした。

という感じだった。

 勉強になったのはバイナリーファイルから読んだ値をstructにまとめて読み込むというテクニック。
 0xAA0xBB0xCC0xDDという列(RGBとか)があったとき、

typedef struct{
    uint8_t a;
    uint8_t b;
    uint8_t c;
}__attribute__((__packed__))
ABC;

int main(void){
    // ファイルは開いてあって、inptrがファイルポインターとする
    ABC abc;
    int cnt = fread(&abc, sizeof(ABC), 1, inptr);
    printf("%d %d %d",abc.a,abc.c,abc.c);
}

みたいにすると、読むときは3byteまとめて読んで、アクセスするときは.aとかで切り出せるのは便利だ(あってるかな?)。
 structの中身が書いた順にメモリーに連続して配置されるからできるんだと思うんだけど、いままでバイナリーファイルなんてせいぜいchar(ちょうど1byteなので都合がいい)の配列などを使ったものだった。structは使ったことなかったので、なるほどなーー、と。
 ビットマップファイル(.bmp)やWAVファイルは同じサイズのデータがならんでいるので、このように読み込めるらしい。

42と50の話をすると

 42はこんなに優しく環境を整えてくれない。50
は任意の文字数の入出力(つまりchar配列や、malloc()/free())を憶えるまで、独自の関数を用意して、それを使わせてくれたりするが、42はしない。むしろなんでも自分で作れっていう感じ。
 が、Week4くらいまで来ると、なんとなく似てきたかもしれないという気がしてきた。
 一方自分の書いた物が自動でテストされるあたりは似ている。ただピアレビューはないし、ポイント制も、時間制限もないから、いくらでも送信できる。
 2024年版にはなかった気がするが、日本語版にはLabという共同でやってもいい課題があるのも似ている。あと、コードのフォーマットを直すコマンドあって、フォーマットの点数が全体の1/4くらいと重視されるのも似ている(normminetteっぽいstyle50というコマンドがある)。

 というわけで、CS50xがPiscineの役に立つかというと、初心者ほどいいかもしれない。ただはじめの方でやるのは常識的なCなことに注意が必要だ。
 もちろん、授業動画ではメモリーの話をかなりしつこくやってくれるので、アドレス? ポインタ? はぁ……? みたいな感じの人ほどいいと思う。
 一方で、Piscineの役に立たないところもある。Piscineでやるのは非常識なCだから。はじめの方の課題はぜんぜん違う。
 それらがWeek4の課題あたりからオーバーラップするようになってくるので、やるならWeek5までやった方がいいと思います。それ以降はPythonとかウェブとかになるみたいです(見てない)。

 PiscineでC言語をそれなりに書いたけど落ちたくらいの経験がある場合、つまり私だけど。Piscine以来Cを書いてなかったから、課題は勉強になった。
 Piscineを体験したら配列、ポインタ、構造体、malloc()、free()くらい使えるようになってるだろう。あとファイルの読み書きも。
 そうすると講義は初回から見るのは飽きるので、適当なとこだけ見ればいいと思う。
 私は構造体の使い方を復習したかったからWeeek4から適当に飛ばしながら見ている。何しろweek当たり2時間以上ある。本編以外に助手による概念ごとの説明(短い動画)もあるので、そっちから気になったところだけ見てもいいかもしれないです。


この記事が気に入ったらサポートをしてみませんか?