繁体   English   中英

二维数组和指针

[英]2-D Arrays and pointers

有人告诉我编译器在必要时将数组名称转换为指向数组第1个元素的指针。 所以我用这个规则解决了很多问题,直到我看到这一切都很好。

int main()
{
    int a[2][3] = {{1,2,3}, {5,6,7}}, (*p)[3];
    p = a[0];
    for(int i = 0; i < 3; i++)
        printf("%d", (*p)[i]);
}

带代码块的输出为123

我试图解决它:

(*p)[i])应该与*((*p)+i) ....(1)相同

如规则所说, “数组名将转换为指向数组第1个元素的指针”。 我将第二条指令p=a[0]p=&a[0][0] (因为a[0]是其第一元素为a[0][0]的子数组名称)。 因此(*p)可以写成(*(&a[0][0])) a[0][0] 因此eqn(1)变为

*(a[0][0]+i). 

这就是我被困住的地方。 a[0][0]+i是一个元素,而不是地址。 因此,对它应用*运算符是无效的。 但是我也替换了语句p=a[0]; p=&a[0][0]; 在原始代码中,答案保持不变。 我也用p=&a[0];代替了它p=&a[0]; 答案仍然保持不变。 现在我超级困惑。

2D数组是1D数组的数组

在一维阵列中

a[0] => *(a)     -> first element of array
a[1] => *(a + 1) -> second element of array

在二维数组中

a => the adress of first array
a[0] => *(a)        -> the first array 
a[0][0] => *(*(a))     -> the first element of first array
a[0][1] => *(*(a) + 1) -> second element of first array
a[1][1] => *(*(a + 1) + 1) -> second element of second array

这行是不正确的:

p = a[0];

p的类型是3 int数组的指针。 a[0]的类型是int指针。 您的编译器应该为此警告您。 如果没有,请启用任何必需的开关以打开大多数或所有编译器警告。 编译器发出警告时,请不要忽略它-在继续之前,请确保您理解了为什么编译器发出警告。 启用将警告转换为错误的编译器功能将是一个好主意。

正确的陈述是p = a; p = &a[0]; 但是,让我们检查一下程序中发生了什么。 在表达式a[0]

  • 根据下标运算符的定义, a[0]等效于*(a+0) (从技术上来说是(*((a)+(0))) ,但在这种情况下我们不需要多余的括号)。
  • a是一个数组,因此将其转换为指向其第一个元素的指针。 因此a被转换为指向a[0]的指针。 因此,表达式现在为*(&a[0] + 0)
  • 0加到&a[0]不会更改它,因此结果是&a[0] ,表达式现在是*&a[0]
  • *应用于指针会产生所指向的内容,因此表达式变为a[0]
  • a[0]是3 int的数组。 由于它是一个数组,因此将其转换为指向其第一个元素的指针。 因此结果实际上是&a[0][0]

观察到&a[0][0]是一个指向int的指针,如我上面所写。 所以现在我们看到p = a[0]; 右侧有一个指向int的指针,而左侧有一个指向3 int数组的指针。 这违反了C标准中的约束,并且编译器必须为其发出诊断消息。

警告之后,编译器可能所做的就是转换指针,导致p设置为指向a[0]

我将第二条指令p=a[0]p=&a[0][0]因为a[0]是其第一元素为a[0][0]的子数组名称 )。 因此(*p)可以写成(*(&a[0][0]))

这是个错误。 尽管您执行了赋值p = a[0] ,但这并未将&a[0][0]赋给p ,并且p行为并不像是&a[0][0] 赋值 &a[0][0]转换为p的类型。 p保持声明的类型,它是一个指向3 int数组的指针。 实际上, p&a[0]的值结束。

现在我们可以评估(*p)[i]

  • p&a[0] ,因此表达式变为(*&a[0])[i])
  • *&a[0]a[0] ,因此表达式变为a[0][i]
  • 从那里,我们可以用通常的表达式求值进行,很明显其结果是元件i的元素0的a

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM