C 这两个定义之间的区别是什么
在下文中,MY_INT2和MY_INT3声明之间的区别是什么? 我在一些代码中有一个相当根深蒂固的问题,因此将生成bug的代码减少到测试用例中是相当具有挑战性的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
#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。正确的解决方案是将括号放在宏本身中。