取消*&在ANSI C中

时间:2014-10-10 21:24:26

标签: c pointers memory

我们与一些朋友讨论了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运行良好......我认为不对。

你怎么看?认为这里有一个糟糕的解决方法(或者这只是愚蠢的?)。谢谢你的建议:)

4 个答案:

答案 0 :(得分:3)

a是左值:变量a
&a是指向此左值的指针。
*&a&a指向的左值 - 也就是a

从技术上讲,*&aa在所有情况下都不完全相同,因为在*&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有意义,*&aa就是一样,可以互换。

答案 3 :(得分:1)

通常,*&aa相同。

不过,还有一些案例:

  1. *&可能无效,因为&a不允许,因为它不是左值,或者是register - storage-class。

  2. 使用a可能是未定义的行为,因为a是一个未初始化的无内存变量(registerauto - 存储类可能是声明register(地址从未被采取过))。

  3. 将其应用于您的案例,省略*&不会改变任何内容。