#include <stdio.h>
void main() {
int a[4][3] = {
{ 3, 5, 7 },
{ 2, 4, 67 },
{ 21, 8, 9 },
{ 2, 45, 6 }
};
printf("%u ", *(&a[0]+1));
}
表达式(&a[0]+1
)给出&a[1]
,输出应为2
,但是上述代码的输出为&a[1]
,为什么?这似乎很愚蠢,但请帮助我。
答案 0 :(得分:5)
您注意到&a[0]+1
是&a[1]
。 a[1]
是3 int
的数组,因此&a[1]
是3 int
的数组的地址。
这意味着*&a[1]
是3 int
的数组。在C语言中,数组会自动转换为其第一个元素的地址(除非它是sizeof
,一元&
或_Alignof
的操作数,或者是用于初始化的字符串文字)数组)。因此*&a[1]
自动成为&a[1][0]
。
由于这是一个指针,因此不应使用%u
打印。正确的打印方法是:
printf("%p\n", (void *) *(&a[0]+1));
但是,假设您确实使用过%u
,似乎发生了什么事,该程序打印了重新解释为unsigned int
的指针的值。这不是您应该依靠的行为。
答案 1 :(得分:3)
表达式
(&a[0]+1)
给出&a[1]
是的
,输出应为2
否。
但是以上代码的输出是
&a[1]
为什么?
您要问的是
的作用printf("%u ",*(&a[0]+1));
。我们已经确定(&a[0]+1)
等效于&a[1]
。因此,*(&a[0]+1)
等效于*(&a[1])
,而后者依次等效于a[1]
。尽管a[1]
是第一个数组元素的值,2
的值是一个数组,而不是2
。
您的上下文不是数组值无法衰减到指针的少数情况,因此整个函数调用实际上等效于
printf("%u ", &a[1][0]);
但是,此时我们遇到了障碍。 %u
伪指令必须与(提升的)类型unsigned int
的实参相对应,而实际实参则具有指针类型。这种不匹配导致不确定的行为。看起来是合理的,但绝不能保证,这表明您在打印对应于部分或全部指针位模式的十进制整数。
如果要打印a[1]
的第零个元素,则最简单地将其写为a[1][0]
,但也可以将其写为*a[1]
或**&a[1]
或**(&a[0] + 1)
或其他多种形式。