多文件程序设计

多文件之间的互相访问

  • 每个文件可以定义功能接口(可被其他文件访问的函数或数据)

    • 源文件:代码实现文件,后缀 .c
    • 头文件:源文件的接口定义文件,后缀为 .h
  • 当需要使用其他文件提供的功能时,包含对应的头文件

1
2
#include<header.h> // 在编译系统文件中查找头文件
#include"header.h" // 先查找当前工程文件夹,再查找编译系统文件夹

a.c 如果想要访问 b.c 中的代码:

b.c 将对应的代码声明在 b.h 头文件中

a.c 引入 b.h 头文件,即可使用对应的代码

多文件程序设计的一些原则

  • 头文件中只做函数声明和变量声明(不做具体定义
  • 头文件中可以定义数据类型(typedef,struct,union,enum)
  • 根据具体实现,一个头文件可以对应多个源文件(多数情况一对一)
  • 不要使用 #include 语句包含源文件

全局变量

普通全局变量

  • 源文件中定义的全局变量可在所有其他源文件中使用
  • 可使用 extern 关键字在头文件中进行声明,并在其他文件中使用

静态全局变量

  • static 修饰的全局变量只能在当前源文件中使用
  • 无法通过 extern 关键字声明,在其他文件中使用
1
2
3
4
5
6
7
// head.h
extern int g_var;
extern int f_var; // 只会有 WARNING 因为语法上是合法的,但记住 f_var 被 static 所修饰只能在本身所在的源文件中使用

// head.c
int g_var = 1;
static int f_var = 2;

注意

  • 函数声明语句默认自带 extern 关键字修饰
  • 类型定义必须在头文件中,仅类型声明无法创建变量
  • 静态全局变量
    • 生命期为程序运行期
    • 作用域仅在定义的文件中
    • 无法直接在其他文件中使用
  • static 关键字可使函数具备文件作用域(静态函数)
  • 静态函数无法在其它文件中被调用
  • 函数设计时需要考虑是否在其他文件中使用

多个 c 文件互相调用再不通过 .h 文件的情况下

在 C 语言中,两个 .c 文件之间可以互相调用对方的函数或变量,但这通常是通过声明的方式来实现的。在不使用 .h 头文件的情况下,可以在一个 .c 文件中通过使用 extern 关键字声明另一个 .c 文件中的函数或变量。extern 告诉编译器某个函数或变量是在其他文件中定义的,链接器在链接时会找到对应的定义。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
// file1
#include <stdio.h>

// 定义变量和函数
int global_variable = 42;

void function_in_file1() {
printf("This is function in file1.c\n");
}

=========================================

file2
#include <stdio.h>

// 声明 file1.c 中的变量和函数
extern int global_variable;
extern void function_in_file1();

void function_in_file2() {
printf("This is function in file2.c\n");
printf("global_variable from file1.c: %d\n", global_variable);
function_in_file1(); // 调用 file1.c 中的函数
}

在 C 语言中,**extern** 关键字的作用是告诉编译器某个变量或函数的定义在别的文件中,但它并不需要知道这个变量具体在哪个文件定义。真正把两个 .c 文件关联起来的过程发生在链接阶段,而不是编译阶段。