C语言 关于宏的 ## 与 #
来源:互联网 发布:童装淘宝店好做吗 编辑:程序博客网 时间:2024/05/29 15:30
宏中"#"和"##"的用法
一、一般用法
我们使用#把宏参数变为一个字符串,用##把两个宏参数贴合在一起.
用法:
一、一般用法
我们使用#把宏参数变为一个字符串,用##把两个宏参数贴合在一起.
用法:
1
2
3
4
5
6
7
8
9
10
11
#include<cstdio>
#include<climits>
using
namespace
std;
#define STR(s) #s
#define CONS(a,b) int(a##e##b)
int
main()
{
printf
(STR(vck));
// 输出字符串"vck"
printf
(
"%d/n"
, CONS(2,3));
// 2e3 输出:2000
return
0;
}
二、当宏参数是另一个宏的时候
需要注意的是凡宏定义里有用'#'或'##'的地方宏参数是不会再展开.
需要注意的是凡宏定义里有用'#'或'##'的地方宏参数是不会再展开.
1, 非'#'和'##'的情况
1
2
3
#define TOW (2)
#define MUL(a,b) (a*b)
printf
(
"%d*%d=%d/n"
, TOW, TOW, MUL(TOW,TOW));
这行的宏会被展开为:
MUL里的参数TOW会被展开为(2).
1
printf
(
"%d*%d=%d/n"
, (2), (2), ((2)*(2)));
2, 当有'#'或'##'的时候
1
2
3
4
#define A (2)
#define STR(s) #s
#define CONS(a,b) int(a##e##b)
printf
(
"int max: %s/n"
, STR(INT_MAX));
// INT_MAX #i nclude<climits>
这行会被展开为:
1
2
printf
(
"int max: %s/n"
,
"INT_MAX"
);
printf
(
"%s/n"
, CONS(A, A));
// compile error <br>这一行则是:<br>printf("%s/n", int(AeA));
INT_MAX和A都不会再被展开, 然而解决这个问题的方法很简单. 加多一层中间转换宏.
加这层宏的用意是把所有宏的参数在这层里全部展开, 那么在转换宏里的那一个宏(_STR)就能得到正确的宏参数.
加这层宏的用意是把所有宏的参数在这层里全部展开, 那么在转换宏里的那一个宏(_STR)就能得到正确的宏参数.
1
2
3
4
5
6
7
8
9
10
11
#define A (2)
#define _STR(s) #s
#define STR(s) _STR(s) // 转换宏
#define _CONS(a,b) int(a##e##b)
#define CONS(a,b) _CONS(a,b) // 转换宏
printf
(
"int max: %s/n"
, STR(INT_MAX));
// INT_MAX,int型的最大值,为一个变量 #i nclude<climits>
输出为:
int
max: 0x7fffffff
STR(INT_MAX) --> _STR(0x7fffffff) 然后再转换成字符串;
printf
(
"%d/n"
, CONS(A, A));
输出为:200
CONS(A, A) --> _CONS((2), (2)) -->
int
((2)e(2))
三、'#'和'##'的一些应用特例
1、合并匿名变量名
例:ANONYMOUS(static int); 即: static int _anonymous70; 70表示该行行号;
第一层:ANONYMOUS(static int); --> __ANONYMOUS0(static int, __LINE__);
第二层: --> ___ANONYMOUS1(static int, _anonymous, 70);
第三层: --> static int _anonymous70;
即每次只能解开当前层的宏,所以__LINE__在第二层才能被解开;
1、合并匿名变量名
1
2
3
#define ___ANONYMOUS1(type, var, line) type var##line
#define __ANONYMOUS0(type, line) ___ANONYMOUS1(type, _anonymous, line)
#define ANONYMOUS(type) __ANONYMOUS0(type, __LINE__)
第一层:ANONYMOUS(static int); --> __ANONYMOUS0(static int, __LINE__);
第二层: --> ___ANONYMOUS1(static int, _anonymous, 70);
第三层: --> static int _anonymous70;
即每次只能解开当前层的宏,所以__LINE__在第二层才能被解开;
2、填充结构
1
2
3
4
5
6
7
8
9
10
#define FILL(a) {a, #a}
enum
IDD{OPEN, CLOSE};
typedef
struct
MSG{
IDD id;
const
char
* msg;
}MSG;
MSG _msg[] = {FILL(OPEN), FILL(CLOSE)};
相当于:
MSG _msg[] = {{OPEN,
"OPEN"
},
{CLOSE,
"CLOSE"
}};
3、记录文件名
1
2
3
#define _GET_FILE_NAME(f) #f
#define GET_FILE_NAME(f) _GET_FILE_NAME(f)
static
char
FILE_NAME[] = GET_FILE_NAME(__FILE__);
4、得到一个数值类型所对应的字符串缓冲大小
这里相当于:
char buf[11];
1
2
3
4
5
#define _TYPE_BUF_SIZE(type) sizeof #type
#define TYPE_BUF_SIZE(type) _TYPE_BUF_SIZE(type)
char
buf[TYPE_BUF_SIZE(INT_MAX)];
-->
char
buf[_TYPE_BUF_SIZE(0x7fffffff)];
-->
char
buf[
sizeof
"0x7fffffff"
];
char buf[11];
阅读全文
0 0
- C语言 关于宏的 ## 与 #
- C语言关于宏
- 关于字符串与数字的转化(C语言)
- 关于C语言的fprintf与fwrite使用区别
- 关于c语言的线程与linux驱动
- 关于C语言协程与网络编程的分析
- C语言 关于sizeof与typedef的解释
- 关于matlab与C语言的混合编程
- 关于c语言传值与传址的理解
- C语言 关于用户名与密码的存放(文件)
- 关于C语言的fprintf与fwrite使用区别
- 关于C语言的"[]"运算符与指针
- C语言中关于const与指针结合的理解
- 关于C语言的fprintf与fwrite使用区别
- matlab 与C语言关于filter函数的实现
- c语言中关于数组与指针的一点心得
- 关于C语言的fprintf与fwrite使用区别
- 关于C语言中*与++的组合问题解析
- 常用图像特征的总结--HARR,HOG,LBP,SIFT,SURF
- 数据结构课程设计代码-家谱管理系统
- IDEA搭建servlet服务器与android客户端通信(二)
- 请编程设计一个登陆界面,要求输入账号和密码(不考虑事件)
- 【自然语言处理入门】03:利用线性回归对数据集进行分析预测(上)
- C语言 关于宏的 ## 与 #
- Android 自己收集的一些有趣的框架(持续更新 2017.12.23)
- Android的设计模式-中介者模式
- jQuery+Ajax+PHP实现异步分页数据显示--js可参考
- leetcode 648. Replace Words 公共前缀
- Error:Failed to find target with hash string 'android-15' 解决办法
- 粒子系统
- datatables插件的应用
- 隐藏服务器版本信息