一般社団法人 全国個人事業主支援協会

COLUMN コラム

  • 「プログラムはなぜ動くのか 第3版」を読んで

はじめに

プログラムはなぜ動くのか 第3版」を読みました。
新しく知ったことを備忘録として記載しておきます。

データ型

データ型とはどのような種類のデータを格納するかを示すものであり、データ型ごとにメモリを占有するサイズが異なります。
つまり、プログラムで指定するデータ型によって、物理的なメモリーの読み書きサイズを変えることができるようになっています。

例えば、C言語では、char型は1バイト、short型は2バイト、long型は4バイト、double型は8バイトで読み書きします。
ではポインタ型はどのように考えれば良いでしょうか?
例えば、C言語では以下のようにポインタ型を表します。

char *a;
short *b;
long *c;
double *d;

まず、ポインタとはデータが格納されたメモリーのアドレスを持つ変数のことです。
Windowsの場合は基本的に、メモリのアドレスは32ビット(4バイト)か64ビット(8バイト)で表します。
なお、32ビットのWindowsで動くように多くのプログラムはメモリアドレスを32ビットで表すことが多いようです。
つまり、多くのプログラムではポインタ型は4バイトで読み書きします。

では、char *aやshort *bのように、*の前にcharやshortを記載する必要があるのはなぜでしょうか?
それはポインタに格納されたアドレスから一度に何バイトのデータを読み書きするかを示す必要があるからです。
char *aであればアドレスから1バイト読み書きしますし、short *bであればアドレスから2バイト読み書きします。

配列の話もします。
配列はメモリの物理的な構造そのものです。
特にchar型のように1バイトのデータ型の配列は物理的なメモリーの構造と完全に一致します。
1バイトずつ読み書きするのは大変なので、任意のデータ型を指定した配列も宣言できます。
例えば、short型の配列であれば、2バイトずつメモリーを読み書きします。

配列のインデックスを指定することで、順番に読み書きしたり、任意の要素を読み書きしたりできます。
ただ、インデックスを毎回指定するのは面倒くさいので、配列を変形したスタック、キュー、リストなどを使うことが多いです。

ネイティブコード(マシン語)

PCはソースコードを直接解釈できないので、コンパイルしてネイティブコード(マシン語)に変換する必要があることはご存知かと思います。
このときOSとCPUごとに作成されるネイティブコードが異なることはご存知でしょうか?

OS

OSとは複数のプログラムの集合体ですが、その一つにハードウェア制御プログラムがあります。
各アプリケーションはOSの機能(システムコール)を利用してハードウェアを制御します。
ただし、C言語などの高水準言語ではOSに依存しないように独自の関数名を定義し、コンパイル時に該当するシステムコールを利用するネイティブコードに変換される仕組みになっています。

つまり、OSごとに作成されるネイティブコードが異なります。
そのため、実行環境のOSに合わせてコンパイルする必要があります。

CPU

CPUはそのマシン固有のマシン語しか解釈できません。
CPUが異なれば解釈できるマシン語も異なります。

つまり、CPUごとに作成されるネイティブコード(マシン語)が異なります。
そのため、実行環境のCPUに合わせてコンパイルする必要があります。

さいごに

さいごに「プログラムはなぜ動くのか 第3版」を読んで一番心に刺さった言葉を引用して終わりにします。

コンピュータの世界には、次々と新しい技術が登場していますが、コンピュータにできることが、データを周辺装置から入力する、データをメモリーに記憶する、データをCPUの内部で演算する、そしてデータを周辺装置に出力する、だけであることは変わりません。必然的にプログラムの内容も、突き詰めればデータの入力、記憶、演算、出力だけです。コンピュータもプログラムも、実にシンプルなものなのです。

 

The following two tabs change content below.

この記事をシェアする

  • Twitterでシェア
  • Facebookでシェア
  • LINEでシェア