C言語応用 ポインタと配列 ポインタと配列 次のように宣言された、大きさ10 である int 型の配列 x と、int への ポインタ p を考える。 int x[10]; int *p ここで x[0] x[1] : : x[9] p = &x[0]; とする。p は x[0] を指しますから、 *p は x[0] のエイリアスとなります。 p *p ポインタと配列 ポインタ ptr に、整数 i を加えて減じたりした式も ポインタとなります。 ptr+i は、ptr が指すオブジェクトの i 個 後ろの要素を指すポインタとなる。 ptr-i は、ptr が指すオブジェクトの i 個 前の要素を指すポインタとなる。 x[0] *p x[1] *(p+1) x[9] ここで考えている例では、たとえば p+1 は x[1] を、p+5 は x[5] を指す ことになる。 p *(p+9) ポインタと配列 ptr がポインタで、i が整数であるとき、次のような 規則が成り立つ。 x[0] *p p[0] x[1] *(p+1) p[1] x[9] *(p+9) p[9] p *(ptr+i) は ptr[i] とも表記できる。 配列の名前 配列に関しても、重要な規則がある。 プログラム中に[ ]を伴わずに単独で現れた配列 名は、その配列の先頭要素へのポインタとみな される。 たとえば、x が配列であるとき、x は、先頭要素 x[0] へのポインタ、すなわち &x[0] を意味する。 配列の名前 補足 原則として、プログラム中に[ ]を伴わずに単独で現れた配列 名は、その配列の先頭要素へのポインタとなるが、若干の例 外がある。 (1) sizeof 演算子のオペランドであるとき sizeof 演算子は、オペランドとして配列が与えられた時は、その 配列の大きさを生成する。たとえば、sizeof(int) が2であるとき、 int a[10]; printf(“%d\n”,sizeof(a)); は、20を出力します。 (2) &演算子のオペランドであるとき 配列名に&演算子が適用されると、その配列全体へのポイン タを生成します(配列の先頭要素へのポインタではない)。 引数としての配列 list6-5.c のプログラムでの、search 関数について search 関数を呼び出す所に着目すると、 no = search(atensu,AMAX,50); となっており、最初の引数 atensu は、配列 atensu の先頭要素 である atensu[0] へのポインタである。したがって配列の先頭 要素へのポインタ &atensu[0] が渡されている。 呼び出される側の search 関数は、引数 mark にそのポインタ を受け取ります。実は、search 関数の頭部は int search(int *mark, int max, int ten) と記述できます。int mark[] と宣言しても int *mark と宣言しても、 全く同じことになるのです。 引数としての配列 重要 関数間での配列の受け渡しは、先頭要素へのポ インタという形で行う。受け取る側の関数は、その ポインタに対して[ ]演算子を適用することによって、 あたかも配列のように扱うことができる。 演習 2つの int 型の配列 a,b と、その大きさを受け取り、 b の全要素を、aの各要素にコピーする関数 void icopy(int *a,int *b, int n){・・・} を作成せよ。 2つの int 型の配列 a,b と、その大きさを受け取り、 全要素を入れ換える関数 void iswap(int *a,int *b, int n){・・・} を作成せよ。
© Copyright 2024 ExpyDoc