勝手に添削


新人研修用に演習問題のネタを漁っていたらヒットしたブログで気になったので勝手に添削してしまう。


まずはコードから。元のコードはだいぶ一般的なコーディングをはずれていたのでK&Rスタイルにして書き直す。

#include<stdio.h>

/* 先頭4要素に2,4,6,8を代入する関数 */
void itoen(int *hot)
{
	int i;

	for (i = 0; i < 4; i++) {
		hot[i] = 2 * (i + 1);
	}
}

int main(void)
{
	int oiotya[7] = {0, 1, 2, 3, 4, 5, 6};
	int i;

	/* 配列初期状態表示 */
	for (i = 0; i < 7; i++) {
		printf("%d ", oiotya[i]);
	}
	printf("\n");

	itoen(oiotya);

	/* 代入後表示 */
	for (i = 0; i < 7; i++) {
		printf("%d ", oiotya[i]);
	}
	printf("\n");

	return 0;
}

課題の意図が全くわかりません。Cでは関数に配列を渡すことはできないんだけど?通常は配列の先頭要素を指すポインタと、配列のサイズを渡す。


配列とポインタの関係性がよくわかっていないようです。

配列をポインタに渡すとき、

hot = &oiotya[0];

とすると

まず、配列をポインタに渡すことはできない。式の中(つまり宣言以外の場所)で配列名を書くと、それは「配列の先頭要素を指すポインタ」として扱われる(いくつか例外あり)。
だけど最後にはhot=oiotya;って書いているね?

配列の1番目を指すから、*(hot+1)は配列の2番目を指すかと思ったがそうはならなかった。

式の中でポインタpと整数iについて以下のように定義する。
 *(p + i) ≡ p[i]
従って*(hot+1)はhot[1]であり、配列の2番目の要素そのものである。(hot + 1)が配列の2番目を指す。

for(i=0;i<7;i++,hot++){
printf("%d ", *hot);
}
と書いたら、ポインタが7番目以降のアドレスを指してしまう。
そうなると配列を指すポインタとならなくなってしまう。

hotの宣言はint *hot;であるから配列を指すことはできない。intを指すことしかできないのである。ついでに言うとポインタは配列の最後の要素の次の要素まで指すことができることが、規格上保証されている。
int oiotya[7];の場合にoiotyaを指すポインタは int (*p)[7];であるが、この課題の場合配列を指すポインタは不要だ。