预处理与宏定义

预处理与宏定义

预处理:

程序员所编写的代码不能被真正的编译器所编译,需要先经过一段程序翻译一下
翻译的过程称为预处理,负责翻译的程序称为预处理器,被翻译的语句叫做预处理指令,以#开头的都是预处理指令

  1. 查看预处理的结果:
    gcc -E code.c 把预处理的结果显示到终端
    gcc -E code.c -o code.i 把预处理的结果存储到.i预处理文件
  2. 预处理指令的分类:
    #include 头文件导入(拷贝)
    #include <> 从系统指定路径查找头文件
    #include “” 从当前工作路径查找,找不到再从系统指定路径查找
    -I path 可以指定要查找的路径path
    还可以通过设置环境变量来指定路径
#define 定义宏
  1. 宏常量:

    #define MAX 50
    

    优点:提高代码可扩展性、提高可读性、提高了安全性、还可以与case配合
    注意:定义宏常量不要加分号,一般宏名全部大写
    预定义好的宏常量:

    printf("%s\n",__func__);    //	获取函数名
    printf("%s\n",__FILE__);    //	获取文件名
    printf("%d\n",__LINE__);    //	获取行号
    printf("%s\n",__DATE__);    //	获取日期
    printf("%s\n",__TIME__);    //	获取时间
    
  2. 宏函数:
    是带参数的宏
    不是真正意义的函数,没有发生传参,也没有返回值,也不会去检查参数的类型

    #define SUM(a,b) a+b	
    

    1、先把在代码中出现了宏函数的位置,替换成宏函数后面的语句
    2、再把代码中使用的参数替换成调用者的参数
    注意:宏的内容必须保证在同一行,如果要换行,要在每一行的末尾添加续行符 \

  3. 宏函数的二义性:
    由于宏函数代码位置、附近的值、参数各种原因的影响,会导致宏函数有不同的解释,这叫做宏的二义性
    如何避免宏的二义性
    每个参数都加小括号,整体也叫小括号,不要在宏函数的参数中使用自变运算符

  4. 宏函数与普通函数的区别?
    是什么?
    普通函数:是一段觉有某项功能的代码集合,会被编译成二进制指令存储在代码段中,函数名就是它的首地址,有独立的栈内存
    宏函数:带参数的宏替换,不是真正的函数,用起来像函数,没有独立的栈内存
    有什么区别?
    函数:返回值、类型检查、安全、入栈出栈调用、跳转、速度慢
    宏函数:运行结果、通用、危险、替换、冗余、速度快

  5. 条件编译:
    根据条件决定让代码是否参与最终的编译
    版本控制:

    #if 
    #elif 
    #else
    #endif
    

    头文件卫士:防止头文件被重复包含,头文件必加

    #ifndef 宏名    //如果宏不存在为真
    #define 宏名
    //
    #endif
    

    判断、调试:

    #ifdef 宏名 //如果宏存在为真
    #else
    #endif
    

    打印调试信息:

    #ifdef DEBUG
    #define debug(...) printf(__VA_ARGS__)
    #else
    #define debug(...)
    #endif
    //	在编译时添加宏DEBUG:gcc 02debug.c -DDEBUG
    

    打印错误信息:

    #define error(...) printf("%s %s:%d %s %m %s %s\n",__FILE__,__func__,__LINE__,__VA_ARGS__,__DATE__,__TIME__)   
    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值