1.変数とアドレス
1.1 データ型とメモリサイズ
コンピュータのプログラムでは様々な値を扱うことになります。その値を格納しておくのが「変数」です。C言語では、プログラムの始めの部分で、そのプログラム内で使う変数を予め「宣言」する必要があります。
変数の宣言文では、以下の例のように、「どのような値を格納するための変数なのか」を「データ型」として指定する必要があります。下の例では変数iを整数型、変数xを実数型(単精度浮動小数点)、変数chを文字型として宣言しています。
int
i;
float
x;
char
ch;
プログラムが実行される時、変数の値は実際にはコンピュータの「メモリ」に記憶されます。コンピュータのメモリは、数値を格納するための「引き出しが非常にたくさん重なったタンス」のようなものと考えればよいかもしれません。上のような宣言文は、プログラムから「これからiとxとchという変数を使うので、その分の引き出しを確保しておいてくれ」と指示を出しているのです。ある変数に対して「確保」されたメモリは、他の変数に使われることはありません。
一つの引き出しに記憶できる情報の量は1バイト(1 byte = 8 bit)と決まっており、これは整数なら0から255までの値(28通りの値)を表すことができるサイズに相当します。当然、より大きな値まで表す整数を格納しようと思えば、2つ以上の引き出しが必要になります。つまり、どのような値を扱う変数かによって確保すべきメモリサイズ(引き出しの数)が異なるわけです。より大きい整数まで表す変数や、より精度の高い実数を表す変数ほど、必要なメモリが多くなります(shortよりlong、floatよりdouble)。
変数が宣言されると、その指定されたデータ型に応じて必要なバイト数のメモリが確保されるわけですが、次の例はint型の変数に必要なメモリサイズを実際に表示するものです。コンパイルして実行してみて下さい。
<例1−1>
#include <stdio.h>
int main(void) {
/*
int型変数のメモリサイズを表示 */
printf("size
of int = %d bytes\n", sizeof(int));
return
0;
}
[解説] printf関数の書式設定
ここで使っているsizeofという演算子は、「あるデータ型のメモリサイズのバイト数」を得るための演算子です。下の課題で、int型以外のデータ型のサイズも確かめて下さい。
【課題1−1】(プログラムと実行結果を提出)
<例1−1>を参考にして、sizeof演算子を使って以下のデータ型のサイズを確かめるプログラムを作る。
整数型 int, short,
long
実数型 float, double
文字型 char
[解説] C言語のデータ型
《プログラム例》
1.2 アドレス
コンピュータの引き出し(メモリ)にはすべて番号がついています。それが「アドレス」です。プログラムの実行時には、変数の宣言で指定されたデータ型に従って、ある番号の引き出しから必要な数だけ並んだ引き出しが(あるアドレスから必要なサイズだけ連続したメモリが)、その変数が占有して使うものとして確保されます。
プログラマが変数を使う時、それに何番の引き出しが割り当てられているかは、通常は意識する必要はありません。以下の例のように、変数に値を「代入」したり、変数の値を「参照」したりすればよいだけです。何番の引き出しに入れたらいいか、何番の引き出しの中身をみればいいかは、コンピュータが勝手にやってくれるわけです。
<例1−2>
float
x;
i
= 1; /*
iにlの値を代入 */
j
= i + 2; /*
jにiの値足す2を代入 */
x
= (float)i/j; /*
xにiの値割るjの値を代入。(float)を書かないと... */
printf("x
= %f\n", x); /*
xの値を表示 */
[解説] データ型の変換
しかし、「変数とアドレスの関係」を実感しておくことは、配列やポインタなどの使い方を理解するときにとても役立ちます。次の例は、変数iに割り当てられた実際のアドレス(引き出しの番号)を表示するものです。
<例1−3>
#include <stdio.h>
int main(void) {
int
i;
printf("address
of i = %p\n", &i); /* 変数iのアドレスを表示 */
return
0;
}
(実行例)
address of i = 0xbffffaa0
[解説] 16進数表記
「ある変数に&記号をつけるとその変数のアドレスがわかる」、というのがポイントです。上記の実行例では、bffffaa0(16進数表記)という番号の引き出しが変数iのために確保されていることを示しています。ただし、int型の変数は4つの引き出し(4バイトのメモリ)が必要ですので(注:処理系によっては2バイトの場合もある)、実際にはbffffaa0を先頭に、bffffaa1、bffffaa2、bffffaa3の計4つが確保されていることになります。
以下の課題は、いろいろな型の変数を宣言し、それらにどのアドレスのメモリが割り当てられたかを実感してもらうためのものです。printfを使って、見やすく出力するようにして下さい。
【課題1−2】(プログラムと実行結果を提出)
<例1−1>と<例1−3>を参考にして、int、short、long、float、double、charの各データ型の変数を宣言し、それぞれの変数が「どこのアドレスから何バイトのメモリを占めているのか」を表示するプログラムを作成する。
[解説] sizeof演算子
《プログラム例》