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", NRBF1);
printf("%i\n", base);
..
}
现在,如果a=0
,NRBF=21
,我有(而不是base=0
)
0 22 1
如果a=1
,NRBF=21
,我有(按预期base=22
)
1 22 22
如果a=2
,NRBF=21
,我有(而不是base=44
)
2 22 43
现在,我必须说我有点困惑。我试图将乘法线改为
base = a* (int_T)NRBF1;
但它没有解决问题。
任何帮助将不胜感激!谢谢!
答案 0 :(得分:5)
问题在于:
您可以像这样定义宏:
#define NRBF 21
#define NRBF1 NRBF+1
当你这样写:
base = a*NRBF1;
预处理器用NRBF1
以文本方式替换21+1
,结果如下:
base = a*21+1;
但你打算这样做:
base = a*(21+1);
因此,您需要像这样定义宏:
#define NRBF1 (NRBF+1)
答案 1 :(得分:3)
随着宏的扩展,该行看起来像:
base = a*NRBF+1;
a
等于0,则表达式为0 * 21 + 1
,即1。a
等于2,则表达式为2 * 21 + 1
,即43。解决方案是将括号放在宏定义中:
#define NRBF1 (NRBF + 1)
对于任何以表达式为右侧的宏来说,这是一个很好的规则。
请记住,宏只是文本替换为代码。
答案 2 :(得分:2)
基本上计算好了
0*21+1 = 1
宏已展开,但*
优先于+
。这就是为什么会发生这种情况。
更详细的解释是
#define NRBF 21
#define NRBF1 NRBF+1
那是怎么回事?
base = a*NRBF1;
或
base = a*NRBF+1
Now when a = 0 then base = 1
when a = 1 then base = 21+1 ...so on.
正确的方法是用aropund括号括起来。
#define NRBF1 (NRBF+1)
更多陷阱:
当您添加像#define SQR(X) X*X
对于像这样的一些例子,其中相同的优先级运算符紧挨着下一个,那么它将是有问题的。
int i = 100/SQR(10);
然后它将扩展为
int i = 100/10*10
现在,从左到右执行相同的优先级运算符。
因此会产生i=100
。
同样的解决方案#define SQR(X) (X*X)
同样,当传递像SQR(i+1)
这样的表达式时,它会扩展为i+1*i+1
= 2*i+1
。所以更正确的是
#define SQR(X) ((X)*(X))
即使如此,如果你忘记了一件事,你就无法避免一些事情宏只是扩展 - 它什么都不做。
你不能像这样使用宏
SQR(i++)
将扩展为((i++)*(i++))
。所以你增加了i
两次,这是你不是故意的。此外,这将导致未定义的行为。
答案 3 :(得分:1)
define不会创建单个值22但是表达式为21 + 1.我想知道如果将第二个#define更改为 #define NBRF1(NBRF + 1)