C中整数的不正确乘法

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"

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

如果
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;
  • 对于
    a
    等于0,表达式为
    0*21+1
    ,即1
  • 对于
    a
    等于2,表达式为
    2*21+1
    ,即43
解决方案是在宏定义中插入括号:

#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)