宏的使用与函数的对比

宏的使用

#define 机制包括了一个规定,允许把参数替换到文本中,这种实现通常称为宏(macro)或定义宏(define macro)。

宏的申明方式:#define name( parament-list ) stuff (注释:parament-list 是一个由逗号隔开的符号表,它们可能出现在stuff中)

#define df(x) x*x

参数列表的左括号必须与name紧邻。
如果两者之间有任何空白存在,参数列表就会被解释为stuff的一部分。

#define df(x) x*x
int main()
{
    int a = 5;
    printf("%d",df(a));
    return 0;
}

这个宏接收一个参数 x .
置于程序中,预处理器就会用下面这个表达式替换上面的表达式:

#define df(x) x*x
int main()
{
    int a = 5;
    printf("%d",a*a);
    return 0;
}

需要注意宏存在一个问题

#define df(x) x*x
int main()
{
    int a = 5;
    printf("%d",df(a+1));
    return 0;
}

会变成如下

printf("%d",a+1*a+1);

在宏定义上加上两个括号,这个问题便轻松的解决了:

#define df(x) (x)*(x)
int main()
{
    int a = 5;
    printf("%d",df(a+1));
    //printf("%d",(a+1)*(a+1));
    return 0;
}

这样预处理之后就产生了预期的效果

这里还有一个宏定义:

#define df(x) (x)+(x)
int main()
{
    int a = 5;
    printf("%d",10*df(a));
    //printf("%d",10*(5)+(5)); 结果为错
    return 0;
}

我们还需要加上一个括号使宏先得出结果后再使用

#define df(x)(x)+(x)
int main()
{
    int a = 5;
    printf("%d",10*df(a));
    //printf("%d",10*((5)+(5))); 
    //printf("%d",10*(10)); 
    return 0;
}

宏和函数对比

宏通常被应用于执行简单的运算
比如在两个数中找出较大的一个

#define df(x,y) ((x) > (y)? (x) : (y))

那为什么不用函数来完成这个任务?

  1. 用于调用函数和从函数返回的代码可能比实际执行这个小型计算工作所需要的时间更多。
    所以宏比函数在程序的规模和速度方面更胜一筹。
  2. 更为重要的是函数的参数必须声明为特定的类型。
    所以函数只能在类型合适的表达式上使用。反之这个宏怎可以适用于整形、长整型、浮点型等可以
    用于>来比较的类型。
    宏是类型无关的。

宏的缺点:
3. 每次使用宏的时候,一份宏定义的代码将插入到程序中。除非宏比较短,否则可能大幅度增加程序
的长度。
4. 宏是没法调试的。
5. 宏由于类型无关,也就不够严谨。
6. 宏可能会带来运算符优先级的问题,导致程容易出现错。.

宏有时候可以做函数做不到的事情

#define MALLOC(num,type) (type*)malloc(num*sizeof(type))
int main()
{   
    MALLOC(10,int);
    //预处理器替换之后:
    (int *)malloc(10 * sizeof(int));
    return 0;
}

宏和函数的一个对比

#define定义宏函数
每次使用时,宏代码都会被插入到程序中。除了非常小的宏之外,程序的长度会大幅度增长函数代码只出现于一个地方;每次使用这个函数时,都调用那个地方的同一份代码
更快存在在函数的调用和返回的额外开销,所以相对慢一些
宏参数的求值是在所有周围表达式的上下文环境里,除非加上括号,否则邻近操作符的优先级可能会产生不可预料的后果,所以建议宏在书写的时候多些括号。函数参数只在函数调用的时候求值一次,它的结果值传递给函数。表达式的求值结果更容易预测。
参数可能被替换到宏体中的多个位置,所以带有副作用的参数求值可能会产生不可预料的结果。函数参数只在传参的时候求值一次,结果更容易控制
宏的参数与类型无关,只要对参数的操作是合法的,它就可以使用于任何参数类型。函数的参数是与类型有关的,如果参数的类型不同,就需要不同的函数,即使他们执行的任务是相同的。
宏是不方便调试的函数是可以逐语句调试的
宏是不能递归的函数是可以递归的
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值