深入理解C语言-04 预处理

提到预处理,不由想起来一个经典问题。

C语言简单吗? 简单,C语言没多少语法,很快就学会。

的确,C语言如果没有预处理,的确会简单很多。但一旦有了,就复杂度上升了好几个等级。

C语言支持面向对象吗? 可以,预处理能帮你实现。

C语言有异常处理吗?可以,预处理能帮你实现。


预处理就是一个潘多拉盒子,可以让你上天堂,也可以让你下地狱。(笑话深入理解C语言-04 预处理


在认真学习C语言时,建议下载C语言规范:

C89  嵌入式领域使用得多,芯片公司提供的工具很多还不支持C99

C99  


规范不是用来看的,是用来查的。(笑话深入理解C语言-04 预处理


关于C语言编译器代码,可以参考下面2个:

TinyCC  (http://bellard.org/tcc/)

gcc (http://mirror.bjtu.edu.cn/gnu/gcc/)


实际项目中用得最多的就是下面几个:


#include 文件

注意:不要受C语言教材的影响,以为只可以加载.h文件。这是一个最大的思维定式。

可以加载任何文本文件。

比如  test.test 内容如下:

int myTestAry[] = { 0, 1, 2,3 ,4, 5};


#include "test.test"


这样,有什么好处呢?

最大的好处是可以和其他语言结合。

比如,我们可以用Python生成符合C语言语法的文本,比如,字体数据,图片数据等。


#define

#ifdef

#undef

#if

#endif

5个指令一起配合,能对源代码进行版本控制。

比如最常见的

#ifdef WIN32   /* 如果当前系统是WIN32平台 */

#endif

当然,#define定义的控制变量,也可以在编译脚本中用 -D变量名=变量值  替换。


#define 还有一个常见的作用是定义常量。

#define PI    3.1415926


不过,这些都是小用途。

真正强大的是用#define构建复杂机制。可惜,实际项目中为了可读性,基本被禁止。

有兴趣的可以搜,C语言与面向对象 C语言与异常处理  C语言与模板 或者看MFC中的宏。

这是一个让人痛苦并快乐的功能。


实际项目中用得最多的是打印Log语句。

比如跟踪函数执行:

#define FUNC_BEGIN()    do { printf("Enter %s %d \n", __FUNCTION__, __LINE__); } while(0)

#define FUNC_END()    do { printf("Leave %s %d \n", __FUNCTION__, __LINE__); } while(0)


在函数进入的地方,加 

FUNC_BEGIN();

函数返回的地方加:

FUNC_END();


更复杂的打印语句:

#define MYPRINT(...)   do { printf(__VA_ARGS__); } while(0)

  

__FUNCTION__: 当前函数名,由编译器决定

__LINE__: 当前代码行号

__VA_ARGS__: 可变参数


#error

编译报错。可以在代码中加下面语句进行测试下。(深入理解C语言-04 预处理

#error "不支持"


#pragma

控制编译器,与编译器实现有关。

实际项目中为了可移植性用得不多。

对于特定项目,建议使用前需要参考编译器说明,并在项目风险管理中加以说明。(这一点很重要,对项目跨平台移植很有意义)


总而言之,预处理是一个编译器展示自我的地方,也是一个让大家疯狂,让大家迷失的地方。

对于开发者来说,这就是天堂,对项目经理来说,这就是地狱。(深入理解C语言-04 预处理

深入理解C语言-04 预处理,布布扣,bubuko.com

深入理解C语言-04 预处理

上一篇:webpack(四)之babel


下一篇:C++ 类继承 常量对象调用函数