int x;带有%d的scanf()和带有%c的printf()
int x; 因此,变量将有2个字节的内存。 现在,如果我输入66,因为scanf()带有%d,66将存储在2字节内存中,因为变量声明为int 现在在带有%c的printf()中,应该只从一个字节的内存中收集数据以显示 但是%c通过从内存中获取正确的数据66来正确显示Bint 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); //
为什么%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二进制代码的内存大小只有一个字节