C宏的功能有多强大?能否实现计数、参数补全等特定功能?
C宏实现你需要的三个进阶功能
C预处理器的宏能力远超基础用法,完全可以实现你提到的三个需求,以下是具体实现方案:
1. 参数计数宏COUNT
利用预处理器可变参数展开特性,通过额外的计数标记匹配参数数量:
// 对外调用的接口宏 #define COUNT(...) _COUNT(__VA_ARGS__, 5, 4, 3, 2, 1) // 内部展开宏,提取对应位置的计数值 #define _COUNT(_1, _2, _3, _4, _5, N, ...) N
工作原理:
- 调用
COUNT(a,b,c)时,宏展开为_COUNT(a,b,c,5,4,3,2,1),此时N对应第三个位置的3,返回结果为3; - 调用
COUNT(e,f)时,展开为_COUNT(e,f,5,4,3,2,1),N对应第五个位置的2,返回结果为2; - 若需要支持更多参数,只需在
_COUNT的参数列表末尾增加更多递减数字即可。
2. 自动补全参数的数组生成宏ARRAY
通过可变参数提取和固定补全值,生成大小为5的数组:
// 对外接口宏,生成固定大小的数组 #define ARRAY(...) const int array[5] = { _ARRAY_ARGS(__VA_ARGS__, -1, -1, -1, -1, -1) } // 内部宏,提取前5个参数(用户传入值+补全的-1) #define _ARRAY_ARGS(_1, _2, _3, _4, _5, ...) _1, _2, _3, _4, _5
效果示例:
ARRAY(a,b,c)展开为:const int array[5]={a,b,c,-1,-1};ARRAY(e,f)展开为:const int array[5]={e,f,-1,-1,-1};- 传入5个参数时(如
ARRAY(1,2,3,4,5)),直接生成无补全的数组:const int array[5]={1,2,3,4,5};
3. 标识符替换为递增计数器的FORMULA宏
将表达式中的自定义标识符替换为array[索引],同一个标识符保持相同索引(以下实现支持最多5个单个字母标识符):
// 对外调用接口 #define FORMULA(expr) _REPLACE_E(_REPLACE_D(_REPLACE_C(_REPLACE_B(_REPLACE_A(expr)))) // 替换a为array[0] #define _REPLACE_A(expr) _REPLACE_A_IMPL(expr) #define _REPLACE_A_IMPL(a) array[0] #define _REPLACE_A_IMPL(x) x // 替换b为array[1] #define _REPLACE_B(expr) _REPLACE_B_IMPL(expr) #define _REPLACE_B_IMPL(b) array[1] #define _REPLACE_B_IMPL(x) x // 替换c为array[2] #define _REPLACE_C(expr) _REPLACE_C_IMPL(expr) #define _REPLACE_C_IMPL(c) array[2] #define _REPLACE_C_IMPL(x) x // 替换d为array[3] #define _REPLACE_D(expr) _REPLACE_D_IMPL(expr) #define _REPLACE_D_IMPL(d) array[3] #define _REPLACE_D_IMPL(x) x // 替换e为array[4] #define _REPLACE_E(expr) _REPLACE_E_IMPL(expr) #define _REPLACE_E_IMPL(e) array[4] #define _REPLACE_E_IMPL(x) x
效果示例:
调用FORMULA(a*3+5*(b+a))时,会依次完成替换:
- 先将所有
a替换为array[0],得到array[0]*3+5*(b+array[0]); - 再将
b替换为array[1],最终得到array[0]*3+5*(array[1]+array[0])。
注意:
- 以上实现针对单个字母标识符,若需要支持更长标识符,需为每个标识符单独编写替换宏;
- 若要自动识别任意标识符并分配递增索引,标准C预处理器难以实现,需借助编译器扩展(如
__COUNTER__)或第三方预处理器库。
内容的提问来源于stack exchange,提问作者Lolo
相关产品推荐
相关产品推荐

