&(*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;
}
没有任何未定义的行为。
1
、a
、x
、*x
都是表达式.
有些表达式有地址(称为“左值”),有些则没有(称为“右值”)。
1
是一个右值,它没有地址。所以 &1
不编译。
a
是一个左值,所以它确实有一个地址。
*x
也是一个左值,所以它也有一个地址。这就是语言的工作原理。它本来可以做成不同的(*x
可以是一个右值),但它是一个左值,因为地址可用很方便。
对于运算符 &
,a
和 *x
没有区别,因为两者具有相同的值类别(均为左值)。
您似乎假设(即使不知道术语)只有变量名是左值(只有它们有地址),但事实并非如此。
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;
}
没有任何未定义的行为。
1
、a
、x
、*x
都是表达式.
有些表达式有地址(称为“左值”),有些则没有(称为“右值”)。
1
是一个右值,它没有地址。所以 &1
不编译。
a
是一个左值,所以它确实有一个地址。
*x
也是一个左值,所以它也有一个地址。这就是语言的工作原理。它本来可以做成不同的(*x
可以是一个右值),但它是一个左值,因为地址可用很方便。
对于运算符 &
,a
和 *x
没有区别,因为两者具有相同的值类别(均为左值)。
您似乎假设(即使不知道术语)只有变量名是左值(只有它们有地址),但事实并非如此。