C 这两个定义之间的区别是什么

C 这两个定义之间的区别是什么,c,c99,C,C99,在下文中,MY_INT2和MY_INT3声明之间的区别是什么? 我在一些代码中有一个相当根深蒂固的问题,因此将生成bug的代码减少到测试用例中是相当具有挑战性的 #define MY_INT1 5 #define MY_INT2 31 #define MY_INT3 (int) pow(2, MY_INT1)-1 我的代码中出现了一些问题,这些问题可以通过使用下面的代码来解决,这感觉非常不必要 int mul(int a, int b) { return a*b; } int som

在下文中,MY_INT2和MY_INT3声明之间的区别是什么? 我在一些代码中有一个相当根深蒂固的问题,因此将生成bug的代码减少到测试用例中是相当具有挑战性的

#define MY_INT1 5
#define MY_INT2 31
#define MY_INT3 (int) pow(2, MY_INT1)-1
我的代码中出现了一些问题,这些问题可以通过使用下面的代码来解决,这感觉非常不必要

int mul(int a, int b) {
    return a*b;
}

int someFunction(int in) {
     //nice
     return floor(in/MY_INT2);
}

int someFunction2(int in) {
     //silly
     return floor(in/mul(1,MY_INT3));
}

int someFunction3(int in) {
     //cast does not solve the issue
     return floor(in/(int)MY_INT3);
}

宏是文本替换。在/(int)中没有括号
,MY_INT3
实际上是

in / (int) (int) pow(2, 5) - 1;
这和

in / 32 - 1;
因此,除法后减去
-1

另外,
mul(1,MY_INT3)
也可以工作,因为实际上,参数在传递给函数时进行计算

in / (MY_INT3);
也应该像你期望的那样“工作”


看起来你认为施法是一种解决问题的魔术,但事实并非如此。强制转换只告诉编译器如何表示该值,其他什么都没有。

错误是什么?你没有说实际发生了什么……欢迎来到奇妙的宏世界,在那里,额外的括号几乎是必须的。而且,你知道
pow
是一个浮点函数吗?如果您想要2的幂作为整数,请使用位移位(例如,
1不要为此使用
pow
。一些数学库实现即使对于整数输入,也会返回带有错误的结果。因此
pow(2,5)
可能返回略低于32的值,将其转换为
int
将产生31。要计算二的幂,请使用位移位,例如
1。正确的解决方案是将括号放在宏本身中。