为什么%d和%p给出不同的值?

时间:2018-04-16 14:55:31

标签: c

正如您在程序中看到的那样,第一个输出是6356744,第二个输出是0060FF08,为什么它不同? %d是否将它转换为整数,如果是,怎么做?

#include<stdio.h>
int main()

{

    int *a;
    int b = 7;
    a = &b;
    printf(" The value of a = %d",a);
    printf("\n The value of a= %p",a);

}

4 个答案:

答案 0 :(得分:1)

使用%d打印指针是正式未定义的行为,这意味着任何事情都可能发生,包括程序崩溃。例如,当您将程序编译为64位应用程序时,您的程序可能会中断,其中int为32位但指针可能为64位。因此,在打印指针时始终使用%p而不要使用其他任何内容。

没有发生隐式转换 - printf系列函数没有那种智能 - 它不知道传递的类型。使用格式说明符,告诉函数它正在获取哪种类型。如果你对printf撒谎并说“我会给你一个int”然后给它一个指针,你就会释放出错误。这使得printf系列函数通常非常危险。

(在printf中发生的唯一隐式转换是当您传递小整数类型或浮点数时,在这种情况下会发生“默认参数促销”并将参数提升为int或{{1}但是,这不是这种情况。)

在这种特定情况下,您碰巧得到了double的十进制表示,这绝不是保证。

迂腐地说,您还应该将指针强制转换为0x0060FF08,因为这是(void*)所期望的。

答案 1 :(得分:0)

%p打印指针,它不一定是十六进制,甚至是数字

答案 2 :(得分:0)

如果格式说明符与提供的参数的数据类型不匹配,则会产生未定义的行为。 %d需要一个整数值,这样当您传递指针值时,您会得到未定义的行为(例如,参见cppreference.com-printf):

  

...如果默认参数促销后的任何参数不是类型   由相应的转换说明符预期,或者如果有的话   参数少于格式所需的参数,行为未定义。

打印指针值的(唯一)正确格式说明符是%p,通常以十六进制格式打印地址。

其中一个未定义的行为是%d将指针值作为32/64位整数值,因此打印小数,如果您使用正确的%p格式打印它 - 对应到地址的十六进制值(十进制格式)。

答案 3 :(得分:0)

%d以小数形式打印int

%p以实现定义的方式打印指针(严格来说,是一个void *指针),通常是十六进制。

int s和指针大小不同的机器上,尝试使用%d打印指针通常会产生无意义的结果。例如,在很多机器上,int是32位,而指针是64位。因此,如果您尝试使用%d打印指针,您可能得到的是 half 指针值,以十进制表示。

(严格来说,无论相对大小是多少,尝试使用%d打印指针都是未定义的。)

底线,为作业使用正确的printf说明符。使用%d打印整数。使用%p打印指针。不要试图混合&#39; n&#39;匹配。