printf("%d", 'c');
但是以下代码输出的结果是0.000000:
printf("%f", 23);
在第二种情况下,为什么整数23没有像第一种情况中那样转换为23.00000?这反映了C语言中隐式转换的实现不够好吗?提前致谢。
编辑:如果像其中一个答案所建议的那样,从int到float不存在升级,那么为什么我们在写```float result = 2 + 3;```时会从int升级到float呢?
float x = 23;
为什么呢?
printf("%d", 'c');
printf("%f", 23);
float x = 23;
int
升级到 double
,而是从 double
降级到 int
。这也与调用带有可变参数的函数不同。一个更紧凑的例子是 void foo(float x){}
并使用 foo('c');
进行调用。目标类型在编译时已知。(向 uptick rici 致意,很好的答案) - WhozCraigprintf
这样的可变参数函数是一种特殊情况,其中类型系统无法识别格式说明符 %f 请求的是浮点数。基本上,在 printf
中,类型系统是“关闭”的。 - VoidStarprintf
是一个可变参数函数,这意味着除了第一个参数以外的其它参数在访问时实际上是无类型的。这排除了在printf
的参数列表中进行任何智能类型转换的可能性(尽管有某些默认转换会发生,有点盲目且与格式说明符无关)。
在第一个例子中,“c”已经是一个int
。但是在浮点数的情况下,它没有执行必要的转换,将一个int
转换为float
,因为编译器不知道它应该这样做,或者更准确地说,根据规范,除了相信格式说明符是关于类型的真相之外,没有其他事情需要做。它认为数据已经是一个浮点数,因为格式说明符%f
告诉它如此,并且它看不到传递的23的类型。
这使得开发人员很容易意外地导致崩溃 - 开发人员必须确保格式说明符(例如%d)与提供的数据匹配。例如,将“%s”指定符与int
输入混合使用会导致运行时崩溃,因为编译器将简单地“相信”格式说明符不是错误的。更糟糕的是,试着完全省略数据... printf(“%f%f%f”)
会导致它寻找甚至不存在的参数,这将导致崩溃。不幸的是,编译器必须接受并构建这个崩溃的代码。
如果您想更仔细地了解这个难题,请搜索va_list
/va_start
/va_stop
,这是printf
使用的机制。请理解这个机制允许我们循环遍历发送到printf
中的数据,但是类型信息丢失了。它是无类型的二进制数据,并且为了使用它,它使用格式说明符%f
来意识到那里有一个浮点数。然后将二进制数据解释为float
并将其写入字符串中以显示出来。
从另一个角度来看,编译器忽略了像%f
这样的字符串内容在其类型系统中的存在...%f
被编译了,但它只在运行函数时应用。但是在运行时,所有类型信息都丢失了 - C具有类型系统,但它仅在编译时存在。基本上,像%f
这样的字符串数据和C类型系统是完全不同的概念,从未进行过通信。因此,请尝试想象一下没有任何像%f
这样的字符串数据的程序。编译器如何知道运行时int->float转换?
请注意,以下内容仅适用于可变参数函数,而非普通函数调用。普通函数调用的类型处理方式类似于大多数现代语言。另一方面,可变参数函数是C语言独有的。与void *
指针类似,它们应该被视为危险的,并小心使用。
编辑:
float x = 23;
会导致提升,因为该语言具有功能型类型系统(尽管类型仅在编译时已知)。类型系统无法在可变参数函数参数内部工作,即printf
的输入参数。
printf
实现中,所以会出现这种问题。这种错误行为只出现在可变参数函数(例如 printf
)中,常规函数调用没有这个问题。printf
接收的是未命名二进制的 va_list
类型,除非格式说明符 %f
告诉它对应的数据类型,否则它无法解释内存中的数据。 - VoidStarprintf("%f", 23)
,编译器不知道期望的类型是double
。格式字符串不必在编译时就已知;它可以是char *format = "%f"; printf(format, 23)
。底线:C语言不同于其他语言。 - Keith Thompsonprintf
需要 double
类型,而不是编译器,因此编译器无法知道它应该如何提升值,只能遵循默认提升。 - phuclv
c
没有被隐式转换为99;它就是99。至于后者,你希望C语言中的printf
如何知道你并没有传递一个float
呢? - WhozCraigprintf(format, 23);
。编译器如何知道format
(在运行时)被赋值为"%f"
的值? - riciconst char *
参数fmt
的可变参数函数进行分析,并检查你传递的参数是否与格式字符串字面量正确匹配。 - Qix - MONICA WAS MISTREATED