a , &a 和 *a 有什么区别?

What is the difference between a , &a and *a?

我试图理解当 a 是指针时 a&a 之间的区别。

在以下示例代码中:

int main()
{
    int b = 100;
    int *a;
    a = &b;
    printf("%d %d %d", a , &a , *a);
    return 0;
}

按照我的理解,a是给a的地址一个name。即:

因此,当 a 是指针时,我希望 a&a 相同。但是在输出中,我得到的前两个值( a&a )不同。

我哪里错了?

首先,使用 %p 并将参数转换为 void * 以打印指针。为任何转换规范传递不兼容(不匹配)类型的参数是 undefined behavior.

也就是说,即使是指针变量,也是一个变量,并且必须在地址中是"stored"。所以,它是一个指针类型变量的地址。

换句话说,

  • b 是一个变量(int 类型)并且它有一个地址。
  • a 是一个变量(int * 类型)并且它 有一个地址。

要添加一些参考,引用 C11,章节 §6.5.3.2,

The operand of the unary & operator shall be either a function designator, the result of a [] or unary * operator, or an lvalue that designates an object that is not a bit-field and is not declared with the register storage-class specifier.

并且,从 §6.3.2.1 开始,

An lvalue is an expression (with an object type other than void) that potentially designates an object. [...]

下面的简单代码示例可能更容易解释:

printf("%d %d %d %d %d", &a , a , *a, &b, b);

其中 returns 例如:

290289632 290289644 100 290289644 100
  • a的地址:&a是启动时分配的东西(输出项 1).
  • a 指向 b 的地址因此输出项 2 和 4 是 一样。
  • 地址 *a = b 处的值:因此输出项 3 和 5 是 一样。

这里基本上*a存放的是b的值100,&a是指针a本身的地址,因为它也是一个变量,所以必须有一个地址,而a指的是变量的地址是指向(在本例中为 b 的地址)