1 功能说明
extern可以放变量或函数前,用以标识变量或者函数的定义在别的文件中,提示编译器遇到此变量和函数时在其他模块中寻找定义。如在头文件中某个变量或者函数前加extern,在头文件中只声明函数或者变量,而在.c文件中进行函数的定义。
2 函数或者变量前加extern
2.1 实例介绍
常见的方式是在一个头文件中声明的函数前加extern,然后在.C文件中先保护头文件,然后再定义。
main.c文件
1 #include <stdio.h>
2 #include "exter.h"
3 #include "exter2.h"
4 int main()
5 {
6 int num1 = 10;
7 int num2 = 20;
8 int num3 = add(num1, num2);
9 printf("sum = %d\n", num3); //sum = 30
10
11 num = 200;
12 printf("now num = %d\n", num); //now num = 200
13
14 multi(num,num2);
15
16 }
exter.h 文件
1 #ifndef EXTER_H
2 #define EXTER_H
3
4 #include <stdio.h>
5
6 extern int num;
7 extern int add(int a, int b);
8
9 #endif
exter.c文件
1 #include "exter.h"
2
3 int num = 120;
4
5 int add(int a, int b)
6 {
7 printf("into exter.c and num = %d\n", num);
8
9 int c = a + b;
10 return c;
11 }
exter2.h
1 #ifndef EXTER2_H
2 #define EXTER2_H
3
4 extern int multi(int a, int b);
5
6 #endif
exter2.c
1 #include "exter2.h"
2 #include "exter.h"
3
4 int multi(int a, int b)
5 {
6 printf("exter2 now num = %d\n",num);
7 printf("a * b = %d\n",a * b); //a * b = 4000
8 }
如上面的一些.h文件中通过extern关键字修饰函数或者变量,然后被修饰的函数和变量在main.c文件中使用。这里变量num在exter.h文件中声明,在exter.c文件中赋值,在main.c中修改,在exter2.c中使用。被修改后变量num的值发生改变,在后面的使用中使用的是新的值。
2.2 编译过程
通过gcc编译查看编译过程会发现,在一个文件中通过include方式包含另一个文件后,在预处理阶段会将包含的头文件中的内容都包含到当前文件中,所以加extern后会被包含一次。gcc的编译链接过程可以参照gcc程序的编译过程和链接原理
这里展示下通过: gcc -E -o main.i main.c 后得到的main.i文件中的形式。
837 # 2 "main.c" 2
838 # 1 "exter.h" 1
839
840
841
842
843
844 extern int num;
845 extern int add(int a, int b);
846 # 3 "main.c" 2
847 # 1 "exter2.h" 1
848
849
850
851 extern int multi(int a, int b);
852 # 4 "main.c" 2
853
854 int main()
855 {
856 int num1 = 10;
857 int num2 = 20;
858 int num3 = add(num1, num2);
859 printf("sum = %d\n", num3);
860
861 num = 200;
862 printf("now num = %d\n", num);
863
864 multi(num,num2);
865
866 }
上面是预处理后的main.i文件,可以看出相当于在main函数前先声明了num变量和add函数
1.2 函数或者变量前加extern C
同样的通过gcc显示编译过程得到的*.o文件可以看出加extern C与不加extern C的区别。
得到汇编文件:gcc -c -o main.o main.c
查看汇编文件:nm main.o
[Humboldt@gld extern]$ gcc -c -o main.o main.c
[Humboldt@gld extern]$ nm main.o
U add
0000000000000000 T main
U multi
U num
U printf