C 当我们尝试将字符打印为浮点和十六进制时,为什么printf的行为不同?
我试图在printf中将字符打印为浮点,结果得到了输出0。原因是什么。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将尝试读取浮点值 这里你可以阅读更多的内容(即
此外:
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);