C 当我们尝试将字符打印为浮点和十六进制时,为什么printf的行为不同?

C 当我们尝试将字符打印为浮点和十六进制时,为什么printf的行为不同?,c,C,我试图在printf中将字符打印为浮点,结果得到了输出0。原因是什么。 此外: char c='z'; printf("%f %X",c,c); 给出了一些奇怪的十六进制输出,而我这样做时输出是正确的: printf("%X",c); 为什么会这样?因为printf和任何使用varargs的函数一样,例如:intfoobar(constcharfmt,…){}试图将其参数解释为某种类型 如果您说%f,然后传递c(作为char),那么printf将尝试读取浮点值 这里你可以阅读更多的内容(即

我试图在printf中将字符打印为浮点,结果得到了输出0。原因是什么。
此外:

char c='z';
printf("%f %X",c,c);
给出了一些奇怪的十六进制输出,而我这样做时输出是正确的:

printf("%X",c); 

为什么会这样?

因为printf和任何使用varargs的函数一样,例如:
intfoobar(constcharfmt,…){}
试图将其参数解释为某种类型

如果您说
%f
,然后传递
c
(作为
char
),那么
printf
将尝试读取
浮点值


这里你可以阅读更多的内容(即使这是C++,它仍然适用).< /P> < p>你需要使用这样的一个强制操作符:

char c = 'z';

printf("%f %X", (float)c, c);

在Xcode中,如果我不这样做,我会得到警告:


格式指定指定“双”,但参数有“char”类型,输出为0 000000。< /P> < P>以理解浮点问题,请考虑阅读:

至于十六进制,让我猜猜。。输出类似于。。。99岁

这是因为编码。。机器必须以某种格式来表示信息,通常这种格式要求对数字中的某些位赋予意义,或者对数字有一个符号表,或者两者兼而有之

浮点有时表示为一个(符号、尾数、指数)三元组,全部压缩在一个32或64位的数字中-字符有时表示为一种名为ASCII的格式,该格式确定了哪个数字对应于您键入的每个字符。
printf()
函数是一个可变函数,这意味着您可以向它传递数量可变的未指定类型的参数。这也意味着编译器不知道函数需要什么类型的参数,因此无法将参数转换为正确的类型。(如果使用足够的警告标志调用,
printf
的参数错误,现代编译器会发出警告。)

由于历史原因,不能将秩小于
int
的整数参数或秩小于
double
的浮点类型传递给变量函数。
float
将通过一个称为默认参数的过程转换为
double
char
将转换为
int
(或
unsigned int
,在奇异的实现中)

printf
解析其参数(参数传递给函数,参数是函数接收的参数)时,它会使用适合格式字符串指定类型的任何方法检索这些参数。
“%f”
说明符需要一个
双精度的
“%X”
说明符需要一个
无符号int

如果您传递一个
int
并且
printf
尝试检索一个
double
,您将调用未定义的行为。
如果您传递一个
int
,并且
printf
尝试检索一个
无符号int
,则调用未定义的行为

未定义的行为可能包括(但不限于)打印奇怪的值、使程序崩溃或(最阴险的行为)完全按照您的预期进行

资料来源:(现行C标准的最终公开草案)

我试图在printf中将字符打印为浮点,结果得到了输出0。原因何在?

问题是,你期望看到什么价值?为什么你会期望0以外的东西


您的问题的简短回答是,如果参数的类型与转换说明符不匹配,
printf
的行为是未定义的。
%f
转换说明符要求其相应的参数具有类型
double
;如果不是这样,那么所有的赌注都没有了,确切的结果也会有所不同

请为试图从堆栈加载8字节的
%f“
显示不正确的输出。然后,对于“%X”`它尝试从堆栈中加载另外4个字节。但是,当您使用两个
char
s调用它时,您只会将两个4字节的单位推入堆栈,因此
printf
基本上“丢失”了它试图从堆栈加载的12个字节中的4个。在这一点上,几乎任何事情都可能发生。它将成功加载4字节的“垃圾”(未知)数据,或者在尝试从无效内存地址加载数据时执行内存访问冲突。欢迎使用StackOverflow。请始终确保显示示例的完整输出。。。请注意,“一些奇怪的输出”并没有准确显示您得到的输出那么有用。另请参阅以获取有关使用代码格式和其他内容的帮助。输出类似于0.000000 401716,我不明白这401716来自何处?@MM123:阅读我上面的评论,它解释了“垃圾”数据一定来自何处。
printf("%f %X", (double)c, c);