C 语言现代编程一 C与模块化
以经典栈的实现方法为例
bool 类型标准 在C99中加入类型标准 通过stdbool.h引入
C99 中废除了程序块的开始处声明变量的限制,可以通过在使用变量前声明变量来限制变量的作用域
在stack.c 中暴露出的问题是变量和函数的作用域。 buf 、top、isStackFull、isStackEmpty都被公开在全局命名空间中。如果其他代码中也使用相同名字的变量和函数就会发生冲突,导致链接错误。
修改方法 使用static 修饰符
static 只在该编译单位内有效,对其他无需对外公开的变量和函数指定static修饰符 实现了独立性和可以与其他程序结合运行
这时候由发现了一个问题,该实现方法中国年仅有一个栈,如果有多个栈道时候,如果再编写两个名字不同的,功能相同的函数:
bool push2(int val){...}
bool pop2(int val){...}
这样出现了代码冗余
解决办法
#define newStack(buf){ \
0,sizeof(buf)/sizeof(int),(buf) \
}
方法使用如下:
int buf[16];
Stack stack = newStack(buf);
宏展开后:
int buf[16];
Stack stack = {0,sizeof(buf)/sizeof(int),(buf)};
extern "C" 是什么
对于通用性的考虑,即使进行C++ 编译时也可以正常通过,也有单元测试工具使用是以C++编程为前提的考虑。这种情况下.c文件因为是被C编译器编译的所有没有什么问题,但是.h文件必须既能在C中编译,也能够在C++中编译。虽然C和C++兼容性很高,也可以几乎不用考虑兼容性问题,但还是必须注意调用规则。C编译和C++编译后,函数被赋予的名字不同,调用时栈中保存的参数的顺序也不同,因此C++ 中无法调用C函数,C亦无法调用C++函数。声明extern “C” 既可以像下面这样单行使用,也可以像上面那样以{}将代码块扩起来使用。
extern "C" bool push(Stack * p , int val);
前后夹着 #ifdef __cplusplus 是为了告诉编译器,extern "C" 仅在C++编译时才有效,C++标准规定了C++中编译时,__cplusplus标识符才会被定义。由于C编译器无法识别extern "C" ,会产生编译错误,因此必须采用以上方法来回避这个问题。
编译运行: