【发布时间】:2015-08-29 06:12:28
【问题描述】:
以下代码打印 99,其中 'c' 已隐式转换为 99。
printf("%d", 'c');
但下面的代码打印出 0.000000:
printf("%f", 23);
为什么在第二种情况下,整数 23 没有像第一种情况那样转换成 23.00000?这是否反映了 C 中隐式转换的糟糕实现?提前致谢。
编辑:如果正如答案之一所暗示的那样,从 int 到 float 的提升是不可能的,那么为什么在我们编写时会提升 int 到 float
float x = 23;
为什么会这样?
【问题讨论】:
-
c没有隐式转换为 99; it is 99。至于后者,您究竟希望 C 中的printf知道您没有 将float传递给它吗? -
当您调用
printf时,编译器无法猜测您要压入堆栈的内容,因为它是一个可变参数函数(接受未知数量的参数,其类型未知,除了第一个)。因此它将每个大小小于int的整数类型(例如char和short)提升(转换)为int,以及每个大小小于double的非整数类型(例如@987654334 @) 到double。这就是为什么您的第二个示例产生错误输出的原因。编译器将23推送为int(在大多数平台上为4 字节),但printf需要double(在大多数平台上为8 字节)。 -
@coder12345:没有答案说从 int 到 double 的转换是不可能的;只是它不会发生在可变参数函数的参数上。为了更清楚为什么不这样做,想象一下代码实际上是:
printf(format, 23);。编译器如何知道format被分配(在运行时)给值"%f"? -
为了记录,现在的许多编译器都有扩展,它们使用名为
const char *的参数对可变参数函数执行分析,称为fmt并将类型检查您传递的参数以确保它们匹配正确使用格式字符串文字。 -
@Qix:是的,但他们会发出警告,而且他们只能检查以文字形式提供的格式字符串,这绝不是必需的。无论如何,没有编译器插入代码来根据格式转换 printf 参数的类型。 (顺便说一下,gcc 期望一个编译指示告诉它一个函数是 printf-like 或 scanf-like)。
标签: c++ c implicit-conversion