• C语言预处理


    By francis_hao May 27,2017

     

    预处理器执行宏替换、条件编译以及包含指定的文件。以#开头的命令行(#前可以有空格)就是预处理的对象,这些命令行的语法独立于语言的其他部分,它们可以出现在任何地方,作用范围是从出现的位置到文件末尾,除非使用显式的取消操作的预处理(undef)。这是一个独立的过程,与之后的编译,汇编和链接相当。

    宏定义和扩展

    宏定义有两种形式,"[]"中的内容是可选的,其中第二种形式中标识符和形参表之间不能有空格。用引号或嵌套的括号括起来的逗号,不能用于分隔实际参数。

    #define 标识符 [实际内容]
    #define
    标识符(形参表) [实际内容]

    宏的取消,两种形式的定义,使用同一种取消的形式:

    #undef 标识符

     

    实际内容中,若存在"#"或"##",则会对实际内容进行一些扩展,但他们都不可以嵌套使用。

    #的扩展

    第一种形式中,"#"无扩展性,包含"#"的实际内容会原样显示。

    第二种形式中,"#"后必须也只能跟参数,会把参数转变为可直接使用的字符串,比如,给定的形参若包含""",则转变为"""。

     

    ##的扩展

    "##"会将实际内容中"##"前后的空白字符都去掉,也就是拼接。它不可以作用于字符串,也不可以出现在实际内容的开头或结尾。

    "##"还有一个特殊的用法,就是和C99标准的__VA_ARGS__配合使用,用在可变参数的宏定义中(第二种形式)。

    __VA_ARGS__ can only appear in the expansion of a C99 variadic macro

    形如:

    #define EE(a, ...) ee(a,##__VA_ARGS__)

    其含义是在使用宏EE时,其参数可以只有一个,也可以有多个。

     

    若使用如下形式,则在调用宏EE时,必须给定两个及以上的参数。因为实参和形参必须要对应。

    #define EE(a, ...) ee(a,__VA_ARGS__)

     

    若执意不使用"##",也可以使用如下形式,

    #define EE(...) ee(__VA_ARGS__)

     

    实例

    main.i是main.c进行预处理后的文件。

    30行:AA的宏定义中实际内容为空,因此被替换为一空行,此例可使用于程序的调试信息的打印中,使用宏控制是否打印,如:

    #ifndef DEBUG
    #define debug_print(fmt, ...)
    #else
    #define debug_print(fmt, ...) printf(fmt,##__VA_ARGS__)
    #endif

     

    31行:BB的宏定义是#在第一种形式的使用,无扩展性,因此被原样显示。

    32-33行:将参数转换为字符串,若参数中包含""",则进行转义。

    35行:"##"在第一种宏定义形式的使用,拼接。其前后不能是字符串,应该只能是数字、字母和下划线。

    36行:"##"在第二种宏定义形式的使用,拼接参数。

    37-38行:"##"和"__VA_ARGS__"的配合使用。若没有"##",EE的参数只有一个时,EE(a)会变成ee(a,),如下:

     

     

    错误信息生成

    #error [记号序列]

    进行预处理到这里的时候会出现错误信息,一般用在条件编译中。

     

    预定义标识符

    有些标识符是预定义的,扩展后将生成特定的信息,它们不能被取消定义或重新定义

    __LINE__    包含当前源文件行数的十进制常量

    __FILE__    包含正在被编译的源文件名字的字符串字面值

    __DATE__    包含编译日期的字符串面值,形式为"Mmm dd yyyy"

    __TIME__    包含编译时间的字符串面值,形式为"hh:mm:ss"

    __STDC__    整形常量1,只有在遵循标准的实现中该标识符才被定义为1

     

     


    本文由 刘英皓 创作,采用 知识共享 署名-非商业性使用-相同方式共享 3.0 中国大陆 许可协议进行许可。欢迎转载,请注明出处:
    转载自:http://www.cnblogs.com/yinghao1991/p/6628815.html

     

    参考

     

    [1] K&R C程序设计语言

  • 相关阅读:
    postman接口测试01_下载安装
    Jenkins持续集成_05_参数化构建
    IntelliJ 中设置与Eclipse中 Ctrl+1 功能类似的快捷键
    JAVA 内部类
    Adobe Air 现在可支持X86的移动设备
    开发一些自动编写代码的工具可以增加效率吗?
    制作 Flex 悬停提示帮助文档(转)
    没什么好说的
    JDK,Tomcat,Maven,Mysql环境变量配置
    神器三、Android端神器东皇钟:天界之门
  • 原文地址:https://www.cnblogs.com/yinghao-liu/p/6628815.html
Copyright © 2020-2023  润新知