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


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

输出:L

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

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

C11标准:7.21.6.1:第9段:

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

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

正如 rsp 的另一个答案所说,行为是不确定的,任何事情都可能发生。

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

它读取一个字节的&n,因为字符的大小为一个字节,大部分为 8 位长,请参阅CHAR_BITSO 的说明。然后它将其打印为字符。
如果计算机上的int*int类型相同,则此字节可能是&n的第一个字节。这意味着您的变量n位于地址0x48...(大端序(或0x...48(小端序(,因为0x48在 Ascci 代码中H。我假设您的程序正在使用 Ascii 进行编码,这不一定必须这样做。
(您将字符从H更改为L,但我保留此答案。
此外,如果int*超过系统中int的大小,则此字节可能位于&n中间的某个位置。

您应该在启用更多警告的情况下进行编译,例如在 gcc 中启用-Wall,您将获得:

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

在将该值强制转换为char的情况下,行为将得到很好的定义,但依赖于实现,因为指向整数的指针类型的强制转换是实现定义的。

然而,你正在做的事情是没有意义的,对于演员来说,它也不会做。

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

最新更新