#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_BIT
SO 的说明。然后它将其打印为字符。
如果计算机上的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 字节显示为字符。