在C/C++中,对于数组a,我刚学会了(void*)&a ==(void*)a.这是如何运作的?

Jul*_*.M. 16 c c++ arrays pointers

所以,我总是知道在C/C++中传递的数组"对象"只包含数组中第一个对象的地址.

指向数组"对象"的指针和它包含的值如何相同?

有人可能会向我指出更多信息,也许是关于汇编中的所有信息.

Pot*_*ter 17

简答:指向数组的指针定义为与指向数组第一个元素的指针具有相同的值.这就是C和C++中的数组如何工作.

迂腐的答案:

C和C++有rvaluelvalue表达式.左值是&操作员可以应用的值.他们也有隐含的转换.在使用之前,对象可以被转换为另一种类型.(例如,如果您调用sqrt( 9 )9转换为double因为sqrt( int )未定义.)

数组类型的左值隐式转换为指针.隐式转换更改array&array[0].这也可以static_cast< int * >( array )在C++中明确写出来.

这样做没关系.铸造void*是另一个故事.void*有点难看.用括号铸造(void*)array也很难看.所以请(void*) a在实际代码中避免.

  • `static_cast`和"使用圆括号"部分适用于C++,而不适用于C. (2认同)

AnT*_*AnT 12

你混合了两个不相关的(实际上是相互排斥的)东西,这会产生更多的混乱.

首先,您正确地说明" 在C/C++ 中传递的数组对象只包含数组中第一个对象的地址".这里的关键词是"传递".实际上,数组不能作为数组对象传递.数组不可复制.无论何时在函数参数列表中使用数组样式声明,它实际上都被解释为指针声明,即它是一个"传递"的指针,而不是数组.但是,在这种情况下,你的平等并不成立

void foo(int a[]) {
  assert((void *) &a == (void *) a); // FAIL!!!
}
Run Code Online (Sandbox Code Playgroud)

上述断言保证失败 - 平等不成立.因此,在这个问题的上下文中,你必须忘记你"传递"的数组(至少对于上面例子中使用的语法).对于已被指针对象替换的数组,您的等式不成立.

其次,实际的数组对象不是指针.并且没有必要将术语对象用作引号.数组是完整的对象,尽管有一些特殊的属性.所讨论的相等确实适用于尚未丢失其"数组"的实际数组,即未被指针对象替换的数组对象.例如

int a[10];
assert((void *) &a == (void *) a); // Never fails
Run Code Online (Sandbox Code Playgroud)

这意味着数字上整个数组的地址与其第一个元素的地址相同.这里没什么不寻常的.事实上,在C/C++中,结构类型可以观察到相同(本质上)相等

struct S { int x; } a;
assert((void *) &a == (void *) &a.x); // Never fails
Run Code Online (Sandbox Code Playgroud)

即整个struct对象的地址与其第一个字段的地址相同.