ポインタと配列の表記上の可換性は、配列を受け取る関数で利用されている。
今回は、「受け取った配列vの先頭n個の要素にvalを代入する関数」をご紹介しよう。
「配列の受渡しをするプログラム」である。
なお、本プログラムは、Windows 11 Home(23H2)上で、 Visual Studio Code(1.90.0)を使用して作成し、gcc (Ubuntu 9.4.0-1ubuntu1~20.04.2) 9.4.0でコンパイルしている。
配列の受渡しをするプログラム
//配列の受渡しをするプログラム
#include <stdio.h>
void ary_set(int v[],int n,int val)
{
for (int i = 0; i < n; i++)
v[i] = val;
}
int main()
{
int a[] = {1,2,3,4,5};
puts("配列の値を表示します。");
for (int i = 0; i < 5; i++)
printf("a[%d] = %d\n",i,a[i]);
ary_set(a,5,99);
puts("配列の先頭5個の要素に99を代入しました。");
for (int i = 0; i < 5; i++)
printf("a[%d] = %d\n",i,a[i]);
return 0;
}
実行結果
配列の値を表示します。
a[0] = 1
a[1] = 2
a[2] = 3
a[3] = 4
a[4] = 5
配列の先頭5個の要素に99を代入しました。
a[0] = 99
a[1] = 99
a[2] = 99
a[3] = 99
a[4] = 99
まずは、関数ary_setの宣言の形式に着目する。
void ary_set(unt v[],・・・)
{
}
仮引数vは、配列ではなく、単なるポインタである。
たとえ、要素数を指定しても無視される。
次に、関数ary_setを呼び出す箇所に着目する。
ary_set(a,5,99);
単独で現れた配列名は、その配列の先頭ポインタなので、第1引数aは、&a[ 0 ]のことである。
関数ary_setが呼び出される際に、int *型の仮引数vは、実引数aすなわち&a[ 0 ]で初期化される。
ポインタvが配列aの先頭要素a[ 0 ]を指すので、ポインタと配列の表記上の可換性によって、ポインタvは、あたかも配列aそのものであるかのように振る舞う。
関数間での配列の受け渡しは、先頭要素へのポインタとして行う。
呼び出された関数では、受け取ったポインタが、呼び出し側が渡した配列そのものであるかのように振る舞う。
やり取りするのが、配列そのものではなく、単なるポインタであるため、要素数は別の引数として受け渡しする必要がある。
これで、関数間で、引数として配列をやり取りする際は、配列と要素数を別々に受け渡す意味がはっきりした。
(参考) 新・明解C言語 入門編 第2版 柴田 望洋 (著)SBクリエイティブ
コメント