【发布时间】:2019-08-27 22:49:17
【问题描述】:
所以有一段时间我对数组名称和指针感到困惑。
我们声明int a[10];
在路上的某个地方也有a 和&a。
所以我知道语法是如何工作的。 a 是数组名称。当它不用作sizeof&等的操作数时,它将被转换或“衰减”,因此它返回一个指向包含数组第一个元素地址的整数的指针。
如果数组名用作sizeof 或& 的操作数,则其类型为int (*)[10]。所以我猜类型是不同的,因为“衰减”不会发生。
但我仍然不明白&a 是如何工作的。我的理解是它给了我whatever it was before the "decay" happened的地址。所以在指针“衰减”发生之前,它是什么以及编译器如何使用“原始”来评估&a?
相比之下,如果我们声明int *p;
后来在代码中的某处有&p 和p...
在这种情况下,指向整数 p 的指针被赋予一个单独的指针单元及其地址,该地址的值将是我们分配给它的任何地址(或该地址预分配的垃圾值)。
a 在声明为int a[10] 时不会在内存中分配一个单独的指针单元。我听说它在寄存器%ebp 上有一个偏移量。那么编译器在评估&a 时会发生什么?指向整数的指针的“衰减”没有发生,首先没有单独的“指针”。那么编译器将a 识别为什么,当它看到一元& 运算符使用数组名称作为操作数时会做什么?
【问题讨论】:
-
第一个代码块只能在 C 中编译,因为 C 将所有指针类型视为兼容的,并且数组的地址与第一个元素的地址相同。在 C++ 中,它是指针类型不匹配。
-
我将删除 c++ 标签
-
@CruzJean
a == &a也是 C 中的指针类型不匹配。 -
@chux 好吧,但据我所知,C 最多只会发出警告。虽然我可能只是习惯了旧版本的 C 编译器。
-
这是另一个要考虑的例子:如果你有
int b[20][10],例如你将b作为函数参数传递,它会衰减为类型int (*)[10]。这是有道理的,因为b[0]的类型为int [10],所以&b[0]的类型为int (*)[10]。当然,&b的类型为int (*)[20][10]。
标签: c arrays pointers type-conversion