#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) |