C原型函数

6
作为一个C语言初学者,我可以理解在文件中需要函数原型的必要性,但是还有一些不确定的事情。
首先,每次在main函数外调用函数时,是否都需要原型声明?是否存在任何可以改变这种情况的条件?
其次,对于方法重载,是否需要单独的函数原型?
4个回答

8
在C语言中,函数调用不需要可见的原型,但强烈建议在范围内有一个正确的原型。这样做的原因是,如果函数定义与函数参数类型不匹配,那么在执行默认函数参数提升后,您很可能会得到未定义的行为。如果有正确的原型可见,则编译器可以检查函数调用的参数,并在存在不匹配时警告程序员。C语言不允许函数重载,因此对于任何函数名,只能有一个原型。默认参数提升可能导致意外的不匹配。例如:
int main(int argc, char **argv)
{
    short s = 5;
    float f = 2.3f;
    x(s, f);     // x implicitly declared; default argument promotions performed
    return 0;
}

int x(short t, float g)  // Error: called with an int and a double
{
    return (int)(t + g);
}

在函数调用中,因为x没有可见的原型(尚未定义),所以s将被提升为int,而f将被提升为double。这些是默认参数提升。这导致在使用一个带有shortfloat参数的原型定义函数时出现了不匹配,即使这些是传递的原始参数的类型。
带有可变数量参数的函数(即使用, ...语法)必须在调用它们的点上具有可见的原型。

4

其他人已经指出,C语言不需要函数原型。我只想补充一些小点。

首先,没有原型的情况下,函数的参数总是在作为参数之前进行“默认提升”,因此(例如)所有较小的整数类型都会被提升为int,而float则会被提升为double。因此,如果没有原型,函数无法接收(例如)charshortfloat。如果函数确实被定义为接收其中某种类型,则传递的参数与函数期望的参数将不匹配,导致未定义的行为(任何其他不匹配也会导致未定义的行为)。

其次,如果一个函数用可变数量的参数定义,那么就需要为它提供原型,否则调用它将导致未定义的行为。


1

不,函数不需要原型。然而,它们很有用,因为它们允许在声明之前调用函数。例如:

int main(int argc, char **argv)
{
    function_x(); // undefined function error
    return 0;
}

void function_x()
{

}

如果您在main上方添加原型(通常在头文件中完成),它将允许您调用function_x,即使它在main之后定义。这就是为什么在使用需要链接的外部库时,您需要包含带有所有函数原型的头文件。
C语言没有函数重载,因此这是无关紧要的。

2
你所注释的地方不会导致编译错误。function_x();将隐式声明为一个未经原型声明的返回int函数。但是,如果该函数后续被声明为返回void,则会出现错误。 - CB Bailey

0

不是每个函数在C语言中都需要原型。但是最好还是包含它,因为原型有助于编译器捕获错误。当然,一些C编译器默认情况下会在函数调用之前抱怨缺少原型,但这种行为并不一定是标准的。

上述逻辑也适用于重载。

当然,由于您是C语言的新手,我认为您最好去查找函数原型和定义之间的区别,以便完全理解。


确保在使用函数之前,找到编译器选项以确保所有函数都声明了完整的原型,并确保始终使用编译器选项并注意其警告,这是良好的编程纪律。 - Jonathan Leffler

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接