作为C的初学者,我可以理解文件中对函数原型的需求,但我不确定几件事情。
首先,在main之外的每个函数调用都需要原型声明吗?有什么条件可以改变吗?
其次,您是否需要单独的函数原型来进行方法重载?
答案 0 :(得分:8)
C语言中的函数调用不需要原型可见,但强烈建议正确的原型在范围内。
原因是如果在执行默认函数参数提升后函数定义与函数参数的类型不匹配,则很可能会得到未定义的行为。
正确的原型可见意味着编译器可以检查函数调用的参数,并警告程序员是否存在不匹配。
C不允许函数重载,因此任何函数名都只能有一个原型。
默认参数促销可能会导致意外不匹配。
E.g。
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
}。这些是默认参数促销。然后,当使用带有short
和float
的原型定义函数时,这会导致不匹配,即使这些是传入的参数的原始类型。
采用可变数量参数的函数(即使用, ...
语法)必须始终在调用它们时具有可见原型。
答案 1 :(得分:4)
其他人已经指出C不需要原型功能。我只想添加几个小点。
首先,没有原型,函数的参数在作为参数传递之前总是经历“默认促销”,因此(例如)所有较小的整数类型都被提升为int
和{{ 1}}被提升为float
。因此,如果没有原型,函数就不可能接收(例如)double
,char
或short
。如果函数 被定义为接收其中一种类型,那么传递的内容与函数期望的内容将不匹配,从而产生未定义的行为(任何其他不匹配也会产生未定义的行为)。
其次,如果使用变量参数列表定义函数,则执行需要原型,否则调用它将导致未定义的行为。
答案 2 :(得分:1)
不,函数不需要原型。但是,它们很有用,因为它们允许在声明函数之前调用它们。例如:
int main(int argc, char **argv)
{
function_x(); // undefined function error
return 0;
}
void function_x()
{
}
如果您在main
上方添加原型(这通常在头文件中完成),它将允许您调用function_x
,即使它是在main
之后定义的。这就是为什么当您使用需要链接的外部库时,包含头文件以及其中的所有函数原型。
C没有函数重载,所以这是无关紧要的。
答案 3 :(得分:0)
没有。在C中,并非每个功能都需要原型。但是包含它是一种很好的做法。原型有助于编译器捕获错误。 当然,一些C编译器默认会在函数调用之前丢失原型,但这种行为不一定是标准。
上述逻辑也适用于过载。
当然,因为你是C的新手。我认为你最好去查看一个Prototype和一个函数的定义之间的区别,以充分发挥作用。