问答文章1 问答文章501 问答文章1001 问答文章1501 问答文章2001 问答文章2501 问答文章3001 问答文章3501 问答文章4001 问答文章4501 问答文章5001 问答文章5501 问答文章6001 问答文章6501 问答文章7001 问答文章7501 问答文章8001 问答文章8501 问答文章9001 问答文章9501

宏定义 #和 ##运算符的区别?

发布网友 发布时间:2024-09-06 13:49

我来回答

1个回答

热心网友 时间:2024-09-09 22:38

宏定义中的运算符:#和##

宏定义可以包含两个运算符:#和##。编译器不会识别这两种运算符相反,它们会在预处理时被执行。
#运算符将一个宏的参数转换为字符串字面量。它仅允许出现在带参数的宏的替换列表中。
(一些C程序员将#操作理解为“stringization(字符串化)”;其他人则认为这实在是对英语的滥用。)
#运算符有大量的用途,这里只来讨论其中的一种。假设我们决定在调试过程中使用PRINT_INT宏作为一个便捷的方法,
来输出一个整型变量或表达式的值。#运算符可以使PRINT_INT为每个输出的值添加标签。下面是改进后的PRINT_INT:
#define PRINT_INT(x) printf(#x " = %d\n", x)
x之前的#运算符通知预处理器根据PRINT_INT的参数创建一个字符串字面量。因此,调用
PRINT_INT(i/j);
会变为
printf("i/j" " = %d\n", i/j);
在C语言中相邻的字符串字面量会被合并,因此上边的语句等价于:
printf("i/j = %d\n", i/j);
当程序执行时,printf函数会同时显示表达式i/j和它的值。例如,如果i是11,j是2的话,输出为
i/j = 5
14.3.4 ##运算符
##运算符可以将两个记号(例如标识符)“粘”在一起,成为一个记号。(无需惊讶,##运算符被称为“记号粘合”。)如果其中一个操作数是宏参数,“粘合”会在当形式参数被相应的实际参数替换后发生。考虑下面的宏:
#define MK_ID(n) i##n
当MK_ID被调用时(比如MK_ID(1)),预处理器首先使用自变量(这个例子中是1)替换参数n。接着,预处理器将i和1连接成为一个记号(i1)。下面的声明使用MK_ID创建了3个标识符:
int MK_ID(1), MK_ID(2), MK_ID(3);
预处理后声明变为:
int i1, i2, i3;
##运算符不属于预处理器经常使用的特性。实际上,想找到一些使用它的情况是比较困难的。为了找到一个有实际意义的##的应用,我们来重新思考前面提到过的MAX宏。如我们所见,当MAX的参数有副作用时会无法正常工作。一种解决方法是用MAX宏来写一个max函数。遗憾的是,往往一个max函数是不够的。我们可能需要一个实际参数是int值的max函数,还需要参数为float值的max函数,等等。除了实际参数的类型和返回值的类型之外,这些函数都一样。因此,这样定义每一个函数似乎是个很蠢的做法。
解决的办法是定义一个宏,并使它展开后成为max函数的定义。宏会有唯一的参数type,它表示形式参数和返回值的类型。这里还有个问题,如果我们是用宏来创建多个max函数,程序将无法编译。(C语言不允许在同一文件中出现两个同名的函数。)为了解决这个问题,我们是用##运算符为每个版本的max函数构造不同的名字。下面是宏的显示形式:
#define GENERIC_MAX (type) \
type type##_max(type x, type y) \
{ \
return x > y ? x : y; \
}
请注意宏的定义中是如何将type和_max相连来形成新函数名的。
现在,假如我们需要一个针对float值的max函数。下面是如何使用GENERIC_MAX宏来定义函数:
GENERIC_MAX(float)
预处理器会将这行展开为下面的代码:
float float_max(float x, float y) { return x > y ? x : y; }
声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com
长沙到西昌。坐火车先从长沙到成都、成都东,再到西昌,哪个方便一些 S先生与P先生谜题的题面 为什么首都设在襄阳 改姓可以不随父母性吗 韩艺瑟怎么改姓? 纸、墨、笔、砚是中国传统的文房四宝,墨的使用最早在 [ ] A.商代后期... 想问下创维光伏E企赢模式有哪些优势,到底值不值得投资啊?有没有合作... 太平洋太享e保百万医疗值得入手吗?每年花多少钱? 爱e满分适合哪些人买?注意哪些问题? 太平洋太享e保百万医疗适合哪些人买?价格多少? 中山工伤待遇包括哪些项目 中山市九级工伤赔偿的项目有哪些? 针灸治腰间盘突出效果怎么样 腰间盘突出针灸多久管用 腰间盘突出扎针灸一般几天有效果 针灸能治腰间盘突出吗 word输入时如何添加右上角标 腰间盘突出可以做针灸治疗吗 腰间盘突出患者能针灸吗 天猫618预售尾款能合并支付吗?定金和尾款规则 天猫618预售付尾款时间是什么时候?何时可以退款? 淘宝618预售定金规则是什么?详细介绍! 淘宝618定金怎么退-威客牛网 2020天猫618预售款交了定金可以退吗?答案在这里 学校美食节,做什么好? 不能用火,电,材料要好买的(在沃尔玛可以买到的... 不上火的外卖美食有哪些? 天猫618预售定金能退吗 ...经常懒在家,有没有不用火,只用冰箱就可以做的美食,要简单,食材要经 ... 不用火就能做的简易美食有哪些? 中山大学新华学院学费 中山大学新华学院简介 数控系统在宏运算时精确到小数点后几位 板式换热器应用场合 亚洲俱乐部冠军联赛简介 2009年亚足联冠军联赛决赛决赛之路 电容测厚仪 王者荣耀投诉专线介绍_王者荣耀投诉专线是什么 王者荣耀投诉中心电话 王者荣耀投诉专线 王者荣耀投诉流程详解-手游资讯-安族网 王者荣耀投诉专线号码是什么_王者荣耀投诉专线号码介绍 “王者荣耀”的投诉电话是什么? 小米1s青春版主要参数 小米1S(青春版)基本参数 最近早上起床口苦口干舌苔黄喉咙有痰吞咽困难喝点水就好了,两脚发软没... 小米1S(青春版/联通版)基本参数 5e天梯等级怎么算的? 5e2100分相当于完美什么段位 5e2500分算什么水平 石化油服为什么那么便宜 重读长辈这本书怎么写重读长辈这本书作文怎么写 联云宝是诈骗公司吗