配列型は,要素数(サイズ)と要素型の2つで特徴化されるデータであることを 9.1 で見ました。この特徴は,メモリ上では,次のような意味を持ちます。すなわち,「要素型をもつオブジェクトが連続してメモリに記憶されるデータ」という意味です。更に,これに次の文法が加わります。
T 型の配列」型をもつ式は,その配列の第1要素を指し示すT へのポインタ型に変換される。但し,それは左辺値ではない。sizeof 演算子や _Alignof 演算子,& 演算子(後出 10.7)や初期化の場合を除きます。また,register記憶域クラスを持つ場合,動作は未定義になります。
ここで「第1要素を指し示すポインタ(pointer that points to the initial element)」とは,例えば,宣言
char str[8] = "ABCDEFG"
の場合,str 自体が,配列の第1要素 'A' を記憶しているアドレスを指し示す char へのポインタになっているという意味です。
/* Example 10.1 */
#include <stdio.h>
int main(void)
{
       char str[] = "ABCDEFG";
       printf("str[0] = '%c' [%p]\n", str[0], str);
       return 0;
}
printf関数内の変換指定子 %p はポインタの(処理系依存の)出力です。ここでは,上の文法に従い,str が第1要素を指し示す char へのポインタになっているため,配列の第1要素のアドレスが出力されます。
実行結果です。
str[0] = 'A' [0xbffffa18]
第1要素のアドレスは 0xbffffa18 です。(十六進法の読み方は整数定数を参照。)char型は1バイトなので,次のようにメモリに値が記憶されていることになります。
+------------+------------+------------+------------+ | 0xbffffa18 | 0xbffffa19 | 0xbffffa1a | 0xbffffa1b | アドレス +------------+------------+------------+------------+ | 'A' | 'B' | 'C' | 'D' | 値 +------------+------------+------------+------------+ +------------+------------+------------+------------+ | 0xbffffa1c | 0xbffffa1d | 0xbffffa1e | 0xbffffa1f | アドレス +------------+------------+------------+------------+ | 'E' | 'F' | 'G' | '\0' | 値 +------------+------------+------------+------------+
+------------+------------+------------+------------+ | 0xbffffa18 | 0xbffffa19 | 0xbffffa1a | 0xbffffa1b | アドレス +------------+------------+------------+------------+ | 0x41 | 0x42 | 0x43 | 0x44 | 値 +------------+------------+------------+------------+ +------------+------------+------------+------------+ | 0xbffffa1c | 0xbffffa1d | 0xbffffa1e | 0xbffffa1f | アドレス +------------+------------+------------+------------+ | 0x45 | 0x46 | 0x47 | 0x00 | 値 +------------+------------+------------+------------+
配列は要素型(この場合 char型)のオブジェクトが連続して記憶されるデータです。
/* Example 10.2 */
#include <stdio.h>
int main(void)
{
       unsigned int m[5] = {3, 7, 10};
       printf("m[0] = %d [%p]\n", m[0], m);
       return 0;
}
実行結果です。
m[0] = 3 [0xbffffa78]
奥山研究室では sizeof(int) = 4 ですので,次のように値がメモリに記憶されていることになります。
+------------+------------+------------+------------+ | 0xbffffa78 | 0xbffffa79 | 0xbffffa7a | 0xbffffa7b | アドレス +------------+------------+------------+------------+ | 0x00 | 0x00 | 0x00 | 0x03 | 値 +------------+------------+------------+------------+ +------------+------------+------------+------------+ | 0xbffffa7c | 0xbffffa7d | 0xbffffa7e | 0xbffffa7f | アドレス +------------+------------+------------+------------+ | 0x00 | 0x00 | 0x00 | 0x07 | 値 +------------+------------+------------+------------+ +------------+------------+------------+------------+ | 0xbffffa80 | 0xbffffa81 | 0xbffffa82 | 0xbffffa83 | アドレス +------------+------------+------------+------------+ | 0x00 | 0x00 | 0x00 | 0x0a | 値 +------------+------------+------------+------------+ +------------+------------+------------+------------+ | 0xbffffa84 | 0xbffffa85 | 0xbffffa86 | 0xbffffa87 | アドレス +------------+------------+------------+------------+ | 0x00 | 0x00 | 0x00 | 0x00 | 値 +------------+------------+------------+------------+ +------------+------------+------------+------------+ | 0xbffffa88 | 0xbffffa89 | 0xbffffa8a | 0xbffffa8b | アドレス +------------+------------+------------+------------+ | 0x00 | 0x00 | 0x00 | 0x00 | 値 +------------+------------+------------+------------+
配列は要素型(この場合 int型)のオブジェクトが連続して記憶されるデータです。