C程序中函数的定义

时间:2014-03-31 20:50:14

标签: c function

在C程序中,您在哪里定义函数? 为什么?

我认为函数定义通常是在main函数之外和函数声明之后编写的。这是正确的?为什么呢?

谢谢大家!

4 个答案:

答案 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();
}

请注意,头文件仅包含foobar声明,而不是其实际代码。为了实现此目的,foo.cbar.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.cbar.c构建一个库并链接到该库(如果您想在其他程序中使用foobar,则非常有用):< / 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,然后只能在该源文件中使用。净效果与范围函数非常相似。