关于宏定义的问题

来源:百度知道 编辑:UC知道 时间:2024/05/31 00:08:49
由于最近上编译原理做了个词法分析器,里面用到了isalpha,isalnum等函数
于是查看了以下Ctype.h头文件发现是这样写的
#define isalnum(c) (_ctype[(c) + 1] & (_IS_DIG | _IS_UPP | _IS_LOW))
#define isalpha(c) (_ctype[(c) + 1] & (_IS_UPP | _IS_LOW))
有人说这个宏定义和函数所完成的功能是一样的
我想问的就是它具体是怎么实现的,高手请指教
标苦运先给了很重要的提示 相当感谢

也谢谢老岩的建议,虽然有点偏题,但是很中肯,很有一番收获,建议大家看看

下面我把我了解到的资料分享一下,也算是做一个补充

CTYPE.H中

#define _U 0x01/* upper */
#define _L 0x02/* lower */
#define _D 0x04/* digit */
#define _C 0x08/* cntrl */
#define _P 0x10/* punct */
#define _S 0x20/* white space (space/lf/tab) */
#define _X 0x40/* hard space (0x20) */
#define _SP 0x80/* hard space */

CTYPE.C中
#include<ctype.h>
unsigned char _ctype_table[] = {0x00, /* EOF */
_C,_C,_C,_C,_C,_C,_C,_C, /* 0-7 ASII中的序号*/
_C,_C|_S,_C|_S,_C|_S,_C|_S,_C|_S,_C,_C, /* 8-15 */
_

宏定义分两部分:
1。_ctype[(c) + 1]
在ctype.h中有声明
extern unsigned short _ctype[];
表示_ctype是个unsigned short类型的全局数组变量;该全局变量用于编译器内部对程序源码中的字符集(ASCII码的子集)进行类别编号
2。_IS_DIG | _IS_UPP | _IS_LOW等等
用来过滤出"指定位"的掩码,通过位运算&获取制定位是否为1,结合1中对字符集的分类,共同用来判断某个字符是否属于特定类别(例如:数字,字母,空格。。。)

第一点:
宏比常规函数复杂,表现最明显的就是括号的应用~
第二点:
编译器对宏的格式要求不一,有的需要一个宏 必须在同一行上,有的不需要,给代码移植带来麻烦。
第三点:
宏不检查宏中的变量类型,这与函数不同。可以是优点也可能是缺点。
第四点:
宏编译以后将产生内联代码,。。。就是。。。。哎。。不好说。来个代码说明一下
#define 宏X(a,b) //实现a+b
main 中计算了50回 a+b的 运算 如:
for (i=0; i<50; i++)
{
X(i,i+1);
}
这样在编译以后 代码变为
X(i,i+1);
i++;
X(i,i+1);
i++;
...
X(i,i+1);
i++;

共有50个。

而函数不同
就一个函数代码
void X(int a, int b)
{
...
}
在main的for里 反复的调用这个函数
也就是goto 的意思。

明白了吗?

宏编译以后比函数要多占用空间,但是没有如goto这样的跳转语句占用cpu
就是空间大了 时间小了
如果 这个程序需要快速的执行而不考虑存储空间的问题 在没有不必要的麻烦情况下 可以尽量用宏。 如atm机