在C程序中,您在哪里定义函数? 为什么?
我认为函数定义通常是在main函数之外和函数声明之后编写的。这是正确的?为什么呢?
谢谢大家!
答案 0 :(得分:4)
您必须在main()
之外定义一个函数,因为main()
本身就是一个函数,C中不支持嵌套函数。
声明函数在现代C中不是必需的,因为函数定义意味着函数声明。这还有两个原因:
函数声明可以在头文件中导出,然后由导入头文件的其他翻译单元使用。
C通常是一次翻译,这意味着在没有警告声明之前你不能使用一个函数。如果函数a()
调用函数b()
,反之亦然,则在声明至少一个函数之前无法定义这两个函数。
答案 1 :(得分:2)
唯一真正的要求是,在一个语句首次调用之前,声明 函数,并且在所有内容链接在一起之前将其定义(在另一个被翻译的源文件,或者在以前翻译的目标文件或库中)。
如果您的程序很小并且您在一个源文件中包含所有内容,我建议的做法是在使用之前定义该函数,如下所示:
void foo( void )
{
// body of foo
}
void bar( void )
{
...
foo();
...
}
int main( void )
{
...
bar();
...
}
函数定义也可用作声明(指定返回类型以及函数的参数数量和类型)。您可以在main
之后添加定义,但在调用它们之前仍需要声明:
int main( void )
{
void bar( void );
...
bar();
...
}
void bar( void )
{
void foo( void );
...
foo();
...
}
void foo ( void )
{
// body of foo
}
您不必在foo
的正文中声明bar
,也不必在bar
正文中声明main
;你可以在`main:
void foo( void );
void bar( void );
int main( void )
{
...
bar();
...
}
void bar( void )
{
...
foo();
...
}
此样式的唯一问题是,如果更改函数的返回类型或更改任何参数,则必须逐步删除任何声明并更改它们。第一种方式(在使用前定义)读取“向后”,但它不是一个维护头痛。
如果您的程序在多个源文件之间划分,通常的做法是为每个源文件创建一个单独的头文件,并在任何其他源文件中创建该标头的#include
使用这些功能,如:
/**
* foo.h - Header file for function foo
*/
#ifndef FOO_H // Include guards; prevents the file from being processed
#define FOO_H // more than once within the same translation unit
void foo( void ); // declaration of foo
#endif
/**
* foo.c - Source file for function foo
*/
#include "foo.h"
...
void foo( void ) // definition of foo
{
// body of foo
}
/**
* bar.h - Header file for bar.h
*/
#ifndef BAR_H
#define BAR_H
void bar( void ); // declaration of bar
#endif
/**
* bar.c - Source file for bar.h
*/
#include "foo.h" // necessary because bar calls foo
void bar( void )
{
...
foo();
}
/**
* main.c - Source file for main
*/
#include "bar.h" // necessary because main includes bar
int main( void )
{
...
bar();
}
请注意,头文件仅包含foo
和bar
的声明,而不是其实际代码。为了实现此目的,foo.c
和bar.c
必须与main.c
一起编译,并且生成的目标文件必须全部链接在一起。你可以一次完成所有这些,例如:
gcc -o blah main.c foo.c bar.c
或者您可以单独编译每个文件并将目标文件链接在一起:
gcc -c foo.c
gcc -c bar.c
gcc -c main.c
gcc -o blan main.o foo.o bar.o
或者您可以使用foo.c
和bar.c
构建一个库并链接到该库(如果您想在其他程序中使用foo
和bar
,则非常有用):< / p>
gcc -c foo.c
gcc -c bar.c
ar cr libblurga.a foo.o bar.o
gcc -o blah main.c -lblurga
标准C不支持嵌套函数(即,在另一个函数体内定义函数)。某些实现(如gcc)支持嵌套函数作为扩展,但这不是通常的做法。
答案 2 :(得分:0)
私人声明会发布在您的.c文件之上:
static int your_function();
如果在您尝试调用它的地方定义了私有声明,则可以发出私有声明,但为了可维护性,最好在一个地方声明您的私人界面,就像您的公共界面一样。
.h文件中的公开声明:
extern int your_function();
头文件中的关键字'extern'总是隐式添加到您的函数声明中,但为了清楚起见,我倾向于明确地附加它。
函数定义适用于私有和公共声明:
int your_function() {
return 5;
}
或仅限私人:
static int your_function() {
return 5;
}
如果将外部函数定义标记为静态,GCC将失败并显示以下内容:
error: static declaration of ‘your_function’ follows non-static declaration
当编译器构建代码时,它几乎将所有#include语句替换为您包含的文件的内容,并且解析从上到下作为一个大文件。一旦你理解了这一点,大部分事情就会开始变得有意义。
答案 3 :(得分:0)
好问题。 Pascal系列中的语言通常具有范围函数的概念,就像任何其他声明/定义一样。
我认为答案在于C的起源,天堂原谅我,一个更好的宏汇编程序(使用标准库)。函数只是跳转地址,带有一点参数和返回值处理的堆栈魔法;功能“范围”在这个世界中是一个过于抽象的概念。
也就是说,通过将“辅助函数”与全局可见函数一起分组可以实现类似的效果,这些函数需要它们在同一个文件中;辅助函数将声明为static,然后只能在该源文件中使用。净效果与范围函数非常相似。