例えば、Cのプログラムで
int a[10];
と書いた場合は、
実行した時に何番地になるか判らないけれど
とりあえず「a」という目印を付けた番地からint型の数値10個分のデータを記憶する領域を連続して確保する、いう意味になる。
配列aの1つめの領域に100を記憶させたい時は、a[0]=100;
配列aの2つめの領域に200を記憶させたい時は、a[1]=200;
の様に書く。カッコの中は0から9であって、COBOLの様に1から10では無い事に注意。
※何故かというと、その方がアドレス計算が楽(a番地+添字×データ型の大きさ)だから。
じゃあ、aの場所(番地)って何処よ、という場合は、単にaと書く。&aとは書かない。
じゃあ、例えばa[5]って何処よ、という場合は、&a[5]と書く。
a番地は配列aの1つめの領域の番地と当然同じなので、aは、&a[0]と同じ意味を持つ。
1次元の数値の配列の例。
int a[5] = {1,3,5,7,9};
(注)intの大きさを2語とする a番地 &a[0]番地 &a[5]番地 | | -+--+--+--+--+--+--+--+--+--+--+--+--+--+--+- | 1 | 3 | 5 | 7 | 9 | | | | | -+--+--+--+--+--+--+--+--+--+--+--+--+--+--+-
2次元の数値の配列の例。
int a[3][2] = {{1,3},{5,7},{9,11}};
(注)intの大きさを2語とする a番地 &a[0][0]番地 &a[1][0]番地 | | -+---+---+---+---+---+---+---+---+---+---+---+---+- | 1 | 3 | 5 | 7 | 9 | 11 | -+---+---+---+---+---+---+---+---+---+---+---+---+-
コンピュータ内部では、文字列は文字の配列として扱うことが出来る。
C言語で、
char c[10];
と書いた場合は、
実行した時に何番地になるか判らないけれど
とりあえず「c」という目印を付けた番地から10文字分を記憶する領域を連続して確保する、いう意味になる。
この10文字の中には、文字列の終わりの目印、’¥0’も含まれる。
char c[10] = "Wednesday";
c番地 &c[0]番地 &c[7]番地 | | +-+-+-+-+-+-+-+-+-+--+-+-+-+-+-+-+-+-+-+-+ |W|e|d|n|e|s|d|a|y|\0| | | | | | | | | | | +-+-+-+-+-+-+-+-+-+--+-+-+-+-+-+-+-+-+-+-+
実は、配列とポインタは表裏一体で、
文字列を配列と見るかどうかは人間の自由なので、以下の様にも書ける。
こちらの方が普通かも。
char *c = "Wednesday";
x番地 | +-+-+-+-+-+-+-+-+-+--+-+-+-+-+-+-+-+-+-+-+ |W|e|d|n|e|s|d|a|y|\0| | | | | | | | | | | +-+-+-+-+-+-+-+-+-+--+-+-+-+-+-+-+-+-+-+-+ | V +-+-+-+-+- | x | ←ポインタ変数 +-+-+-+-+- | c番地
文字列の配列は、文字型データの二次元配列として扱うことが出来る。
C言語で、
char c[7][10];
と書いた場合は、
実行した時に何番地になるか判らないけれど
とりあえず「c」という目印を付けた番地から、
1つが10文字まで(終わりの目印、’¥0’の分も含まれる)の文字列を、7個記憶する領域を連続して確保する、いう意味になる。
char c[7][10] = {"Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"};
c番地 &c[0][0]番地 &c[1][0]番地 | | +-+-+-+-+-+-+--+-+-+-+-+-+-+-+-+-+--+-+-+-+ |S|u|n|d|a|y|\0| | | |M|o|n|d|a|y|\0| | | | +-+-+-+-+-+-+--+-+-+-+-+-+-+-+-+-+--+-+-+-+
ポインタ変数の配列ということも出来る。
文字数の違う文字列の配列や、メモリ上の彼方此方に散らかったデータをまとめたり、
一連のデータを一度に並べ替えたり、
といった処理をするのに便利である。
前述した様に、Cプログラムの場合、配列とポインタは表裏一体なので、次の様に書いて初期化すると、
pは7つの文字列の各々の先頭の番地を記憶しているポインタの配列とみなすことが出来る。
char *p[7] = {"Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"};
x番地 y番地 z番地 | | | +-+-+-+-+-+-+--+-+-+-+-+-+-+--+-+-+-+-+-+-+ |S|u|n|d|a|y|\0|M|o|n|d|a|y|\0|T|u|e|s|d|a| +-+-+-+-+-+-+--+-+-+-+-+-+-+--+-+-+-+-+-+-+ | __| _____| | | | V V V +--+--+--+--+--+--+--+--+--+--+--+--+- | x | y | z | ←ポインタ変数の配列 +--+--+--+--+--+--+--+--+--+--+--+--+- | | | p番地 | | &p[0]番地 &p[1]番地 &p[2]番地
かなり乱暴な数値の配列のプログラム。
3人の社員に、10個のデータの合計を報告させている。
#include <stdio.h>
int syain_x(int data[10]); int syain_y(int *data); int syain_z(int *ptr); void main(void){ int a[10]={1,2,4,8,16,32,64,128,256,512}; /* 10個のデータを初期化 */ int x,y,z; x=syain_x(a); printf("x = %d¥n",x); y=syain_y(a); printf("y = %d¥n",y); z=syain_z(a); printf("z = %d¥n",z); } /* a番地から10個分のデータのコピーを配列dataに受け取る(値渡し) */ int syain_x(int data[10]){ int i,sum=0; for(i=0;i<10;++i){ sum+=data[i]; } return sum; } /* a番地を受け取り、配列dataの先頭番地とみなす(参照渡し) */ int syain_y(int *data){ int i,sum=0; for(i=0;i<10;++i){ sum+=data[i]; } return sum; } /* a番地を受け取る(参照渡し) */ int syain_z(int *ptr){ int i,sum=0; for(i=0;i<10;++i){ sum+=*ptr; if(i<9) ++ptr; /* int型の分だけ番地を加算し次のデータへ */ } return sum; }
C言語の配列って、最初に配列として定義しなくとも、 配列とみなして処理出来るのが、便利というか、いい加減と言うか...。