宏定义 使用分析

宏定义:

在程序中,以#开头的都是预处理指令。
#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;
}

函数与宏的详细对比:

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

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

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

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

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值