当我们尝试将字符作为浮点数和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 ++,它仍然适用)。