我对以下代码的问题:
int main() {
int i = 0;
int array[2][2] = { {1,2} , {3,4}};
for(int j = 0; j<2; j++) {
for(int k = 0; k < 2;k++) {
printf("%d", *(*(*(array+i)+j)+k));
}
printf("n");
}
}
为什么这不起作用?
我的想法:我有 i^th 2 d 数组(它是 0,因为我只有一个 2d 数组),然后是 i^th 2d 数组的 j^th 1d 数组,因此 i^th 2d 数组的 j^th 1d 数组的第 k^th 元素。
表达式中使用的数组(极少数例外)将隐式转换为指向其第一个元素的指针。
来自 C 标准(6.3.2.1 左值、数组和函数指示符)
3 除非是 sizeof 运算符或一元运算符的操作数和 运算符,或者 是用于初始化数组的字符串文本,一个 类型为"类型数组"的表达式将转换为 类型为"指向类型的指针"的表达式,该表达式指向初始 元素,并且不是左值。如果数组对象 具有寄存器存储类,行为未定义。
您有以下二维数组
int array[2][2] = { {1,2} , {3,4}};
数组的元素又是int[2]
类型的一维数组。
因此,调用printf
时使用的数组指示符被转换为指向其类型为int( * )[2]
的第一个元素(行)的指针。
要使用指针算法获取指向数组第 i 行的指针,您应该编写
array + i
如前所述,表达式的类型为int ( * )[2]
。
取消引用指针表达式
*( array + i )
您将获得其第 i 行,该行是int[2]
类型的数组,该数组又转换为类型int *
指向其第一个元素的指针。
要使用指针算法获取指向行的第 j 个元素的指针,您应该编写
*( array + i ) + j
表达式的类型为int *
。
因此,要获取指针表达式指向的元素,您需要取消引用它,例如
*( *( array + i ) + j )
因此,嵌套的 for 循环将如下所示
for( int i = 0; i < 2; i++)
{
for ( int j = 0; j < 2; j++ )
{
printf("%d", *( *( array + i )+j ) );
}
printf("n");
}
*(array + i)
为您提供i
的第1D数组,而不是第i
个 2D 数组。
表达式*(array + i)
的类型为int [2]
,衰减为int *
。 因此,表达式*(*(array + i) + j)
的类型为int
,不能进一步取消引用。 请记住,如果
a[i] == *(a + i)
然后
a[i][j] == *(a[i] + j) == *(*(a + i) + j)
和
a[i][j][k] ==
*(a[i][j] + k) ==
*(*(a[i] + j) + k) ==
*(*(*(a + i) + j) + k)
等。
为了您和其他人的理智,只需使用数组下标表示法即可。 像这样的练习有助于理解数组下标在 C 中的实际工作原理,但下标表示法更清晰,你不太可能犯错误。