【问题标题】:what will happen if we use %p instead of %d while printing an int如果我们在打印 int 时使用 %p 而不是 %d 会发生什么
【发布时间】:2017-09-04 01:15:58
【问题描述】:

有人可以解释第二行的输出吗?

int x=10;
printf("%d\n",x);
printf("%p\n",x);
printf("%p\n",&x);

输出:

10
0000000a
006aff0c

【问题讨论】:

  • 嗯,使用不匹配的printf() 转换说明符和参数是未定义的行为;也就是说,0000000a 是十进制 10 的十六进制表示。
  • 使用%p 打印整数并不能保证工作(并且,在不常见的情况下,例如 64 位编程,几乎可以保证不能工作),但令人惊讶的是 10 (base 10) 输出为 0x0a (base 16)?
  • 看起来 %p 总是将通过他的任何东西转换成十六进制 @DavidBowling
  • @ToufiqueImam——不完全是; %p 转换说明符打印指针 in an implementation-defined way 的值。这可能是也可能不是十六进制表示。请注意,在使用%p 打印之前,必须将指针转换为(void *),以避免未定义的行为;例如,printf("%p\n",(void *) &x);

标签: c pointers int


【解决方案1】:

在您的情况下,它似乎将值 10 视为指针并将其输出为第 8 位、左侧填充零、十六进制数(a).

然而, 根据C11 7.21.6.1 The fprintf function, /9(以下所有标准引用也参考C11):

如果转换规范无效,则行为未定义。 如果任何参数不是对应转换规范的正确类型,则行为未定义。

所以,从字面上看,任何事情都是允许发生的。您通常希望尽可能避免未定义的行为,因为行为可能会在实现、版本甚至星期几之间发生变化:-)

您的第三行行在技术上也存在问题。标准规定,7.21.6.1 /8 中的 p 转换说明符:

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

由于&x 实际上是一个指向int 的指针,因此它违反了同一合约。您可能应该改用这样的东西:

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

(a)实际上所做的是实现定义的,如上面最后引用中的第二句。它基本上可以做任何事情,只要它的实现文档,如J.3 Implementation-defined behavior中所述:

一个符合要求的实现需要记录它在本小节列出的每个领域中的行为选择。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-07
    • 2012-01-13
    • 2010-12-27
    • 2023-04-07
    相关资源
    最近更新 更多