0

诠释 x; 因此变量将有 2 个字节的内存。现在,如果我输入 66 并且因为 scanf() 带有 %d,66 将存储在 2 个字节的内存中,因为变量被声明为 int。

现在在带有 %c 的 printf() 中,应该只从一个字节的内存中收集数据来显示。

但是 %c 通过从内存中获取正确的数据 66 来正确显示 B。

为什么它 %c 不只是从一个字节中获取数据?

4

3 回答 3

6

%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 在技术上是实现定义的设计决策。只是一个非常常见的。

于 2017-07-15T23:54:36.017 回答
4

语句中的%c转换说明符printf()需要一个int参数。此外,由于printf()is 是一个可变参数函数,因此 a通过默认参数charPromotions转换为a 。int

int传递给与说明符printf()相对应的参数%c然后在打印之前转换为unsigned charby 。请注意,整数类型到整数类型的转换在 C 中是明确定义的,并且不涉及收集“仅来自一个字节的数据”。相反,如果新类型可以保持原始值,则该值保持不变;否则,在旧 ( ) 值上加上(或减去)新类型最大值的 1 。例如, 的值将转换为 或 的值(假设为 255),该值在 的范围内。printf()signedunsignedsignedint-1unsigned charUCHAR_MAX-1 + 256255unsigned char

请注意,int值为 的an66在转换为 时将保持不变unsigned char,因为 66 正好在 an 的范围内unsigned charUCHAR_MAX必须至少为 255。

于 2017-07-15T23:54:56.573 回答
1

不管参数如何传递,%c格式说明符总是unsigned char在打印之前将其参数转换为。所以,%c总是打印一个字节。

%c您从一个以上字节获取数据的断言是没有根据的。给出的示例没有显示任何相反的证据 -66是一个适合一个字节的数字。

在这种情况下,可变参数传递的复杂性(是的,它作为一个传递int)与观察到的行为无关。

于 2017-07-16T00:22:15.653 回答