配列に文字列を格納した場合の配列や配列変数のアドレスはどうなっているのでしょうか?調べてみます。

アレサ 「ソーラーさん!(^^)! 」


ソーラー「はい(^▽^;)」


アレサ 「先のエピソードでは


int型の配列変数


hairetu[0]

hairetu[1]

hairetu[2]


に整数値を格納したときの


int型の配列変数の


アドレスを配列のポインタ変数を使って調べることができましたの。」


ソーラー「はい(#^.^#)」


アレサ 「今度はhairetuのchar型の配列宣言をおこない


作製された配列hairetuに文字列データを格納してみます


文字列データが"neko"なら


文字列データは


char型の配列変数


hairetu[0]

hairetu[1]

hairetu[2]

hairetu[3]

hairetu[4]



hairetu[0]='n';

hairetu[1]='e';

hairetu[2]='k';

hairetu[3]='o';

hairetu[4]='\0';


と8ビットずつ格納されていくのでした


(文字データ

'n'

'e'

'k'

'o'

'\0'

は8ビットのデータ量を持っているのでした)


そのときの


char型の配列変数


hairetu[0]

hairetu[1]

hairetu[2]

hairetu[3]

hairetu[4]



アドレスを配列のポインタ変数を使って調べてみませんか。」


ソーラー「は、はい、がっつり邁進させていただきます。」


アレサ 「さあ、いきますよ(*´▽`*)ソーラーさん」


ソーラー「わおっ最高だね😊」


アレサ 「それでは


まず配列に文字列データを格納するので


char型の配列宣言をおこないます。


そうして作製された配列に


文字列データ"neko"を格納してみます。


char hairetu[]="neko";


あるいは


char hairetu[5];


hairetu[0]='n';

hairetu[1]='e';

hairetu[2]='k';

hairetu[3]='o';

hairetu[4]='\0';


と命令文を記述すればよかったのですね。


このように


配列hairetuに文字列データ"neko"を格納した時点で


文字データ'n'を格納した配列変数

hairetu[0]のアドレスを格納しているポインタ変数hairetu


文字データ'e'を格納した配列変数

hairetu[1]のアドレスを格納しているポインタ変数hairetu+1


文字データ'k'を格納した配列変数

hairetu[2]のアドレスを格納しているポインタ変数hairetu+2


文字データ'o'を格納した配列変数

hairetu[3]のアドレスを格納しているポインタ変数hairetu+3


文字データ\0を格納した配列変数

hairetu[4]のアドレスを格納しているポインタ変数hairetu+4


が自動的に生成されています。


これらのポインタ変数

hairetu

hairetu+1

hairetu+2

hairetu+3

hairetu+4

を使って

配列変数

hairetu[0]

hairetu[1]

hairetu[2]

hairetu[3]

hairetu[4]


のアドレスをもとめてみますよ。」


ソーラー「は~い」


アレサ「それでは

配列変数

hairetu[0]

hairetu[1]

hairetu[2]

hairetu[3]

hairetu[4]


のアドレスをもとめるプログラムを構成してみます。


#include <stdio.h>


int main(void){


char hairetu[5];

hairetu[0]='n';

hairetu[1]='e';

hairetu[2]='k';

hairetu[3]='o';

hairetu[4]='\0';


printf("%p\n",hairetu);

/*hairetu[0]のアドレスを表示する*/


printf("%p\n",hairetu+1);

/*hairetu[1]のアドレスを表示する*/


printf("%p\n",hairetu+2);

/*hairetu[2]のアドレスを表示する*/


printf("%p\n",hairetu+3);

/*hairetu[3]のアドレスを表示する*/


printf("%p\n",hairetu+4);

/*hairetu[4]のアドレスを表示する*/


return 0;

}


(EAZY IDECの場合)


コンパイル結果


0019FF53

0019FF54

0019FF55

0019FF56

0019FF57


(Visual Studioの場合)


007CFD20

007CFD21

007CFD22

007CFD23

007CFD24


ソーラー「おおうっ


綺麗に16進数が1ずつ値を大きくしながら順番にならんでる。


なんと・・・


さきほど数値を


int型の配列変数

hairetu[0]

hairetu[1]

hairetu[2]


に格納したときは


int型の配列変数

hairetu[0]

hairetu[1]

hairetu[2]

のアドレス


&hairetu[0]

&hairetu[1]

&hairetu[2]

0019FF4C

0019FF50

0019FF54


のように4つの数値おきに表示されていたよね。



int型の配列変数に


数値が格納されるとき


その数値は4バイトのメモリにわたって格納されます


つまり

int型の配列変数は


4バイトのデータ格納容量をもつんだったね。


その4バイトの中の1バイトごとにアドレスはつけられているので


int型の配列変数

hairetu[0]

なら

0019FF4C

0019FF4D

0019FF4E

0019FF4F


の4つのアドレスをもつというわけです。


このとき


int型の配列変数

hairetu[0]

のアドレス


&hairetu[0]


0019FF4C

0019FF4D

0019FF4E

0019FF4F

の先頭の

0019FF4Cで表されるんでしたね。


同様に


int型の配列変数

hairetu[1]

のアドレス


&hairetu[1]


0019FF50

0019FF51

0019FF52

0019FF53

の先頭の

0019FF50で表されるんでしたね。


同様に

int型の配列変数

hairetu[2]

のアドレス


&hairetu[2]


0019FF54

0019FF55

0019FF56

0019FF57

の先頭の

0019FF54で表されるんでしたね。


そのため

int型の配列変数

hairetu[0]

hairetu[1]

hairetu[2]


のアドレスをprintf出力表示すると


0019FF4C

0019FF50

0019FF54

のように


4つとびで


コンパイル結果に表示されていました。


それに対し


文字データは


1バイトのデータ格納容量を持つ


char型の配列変数に格納されています


メモリには1バイトごとにアドレスが割り振られているので


1バイトのデータ格納容量を持つchar型の配列変数は


1つのアドレスをもっているわけです。


ですから


printf("%p\n",hairetu);

/*hairetu[0]のアドレスを表示する*/


printf("%p\n",hairetu+1);

/*hairetu[1]のアドレスを表示する*/


printf("%p\n",hairetu+2);

/*hairetu[2]のアドレスを表示する*/


printf("%p\n",hairetu+3);

/*hairetu[3]のアドレスを表示する*/


printf("%p\n",hairetu+4);

/*hairetu[4]のアドレスを表示する*/


が実行されると


コンパイル結果


0019FF53

0019FF54

0019FF55

0019FF56

0019FF57


と表示されたことからも分かるように


文字データ'n'は0019FF53のアドレスをもつchar型の配列変数hairetu[0]に

文字データ'e'は0019FF54のアドレスをもつchar型の配列変数hairetu[1]に

文字データ'k'は0019FF55のアドレスをもつchar型の配列変数hairetu[2]に

文字データ'o'は0019FF56のアドレスをもつchar型の配列変数hairetu[3]に

ナル文字\0は0019FF57のアドレスをもつchar型の配列変数hairetu[4]に


1つずつアドレス番号を増やしながら格納されています。」


アレサ「ここで配列hairetu内には


0019FF53

0019FF54

0019FF55

0019FF56

0019FF57


のアドレスを持つ5つの配列変数がつくられています。


そしてhairetu[0]のアドレスをもとめるために


printf("%p\n",hairetu);


を実行すれば


0019FF53と表示されますが


0019FF53は


配列変数


hairetu[0]のアドレスを表しているだけでなく


この配列hairetu内に文字を格納し始める最初のお部屋の


アドレスとなっています。


つまり0019FF53は配列hairetu自体を代表するアドレス


となっているのですね」


ソーラー「やったね、アレサ、これもなんか簡単だったね。(*'▽')」