历史上,模块化作为将大型项目分割成独立的逻辑部分的方式出现,以提高可读性、代码重用性和开发者之间的责任分离。在C语言中,模块化在文件级别实现——源文件(.c)和头文件(.h)。
程序员面临的问题是:如何组织代码之间的交互,避免定义重复,不破坏封装性并简化构建过程。
解决方案是使用接口与实现的分离:
模块化代码的结构示例:
// mymath.h #ifndef MYMATH_H #define MYMATH_H int add(int, int); #endif // mymath.c #include "mymath.h" int add(int a, int b) { return a + b; } // main.c #include "mymath.h" #include <stdio.h> int main() { printf("%d ", add(3, 4)); return 0; }
主要特点:
可以在头文件中用extern定义变量,并安全地在多个模块中使用它吗?
不可以!应该只在一个*.c*文件中定义全局变量,而在头文件中只通过extern声明它们。否则将会由于“多个定义”而出现链接错误。
包含每个头文件时是否必须只使用一次 #include?
必须用保护宏(#ifndef/#define/#endif)将每个*.h*文件包裹起来,否则在多次包含时会导致声明冲突和编译错误。
能否在C语言中实现对私有数据结构的完全封装(不透明指针)?
可以。所谓的“不透明指针”允许隐蔽用户对结构的细节:
// mystruct.h typedef struct MyStruct MyStruct; MyStruct* create(void); void destroy(MyStruct*); // mystruct.c struct MyStruct { int a; };
所有逻辑都实现于一个长*.c*文件中,代码重复,全局变量冲突,导致链接错误。
优点:
缺点:
代码按模块进行了解耦,使用了包含保护,私有数据通过不透明指针封装。
优点:
缺点: