我有以下代码:
int ia[3][4] = { //
{0, 1, 2, 3}, //
{4, 5, 6, 7}, //
{8, 9, 10, 11} //
};
int (*p4)[4] = ia;
cout << "(*(p4 + 0))[3] = " << (*(p4 + 0))[3] << endl;
cout << "*(p4 + 0)[3] = " << *(p4 + 0)[3] << endl;
得到以下输出:
(*(p4 + 0))[3] = 3
*(p4 + 0)[3] = 1
我不明白最后一个如何到达1。 任何帮助都会很棒。 感谢。
答案 0 :(得分:5)
我不明白最后一个如何到达1。
未定义的行为让你在那里。
由于运算符优先级(数组索引运算符绑定比指针解引用运算符更紧),
*(p4 + 0)[3]
与以下相同:
*((p4 + 0)[3])
,与以下内容相同:
*(p4[3])
,与以下内容相同:
p4[3][0]
。
对于你的阵列。第一维的有效索引是:0
,1
和2
。使用索引值3
访问数组会访问超出有效范围的内存,从而导致未定义的行为。
答案 1 :(得分:1)
Postfix表达式的优先级高于一元表达式。
所以这个表达
*(p4 + 0)[3]
等同于表达式
*( (p4 + 0)[3] )
因为它被看作与
不一样( *(p4 + 0) )[3]
此表达式*( (p4 + 0)[3] )
可以像*p4[3]
一样编写,相当于*ia[3]
,并且由于优先级被视为
*( ia[3] )
或喜欢
ia[3][0]
数组ia
的第一个维度的索引的有效范围是[0, 2]
,因为数组声明为
int ia[3][4] = { /*...*/ };
^^^
因此表达式ia[3]
尝试访问数组之外的内存。因此,代码段具有未定义的行为。
简而言之,你应该明白这些表达方式
(*(p4 + 0))[3]
*(p4 + 0)[3]
反过来相当于以下一对表达式
ia[0][3]
io[3][0]
由于操作的优先级,不等同。