宏定义基本用法

来源:互联网 发布:淘宝上色盲眼镜有用吗 编辑:程序博客网 时间:2024/06/07 03:04

宏定义

不带参数

宏定义又称为宏代换、宏替换,简称“宏”。

格式:

#define 标识符 字符串

其中的标识符就是所谓的符号常量,也称为“宏名”。
预处理(预编译)工作也叫做宏展开:将宏名替换为字符串。
掌握”宏”概念的关键是“换”。一切以换为前提、做任何事情之前先要换,准确理解之前就要“换”。

例:

#define Pi 3.1415926

把程序中出现的Pi全部换成3.1415926

带参数(宏函数)

宏名之后带括号的宏被认为是宏函数。用法和普通函数一样,只不过在预处理阶段,宏函数会被展开。优点是没有普通函数保存寄存器和参数传递的开销,展开后的代码有利于CPU cache的利用和指令预测,速度快。缺点是可执行代码体积大。

和不带参数的宏定义一样,除了一般的字符串替换,还要做参数代换。

格式:

#define <宏名> (<参数表>) <宏体>

例如:

#define S(a,b) a*b

area=S(3,2);第一步被换为area=a * b; ,第二步被换为area=3 * 2;

(1)实参如果是表达式容易出问题

例如:

#define S(r) r*r

area=S(a+b);第一步换为area=r * r;,第二步被换为area=a+b * a+b;

正确的宏定义是#define S(r) ((r)*(r))

(2)带参宏一般用法

例如:

#define MIN(A, B)   A < B ? A : Bint a = 2 * MIN(3, 4);printf("%d", a);

展开结果:

int a = 2 * MIN(3, 4);//=> int a = 2 * 3 < 4 ? 3 : 4;//=> int a = 6 < 4 ? 3 : 4;//=> int a = 4;

正确如下:

#define MAX(a,b) ((a)>(b)?(a):(b))

则遇到MAX(1+2,value)则会把它替换成:
((1+2)>(value)?(1+2):(value))

(3)有参宏定义中#的用法

需要注意的是凡宏定义里有用’#’或’##’的地方宏参数是不会再展开,被当做字符串处理

#define STR(str) #str

“#”号用于把宏定义中的参数两端加上字符串的”“

比如,这里 STR(my#name) 会被替换成”my#name”

(4)有参宏定义中##的用法

例如:

#define WIDE(str) L##str

则会将形参str的前面加上L

比如:

WIDE(“abc”)就会被替换成L”abc”

如果有:

#define FUN(a,b) vo##a##b()

那么FUN(id ma,in)会被替换成void main()

多行宏定义

每一次换行都必须要有 “ \ ”结尾,末尾行不需要“ \ ” 结尾。

例如:

#define doit(m,n) for(int i=0;i<(n);++i)\    {\    m+=i;\    }
#define WARN_IF(EXP) \     do { if (EXP) \             fprintf (stderr, "Warning: " #EXP "\n"); } \     while (0)

WARN_IF (x == 0);会被扩展成:

do {     if (x == 0)        fprintf (stderr, "Warning: " "x == 0" "\n"); }while (0);
#define VAR_TO_STR(var)\    ({\        std::string name = (#var);\        int pos = 0;\        int length = 0;\        length = name.length();\        pos = name.find_last_of(':',length);\        if ( pos == -1 )\        {\            pos = 0;\            name = name.substr(pos,length);\        }\        else\        {\            name = name.substr( pos + 1,length);\        }\        (name);\    })

std::string str = VAR_TO_STR(VDAD::RRR) 展开后:

int main(){    std::string ss =({        std::string name = ("VDAD::RRR");        int pos = 0;        int length = 0;        length = name.length();        pos = name.find_last_of(':',length);        if ( pos == -1 )        {            pos = 0;            name = name.substr(pos,length);        }        else        {            name = name.substr( pos + 1,length);        }        (name);    });    cout << ss<< endl;    return 0;}

输出为:

相关链接

1.C语言宏的特殊用法和几个坑
2.C/C++ 宏定义

原创粉丝点击