私が42で取り組んだこと
2021年2月に入学試験であるPiscineを受け、2021年4月に入学してから約1年が経ちました。
私は大学と並行しながら取り組んできたので、課題の進度はそこまで早い方ではありませんが、なんとか退学にならずに勉強できています。
C言語の勉強を通してコンピュータサイエンスの学習をしています。
この記事では約1年間で学んだことをまとめていきたいと思います。
課題
Libcの再実装
strlcpyやstrlcat、atoi、などの関数を再実装し、ライブラリにまとめたものを実装しました。
実装に使っていい関数は
malloc
write
のみです。
課題の採点はかなり色々なケースでテストされるため、クリアするにはどんなケースにも対応できるように実装する必要があります。
普段、何気なく利用している関数や、文字列の代入や比較などの操作が、内部でどのような処理がされているのかを学ぶことができました。
また、とにかく本家に寄せた挙動をする必要があるため、関数の定義をmanコマンドで確認するようにしました。
この経験から、1次情報から実装に必要な情報を読み取って実装する力が少しは身に付いたと思います。
この課題は入学して初めての課題でsplitの実装がなかなか上手くいかず、提出期限ぎりぎりで本当に焦った思い出があります。
また、ここで実装したライブラリを使って、これから紹介する課題に取り組みました!
fgetsの再実装
ファイルディスクリプタから改行まで読み込む関数を実装しました。
この課題を通して以下に力が鍛えられました。
ファイルディスクリプタの知識
static変数の扱い
メモリリークへの対処
fgetsは複数回呼ぶとどんどん次の行を返すので、static変数を使って前回どこまで読み込んだのか保持しておく必要があります。
また、同時にstatic変数に保持しておいた文字列に対して、適切にメモリの解放をする必要があります。
このメモリリークが厄介でしたが、Libcの再実装課題で実装したstrjoin関数を改良することで解決しました。
printfの再実装
C言語を使ったことがある人は全員使っているであろう、printfも再実装しました。
対応した変換識別子は以下になります。
%s, d, u, p, x, X
そして以下のオプションにも対応しました。
0埋め
精度
長さ
課題を取り組んだ最初は本当に何から取り組めばいいのかわからなくて、苦労した記憶があります笑
とにかく調べるのと、学生に質問するので、どうにか課題を進めていきました。
入力のパターンが本当に無数にあるので、全ての入力に対して正しい挙動を実装するのに本当に苦労しました。
一つの変換識別子につき適宜テストを作成して、自分なりに実装して、完成したときは本当に達成感がありました。
とても思い出深い課題です。。。
2つのスタックを使ったソートアルゴリズム
二つのスタックaとbを用いたソートアルゴリズムです。
最初にコマンドライン引数から与えられた整数の数列はスタックaにあります。
そして数列をソートするために必要な操作を出力するといった内容になっています。(操作方法等の詳しい内容は以下のgithubをご覧ください。)
課題の要件をクリアするためには、操作回数が決められた回数よりも小さい必要があるため、アルゴリズムを工夫する必要があります。
私はクイックソートを元に、二つのスタックを用いて実装しました。
ただの配列のクイックソートであれば簡単ですが、決められた操作を使ってかつ少ない手順でクイックソートを実装する必要があるため、かなり苦しめられました。
Bashのパイプの再実装
この課題では普段何気なく、ターミナルで利用しているパイプ「|」を再実装しました。
この課題で、fork関数を使ったプロセス制御や、pipe関数やdup2関数を使ったファイルディスクリプタを扱う力が身に付けられたと思います。
パイプには最大サイズがあり、普通に頭で考えられるような実装ではサイズの大きなファイルには対応することができません。
子プロセスの終了を待つ、wait関数の使い方を工夫する必要があり、とても苦労した思い出があります。
実装イメージは以下となっています。
2Dゲームの開発
ここまでとは雰囲気が変わって、C言語を使って2Dゲームの開発もしました!
ライブラリはminilibxを使って、グラフィックを表現しました。
主人公をキーで操作し、おばけから逃げながらアイテムを全て集めてゴールを目指すゲームです。
アニメーションをつけたことと、おばけが常に自分との距離を最小化する選択肢を取るように、工夫しました!
楽しくて、結構かわいいゲームができたなぁと気に入っています。
ゲームはこんな感じです↓
Bashの再実装
これまでの集大成的な課題としてBashを再実装しました!
この課題は、チーム課題で同じ学生の方と協力しながら開発しました。
いつも使っているシェルを実装できたことは、自分にとって大きな自信になりました!
動画を見ていただくとわかる通り、普通に使用する分には本物とほぼ遜色のないものになっていると思います!
Bashの実装に当たり、Bashの公式ドキュメントとオープンソースアーキテクチャのBash部分を読み込みました。
ドキュメントを読んだ結果、Bashのアーキテクチャは以下の通りであることがわかりました。
lexer (単語分割)
parser (構文解析)
expander (環境変数展開)
executer (コマンド実行)
それぞれのテストを作成し、丁寧に実装していきました。
特に苦労した点は
リダイレクトを指定しながら複数のコマンドをパイプを使って実行
子プロセス実行中にシグナルで終了
環境変数の展開をしながらコマンド実行
ここら辺の複雑な処理はモブプログラミングをしながら実装しました。
まとめ
以上が私が42tokyoでこれまでに取り組んだ内容になります。
いつも最初は全くわからない課題を手探りで実装していくことになるため、わからないことに慣れてきました。
全くわからない状態からとにかく調べて実装していく、力が付いたと思います。そのため、新たな言語の習得にかかる時間が確実に早くなったと思います!
また、課題をクリアするには複数の学生からのコードレビューと挙動をテストしてもらい、採点してもらう必要があります。
そのため、自分が書いたコードを説明する力や、コミュニケーション能力も鍛えられたと思います。
これからも42の課題を通して、エンジニアに必要な力を身に着けていきたいと思っています。
ちなみに、現在はマルチスレッドプログラミングに挑戦しています!!
この記事が気に入ったらサポートをしてみませんか?