C 宏函数

宏函数(带参宏)

#define ADD(A,B) ((A)+(B))

✅ 要点:

● 无类型,不做类型检查

● 参数 A、B 各自加括号,整体表达式也要套括号,防止运算符优先级灾难

● 末尾不能加分号,加分号会把;一并替换进代码

普通函数 vs 宏函数

对比项 普通函数 Add(int a, int b) 宏函数 ADD(A,B)
处理时机 编译阶段,生成独立函数,调用时 call 跳转 预处理阶段文本替换,没有函数实体
调用开销 参数传递、call/ret、栈操作,有开销 无函数调用开销,直接原地展开代码
类型检查 有,参数类型不匹配直接报错 无,随便传,编译不报错,容易出诡异 bug
返回值 有固定返回类型 只是文本替换,没有返回值概念
调试 可以断点进入函数内部 不能断点,宏展开后不存在这个 "函数"

错误示范(不加括号)

c 复制代码
#define BAD_ADD(A,B) A+B
// 调用:BAD_ADD(1,2)*10
// 替换后:1+2*10 → 结果21,预期30,优先级出错
c 复制代码
#define BAD_ADD(A,B) (A+B)
// 调用:BAD_ADD(1||2,3) ? 1 :0 ,缺少外层括号也会出问题

宏函数典型坑点

坑 1:参数带自增 / 自减

c 复制代码
#define ADD(A,B) ((A)+(B))
int a=1;
int res = ADD(a++, a);
// 展开:((a++) + (a)),a++会执行两次,结果不符合预期

宏只是文本替换,参数如果带有副作用(++、--、函数调用),会多次执行!普通函数不会

坑 2:末尾加分号

c 复制代码
#define ADD(A,B) ((A)+(B));
int r = ADD(1,2);
//替换后 int r = ((1)+(2)); ;  多一个空语句,部分场景语法报错

坑 3:无类型检查

c 复制代码
ADD("123",123);

不会报错,直接计算字符串字面量地址 + 123,得到一个无意义数字

什么时候用宏函数,什么时候用普通函数

✅ 适合宏:极简短运算,求最大最小值、简单位运算,追求极小开销

❌ 不要宏:代码逻辑复杂、参数有 ++ 这类副作用、需要断点调试、需要类型安全 → 用内联函数inline

补充:inline 内联函数(用来替代宏函数)

C99 引入,兼顾两者优点:

  1. 有类型检查
  2. 编译器原地展开,没有 call 调用开销
  3. 可以断点调试
c 复制代码
inline int Add(int a,int b)
{
    return a+b;
}
相关推荐
愤怒火龙果41 分钟前
蓝队笔记整理01 C2 远控与 Webshell 流量特征
笔记·网络安全
Code_Solitude43 分钟前
C语言:指针题型总结
c语言·开发语言
曹牧44 分钟前
Java:`tools.jar`
java·开发语言·jar
wyhwust1 小时前
程序设计基础-No5课件知识点
c语言
小白旗1 小时前
PHP 严重漏洞风险提醒:如何排查运行环境并做好安全更新
开发语言·php
丑梨数据1 小时前
法律合同知识库怎么搭:从图片压缩到私有化 RAG 的工程笔记
开发语言·笔记·c#
小羊没烦恼!1 小时前
TypedSql:在 C# 类型系统上实现一个 SQL 查询引擎
java·linux·运维·服务器·开发语言·数据库·mysql
FLJwu1 小时前
运动相机采购选型避坑实战|第二篇
c语言·开发语言·数码相机·运动相机·oem 量产
启博网络1 小时前
智慧档案库房工业组网:MR-1280 边缘大脑,实现温湿度、漏水、防火防盗设备智能联动教程
运维·网络·物联网·网络协议·网络安全·信息与通信·sdwan