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時間以上ある。本編以外に助手による概念ごとの説明(短い動画)もあるので、そっちから気になったところだけ見てもいいかもしれないです。