诠释 x; 因此变量将有 2 个字节的内存。现在,如果我输入 66 并且因为 scanf() 带有 %d,66 将存储在 2 个字节的内存中,因为变量被声明为 int。
现在在带有 %c 的 printf() 中,应该只从一个字节的内存中收集数据来显示。
但是 %c 通过从内存中获取正确的数据 66 来正确显示 B。
为什么它 %c 不只是从一个字节中获取数据?
诠释 x; 因此变量将有 2 个字节的内存。现在,如果我输入 66 并且因为 scanf() 带有 %d,66 将存储在 2 个字节的内存中,因为变量被声明为 int。
现在在带有 %c 的 printf() 中,应该只从一个字节的内存中收集数据来显示。
但是 %c 通过从内存中获取正确的数据 66 来正确显示 B。
为什么它 %c 不只是从一个字节中获取数据?
%c
int
由于vararg 函数的默认参数提升,需要一个参数。换句话说,以下所有内容都是完全等价的:
int x = 66;
char y = 66;
printf("%c", x); // A
printf("%c", (char)x); // B
printf("%c", y); // C
printf("%c", (int)y); // D
所以所发生的只是将66printf
的值解释为 ASCII 代码1并打印相应的字符。int
1. 请注意,ASCII 在技术上是实现定义的设计决策。只是一个非常常见的。
语句中的%c
转换说明符printf()
需要一个int
参数。此外,由于printf()
is 是一个可变参数函数,因此 a通过默认参数char
Promotions转换为a 。int
int
传递给与说明符printf()
相对应的参数%c
然后在打印之前转换为unsigned char
by 。请注意,整数类型到整数类型的转换在 C 中是明确定义的,并且不涉及收集“仅来自一个字节的数据”。相反,如果新类型可以保持原始值,则该值保持不变;否则,在旧 ( ) 值上加上(或减去)新类型最大值的 1 。例如, 的值将转换为 或 的值(假设为 255),该值在 的范围内。printf()
signed
unsigned
signed
int
-1
unsigned char
UCHAR_MAX
-1 + 256
255
unsigned char
请注意,int
值为 的an66
在转换为 时将保持不变unsigned char
,因为 66 正好在 an 的范围内unsigned char
。UCHAR_MAX
必须至少为 255。
不管参数如何传递,%c
格式说明符总是unsigned char
在打印之前将其参数转换为。所以,%c
总是打印一个字节。
%c
您从一个以上字节获取数据的断言是没有根据的。给出的示例没有显示任何相反的证据 -66
是一个适合一个字节的数字。
在这种情况下,可变参数传递的复杂性(是的,它作为一个传递int
)与观察到的行为无关。