&(*x) 是如何工作的?详情如下

How &(*x) works? Details below

int a = 1;
int* x = &a;
//-> &*x equal to &a

如果指针 x 的地址为 a*x 指向 a 的值,编译器无法知道 *x指的是 a,如果我传递 *x,它只能知道 a 的值。

但事实证明它知道。那么这是如何工作的呢?编译器是否也传递了地址,或者当我像 &*x 一样放置 & 时它只是取消 * 编译就好像它就像 x 或其他方式一样?

关于 &(*x),来自 C11,第 6.5.3.2 章,

The unary & operator yields 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. [...]

&*p 形式的表达式有一些特殊的注意事项。它是 not 通过首先评估 *p 并获取它的地址来评估,而是 &* 取消,以简单地产生 p.

这允许你写类似

的东西
#include <iostream> 
int main() {
    int* p = nullptr; 
    int* q = &*p;
    std::cout << p << q;
}

没有任何未定义的行为。

1ax*x都是表达式.

有些表达式有地址(称为“左值”),有些则没有(称为“右值”)。

1 是一个右值,它没有地址。所以 &1 不编译。

a 是一个左值,所以它确实有一个地址。

*x 也是一个左值,所以它也有一个地址。这就是语言的工作原理。它本来可以做成不同的(*x 可以是一个右值),但它是一个左值,因为地址可用很方便。

对于运算符 &a*x 没有区别,因为两者具有相同的值类别(均为左值)。

您似乎假设(即使不知道术语)只有变量名是左值(只有它们有地址),但事实并非如此。