int x;带有%d的scanf()和带有%c的printf()

int x;带有%d的scanf()和带有%c的printf(),c,format-specifiers,conversion-specifier,C,Format Specifiers,Conversion Specifier,int 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); //

int 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
因此所发生的一切都是
printf
将66的
int
值解释为ASCII代码1并打印相应的字符



一,。请注意,ASCII在技术上是一个由实现定义的设计决策。非常常见。

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

%c
说明符相对应的
int
参数传递给
printf()
,然后在打印之前由
printf()
执行,而且不涉及“仅从一个字节收集数据”,相反,如果新类型可以保留原始值,则该值保持不变;否则,大于新类型的最大值的一个将添加到旧(
已签名的
)值中(或从中减去)。例如,
-1
int
值将被转换为
无符号字符
值(假设
UCHAR_MAX
为255),
-1+256
255
,该值在
无符号字符
的范围内


请注意,值为
66
int
在转换为
无符号字符时将保持不变,因为66完全在
无符号字符的范围内
UCHAR_MAX
必须至少为255。

无论参数是如何传递的,
%c
格式说明符总是在打印前将其参数转换为
无符号字符。所以,
%c
总是打印一个字节

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


在这种情况下,变量参数传递的复杂性(是的,它作为
int
传递)对观察到的行为没有影响。

请提供一个。注意
int
必须至少有16位宽,但可能更宽,通常更宽……猜测时,您的int被隐式转换为char,保留值66,这符合字符的8位。没有MCVE,更精确是不可能的。@Yunnosch-不需要MCVE-这种行为定义良好。“它%c不仅仅从一个字节获取数据?”-->它获取2(或4)个字节,然后忽略除1以外的所有字节进行打印。OP在哪里提到他正在将
字符传递给
printf
?@chqrlie-哪里都没有,在我看来;只需添加一个细节,说明为什么
printf()
需要
int
,但通常使用
%c
转换说明符传递
char
。这一点很好。更让人困惑的是,
'a'
实际上是C语言中的
int
。@chqrlie——这也是一个很好的观点,字符常量从类型
int
开始。这对学习者来说有点困惑,这有什么奇怪吗?“a”实际上是C中的int,我知道。我认为等于65,并以80和1的对应二进制值组合作为二进制代码保存在内存中。我可能错了,但OP似乎认为
%c
需要
字符,并且对实际参数大于
字符时可能发生的情况感到困惑;因此,我试图描述发生的事情。也许还对整数类型的表示感到困惑……是的,先生。我对实际参数大于字符大小(即一个字节)时可能发生的情况感到困惑。那么多个字节的数据应该放在内存中的哪个位置?因为只有一个字节和char变量有关,我知道char实际上什么都不是,只是一个整数,但char二进制代码的内存大小只有一个字节