Chinaunix首页 | 论坛 | 博客
  • 博客访问: 560240
  • 博文数量: 252
  • 博客积分: 1068
  • 博客等级: 少尉
  • 技术积分: 1775
  • 用 户 组: 普通用户
  • 注册时间: 2012-05-05 21:33
文章分类

全部博文(252)

文章存档

2013年(21)

2012年(231)

分类:

2012-05-05 21:34:41

原文地址:C99的预处理 作者:yourtommy

#line可以改变当前文件名和当前行的编译信息,语法为:#line digit-sequence ["filename"]

比如#line 333 "whatever.c"

使得当前文件名为"whatever.c",当前行为333。此后编译器所有的警告、错误信息里的文件名和行号都会基于这个设定。同时__FILE__宏和__LINE__也会受到影响。

另一些预定义的宏有:__DATE__为源文件编译的日期;__TIME__为源文件编译的时间;__TIMESTAMP__为源文件编译的日期和时间;__STDC__指明编译是否完全遵守C标准而没有实现定义的扩展或在编译C++代码。C9X新增的__STDC_VERSION___给出使用的C标准。

#error可以报一个编译错误。相应的,#warning给出一个编译警告。

#pragma用于传递给编译器额外的信息,不同的编译器参数会有不同。在VC上最常用的有#pragma once,但这不是C标准。

C9X提供了一个_Pragma操作符。它接受字符串作为参数。比如:

_Pragma ("GCC dependency \"parse.y\"")

等价于

#pragma GCC dependency "parse.y"


C9X加入了一个很有趣的特性:可变宏参数
#define PRINTF(format, ...) \
    printf(format, __VA_ARGS__);
PRINTF("%s, %s\n", "OK", "bye");
会等价于:
printf("%s, %s\n", "OK", "bye");

注意__VA_ARGS__展开后会是以逗号分隔的多个参数。C99并没有内置一个方法来得到每个参数,所以我们需要自己想办法。

首先是得到参数的个数:
#define N_ARGS(...) N_ARGS_HELPER(__VA_ARGS__, 9, 8, 7, 6, 5, 4, 3, 2, 1)
#define N_ARGS_HELPER(x1, x2, x3, x4, x5, x6, x7, x8, x9, n, ...) n
这种方法不是我创的,能想出这种方法的人真是牛X。当然这里最多只能支持9个参数,你可以随便添加更多的参数。

然后是遍历每个参数,这里举一个求和的宏:
#define SUM1(x, ...) (x)
#define SUM2(x, ...) (x) + SUM1(__VA_ARGS__)
#define SUM3(x, ...) (x) + SUM2(__VA_ARGS__)

#define SUM(...) SUM_HELPER(N_ARGS(__VA_ARGS__), __VA_ARGS__)
#define SUM_HELPER(n, ...) SUM_HELPER_2(n, __VA_ARGS__)
#define SUM_HELPER_2(n, ...) SUM##n(__VA_ARGS__)

注意这里SUM##n的操作只能在SUM_HELPER_2做,而不能直接在SUM_HELPER里进行,否则得到的结果会为SUMN_ARGS...。我们需要对N_ARGS的值通过另一个宏再次转义。
你可以随你喜欢求任何个数的数的和。

阅读(578) | 评论(0) | 转发(0) |
0

上一篇:C99的字符集

下一篇:C99的数组

给主人留下些什么吧!~~