📔

本_Cプログラミング入門以前 第2版を読んで、改めて意識した事

2023/03/26に公開

はじめに

プログラミングを始めて、2年7ヶ月、エンジニアになって、1年9ヶ月。
開発に携わり、わからないことにぶつかりながらも、何とか業務しております。
ふと、弊社の課題図書として推奨されている本を読み進めていこうと思いこの本を手にしました。
プログラミングの入門書のようなものですが、改めて意識すべきと思ったことがあったので、こちらに記載していこうと思います。

改めて意識すること

詰まったら声に出して読む

この2年ほど、開発を進める中で、納期を意識してなんとか形にすることを意識していました。お客様が待っている以上、一つひとつ理解して進めていくには時間もなく、経験の浅い中で納期を意識することが最善と思って進めていました。
その為、使いまわせる部分は、意味を理解せずに使い回し、理解することは飛ばしがちでした。
しかしながら、問題が起こるのは大抵読み飛ばしたところにあり、結果的に修正する時間がかかってしまう、ということもありました。
自分の頭の構造上、わからないことはわからないまま飛ばして、わかる部分だけつまんでいく構造になっていた為、改めないと、と思っていました。
そんな思いがあった中でこの本を読んで、「声に出して読むことの重要性」を改めて感じました。

細かいところに気づく必要がある

他の人はわからないですが、こと自分においては、細かいことを気にせずに進める「癖」があり、これが深い理解を妨げていました。しかしながら、声に出して読むことで、理解していない引っ掛かりを認知することができるため、何がわかっていないかを理解する助けになると感じました。

読めない == わかっていない

関数においても、どんなことをするのかわかっていなければコード自体読むことができません。読むことができないということは理解していないということです。関数の深い中身までは見る必要がない場合も多いにあります。(例えばライブラリの中身とか)ただ、その関数が何をしているのかイメージできなければ、結果、後で問題が発生することになりかねないと思いました。

テストやデバッグの際に役立つ

声に出して読むことができれば、問題が発生したときに、どこが間違っているかの特定が早くなります。自分の書いたコードであればなおさら、意味を理解して、テストやデバッグに役立てることができます。

CPUがプログラムを実行するステップの理解

CPUがプログラムを実行するステップは以下のようになります。

1. フェッチ(fetch)
メモリから命令を読み込む
2. デコード(decode)
命令を解読する
3. オペランドフェッチ(operand fetch)
実行する命令で必要なデータを取得
4. 実行(execution)
命令を実行する
5. ストア(store)
実行した結果をメモリに書き込み

理解する必要性

バグの解決

CPUがプログラムを実行する過程で問題が発生することがあります。プログラムが停止したり、期待した出力が得られなかったりする場合があります。CPUがプログラムを実行する方法を理解することで、問題の原因を特定して修正することができます。
この2年の開発においても、メモリ不足によるエラーが多々発生していました。

 Fatal error: Allowed memory size of xxx bytes exhausted

このような発生がどこで起こっているか理解し改善するためにも、プログラム実行のステップは理解しておく必要があると感じました。

プログラムの最適化

上記と似ていますが、CPUがプログラムを実行する方法を理解することで、プログラムの最適化が可能になります。プログラムを効率的に実行するためには、CPUの処理能力とプログラムの要件を最適に調整する必要があることが多々あります。

メモリの理解

こちらも、上記プログラム実行のステップの理解に似ていますが、メモリにおかれたプログラムをCPUが実行する、という理解が改めて必要だと感じました。

プログラムは、実行する前にメモリ上にロードされます。コンピュータは、プログラムを実行するために、プログラムをメモリ上に置きます。プログラムが実行されるとき、コンピュータはメモリ上にロードされたプログラムを使用して、必要な処理を実行します。

プログラムをメモリ上に置くことにより、コンピュータはプログラムにアクセスしやすくなります。プログラムがメモリ上に置かれると、CPUはプログラムを読み取り、必要な処理を実行します。また、プログラムがメモリ上に置かれることにより、プログラムが使用する変数やオブジェクトなどのデータもメモリ上に置かれます。

プログラムがメモリ上に置かれる場所には、主に2つの領域があります。それは、スタック領域とヒープ領域です。

スタック領域

静的なメモリ割り当てを行う領域であり、関数の呼び出し時に使用される一時的なメモリ領域です。スタック領域には、関数呼び出し時に引数やローカル変数、戻り番号などが格納されます。スタック領域は、割り当てられたメモリ領域を超えた場合には、スタック領域のオーバーフローが発生してプログラムが異常終了することがあります。

ヒープ領域

動的なメモリ割り当てを行う領域であり、プログラム実行中に必要に応じてメモリを確保することができます。ヒープ領域には、malloc()、calloc()、realloc() などの関数を使用してメモリを確保し、free() 関数を使用して解放することができます。ヒープ領域は、割り当てられたメモリ領域を超えた場合には、動的にメモリを確保することができなくなって、プログラムが異常終了することがあります。

上記のようにスタック領域は、一時的なデータを格納するために使用されます。一方、ヒープ領域は、より大きなデータや、動的に確保されたデータを格納するために使用されます。プログラムが実行されるときに、それぞれの領域に必要なデータが割り当てられます。
この理解をすることで、今、メモリのどの領域を使用しているのかを理解することができ、問題の発見がより早くなるのではと感じています。

おわりに

上記の通り、プログラムの理解と、コンピュータの理解がさらに必要と感じています。
目の前の「納期」にのみにフォーカスせず、全体像の理解を深めることで、より素早いコーディングができるようになると感じている時期です。

Discussion