学科分类
目录
C语言

多文件之间的函数调用

多文件之间也可以进行函数的相互调用,根据函数能否被其他源文件调用,可以将函数分为外部函数和内部函数,下面分别进行讲解。

1、 外部函数

在实际开发中,一个项目的所有代码不可能在一个源文件中实现,而是把项目拆分成多个模块,在不同的源文件中分别实现,最终再把它们整合在一起。为了减少重复代码,一个源文件有时需要调用其他源文件中定义的函数。在C语言中,可以被其他源文件调用的函数称为外部函数。

外部函数的定义方式是在函数的返回值类型前面添加extern关键字,表明该函数可以被其他的源文件调用。当有源文件要调用其他源文件中的外部函数时,需要在本文件中使用extern关键字声明要调用的外部函数,示例代码如下:

extern int add(int x,int y); //add()函数是定义在其他源文件中的外部函数

在上述示例代码中,编译器会通过extern关键字判知add()函数是定义在其他文件中的外部函数。

为了帮助大家理解外部函数的概念,下面通过一个案例演示外部函数地调用,该案例中有first.c与second.c两个源文件,first.c文件中定义了一个外部函数add(),second.c文件中需要调用add()函数,则first.c文件与second.c文件的代码分别如例1所示。

例1

first.c

 1    extern int add(int x,int y)     //定义外部函数add()
 2    {
 3        return x+y;
 4    }
second.c
 1    extern int add(int x,int y);     //使用 extern 关键字声明要调用的外部函数add()
 2    int main()
 3    {
 4        printf("%d",add(1,2));         //调用外部函数add()
 5        return 0;
 6    }

例1的运行结果如图1所示。

图1 例1运行结果

在例1中, first.c文件使用extern关键字定义了外部函数add(),表明add()函数可以被其他源文件调用。second.c文件中,第1行代码使用extern关键字声明add()函数;第4行代码调用add()函数,并传入参数1和2。由图1可知,成功输出结果3。

需要注意的是,在使用extern关键字声明外部函数时,函数的返回值类型、函数名与参数列表都需要与原函数保持一致。

上面讲解的内容是外部函数的标准定义与调用方式,但随着编译器地发展,编译器默认用户定义的函数都是外部函数,因此用户在定义函数时即使不写extern关键字,定义的函数也可以被其他源文件调用,调用外部函数的源文件也不必在本文件中使用extern关键字声明外部函数。例如例1中first.c文件中的代码可以简化如下:

int add(int x,int y) //编译器默认add()函数为外部函数
{
  return x+y;
}

second.c文件中代码可以简化如下:

int main()
{
  printf("%d",add(1,2)); //在 second.c 文件中可以直接调用 add()函数
  return 0;
}

2、 内部函数

在C语言程序中,只要在当前文件中声明一个函数,该函数就能够被其他文件调用。但是当多人参与开发一个项目时,很有可能会出现函数重名的情况,这样,不同源文件中重名的函数就会互相干扰。此时,就需要一些特殊函数,这些函数只在它的定义文件中有效,不能被其他源文件调用,该类函数称为内部函数。

在定义内部函数时,需要在函数的返回值类型前面添加static关键字(又称为静态函数),被声明为静态函数后,函数只能在本文件中调用,内部函数定义示例代码如下:

static void show(int x)      //添加static关键字定义内部函数
{
  printf("%d",x);
}

为了让读者熟悉内部函数的作用,接下来通过一个案例演示内部函数的用法,该案例包含first.c、second.c和main.c三个文件,在first.c和second.c文件中都定义了一个show()函数,只是second.c文件将show()函数声明为了内部函数。在main.c文件中调用show()函数。first.c、second.c和main.c文件代码如例2所示。

例2

first.c

 1  void show()
 2  {
 3    printf("%s \n","first.c" );
 4  }

second.c

 1  static void show()       //show()函数为内部函数
 2  {
 3    printf("%s \n","second.c");
 4  }

main.c

 1  int main()
 2  {
 3    show();          //调用show()函数
 4    return 0;
 5  }

例2运行结果如图2所示。

图2 例2运行结果

在例2中,first.c文件与second.c文件中分别定义了show()函数,second.c文件中的show()函数被定义为了静态函数。在main.c文件中调用show()函数,从图2可以看出,first.c中的show()函数被调用成功了,而second.c文件中的show()函数未被调用,因此说明内部函数只在second.c文件中有效,无法在别的文件中调用。

image-20200521111440552脚下留心:多文件中的函数重名

在例2中,如果将second.c中修饰show()函数的关键字static删除,运行时程序会提示错误,如图3所示。

图3 程序提示错误

从图3中的错误结果可以看出,多个源文件中出现同名函数,在调用时会发生重定义错误。

点击此处
隐藏目录