当我们尝试将字符作为浮点数和hex打印时,printf的行为有何不同?
我试图在printf中打印字符作为浮点数并获得输出0.这是什么原因。
也:
char c='z'; printf("%f %X",c,c);
当我这样做时,输出是正确的,为hex提供了一些奇怪的输出:
printf("%X",c);
为什么会这样?
printf()
函数是一个可变函数,这意味着您可以向其传递可变数量的未指定类型的参数。 这也意味着编译器不知道函数期望什么类型的参数,因此它不能将参数转换为正确的类型。 (如果你使用足够的警告标志来调用printf
,那么现代编译器可以警告你。)
由于历史原因,您不能传递秩小于int
的整数参数,或者传递小于等级的浮点类型的可变参数函数。 float
将被转换为double
并且char
将通过称为默认参数提升的进程转换为int
(或奇怪实现中的unsigned int
)。
当printf
解析其参数(参数传递给函数,参数是函数接收的参数)时,它使用适合格式字符串指定的类型的任何方法检索它们。 "%f"
说明符期望double
。 "%X"
说明符需要unsigned int
。
如果传递int
并且printf
尝试检索double
,则调用未定义的行为 。
如果传递int
并且printf
尝试检索unsigned int
,则调用未定义的行为 。
未定义的行为可能包括(但不限于)打印奇怪的值,崩溃您的程序或(最阴险的是所有)完全按照您的期望。
资料来源: n1570 (现行C标准的最终公开草案)
您需要使用这样的强制转换运算符:
char c = 'z'; printf("%f %X", (float)c, c);
要么
printf("%f %X", (double)c, c);
在Xcode中,如果我不这样做,我会收到警告:
Format指定’double’,但参数的类型为’char’,输出为0.000000。
我试图在printf中打印字符作为浮点数并获得输出0.这是什么原因。
问题是,您期望看到什么价值? 为什么你会期待0以外的东西?
对你的问题的简短回答是,如果参数的类型与转换说明符不匹配,则printf
的行为是未定义的。 %f
转换说明符期望其对应的参数具有double
类型; 如果不是,所有投注都会关闭,确切的输出会有所不同。
要了解浮点问题,请考虑阅读: http : //en.wikipedia.org/wiki/IEEE_floating_point
至于hex,让我猜一下……输出就像…… 99?
这是因为编码…机器必须以某种格式表示信息,并且通常该格式要么给出数字中某些位的含义,要么给数字有符号表,或者两者都有
浮点有时表示为(符号,尾数,指数)三元组,所有三元组都以32位或64位数字打包 – 字符有时以ASCII格式表示,它确定哪个数字对应于您键入的每个字符
因为printf与任何使用varargs的函数一样,例如: int foobar(const char fmt, ...) {}
试图将其参数解释为某种类型。
如果你说"%f"
,那么传递c
(作为一个char
),然后printf
将尝试读取一个float
。
你可以在这里阅读更多: var_arg (即使这是C ++,它仍然适用)。