#define宏能否定义多值集合?下述代码无法运行的原因是什么
问题解答
1. 宏定义多值集合的可行性
C语言的#define是预处理阶段的纯文本替换工具,本身没有语法校验,所以你完全可以用它定义包含多个数值的集合序列,只是不能直接用你给出的这种语法做「变量是否属于集合」的判断。
2. 代码无法正常运行的核心原因
你写的宏定义#define SVALUES (1.2, 2.2, ..., 82)里,括号包裹的逗号序列触发了C的逗号运算符规则:
- 逗号运算符会从左到右依次计算每个表达式,最终仅返回最后一个表达式的值
- 也就是说
SVALUES经过预处理器展开后,实际等价于单个数值82,CVALUES等价于单个数值68 - 你写的
if(rA == SVALUES)本质上是在判断rA == 82,完全不是判断rA是否属于你定义的数值集合,自然达不到预期效果。
另外补充一个隐藏问题:你的SVALUES存储的是浮点数值,浮点型因为存储精度问题,永远不能直接用==做相等判断,必须通过判断两个数的差值小于极小精度阈值的方式实现判等。
3. 正确实现方案
如果要实现「判断变量是否属于指定数值集合」的需求,常见有两种实现方案:
方案1:数组+遍历判断(适用大集合场景)
#include <math.h> #include <stdio.h> // 定义集合数组 const double SVALUES[] = {1.2, 2.2, 1.5, 1.8, 2.2, 2.7, 3.3, 3.9, 4.7, 5.6, 6.8, 8.2, 10, 12, 15, 18, 22, 27, 33, 39, 47, 56, 68, 82}; const int SCOUNT = sizeof(SVALUES) / sizeof(SVALUES[0]); const int CVALUES[] = {10,15,22,33,47,68}; const int CCOUNT = sizeof(CVALUES) / sizeof(CVALUES[0]); // 浮点集合成员判断 int is_in_double(double val, const double arr[], int len) { for (int i = 0; i < len; i++) { // 浮点判等用精度阈值判断 if (fabs(val - arr[i]) < 1e-6) { return 1; } } return 0; } // 整型集合成员判断 int is_in_int(int val, const int arr[], int len) { for (int i = 0; i < len; i++) { if (val == arr[i]) { return 1; } } return 0; } int main() { double rA = 2.2, rB = 9.9; int c = 15; // 调用判断 if (is_in_double(rA, SVALUES, SCOUNT)) { printf("Ra is a standard value.\n"); } else { printf("Ra is not a standard value.\n"); } if (is_in_double(rB, SVALUES, SCOUNT)) { printf("Rb is a standard value.\n"); } else { printf("Rb is not a standard value.\n"); } if (is_in_int(c, CVALUES, CCOUNT)) { printf("c is a standard value.\n"); } else { printf("c is not a standard value.\n"); } return 0; }
方案2:宏封装(适用小集合场景)
#include <math.h> // 封装集合判断宏 #define IS_IN_SVALUES(val) (fabs(val-1.2)<1e-6 || fabs(val-2.2)<1e-6 || fabs(val-1.5)<1e-6 || fabs(val-1.8)<1e-6 || fabs(val-2.2)<1e-6 || fabs(val-2.7)<1e-6 || fabs(val-3.3)<1e-6 || fabs(val-3.9)<1e-6 || fabs(val-4.7)<1e-6 || fabs(val-5.6)<1e-6 || fabs(val-6.8)<1e-6 || fabs(val-8.2)<1e-6 || fabs(val-10)<1e-6 || fabs(val-12)<1e-6 || fabs(val-15)<1e-6 || fabs(val-18)<1e-6 || fabs(val-22)<1e-6 || fabs(val-27)<1e-6 || fabs(val-33)<1e-6 || fabs(val-39)<1e-6 || fabs(val-47)<1e-6 || fabs(val-56)<1e-6 || fabs(val-68)<1e-6 || fabs(val-82)<1e-6) #define IS_IN_CVALUES(val) (val==10 || val==15 || val==22 || val==33 || val==47 || val==68) // 调用示例 if (IS_IN_SVALUES(rA)) { printf("Ra is a standard value.\n"); }
内容的提问来源于stack exchange,提问作者jimbo
相关产品推荐
相关产品推荐

