您的位置:首页 > 编程语言 > C语言/C++

C语言学习——宏

2015-05-26 07:28 148 查看
C语言学习——宏

1、#

#运算符用于创建字符串,#运算符后面跟一个形参(中间可以有空格或Tab),只能用于函数式宏定义

#define STR(s) $ s
STR(hello      world)           //=="hello world"

自动用"把实参括起来成为一个字符串,并且实参中的连续多个空白字符被替换成一个空格

2、##

##运算符把前后两个预处理Token连接成一个预处理Token,##不仅限于函数式宏定义,变量式宏定义也可以用

#define CONCAT(a,b) a##b
CONCAT(con,cat)                    //==concat

要定义一个宏展开成两个#,可以这样定义

#define HASH_HASH # ## #

中间的##是运算符,宏展开前后两个#被连接在一起,注意中间的两个空格不可少,如果写成####,会被划分为##和##两个Token

3、可变参数

函数式宏定义也可以带可变参数,同样是在参数列表中用…表示可变函数,函数体中用_VAARGS_表示。

#define showlist(...) printf(#__VA__ARGS__)
#define report(test,...)((test)?printf(#test):printf(__VA_ARGS__))


4、空参数

调用函数式宏定义可以传空参数

#define FOO(a) foo##a
FOO()             //==foo

FOO在定义时带一个参数,在调用时必须传一个参数给它,如果不传参数表示传了一个空参数

#+define FOO(a,b,c) a##b##c
FOO(1,,3)         //==13
FOO(,,3)          //==3

FOO在定义时带三个参数,在调用时也必须传入三个参数给它,空参数的位置可以空着,但必须给够三个参数

#define FOO(a,...) a##__VA_ARGS__
FOO(1)            //==1
FOO(1,2,3)        //==12,3


5、宏展开的步骤

宏的嵌套替换是从上替换到下的,哪个宏先定义,先替换哪个

除了带#和##运算符的参数之外,其他参数在替换之前要对实参本身做充分的展开。

6、#if

* #if defined x == #ifdef x

* #if !defined x == #ifndef x

* 如果x有定义,则#define x替换成1,否则替换成0

7、其他预处理特性

* #pragma预处理指示供编译器实现一些非标准的特性,如果编译器在代码中遇到不认识的#pragma指示则忽略它

* __FILE__:展开为当前源文件的文件名,是一个字符串

* __LINE__:展开为当前代码行的行号,是一个整数

* C99引入一个特殊的标识符__func__标识当前函数名。这个标示符应该是一个变量名而不是宏定义,不属于预处理的范畴,但作用和__FILE__,__LINE__类似

本文出自 “暗日” 博客,请务必保留此出处http://darksun.blog.51cto.com/3874064/1071306
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: