宏——初识

宏定义( 宏定义又称为宏代换、宏替换)

在 C 语言中,可以采用命令 #define 来定义宏。该命令允许把一个名称指定成任何所需的文本,例如一个常量值或者一条语句。在定义了宏之后,无论宏名称出现在源代码的何处,预处理器都会把它用定义时指定的文本替换掉。

惯例将宏名称每个字母采用大写,这有助于区分宏与一般的变量

宏不可以递归地展开:如果预处理器在 A 宏的替换文本中又遇到了 A 宏的名称,或者从嵌套在 A 宏内的 B 宏内又遇到了 A 宏的名称,那么 A 宏的名称就会无法展开。

没有参数的宏

没有参数的宏定义,采用如下形式:

  1. #define 宏名称 替换文本

“替换文本”前面和后面的空格符不属于替换文本中的内容。替代文本本身也可以为空。下面是一些示例:

  1. #define TITLE "*** Examples of Macros Without Parameters ***"

  2. #define BUFFER_SIZE (4 * 512)

  3. #define RANDOM (-1.0 + 2.0*(double)rand() / RAND_MAX)

标准函数 rand()返回一个伪随机整数,范围在 [0,RAND_MAX] 之间。rand()的原型和 RAND_MAX 宏都定义在标准库头文件 stdlib.h 中。

带参数的宏

你可以定义具有形式参数(简称“形参”)的宏。当预处理器展开这类宏时,它先使用调用宏时指定的实际参数(简称“实参”)取代替换文本中对应的形参。带有形参的宏通常也称为类函数宏(function-like macro)。

可以使用下面两种方式定义带有参数的宏:

  1. #define 宏名称( [形参列表] ) 替换文本

  2. #define 宏名称( [形参列表 ,] ... ) 替换文本

“形参列表”是用逗号隔开的多个标识符,它们都作为宏的形参。当使用这类宏时,实参列表中的实参数量必须与宏定义中的形参数量一样多

当定义一个宏时,必须确保宏名称与左括号之间没有空白符。如果在名称后面有任何空白,那么命令就会把宏作为没有参数的宏,且从左括号开始采用替换文本。

宏只是进行机械地替换

area=3+1*3+4=10

若想有(3+1)*(3+D)

宏的作用域和重新定义

你无法再次使用 #define 命令重新定义一个已经被定义为宏的标识符,除非重新定义所使用的替换文本与已经被定义的替换文本完全相同。如果该宏具有形参,重新定义的形参名称也必须与已定义形参名称的一样。

如果想改变一个宏的内容,必须首先使用下面的命令取消现在的定义:

  1. #undef 宏名称

执行上面的命令之后,标识符“宏名称”可以再次在新的宏定义中使用。如果上面指定的标识符并非一个已定义的宏名称,那么预处理器会忽略这个 #undef 命令。

标准库中的多个函数名称也被定义成了宏。如果想直接调用这些函数,而不是调用同名称的宏,可以使用 #undef 命令取消对这些宏的定义。即使准备取消定义的宏是带有参数的,也不需要在 #undef 命令中指定参数列表。如下例所示:

  1. #include <ctype.h>

  2. #undef isdigit // 移除任何使用该名称的宏定义

  3. /* ... */

  4. if ( isdigit(c) ) // 调用函数isdigit()

  5. /* ... */

当某个宏首次遇到它的 #undef 命令时,它的作用域就会结束。如果没有关于该宏的 #undef 命令,那么它的作用域在该翻译单元结束时终止。

宏展开

在预处理中,预处理器会分析源文件,把它们转换为预处理器记号和空白符。如果遇到的记号是宏名称,预处理器就会展开(expand)该宏;也就是说,会用定义的文本来取代宏名称。出现在字符串字面量中的宏名称不会被展开,因为整个字符串字面量算作一个预处理器记号。

宏定义和函数调用的区别

1.宏替换不占运行时间,只占编译时间;而函数调用则占运行时间(分配单元、保留现场、值传递、返回),所以每次执行都要载入所以执行起来比较慢一些。

2.  定义宏的时候不要在宏及其参数之间键入空格,因为宏替换的时候会把你不经意打的空格当作宏的一部分进去。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值