宏定义 使用分析

来源:互联网 发布:c 的sms源码 编辑:程序博客网 时间:2024/04/29 21:21

宏定义:

在程序中,以#开头的都是预处理指令。
#define定义宏常量可以出现在代码的任何地方。

如下图所示:
这里写图片描述
判断宏定义是否正确,要把宏定义的内容代到真正的程序中,根据实际的程序来看。

#define从本行开始,之后的代码都可以使用这个宏常量。这里的之后是指文本的排列顺序的之后,不是程序代码运行的顺序。

使用#undef来结束一个宏定义。 以此限制宏定义的作用范围。
例如:

int f1(int a, int b){    #define _MIN_(a,b) ((a)<(b) ? a : b)    return _MIN_(a, b);    #undef _MIN_}

可以在一个函数里定义一个宏定义。

定义宏表达式:

 #define表达式给有函数调用的假象,却不是函数
 #define表达式可以比函数更强大
 #define表达式比函数更容易出错

举例说明,宏表达式的优点:

#define DIM(array) (sizeof(array)/sizeof(*array))...int a[] = {1, 2, 3, 4};printf("%d\n", DIM(a));

这段程序会输出数组的元素个数4,但是如果使用函数来表示的话,输出的结果为1。因为,函数有弱点,他的参数传入的只是一个指针,sizeof(array)计算的是地址的长度,地址是32位4个字节,计算结果为1,但是宏表达式中sizeof(array)是计算整个数组的字节数。

举例说明,宏表达式的副作用:

#define SUM(a, b) (a)+(b)...printf("%d\n", SUM(1,2) * SUM(1,2));

预期程序会输出9,但是不对,程序输出5,因为宏定义是文本替换,替换结果为:1+2*1+2=5。因此宏定义表达式也有很大的副作用。

宏表达式与函数的对比:
宏表达式在预编译期被处理,编译器不知道宏表达式的存在。
宏表达式用“实参”完全替代形参,不进行任何运算。
宏表达式没有任何的“调用”开销。节省时间空间。
宏表达式中不能出现递归定义
这里写图片描述
这样的递归写法是错误的,会把define中第二个FAC当作函数来看,会报错。

举例程来表明宏定义的优点:

#include <stdio.h>#include <malloc.h>#define MALLOC(type, x) (type*)malloc(sizeof(type)*x)#define FOREVER() while(1)#define BEGIN {#define END   }#define FOREACH(i, m) for(i=0; i<m; i++)int main(){    int array[] = {1, 2, 3, 4, 5};    int x = 0;    int*p = MALLOC(int, 5);    FOREACH(x, 5)    BEGIN        p[x] = array[x];    END    FOREACH(x, 5)    BEGIN        printf("%d\n", p[x]);    END    FOREVER();    free(p);    printf("Last printf...\n");    return 0;}

上面的程序看起来已经不像C语言了。

内置宏定义

这里写图片描述
有的编译器没有 _ STDC _

利用内置宏来定义日志宏,即打印相关的操作内容。

#include <stdio.h>#define LOG(s) printf("%s,%d,%s,%s\n",__FILE__,__LINE__,__DATE__,s)void f(){    LOG("Enter f()");    LOG("Exit f()");}int main(){    LOG("Enter main()");    f();    LOG("Exit main()");    return 0;}

函数与宏的详细对比:

宏是由预处理直接替换展开的,编译器不知道宏的存在
函数是由编译器直接编译的实体,调用行为由编译器决定

多次使用宏会导致程序代码量增加
函数是跳转执行的,因此代码量不会增加

宏的效率比函数要高,因为是直接展开,无调用开销
函数调用时会创建活动记录,效率不如宏

宏的效率比函数稍高,但是其副作用巨大,容易出错。
函数存在实参到形参的传递,因此无任何副作用,但是函数需要建立活动对象,效率受影响

宏的参数可以是类型名
函数的参数必须是固定类型,效率稍低,不易出错
宏可以实现函数不能实现的功能,如计算数组的元素个数

0 0
原创粉丝点击