首页 > 解决方案 > 仅当未指定函数原型时才将浮点数转换为双精度数

问题描述

前几天我一直在学习 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 呢?

标签: c

解决方案


您看到的是默认参数提升的效果,它适用于 (a) 可变长度参数列表的可变长度部分,以及 (b) 当函数在范围内没有原型的情况下被调用时。默认的参数promotions 说,基本上,任何小于的东西int都被提升为int,并且float被提升为double

当 C 是新的并且还没有发明函数原型时,这些规则使调用约定更简单,编译器更小。

今天,随着函数原型或多或少普遍存在,这些规则几乎是不必要的,几乎被遗忘了,尽管它们可能比过去更令人困惑,因为它们仍然出现在 variable 的可变长度部分-length 参数列表,并考虑到%f%lf之间的不对称printf等怪癖scanf


推荐阅读