以前習ったように(文字列を含む)配列の変数名を単独で(添え字を付けずに)使うと、配列の先頭のアドレスを意味する。
#include <stdio.h>
int main() {
int numbers[] = {5,10,15,20};
printf("&numbers[0]: %p\n", &numbers[0]);
printf(" numbers: %p\n", numbers);
}
実行結果の例:
&numbers[0]: 0x7ffd2a2f2370
numbers: 0x7ffd2a2f2370
ようするに、関数名(配列名, ...) のように配列を引数として関数に渡す場合は、配列の中身がコピーされるのではなく常にアドレスを用いた参照渡しになる(関数中の配列名が違うだけで、元の配列と同じデータを参照している)。したがって、関数の中で配列の中身を変更すれば、元の(呼び出し側)の配列にもその変化が反映される。
例:
#include <stdio.h>
void update_arr(int arr[], int id, int val) {
arr[id] = val;
}
int main() {
int numbers[4] = {0,10,20,30};
printf("呼び出し前の numbers[0] の値: %d\n", numbers[0]);
update_arr(numbers, 0, 5);
printf("呼び出し後の numbers[0] の値: %d\n", numbers[0]);
}
実行結果:
呼び出し前の numbers[0] の値: 0
呼び出し後の numbers[0] の値: 5
文字列を使った例:
#include <stdio.h>
#include <string.h>
void query(char msg[], char buf[], int len) {
printf("%s", msg); /* 引数として受け取ったメッセージを表示 */
fgets(buf, len, stdin); /* 標準入力からの読み込み */
if ('\n' == buf[strlen(buf)-1]) {
buf[strlen(buf)-1] = '\0'; /* 改行を削除 */
}
}
int main() {
char name[100];
query("あなたの名前は?: ", name, sizeof name);
printf("あなたは %s ですね\n", name);
}
実行結果の例:
あなたの名前は?: Tarou
あなたは Tarou ですね
配列を受ける関数の仮引数の書き方は2つある(意味は同じ):
型 配列名[]
(例:void my_func(int arr[]))
または
型 *配列名
(例:void my_func(int *arr))