C语言 预处理

  • Post author:
  • Post category:其他

一、预处理内容

C语言的编译过程

预处理(-E生成.i)——>编译(-S 生成.s)——>汇编(-c生成.o)——>链接(.elf)

预处理内容

1、头文件展开

2、宏替换

3、条件编译

二、头文件展开——库文件展开

三、宏定义  

定义常量      #define MAX 100

定义表达式    

定义函数

1、替换逻辑     宏替换只做简单的替换,不检查语法,在预处理阶段进行

 2、宏定义的使用 定义预定俗成 字母大写

优点:

        1.定义常数时可以杜绝幻数(具体的数,不知道为啥是这些,可以用宏定义例如直接在程序中表现176表达不清楚   可以 #define high 176,),用一些自定义标识符去代替,提高代码可读性,方便修改数值 

        2.定义宏函数 对于一些小而频繁使用的函数功能用宏定义,本质就是一个宏,只在预处理阶段进行替换,不占用运行时的时间,减少了函数调用、返回、和系统为函数分配释放空间的过程(不绝对比它慢),用编译时间和内存空间换运行时间

缺点:简单替换,不做与语法检查,宏函数的定义中常使用do{}while(0)防止出现语法错误

3、内置宏函数   系统内置宏常用__***__表示,自定义时应避免,

__LINE__ 显示行号

__func__ 显示函数名

__DATE–显示日期

__TIME__显示时间

4、#和##      #字符串化运算符      ## 并接运算符

1.不替换参数,只替换对应字符

2、将对应字符字符串化

3、把宏参数名和宏定义代码连接在一起,形成一个新的标识符(只能两个)

        

四、条件编译  按照给定条件编译代码(只影响编译,不影响运行)

1、常见宏定义

#define            定义一个预处理宏
#undef            取消宏的定义

#if                   编译预处理中的条件命令,相当于C语法中的if语句
#ifdef              判断某个宏是否被定义,若已定义,执行随后的语句
#ifndef            与#ifdef相反,判断某个宏是否未被定义
#elif                若#if, #ifdef, #ifndef或前面的#elif条件不满足,则执行#elif之后的语句,相当于C语法中的else-if
#else              与#if, #ifdef, #ifndef对应, 若这些条件不满足,则执行#else之后的语句,相当于C语法中的else
#endif             #if, #ifdef, #ifndef这些条件命令的结束标志.
defined         与#if, #elif配合使用,判断某个宏是否被定义

2、常见的条件编译的三种形式

(1) #if defined(或者是ifdef)  <标识符(条件)>

     // 程序段

     #endif

(2)  #if !defined(或者是ifndef)  <标识符(条件)>

      //程序段

     //endif

(3)  #if ()

      //程序段1

      #elif ()

      //程序段2

      …….

      #else

      //程序段n

       #endif

应用:

1:注释代码

2、调试

3、避免头文件的重复包含

https://blog.csdn.net/xingerr/article/details/71566385?ops_request_misc=&request_id=&biz_id=102&utm_term=C语言如何进行条件编译&utm_medium=distribute.pc_sehttps://blog.csdn.net/xingerr/article/details/71566385?ops_request_misc=&request_id=&biz_id=102&utm_term=C%E8%AF%AD%E8%A8%80%E5%A6%82%E4%BD%95%E8%BF%9B%E8%A1%8C%E6%9D%A1%E4%BB%B6%E7%BC%96%E8%AF%91&utm_medium=distribute.pc_se

五、gcc -D

D选项是用来在使用gcc/g++编译的时候定义宏的。

    gcc -DDEBUG -D 后面直接跟宏命,相当于定义这个宏,默认这个宏的内容是1
    gcc -DNAME=Peter -D 后面跟 key=value 表示定义key这个宏,它的内容是value

常用场景

    -DDEBUG 定义DEBUG宏,可能文件中有DEBUG宏部分的相关信息,用个DDEBUG来选择开启或关闭DEBUG
    -Dprivate=public -Dprotected=public 通常用于测试环境,把private 与 protected全替换为public 的。这个还是很常用的,比如我们使用gtest去单元测试,直接测试目标类的成员函数,但是可能目标类的成员函数为了封装性,它可能是protected,所以我们使用这个宏把它全变成public。

gcc -D 选项_我喜欢雨天的清新的博客-CSDN博客https://blog.csdn.net/sdoyuxuan/article/details/85050553