c - 仅当未指定函数原型时才将浮点数转换为双精度数
问题描述
前几天我一直在学习 C 语言,发现了“函数原型”的概念。
基本上,如果你想在定义之前调用一个函数,做法是指定函数的参数和返回类型。
然后我尝试了以下代码(没有原型),它起作用了,因为 GCC 可以计算出函数的签名。
#include <stdio.h>
int main(void)
{
printf("%d", my_print(123123));
}
int my_print(int a)
{
printf("%d\n", a);
return 456;
}
//code works
但是,该代码无法编译:
#include <stdio.h>
int main(void)
{
printf("%d", my_print(123123.0f));
}
int my_print(float a)
{
printf("%f\n", a);
return 456;
}
//code DOES NOT compile
更进一步,下面的代码可以顺利编译和运行:
#include <stdio.h>
int main(void)
{
printf("%d", my_print((float) 123123.0f));
}
int my_print(double a)
{
printf("%f\n", a);
return 456;
}
//code compiles 0_o
最后,当您指定函数的签名时,编译器现在希望查看“float”类型的参数。
#include <stdio.h>
int my_print(float a);
int main(void)
{
printf("%d", my_print((float) 123123.0f));
}
int my_print(float a)
{
printf("%f\n", a);
return 456;
}
//code compiles
那么问题来了,为什么只有在没有指定函数原型的情况下,地狱编译器才想将 float 转换为 double 呢?
解决方案
您看到的是默认参数提升的效果,它适用于 (a) 可变长度参数列表的可变长度部分,以及 (b) 当函数在范围内没有原型的情况下被调用时。默认的参数promotions 说,基本上,任何小于的东西int
都被提升为int
,并且float
被提升为double
。
当 C 是新的并且还没有发明函数原型时,这些规则使调用约定更简单,编译器更小。
今天,随着函数原型或多或少普遍存在,这些规则几乎是不必要的,几乎被遗忘了,尽管它们可能比过去更令人困惑,因为它们仍然出现在 variable 的可变长度部分-length 参数列表,并考虑到%f
和%lf
之间的不对称printf
等怪癖scanf
。
推荐阅读
- arrays - Raku:有没有一种超级快速的方法可以将数组转换为字符串,而无需空格分隔元素?
- docker - sam build --use-container 失败,但 sam build 成功
- jquery - 如何初始化 Cropme
- c# - 与 Xamarin.Forms 中用于 Ios 设备的材料条目的条目行相比,需要解决光标定位为额外空间
- c# - .NET Framework 和 Entity Framework Core:如何获取连接字符串
- mysql - 存储二进制字符串mysql
- node.js - Node/RabbitMQ - 向 nodejs 路由发送消费者响应
- html - 我想用 Unity3D 修改 Webgl Platform Building 的输出
- python - scikit multilearn:accuracy_score ValueError:不支持多类多输出
- flutter - 如何在flutter Map构造函数中处理来自Firestore的可选字段?