试图理解printf带有char说明符的指针(%c)

时间:2017-07-18 11:37:28

标签: c format-specifiers

#include<stdio.h>
void main()
{
   int n = 2;
   printf("%c",&n);
}

输出:L

在使用%d时,它当然会提供变量n的地址,但为什么使用%c输出L?

3 个答案:

答案 0 :(得分:8)

未定义的行为,因为您使用了错误的格式说明符

C11标准:7.21.6.1:第9段:

  

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

这意味着如果使用错误的格式说明符调用printf,就会发生任何事情。

答案 1 :(得分:4)

正如answer的另一个rsp所说,行为未定义且任何事情都可能发生。

在您的情况下会发生以下情况:

它读取&n的一个字节,因为字符大小为一个字节,大多数是8位长,请参阅CHAR_BIT explanation on SO。然后将其打印为字符 如果您的计算机上的&nint*类型相同,则此字节可能是int的第一个字节。这意味着您的变量n位于地址0x48...(big-endian)或0x...48(little-endian),而0x48位于H H {3}}。我假设您的程序使用Ascii进行编码,但这并不是必须的 (您将角色从L更改为&n,但我保留此答案。)
如果int*超过系统中int的大小,此字节也可位于-Wall的中间位置。

您应该编译并在gcc中启用更多警告,例如char,您将获得:

  

警告:格式'%c'需要类型为'int'的参数,但参数2的类型为'int *'[-Wformat =]

如果将该值转换为@TestExecutionListeners,则行为将被很好地定义,但依赖于实现,因为实现定义了对整数的指针类型的强制转换。

然而,你所做的事情也没有任何意义,因为它不会做一个演员。

答案 2 :(得分:-1)

这是因为你告诉printf()函数将int n的地址的第一个1字节显示为char。