int a=10;
int *p=&a;
现在看
&*p
,我们首先看*p
,即10
,然后看&10
这是 10
的地址或 a
的地址
对于
*&p
,我们首先查看p
的地址,然后查看该地址中的值,即10
但我明白
*&p
和 &*p
是一样的,为什么?
让我们画出你的变量:
+---+ +---+ | p| --> |一个 | +---+ +---+
也就是说,
p
指向a
。
现在,如果你这样做
&*p
那么你首先取消引用 p
以获得 a
,然后你得到 a
的地址,这给你留下一个指向 a
的指针。
如果我们采用
*&p
,那么您将获得 p
的地址以获取指向 p
的指针,然后取消引用该指针以获取 p
。这是指向 a
的指针。
因此,虽然表达式执行不同的操作,但最终结果是相同的:指向
a
的指针。
下降编译器可能什么也不做,因为解引用运算符
*
和地址运算符 &
在一起总是会相互抵消,无论它们的顺序如何。
虽然这个问题被标记为 C 语言,但 C++ 的答案可能非常不同,因为这取决于可能重载的运算符。
考虑下面的例子
int a=10;
int *p=&a;
这个
*&p
意味着这里
*
和 &
都被取消,并导致 p
只不过是 &a
。
还有这个
&*p
意味着首先取消引用
p
,它给出a
,然后引用&
,即a
的地址,它只不过是p
,与第一种情况相同。
根据顺时针/螺旋规则:
对于
*&p
:
+-----+
| +-+ |
| ^ | |
* & p ; |
^ ^ | |
| +---+ |
+-------+
p
的地址,此时就是a
的地址。 a
的地址。对于
&*p
:
+-----+
| +-+ |
| ^ | |
& * p ; |
^ ^ | |
| +---+ |
+-------+
p
,这给了我们a
。 a
的地址,就像以前一样。在这种情况下,
&
获取地址(即,非正式地“将*
”添加到表达式的类型中)。同时 *
取消引用指针(即,“从表达式的类型中删除 *
”)。因此:
int *p = …;
p; // int *
*p; // int
&*p; // int *
&p; // int **
*&p; // int *
所以,是的,在这种情况下,结果是相同的:指向
int
的指针,因为 &
和 *
抵消了。然而,这也是组合毫无意义的原因:结果与 p
本身相同。
*&p
==*(&p)
。 &p
是指向指针或 int 的指针。 *(&p)
是指针所指向的值,即p
的值。要继续,**&p
将打印“10”。
&*p
== &(*p)
其中 *p
是指针指向的值(a
的值)。现在&
是a
的地址,又是p
。更进一步,*&*p
将打印 a
(10) 的值。