宏函数操作符
2018-05-31 本文已影响2人
木鱼_cc
宏最大的坏处就是不判断输入类型,所以编译时容易出错
#pragma once与#ifndef #define ...#endif的区别
1. # ##
1.1 #
# 和 ## 操作符是和 #define 宏使用的. 使用# 使在#后的首个参数返回为一个带引号的字符串. 例如, 命令
#define to_string( s ) # s
#define STR(s) #s
将会使编译器把以下命令
cout << to_string( Hello World! ) << endl;
printf("%s\n", STR(fsdbgkjhgkjdfhgks));//输出fsdbgkjhgkjdfhgks
理解为
cout << "Hello World!" << endl;
1.2 ##
使用##连结##前后的内容,但是要注意##代表C token拼接,如:
#define A(first,second) first##second//这个拼接不是字符串的拼接,是token的拼接
A(printf,("%s\n", "abc"));//拼接printf和("%s\n","abc");
//等价于printf("%s\n","abc");
#define ITCAST(a) itcast_##a//修改变量名
#define G(a) g_##a
int ITCAST(a) = 10; //itcast_a = 10;
int G(value) = 10; //g_value = 10;
#define concatenate( x, y ) x ## y
若定义: int xy = 10;
cout << concatenate( x, y ) << endl;
等价于:
cout << xy << endl;
2. #define
语法:#define macro-name replacement-string
#define命令用于把指定的字符串替换文件中的宏名称
也就是说#define使编译器把文件中每一个macro-name替换为replacement-string
替换的字符串结束于行末.
这里是一个经典的#define应用 (至少是在C中):
#define TRUE 1
#define FALSE 0
...
int done = 0;
while( done != TRUE ) {
...
}
#define命令的另外一个功能就是替换参数,使它假冒创建函数一样使用. 如下的代码:
#define absolute_value( x ) ( ((x) < 0) ? -(x) : (x) )
...
int x = -1;
while( absolute_value( x ) ) {
...
}
当使用复杂的宏时,最好使用额外的圆括号.
3.#pragma
#pragma warning -todo
#pragma命令可以让编程者让编译器执行某些事. 因为#pragma命令的执行很特殊,不同的编译器使用有所不同. 一个选项可以跟踪程序的执行.
4.预定义变量
语法:
__LINE__
__FILE__
__DATE__
__TIME__
_cplusplus
__STDC__
下列参数在不同的编译器可能会有所不同, 但是一般是可用的:
- __LINE__ 和__FILE__ 变量表示正在处理的当前行和当前文件.
- __DATE__ 变量表示当前日期,格式为month/day/year(月/日/年).
- __TIME__ 变量描述当前的时间,格式为hour:minute:second(时:分:秒).
- _cplusplus 变量只在编译一个C++程序时定义.
- __STDC__ 变量在编译一个C程序时定义,编译C++时也有可能定义.
5.__VA_ARGS__
//...代表可变参数
//__VA_ARGS__代表前面的...接收的所有参数
//#号见上面
#define showlist(...) printf(#__VA_ARGS__);
//先传一个test表达式,如果为真,则输出,否则输出...可变值
#define compare(test,...) (test)?(#test):printf(#__VA_ARGS__);
showlist(gjdifjgsdjg);
int a = 10;
int b = 20;
//如果a>b为真,则输出字符串 a>b ; f否则输出 a is little than b
compare(a>b,a is little than b);
6.宏函数封装debug接口
#include <stdio.h>
#include <stdlib.h>
//__FUNCTION 函数名
//__LINE__ 行号
//__DATE__ 日期
//__TIME__ 时间
//"[DEBUG][%s:%d][%s][%s]"format 自动拼接!
#define DEBUG(format,...)\
fprintf(stderr,"[DEBUG][%s:%d][%s][%s]"format,__FUNCTION__,__LINE__,__DATE__,__TIME__,##__VA_ARGS__)//把__VA_ARGS__和format拼接起来
#define ERROR(format,...)\
fprintf(stderr,"[ERROR][%s:%d][%s][%s]"format,__FUNCTION__,__LINE__,__DATE__,__TIME__,##__VA_ARGS__ );
#define LOG(format,...)\
fprintf(stderr,"[LOG][%s:%d][%s][%s]"format,__FUNCTION__,__LINE__,__DATE__,__TIME__,##__VA_ARGS__ );
int main(int argc, char const *argv[])
{
int a = 10;
int b = 0;
int c = 0;
char *p = NULL;
p = malloc(100);
if (p == NULL)
{
ERROR("malloc p error");
}
printf("[LOG] a = %d %d %d\n",a,b,c);
DEBUG("a=%d b = %d\n",a,b);
//等价于==> fprintf(stderr, "a=%d b = %d\n",a,b);
LOG("a=%d b = %d\n",a,b);
return 0;
}