| 属性 | #define定义宏 | 函数 |
| 代码长度 |
每次使用时,宏代码都会被插入到程序中。 除了非常 小的宏之外,程序的长度会大幅度增长 | 函数代码只出现于一个地方;每次使用这个函数时,都调用那个地方的同一份代码 |
| 执行速度 | 更快 | 调用和返回的运行会相对较慢 |
| 操作符优先级 | 宏参数的求值是在所有周围表达式的上下文环境里, 除非加上括号,否则邻近操作符的优先级可能会产生 不可预料的后果,所以建议宏在书写的时候多些括 号。 | 函数参数只在函数调用的时候求 值一次,它的结果值传递给函 数。表达式的求值结果更容易预 测。 |
| 带有副作用的参数 | 参数可能被替换到宏体中的多个位置,所以带有副作 用的参数求值可能会产生不可预料的结果 | 函数参数只在传参的时候求值一 次,结果更容易控制。 |
| 参数类型 | 宏的参数与类型无关,只要对参数的操作是合法的, 它就可以使用于任何参数类型 | 函数的参数是与类型有关的,如 果参数的类型不同,就需要不同 的函数,即使他们执行的任务是 不同的 |
| 调试 | 不便调试 | 可调试 |
| 递归 | 无法递归 | 可递归 |
offsetof宏的模拟实现
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stddef.h>
struct stu
{
int a;
char b;
double c;
};
#define OFFSETOF(struct_type,mem_name) (size_t)&(((struct_type*)0)->mem_name)
int main()
{
printf("%d\n", OFFSETOF(struct stu, a));
printf("%d\n", OFFSETOF(struct stu, b));
printf("%d\n", OFFSETOF(struct stu, c));
return 0;
}
本文探讨了宏和函数在代码长度、执行速度、操作符优先级、副作用、参数类型、调试和递归等方面的差异。宏在某些情况下提供更快的执行速度,但可能导致不可预测的行为和调试困难。函数则更易于管理和调试,支持递归。文章还通过示例展示了如何模拟实现offsetof宏,用于获取结构体成员的偏移量。
565

被折叠的 条评论
为什么被折叠?



