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

如果指针x具有的地址a*x指向a' 的值,编译器无法知道它*x指的是准确的 ,如果我通过a,它只能知道a' 的值*x

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

4

3 回答 3

5

1, a, x,*x都是表达式

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

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

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

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

对于 operator , and&之间没有区别,因为两者具有相同的值类别(都是左值)。a*x

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

于 2021-04-21T09:24:20.423 回答
4

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

一元运算&符产生其操作数的地址。如果操作数具有 type类型,则结果具有指向 type 的类型指针。如果操作数是一元运算符的结果,则该运算*符和该&运算符都不会被计算,并且结果好像两者都被省略了,除了对运算符的约束仍然适用并且结果不是左值。[...]

于 2021-04-21T09:14:27.780 回答
1

形式的表达&*p有一些特殊的考虑。它不是通过首先评估*p和获取那个地址来评估的,而是通过&*取消来简单地产生p

这使您可以编写类似

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

没有任何未定义的行为。

于 2021-04-21T09:18:13.553 回答