第十四章

第十四章

  • 指令的规则
    • 指令都以#开始
    • 在指令的符号之间可以插入任意数量的空格或水平制表符
    • 指令总是在第一个换行符处结束,除非明确的指明要延续
    • 指令可以出现在程序中的任意地方
    • 注释可以和指令放在同一行
  • 使用带参数宏替代函数的优缺点
    • 程序可能会稍微快些,程序调用函数会有些额外的开销——存储上下文信息,复制参数值等(C99的内联函数提供了另一种避免这种开销办法)
    • 宏更“通用”:可以接受任意类型的参数
    • 编译后的代码通常会变大
    • 宏参数没有类型检查
    • 无法使用一个指针指向一个宏
    • 宏可能不止一次的计算参数
  • #运算符:将宏的一个参数转换为字符串字面量
    • #define PRINT_INT(X) printf(#x " =%d\n",x)
  • ##运算符:将两个记号(如标识符)“粘合”在一起,成为一个记号。
    • 用的地方不是很多,可用于生成标识符,或者函数
  • 宏的通用属性
    • 宏的替换列表可以包含对其它宏的调用
    • 预处理器只会替换完整地记号,不会替换记号的片段
    • 宏定义的作用范围通常到出现这个宏的文件末尾
    • 宏不可以被定义两遍,除非新的定义与旧的定义是一样的
    • 宏可以使用#undef指令“取消定义”
  • 空的宏参数
    • C99允许宏调用中的任意或所有参数为空。当然这样的调用需要和一般调用有一样多的逗号。
    • 当空参数是#运算符的操作数,空的实际参数被#运算符“字符串化”,则结果为""(空字符串)
    • 当空参数是##运算符的操作数,空的实际参数会被不可见的“位置标记”记号代替。把原始的记号与位置标记记号相连接,得到的还是原来的记号(位置标记记号消失了),如果连接两个位置标记记号,得到的是一个位置标记记号。宏扩展完成后,位置记号标记从程序中消失。
  • 参数个数可变的宏
    • C89中,如果宏有参数,那么个数是固定的。C99中可变,例:#define TEST(...) printf(__VA_ARGS__)
  • __func__标识符
    • 跟踪函数调用

      #define FUNCTION_CALLED() printf("%s called\n", __func__)
      #define FUNCTION_RETURNS() printf("%s returns\n", __func__)
      
      void f(){
          FUNCTION_CALLED() ;
          ...
          FUNCTION_RETURNS();
      }
      
    • 作为参数传递给函数,让函数知道调用他的函数的名字

  • #line指令用法:#line n#line n "文件"

你可能感兴趣的:(第十四章)