C 预处理

2016-08-21  本文已影响44人  adousj

C 语言提供了三种预处理功能:宏定义、文件包含、条件编译。这些操作都在预处理阶段完成,因此他们只做替换,不进行计算。

1. 防止文件重复包含

#ifndef PROGRAM_H
#define PROGRAM_H

// .h file, usually declaration

#endif

现在使用新编译器可以如下替换:

#pragma once

2. 条件编译

#define TWO
//#define TWO 0  //此时为假
int main()
{
   #ifdef ONE
          printf("1\n");
   #elif defined TWO
          printf("2\n");
   #else
          printf("3\n");
   #endif
}
// 输出 2

在编译的时候指定 -DONE-DONE=1 就能够指定编译条件。

3. 特殊符号

以下是双下划线

符号 备注
__FILE__ 当前程序文件名的字符串
__LINE__ 当前行号的整数
__STDC__ 如果编译器遵循ANSI C标准,它就是个非零值
__DATE__ 当前日期的字符串
__TIME__ 当前时间的字符串
#error 将使编译器显示一条错误信息,然后停止编译
#line 指令改变LINEFILE的内容,它们是在编译程序中预先定义的标识符
#pragma 没有正式的定义。编译器可以自定义其用途。典型的用法是禁止或允许某些烦人的警告信息

4. 无参宏定义

#define PI 3.141592653
  1. 宏名一般大写

无参数宏定义更推荐使用常量类型代替

const double PI = 3.141592653;

5. 带参宏定义

#define AREA(a,b) ((a)*(b))
  1. 记得要给参数加括号
#define AREA(a,b) a*b

AREA(2+3, 4) × 5
// 替换成 2 + 3 × 4 × 5
// 应该是 ((2×+3)×4) × 5

对于 decltype 而言, () 有特殊含义,表示引用类型,因此当宏定义的结果为左值,并且宏定义外层加有括号,那么 decltype 结果就是引用类型。

#define INC(a) (++a)

int x = 1;
// decltype(INC(x))  y;
// y 是引用类型,必须初始化
decltype(INC(x))  y = x;
decltype(INC(x) + 0)  z;
// z 是值类型
  1. 宏名和参数的括号间不能有空格
  2. 宏定义换行
#define _range(x,y)  []{               \
    std::vector<int> v((y-x));            \
    std::iota(v.begin(), v.end(), x);     \
    return v;                             \
}()
  1. 宏定义展开会使源程序变长

6. 宏定义中 #

# 字符串化操作符
用于把宏定义中参数两端加上 引号""

#define STR(str) #str

STR(my#name)      // "my#name"
STR( abc )        // 忽略参数名前后空格,"abc"
STR(abc     def ) // 中间多个空格只保留一个 "abc def"

一般由任意字符都可以做形参,但以下情况会出错:

7. 宏定义中##

## 是记号粘贴操作符
普通的宏定义中,预处理器一般把空格解释成分段标志,对于每一段和前面比较,相同的就被替换。但是这样做的结果是,被替换段之间存在一些空格。如果我们不希望出现这些空格,就可以通过添加一些##来替代空格。

#define A1(name, type)  type name_##type##_type
#define A2(name, type)  type name ##_##type##_type

A1(a1, int);   // int name_int_type;
A2(a1, int);   // int a1_int_type;

8. 宏支持可变参数

使用 VA_ARGS 把参数传递给宏

#define PRINT(...)  printf(__VA_ARGS__) 
// or
// #define PRINT(fmt, args...)  printf(fmt, args)

PRINT("%d %c\n", 10, 'c');

9. 参考

上一篇下一篇

猜你喜欢

热点阅读