C 数组指针表示法



我对以下代码的问题:

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 中的实际工作原理,但下标表示法更清晰,你不太可能犯错误。

最新更新