2017-10-12 143 views
0

我试着玩一些指针来指向'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); 

} 

这是输出 -

[email protected]:~/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,它的物理意义是什么。

回答

6

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

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

正如你所看到的具体行为,您的具体实施指针可能是一个8字节的值,而一个intunsigned int可能是一个4字节的值。因此,使用%d%u只读取传入该函数的8字节值的前4个字节并打印该值。当您使用%lu%llu时,所有8个字节都会被读取并打印。

再次,因为你调用未定义行为,你不能依赖于这个特定的输出是一致的。例如,在32位模式和64位模式下编译可能会产生不同的结果。最好使用%p,并且将指针投射到void *,因为这是%p预期的特定指针类型。

+2

细节:用于打印'void *'指针的适当格式说明符是'“%p”'。 ''%p“'可能不适用于'int *',但常见。 – chux

+1

@chux好点。我已经添加了这个细节 – dbush

2

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

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

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

3

您使用了错误的格式说明,这会导致undefined behavior。在这种特殊情况下的行为是1193639268(0x47257D64)是140725797092708(0x7FFD47257D64)下部

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

4

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

有一个专用的格式代码,%p了一种旨在用于打印指针,使用,非整打码。

相关问题