是否应使用extern?C语言多文件全局变量声明方案咨询
全局变量的正确管理方案
先直接给结论:绝对不要像你示例里那样在头文件直接定义全局变量——每个包含该头文件的.c文件都会生成一个变量副本,链接时必然报重复定义错误。针对你的场景,更推荐第二种方案:
两种方案对比
方案1:在需要的头文件逐个加extern声明
- 操作:在
pass_args.h、kbd.h这些需要用到全局变量的头文件里,分别写extern double freq; extern double amp; extern [waveforms的类型] waveforms; - 然后在某一个.c文件(比如
main.c)里定义这些变量:double freq; double amp; [类型] waveforms; - 缺点:变量多的话,每个头文件都要重复写extern,维护起来麻烦,容易漏写或写错类型。
方案2:单独创建global_variables.h(推荐)
这是更规范、易维护的做法,步骤如下:
- 声明变量:在
global_variables.h里用extern声明所有全局变量,加上头文件保护避免重复包含:#ifndef GLOBAL_VARIABLES_H #define GLOBAL_VARIABLES_H extern double freq; extern double amp; extern [你的waveforms类型] waveforms; // 比如是浮点数组就写extern double waveforms[10]; #endif - 定义变量:找一个单独的.c文件(比如新建
global_vars.c,或者用main.c也可以),定义这些变量(这里不要加extern):#include "global_variables.h" double freq; double amp; [你的waveforms类型] waveforms; - 使用变量:在所有需要用到这些全局变量的.c文件里,直接包含
global_variables.h就行,不用再单独写extern。
修正你的示例代码
你原来的示例错误在于头文件直接定义变量(没加extern),导致main.c和change_freq.c各生成一个freq和amp,链接时会报错。修正后的代码如下:
global_variables.h(修正版)
#ifndef GLOBAL_VARIABLES_H #define GLOBAL_VARIABLES_H extern double freq; extern double amp; #endif
global_vars.c(新增文件,专门用来定义全局变量)
#include "global_variables.h" double freq; double amp;
change_freq.c(保持不变)
#include "change_freq.h" void increment_freq(double *frequency) { (*frequency)++; if (*frequency == 1) { amp++; } }
change_freq.h(保持不变)
#ifndef CHANGE_FREQ_H #define CHANGE_FREQ_H #include "global_variables.h" void increment_freq(double *frequency); #endif
main.c(补充了stdio.h,因为要用printf)
#include "global_variables.h" #include "change_freq.h" #include <stdio.h> int main() { freq = 0; increment_freq(&freq); printf("Hello World!\n"); printf("freq %lf\n", freq); printf("amp %lf\n", amp); return 0; }
关键原理
C语言中,头文件被多个.c文件包含时,代码会被拷贝到每个.c文件中。如果头文件里直接写double freq;,这是定义变量,每个.c文件都会生成一个独立的freq变量;而extern double freq;是声明变量,只是告诉编译器“这个变量在其他地方已经定义了”,不会生成新的变量副本,所以链接时不会冲突。
内容的提问来源于stack exchange,提问作者Jayden
相关产品推荐
相关产品推荐

