wrsvrsk さんが書きました: ↑5年前
結局のところa[5]のaには配列aの先頭アドレス、例えば642296が代入されるので
a に、a の先頭アドレスが代入される?
代入演算子 = を使わない限り、代入は実行されません。
ポインタの値(アドレス)は、"%d" ではなく、"%p" で表示しましょう。
コード:
#include <stdio.h>
int main(void)
{
int a[6] = { 1, 2, 3, 4, 5, 6 };
*(a + 3) = 20; // a[3] = 20; と同じ
a[5] = 10; // *(a + 5) = 10; と同じ
for (int i = 0; i < 6; i++)
printf("&a[%d]: %p, a[%d]: %d\n", i, &a[i], i, a[i]);
printf(" a: %p\n", a); // a は 先頭要素へのポインタ。&a[0] と同じ
printf(" &a: %p\n", &a); // &a は 配列全体へのポインタ
printf(" a+1: %p\n", a + 1); // a + 1 は、&a[1]
printf(" &a+1: %p\n", &a + 1); // &a + 1 は、&a[6] の次のアドレス
}
実行結果
コード:
&a[0]: 00D8FA50, a[0]: 1
&a[1]: 00D8FA54, a[1]: 2
&a[2]: 00D8FA58, a[2]: 3
&a[3]: 00D8FA5C, a[3]: 20
&a[4]: 00D8FA60, a[4]: 5
&a[5]: 00D8FA64, a[5]: 10
a: 00D8FA50
&a: 00D8FA50
a+1: 00D8FA54
&a+1: 00D8FA68
int a[6] = { 1, 2, 3, 4, 5, 6 }; の宣言時、
a の値は、{ 1, 2, 3, 4, 5, 6 }。
a の型は、int [6]。すなわち、int の配列(要素数 6)。
しかし、式の中で a を参照するとき、a は次のように変換されます。
a の値は、配列の先頭要素である a[0] のアドレス。
a の型は、「配列の先頭要素である a[0] の型である int」へのポインタ。
a と &a[0] は、値も型も同じです。
式の中で a[ i] は *(a + i) と同じです。
配列 a は、配列の先頭要素へのポインタに変換され、
+i で i個先の要素を参照します。
&a の場合、a は a[0] へのポインタに変換されません。
&a の値は、配列 a 全体のアドレスで、a[0] のアドレスと同じになります。
&a の型は、int * ではなく、int (*)[6] です。
wrsvrsk さんが書きました: ↑5年前
さらに読み進めると2次元配列の全体を渡す時、ポインタとして受けることが出来ないとあります
いいえ、ポインタとして受け取ります。
2次元配列を関数に渡す場合は次のようになります。
コード:
#include <stdio.h>
void func(int (*a)[4]) // int a[][4] または int a[3][4] とも書いても同じ
{
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 4; j++)
printf("%6d", a[i][j]);
putchar('\n');
}
}
int main(void)
{
int a[3][4] = {
{ 100, 101, 102, 103 },
{ 110, 111, 112, 113 },
{ 120, 121, 122, 123 },
};
func(a);
}
宣言時の a の値は、12個の整数。a の型は、int [3][4]。
a は、要素数 3 の配列で、要素の型は int [4]。
func(a); の実行時、配列 a は、先頭要素 a[0] へのポインタに変換されます。
a[0] の型は int [4] なので、
a の型は a[0]全体へのポインタとなり、それは int (*)[4]。
a の値は、a[0] のアドレスです。