打印地址时出现意外的值

时间:2015-12-22 10:24:18

标签: c pointers

这是我的计划。输出如下。

#include <stdio.h>
#include <stdlib.h>

int main(void) {
    int n = 3, *pt;
    pt = &n;
    printf("\n%d", pt);
    printf("\n%d", &n);
    printf("\n%d", &pt);
    return 0;
}

输出:

-9705676
-9705676
-9705672

但我认为第三个数字应与前两个相同? 请有人解释一下为什么不是这样?

4 个答案:

答案 0 :(得分:13)

全部是undefined behaviour,因为您使用了错误的格式说明符来打印指针。

使用%p打印指针并将其转换为void*

printf("\n%p",(void*) pt);
printf("\n%p",(void*) &n);
printf("\n%p",(void*) &pt);

C标准要求格式规范%p对应的参数属于void*类型。

C11,7.21.6,说:

  

p参数应该是指向void的指针。指针的值是   转换为一系列打印字符,在   实现定义的方式。

通常,T *(任何对象指针)可以隐式转换为void *而无需显式转换(例如,在赋值中)。但是printf()是一个可变函数,这里没有发生这样的转换。因此演员阵容是必需的。

  

但我认为第三个数字应与前两个相同?

没有。在第三个中,您将打印指针本身的地址。而在前两个中,您打印的地址为n

为了说明这一点:

             +------+      
       n --> |      |  
      0x1000 |  3   |  n is stored at address 0x1000
             |      |
             +------+

             +------+      
      pt --> |      |  
      0x2000 |0x1000|  pt stores the address of n. 
             |      |  But the address of pt is different.
             +------+

答案 1 :(得分:3)

首先,使用%p打印指针,而不是%d

在程序开始时,在堆栈上分配两个变量:integer n(4个字节)和int *pt(4个字节)。

n包含整数3,pt包含n的地址。所以,&n == pt

然后,第三个输出。在这里打印pt变量的地址(位于堆栈上,n旁边,见4个字节的差异)。

答案 2 :(得分:2)

不是真的。在第3个数字中,您将打印指针本身的地址。第一个打印指针的内容,即n的地址。指针是一个具有自己地址的变量,与它指向的地址不同。

答案 3 :(得分:-3)

select s1.name, s2.name, utl_match.jaro_winkler(s1.name, s2.name) jw from source1 s1 join source2 s2 on utl_match.jaro_winkler(s1.name, s2.name) > .9; NAME NAME JW -------------------------------------------------- -------------------------------------------------- -- Adda Clevenger Jr Prep School Adda Clevenger Junior Preparatory School 0.904 Alice Fong Yu Alt School Alice Fong Yu Alternative School 0.925 Convent Of Sacred Heart Es Convent of Sacred Heart Elementary School 0.902 Rosa Parks Elementary School Rosa Parks Elementary School 1.000 打印传递给它的实际变量值。 当您传递pt(一个指针)并将其作为有符号整数打印时,指针被“强制转换”为整数,而printf( "%d" )将产生内存地址作为有符号整数。对于指针(printf())的指针也是如此! 期望负数,因为50%的整数是负数!

我建议你学习this document