我正在开发一个嵌入式项目,项目的源代码(在C中)包含一个函数,用于检查以太网类型是否为轮询或中断。 我们有如下功能
unsigned char mode(void);
unsigned char xmode(void)
{
if(mode())
return 1;
return 0;
}
功能模式()没有正文。当xmode()函数调用函数mode()时会发生什么?
答案 0 :(得分:3)
在上面的代码中,unsigned char mode(void);
告诉编译器函数mode()
存在且它不接受任何参数但返回unsigned char
。
这并没有真正定义这个功能。它只定义了调用它的方式。这件事叫做function prototype
。
函数mode()
稍后在同一文件或另一个文件(可能是程序集文件)中定义。
函数原型的一个常见用途是实现递归。
考虑函数a()
和b()
,每个函数调用另一个函数,并在同一个文件中定义:
void a()
{
b();
}
void b()
{
a();
}
当编译器在b()
内看到a()
时,它对b()
实际上是什么或它应该是什么没有任何想法。显然,如果您更改定义a()
和b()
的顺序,则会遇到同样的问题,但现在a()
内部不会知道b()
。
要解决此问题,请添加原型:
void b();
void a()
{
b();
}
void b()
{
a();
}
现在编译器将知道b()
是什么(一个函数)并知道如何调用和使用它。
答案 1 :(得分:3)
扩展先前的答案。
这不是一个“空”函数,它是一个原型。
编译器使用它来输出您拥有的函数的对象代码。它需要能够正确设置函数调用并确保它处理任何转换等。目标代码将包含对函数的引用,链接器将使用正确的值替换这些引用。
这也意味着编译器可以为您执行错误检查,并获得比链接器更多的信息。有趣的是,C标准用于允许隐式声明函数。
(为简洁起见,这是简化的。)
答案 2 :(得分:2)
这将无法链接,或者您正在链接的文件包含实际的mode()
函数。