变量如何在同一时间点有两个不同的地址?

时间:2017-10-12 16:46:28

标签: c pointers memory-address

我尝试使用指针来玩一些指定值的' i'而我发现的是,有两个不同的地址分配给声明%u和%lu,%llu。变量如何可能在同一个执行实例中具有两个不同的地址 -

#include <stdio.h>
int main(void)
{
  int i;
  float f;
 printf("\nEnter an integer:\t");
 scanf("%d",&i);

  printf("\nValue of address of i=%u",&i);
  printf("\nvalue of address of i=%d",&i);
  printf("\nValue of address of i=%lu",&i);
  printf("\nValue of address of i=%llu",&i);

  printf("\nvalue of i=%d",i);
  printf("\nvalue of i=%u",i);
  printf("\nvalue of i=%lu",i);
  printf("\nvalue of i=%llu\n",i);

}

这是输出 -

aalpanigrahi@aalpanigrahi-HP-Pavilion-g4-Notebook-PC:~/Desktop/Daily programs/pointers$ ./pointer001

    Enter an integer:   12

    Value of address of i=1193639268
    value of address of i=1193639268
    Value of address of i=140725797092708
    Value of address of i=140725797092708
    value of i=12
    value of i=12
    value of i=12
    value of i=12

在这里我们可以清楚地看到,对于%u和%d,地址是1193639268(尽管%d和%u的输出在所有情况下可能不相等),%lu和%llu的输出是140725797092708它是否具有物理意义。

4 个答案:

答案 0 :(得分:6)

用于打印指针的正确格式说明符是%p

使用错误的格式说明符,例如%d%u%lu%llu会调用undefined behavior

正如您所看到的特定行为,特定实现上的指针可能是8字节值,而intunsigned int可能是4字节值。因此,使用%d%u只读取传递给函数的8字节值的前4个字节并打印该值。然后,当您使用%lu%llu时,将读取并打印所有8个字节。

同样,因为您正在调用未定义的行为,所以您不能依赖此特定输出来保持一致。例如,在32位模式和64位模式下编译可能会产生不同的结果。最好使用%p,并将指针强制转换为void *,因为这是%p所期望的特定指针类型。

答案 1 :(得分:4)

只有一个地址。您正在使用不同宽度的整数打印代码,因此有时您会看到32位地址,有时您会看到64位地址。多少有效取决于您的系统;在32位系统上,打印64位意味着32位的值是垃圾;在64位系统上,打印32位意味着你省略了指针的一半。

有一个专用的格式代码,%p用于打印指针,使用它而不是整数打印代码。

答案 2 :(得分:3)

您使用了错误的格式说明符,结果为undefined behavior。在这种特定情况下,行为是1193639268(0x47257D64)是140725797092708(0x7FFD47257D64)的下半部分

地址的正确格式说明符是%p

答案 3 :(得分:2)

没有。只是你为指针类型使用了不正确的格式说明符。

这样做的行为是未定义的。您观察到的输出是未定义行为的表现。

使用%p作为指针,并将指针参数转换为const void *类型(许多编译器在这最后一点上是松散的,但它仍然是很好的做法)。