有很多像这样的代码:
#include <stdio.h>
int main(void)
{
int a[2][2] = {{0, 1}, {2, -1}};
int *p = &a[0][0];
while (*p != -1) {
printf("%d\n", *p);
p++;
}
return 0;
}
但是根据这个答案,行为是未定义的。
N1570. 6.5.6 p8:
当将整数类型的表达式添加到指针或从指针中减去时,结果具有指针操作数的类型。如果指针操作数指向数组对象的元素,并且该数组足够大,则结果指向相对于原始元素偏移量的元素,使得所得到的和原始数组元素下标之间的差等于该整数表达式。换句话说,如果表达式P指向数组对象的第i个元素,则表达式(P)+N(等效于N +(P))和(P)-N(其中N的值为n)分别指向数组对象的第i+n个和第i−n个元素(如果它们存在)。此外,如果表达式P指向数组对象的最后一个元素,则表达式(P)+1指向数组对象的最后一个元素之后的位置,如果表达式Q指向数组对象的最后一个元素之后的位置,表达式(Q)-1指向数组对象的最后一个元素。如果指针操作数和结果都指向同一数组对象的元素或超出数组对象的最后一个元素,则评估不得产生溢出;否则,行为是未定义的。如果结果指向数组对象的最后一个元素之后的位置,则不能将其用作评估的一元*运算符的操作数。
sizeof
规则防止在不同的数组维度之间有任何填充。我想知道是否有任何符合标准的系统会破坏上述代码。 - user694733