C语言多文件编程中全局变量的声明与定义会遇到的问题
描述:
- 在学习C语言的多文件编程的时候,看到声明全局变量竟然和声明函数一样,在.h文件中通过extern关键字声明后,还要在.c文件中"定义一次"有些不解,所以我到百度上看了些博客,那些博客对声明和定义的说法是:
- extern int a;// 这个是声明。
- int a;// 这个是定义。
- int a = 10;// 这样也是定义。
- 对于网上的声明的定义的说法,我觉得有些问题。
- 开发工具Clion,编译工具:mingw。
1.创建3个文件,分别是main.c、test.h、test.c,具体代码如下:
1.1.1 test.h
| #ifndef _TEST_H |
| #define _TEST_H |
| |
| #include <stdio.h> |
| |
| |
| extern int a; |
| |
| extern void show(); |
| |
| #endif |
1.1.2 test.h
| #include "test.h" |
| |
| |
| int a; |
| |
| void show(){ |
| printf("show函数\n"); |
| } |
1.1.3 main.c
| #include "test.h" |
| |
| |
| int main(void) { |
| a = 10; |
| printf("%d",a); |
| |
| show(); |
| return 0; |
| } |
1.1.4 这样能直接编译通过。
2.创建3个文件,分别是main.c、test.h、test.c,具体代码如下:
2.1.1 test.h
| #ifndef _TEST_H |
| #define _TEST_H |
| |
| #include <stdio.h> |
| |
| |
| extern int a; |
| |
| extern void show(); |
| |
| #endif |
2.1.2 test.h
| #include "test.h" |
| |
| |
| |
| |
| void show(){ |
| printf("show函数\n"); |
| } |
1.1.3 main.c
| #include "test.h" |
| |
| |
| int main(void) { |
| a = 10; |
| printf("%d",a); |
| |
| show(); |
| return 0; |
| } |
1.1.4 这样不能直接编译通过。
- 报了这样一个错:undefined reference to `a'
- 意思是对“a”的未定义引用。
3.创建3个文件,分别是main.c、test.h、test.c,具体代码如下:
3.1.1 test.h
| #ifndef _TEST_H |
| #define _TEST_H |
| |
| #include <stdio.h> |
| |
| |
| |
| |
| extern void show(); |
| |
| #endif |
3.1.2 test.h
| #include "test.h" |
| |
| |
| int a; |
| |
| void show(){ |
| printf("show函数\n"); |
| } |
3.1.3 main.c
| #include "test.h" |
| |
| int main(void) { |
| a = 10; |
| printf("%d",a); |
| |
| show(); |
| return 0; |
| } |
3.1.4 这样开发工具直接报错,也不能编译通过。
- 开发工具报错:Use of undeclared identifier 'a'。
- 意思是:使用未定义的标识符 'a'。
- 编译报错:error: 'a' undeclared (first use in this function)。
- 大致意思是:'a' 在main函数第一次使用时,没有定义。
4.创建3个文件,分别是main.c、test.h、test.c,具体代码如下:
4.1.1 test.h
| #ifndef _TEST_H |
| #define _TEST_H |
| |
| #include <stdio.h> |
| |
| |
| extern int a; |
| |
| extern void show(); |
| |
| #endif |
4.1.2 test.h
| #include "test.h" |
| |
| |
| int a; |
| |
| void show(){ |
| a = 10; |
| printf("%d\n",a); |
| printf("show函数\n"); |
| } |
4.1.3 main.c
| #include "test.h" |
| |
| int main(void) { |
| show(); |
| return 0; |
| } |
4.1.4 这样能直接编译通过。
4.创建4个文件,分别是main.c、test.h、test.c、test2.c 具体代码如下:
4.1.1 test.h
| #ifndef _TEST_H |
| #define _TEST_H |
| |
| #include <stdio.h> |
| |
| |
| extern int a; |
| |
| extern void show(); |
| extern void show2(); |
| |
| #endif |
4.1.2 test.h
| #include "test.h" |
| |
| |
| int a; |
| |
| void show(){ |
| printf("show函数\n"); |
| } |
4.1.3 test.h
| #include "test.h" |
| |
| int a; |
| |
| void show2(){ |
| printf("test2.h"); |
| } |
4.1.4 main.c
| #include "test.h" |
| |
| int main(void) { |
| a = 10; |
| printf("%d",a); |
| |
| show(); |
| show2(); |
| return 0; |
| } |
4.1.5 这样能直接编译通过。
- 这次,在test.c和test2.c中,都有“ int a; ”这行代码,没有对a进行赋值操作,在main函数中才进制赋值操作。
5.创建4个文件,分别是main.c、test.h、test.c、test2.c 具体代码如下:
5.1.1 test.h
| #ifndef _TEST_H |
| #define _TEST_H |
| |
| #include <stdio.h> |
| |
| |
| extern int a; |
| |
| extern void show(); |
| extern void show2(); |
| |
| #endif |
5.1.2 test.h
| #include "test.h" |
| |
| |
| int a = 10; |
| |
| void show(){ |
| printf("show函数\n"); |
| } |
5.1.3 test.h
| #include "test.h" |
| |
| int a = 20; |
| |
| void show2(){ |
| printf("test2.h"); |
| } |
5.1.4 main.c
| #include "test.h" |
| |
| int main(void) { |
| a = 10; |
| printf("%d",a); |
| |
| show(); |
| show2(); |
| return 0; |
| } |
5.1.5 这次不能直接编译通过。
- 这次,在test.c和test2.c中,int a 后面加上赋值操作。
- 这次编译报错: multiple definition of `a'。
- 意思是:多次定义 ' a '。
6.创建4个文件,分别是main.c、test.h、test.c、test2.c 具体代码如下:
6.1.1 test.h
| #ifndef _TEST_H |
| #define _TEST_H |
| |
| #include <stdio.h> |
| |
| |
| |
| |
| extern void show(); |
| extern void show2(); |
| |
| #endif |
6.1.2 test.h
| #include "test.h" |
| |
| |
| int a; |
| |
| void show(){ |
| a = 10; |
| printf("%d\n",a); |
| printf("show函数\n"); |
| } |
6.1.3 test.h
| #include "test.h" |
| |
| int a; |
| |
| void show2(){ |
| a = 20; |
| printf("%d\n",a); |
| printf("test2.h"); |
| } |
6.1.4 main.c
| #include "test.h" |
| |
| int main(void) { |
| show(); |
| show2(); |
| return 0; |
| } |
5.1.5 这次能直接编译通过。
- 这次 a 没有在.h文件中声明。
- 这次在test.c和test2.c文件中,都对a进行定义且赋值操作。
总结:
- 1.1 在多文件编程中,如果在.h文件中,通过extern关键字声明了某个全局变量(这里假定为:a),其他.c文件如果想使用这个变量的话,必须定义一次(也就是没有赋值的定义,类似:int a;)
- 1.2 且无论多少个.c文件导入了该头文件,都可以定义一次该变量,但有个前提,该变量都不能在函数体外赋值。
- 2.1 在多文件编程中,如果 没有 在.h文件中,通过extern关键字声明了某个全局变量(这里假定为:a),只要 不同时 在定义的时候不赋予初始值,那么都可以定义(类似:int a;)。(赋值方式:在函数中赋值)。
- 2.2 在不同的.c文件中,定义相同的全局变量(假定为a),他们的地址都相同。
- 后续会查询资料更新这个博客。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· .NET10 - 预览版1新功能体验(一)