在C语言中,可以使用多文件进行代码组织和模块化开发。这有助于提高代码的可读性、可维护性和重用性。
单纯的使用源文件,组织项目结构的时候,项目越大越复杂的时候,维护的成本会变的越高!
.h: 头文件,组织项目结构的时候,减少大型项目的维护成本问题。
头文件包含函数原型、宏定义、类型定义等。将相关的函数原型和共享的变量放在头文件中,并使用预处理指令 #ifndef、#define、#endif 进行条件编译保护,以防止头文件被重复包含。
test.h 头文件内容:
#pragma once//解决头文件重复包含问题
#include
//1、c头文件
//2、所有的变量声明
//3、所有的函数声明
//4、#define,类型typedef,struct
extern void show(int x);//函数的声明,函数中的extern建议带上extern!
将具体的函数实现放在源文件中。可以根据逻辑关系和功能进行划分,一个功能模块通常对应一个源文件。
test.c 源文件内容:
#include"test.h"
void show(int x)
{
printf("show_hallo\n");
}
main.c 源文件内容:
#include"test.h"
int main()
{
show(100);
return 0;
}
在需要使用某个模块的源文件中,使用 #include 指令包含对应的头文件。这样,可以在当前源文件中访问该模块的函数和变量。
使用编译器将所有的源文件编译成目标文件(.o文件),然后通过链接器将各个目标文件链接成最终的可执行程序。在编译时,需要同时指定所有的源文件
在C语言中,要在多个文件中共享全局变量和函数,需要进行一些额外的操作。下面是一些方法来实现全局变量和函数的跨文件使用:
将需要在多个文件中使用的全局变量和函数的声明放在一个头文件中,并在需要使用它们的源文件中包含该头文件。这样,所有包含该头文件的源文件都可以访问这些全局变量和函数。
在定义全局变量的源文件中,使用 extern 关键字进行外部变量声明。外部变量声明告诉编译器该变量已经在其他地方定义,避免重复定义。
在编译和链接时,将所有涉及到全局变量和函数的源文件一起编译,并将它们链接成最终的可执行文件。
假设我们有两个源文件:main.c 和 test.c,以及一个头文件 test.h。我们要在 main.c 中调用 test.c 中定义的全局变量和函数。
//test.h
#pragma once//解决头文件重复包含问题
#include
extern int g_val;//全局变量声明,变量声明必须带上extern!
//extern int g_val = 100; 这样写是不行的
//声明并没有开辟空间!
//=100,叫做赋值或者初始化
//所有的变量声明的时候,不能设置初始值
extern void show(int x);//函数的声明,函数中的extern建议带上extern!
//test.c
#include"test.h"
void show(int x)
{
printf("show_hallo\n");
}
//main.c
#include"test.h"
int main()
{
printf("%d\n", g_val);//打印全局变量
show(100);
return 0;
}
在具体的运用场景中,有没有可能,我们不想让全局变量或者函数跨文件访问,只在文件的内部被访问?
static修饰全局变量,该变量只在本文件被访问,不能被外部文件访问
改变作用域:使用 static
关键字修饰全局变量时,变量的作用域限定在声明它的源文件中,无法被其他源文件访问。这样做可以避免全局变量被意外地修改或访问。
延长生命周期:使用 static
关键字修饰全局变量时,变量的生命周期与整个程序的执行周期相同,即从程序启动到结束。与普通的全局变量不同,static关键字修饰的全局变量始终存在于内存中,不会因函数的调用而创建或销毁。
示例
// file1.c
#include
static int staticGlobalVariable = 10; // 使用static修饰的全局变量
int GlobalVariable = 10; //不使用static修饰全局变量
void printStaticGlobalVariable(void) {
printf("Static Global Variable in file1.c: %d\n", staticGlobalVariable);
}
// file2.c
#include
//extern int staticGlobalVariable; // 在file1.c中声明的全局变量
extern int GlobalVariable;
/*
void modifyStaticGlobalVariable(void) {
staticGlobalVariable = 20;// 如果像这样尝试更改会出现链接错误,也就是说在链接时找不到全局变量
printf("Modified Static Global Variable in file2.c: %d\n", staticGlobalVariable);
}//报错
*/
void modifyGlobalVariable(void) {
GlobalVariable = 20;
printf("Modified Global Variable in file2.c: %d\n", GlobalVariable);
}
// main.c
extern void printStaticGlobalVariable(void); //声明函数
//extern void modifyStaticGlobalVariable(void);
extern void modifyGlobalVariable(void);
int main() {
printStaticGlobalVariable();
//modifyStaticGlobalVariable();
modifyGlobalVariable();
printStaticGlobalVariable();
return 0;
}
Static Global Variable in file1.c: 10
Modified Global Variable in file2.c: 20
Global Variable in file1.c: 20
在上述示例中,staticGlobalVariable 是一个使用 static 关键字修饰的全局变量,它的作用域限定在 file1.c 内部,GlobalVariable是一个普通全局变量,其作用域是在整个工程内。
在 file2.c 中,通过 extern 关键字声明该全局变量GlobalVariable,可以访问和修改它。在 main.c 中,调用 printGlobalVariable 和 modifyGlobalVariable 函数来展示静态全局变量的值。
//test.h
#pragma once
#include
extern void show(int num);
//test.c
#include"test.h"
static void show(int num)
{
printf("hello show()! %d", num);
}
//main.c
#include"test.h"
int main()
{
show(200);
return 0;
}
//test.h
#pragma once
#include
//extern void show(int num);
extern void show_helper();
//test.c
#include"test.h"
static void show(int num)
{
printf("hello show()! %d", num);
}
void show_helper()
{
show(200);
}
//main.c
#include"test.h"
int main()
{
//show(200);
show_helper();
return 0;
}