我们与一些朋友讨论了ANSI C中这个简单的以下代码的核心性。
#include <stdio.h>
int main(void)
{
int a=2;
printf("%d", *&a);
return 0;
}
主要讨论是关于*&amp;。如果*访问内存位置(也称为指针)和&amp;给出一些变量的内存地址......我认为*试图访问一个int值作为内存地址(显然不起作用),但我的朋友说*&amp;它会自动取消(或解释为&amp; *)。我们用GCC 4.8.1(MinGW)进行了测试,代码avobe运行良好......我认为不对。
你怎么看?认为这里有一个糟糕的解决方法(或者这只是愚蠢的?)。谢谢你的建议:)答案 0 :(得分:3)
a
是左值:变量a
。
&a
是指向此左值的指针。
*&a
是&a
指向的左值 - 也就是a
。
从技术上讲,*&a
和a
在所有情况下都不完全相同,因为在*&a
所有情况下a
不允许a
(例如,如果register
被声明为{{1}}),但在您的示例中,它们完全相同。
答案 1 :(得分:2)
C标准(作为脚注)有一个有趣的摘录,即C11§6.5.3.2/ 4(脚注102,强调我的),它直接讨论了这个方面:
因此,
&*E
相当于E
(即使E
是空指针),&(E1[E2])
到((E1)+(E2))
。如果E
是一个函数,那么总是如此 指定符或左值,它是一元&
的有效操作数 运算符*&E
是函数指示符或等于E
的左值。如果*P
是一个左值,T
是对象指针类型的名称,*(T)P
是一个 lvalue的类型与T
指向的类型兼容。
在您的情况下a
是一个(可修改的)左值,它反映了标准的E
符号,并且它是&
运算符的标准要求的有效操作数,因此{{1} }(即*&a
)是一个等于*&E
的左值。
请注意,您不能获取a
存储类变量的地址(由@Deduplicator指出),因此它不符合此类缩减(即使是可修改的左值)。
答案 2 :(得分:1)
只要*&a
有意义,*&a
和a
就是一样,可以互换。
答案 3 :(得分:1)
通常,*&a
与a
相同。
不过,还有一些案例:
*&
可能无效,因为&a
不允许,因为它不是左值,或者是register
- storage-class。
使用a
可能是未定义的行为,因为a
是一个未初始化的无内存变量(register
或auto
- 存储类可能是声明register
(地址从未被采取过))。
将其应用于您的案例,省略*&
不会改变任何内容。