C中整数的不正确乘法
Simulink中的C编码S函数显示出不正确的行为,我已设法将问题缩小到整数的错误乘法 在代码的开头,我有如下内容:C中整数的不正确乘法,c,c-preprocessor,C,C Preprocessor,Simulink中的C编码S函数显示出不正确的行为,我已设法将问题缩小到整数的错误乘法 在代码的开头,我有如下内容: #define NRBF 21 #define NRBF1 NRBF+1 然后,在脚本中的函数中,我有: void function_name(SimStruct *S, const int_T a) { ... int_T base; base = a*NRBF1; printf("%i\t", a); printf("%i\t"
#define NRBF 21
#define NRBF1 NRBF+1
然后,在脚本中的函数中,我有:
void function_name(SimStruct *S, const int_T a)
{
...
int_T base;
base = a*NRBF1;
printf("%i\t", a);
printf("%i\t", NRBF1);
printf("%i\n", base);
..
}
现在,如果a=0
,NRBF=21
,我有(而不是base=0
)
如果a=1
,NRBF=21
,我有(正如预期的base=22
)
如果a=2
,NRBF=21
,我有(而不是base=44
)
现在,我必须说我有点困惑。我试着把乘法的行改成
base = a* (int_T)NRBF1;
但这并不能解决问题
任何帮助都将不胜感激!谢谢大家! 基本上是在计算
0*21+1 = 1
宏已展开,但*
的优先级高于+
。这就是为什么会发生这种情况
更详细的解释是
#define NRBF 21
#define NRBF1 NRBF+1
那么到底发生了什么
base = a*NRBF1;
或
正确的方法是用括号把它括起来
#define NRBF1 (NRBF+1)
还有一些陷阱: 当您添加这样的宏时,
#定义SQR(X)X*X
对于像这样的一些例子,相同的优先级运算符相邻存在,这将是有问题的
int i = 100/SQR(10);
然后将其扩展到
int i = 100/10*10
现在,相同的优先级操作符从左到右执行
因此,它将导致i=100
解决方案相同#定义SQR(X)(X*X)
同样,当传递这样一个表达式时SQR(i+1)
,它将扩展为i+1*i+1
=2*i+1
。所以稍微正确一点就好了
#define SQR(X) ((X)*(X))
即使这样,若你们忘记了一件事,那个么你们也无法避免几件事——宏只是扩展了一件事——它什么也不做
不能像这样使用宏
SQR(i++)
将扩展为((i++)*(i++)
)。所以你把i
增加了两倍,这不是你的意思。此外,这将导致未定义的行为随着宏的展开,该行如下所示:
base = a*NRBF+1;
- 对于
等于0,表达式为a
,即10*21+1
- 对于
等于2,表达式为a
,即432*21+1
#define NRBF1 (NRBF + 1)
对于任何以表达式作为其右侧的宏,这是一条很好的规则
请记住,宏只是被文本替换到代码中。问题在于:
您可以这样定义宏:
#define NRBF 21
#define NRBF1 NRBF+1
#define NRBF1 (NRBF+1)
当你写这篇文章时:
base = a*NRBF1;
预处理器将NRBF1
文本替换为21+1
,结果如下:
base = a*21+1;
但你的本意是:
base = a*(21+1);
因此,您需要像这样定义宏:
#define NRBF 21
#define NRBF1 NRBF+1
#define NRBF1 (NRBF+1)
define不创建单个值22,而是创建表达式21+1。我想知道如果你把第二个定义改为
#定义NBRF1(NBRF+1)
a*NRBF1
扩展为a*21+1
。使用括号,如#定义NRBF1(NRBF+1)
重复候选项:。可能还有其他问题。对于SQR(X)(X*X)
甚至SQR(X)((X)*(X))
问题更棘手,因为X
可能是一个副作用表达式或函数,两次调用可能会产生意想不到的结果。@Jean-Françoisfare.:是的,这就是为什么我要写它,并将它放在以后的编辑中,否则它将被错误地解释。看起来很像:@Jean-Françoisfare.:我在写。是的,SQR(i++)
展开两次时出现问题。如果a
等于2
@mch,则表达式结果为43
,请更正。咖啡前的小整数运算对我来说算不了什么。非常感谢你的回答!绝对正确!非常感谢你!你完全正确。我真傻。
base = a*(21+1);
#define NRBF1 (NRBF+1)