C++:对于数组声明,&*A 不等同于 A?

C++: &*A is not equivalent to A for array declaration?

C 标准 6.5.3.2 地址和间接运算符 (3) 说:

"The unary & operator returns the address of its operand. If the operand has type ‘‘type’’, the result has type ‘‘pointer to type’’. If the operand is the result of a unary * operator, neither that operator nor the & operator is evaluated and the result is as if both were omitted, except that the constraints on the operators still apply and the result is not an lvalue."


"83) Thus, &*E is equivalent to E (even if E is a null pointer), and &(E1[E2]) to ((E1)+(E2)). It is always true that if E is a function designator or an lvalue that is a valid operand of the unary & operator, *&E is a function designator or an lvalue equal to E. If *P is an lvalue and T is the name of an object pointer type, *(T)P is an lvalue that has a type compatible with that to which T points."

所以如果我理解得很好,&*E 的行为就好像我们要删除 &*。然而,

#include <cstdio>
#include <typeinfo>

int main()
{
    float A[2];
    printf( "name: %s\n", typeid( &*A ).name());
    printf( "name: %s\n", typeid( A ).name());
    getchar();
    return 0;
}

将给予:

name: Pf
name: A2_f

所以他们不一样。

怎么了?我误会了什么?我将不胜感激你的帮助, 谢谢。

这些不一样。

&*A 为您提供 A 数组中第一个元素的地址作为衰减指针 float*,并且 A 是声明的特定数组类型float A[2].

如果typeid

Lvalue-to-rvalue, array-to-pointer, or function-to-pointer conversions are not performed.

所以,&*AA 在这种情况下是不一样的。 A 不会衰减到指向其在 typeid( A ).name() 中的第一个元素的指针。

使用 sizeof 运算符

可以看到相同的行为
int main()
{
    float A[10];
    printf( "name: %zu\n", sizeof( &*A )); // &*A --> float * type
    printf( "name: %zu\n", sizeof( A ));   // A   --> float[10] type
    getchar();
    return 0;
}

输出:

name: 8
name: 40

答案解释了为什么 &*AA 对于 A 是数组的简单情况是不同的。

但更一般地说,由于 C++ 允许 operator*operator& 的重载,因此两者可能有很大的不同。对于像 std::unique_ptr<int> p 这样的智能指针,&*p 是一个 int*,它甚至与 p 不是同一类型。