#define在C语言中表现奇怪的除法

时间:2018-08-21 09:27:19

标签: c c-preprocessor division

我在C语言中有一个定义,看起来像这样

#define ROW_SIZE ID_SIZE + USERNAME_SIZE + EMAIL_SIZE

评估为293 然后我这样做

uint32_t num_rows = pager->file_length / ROW_SIZE;

pager->file_length肯定为0
num_rows的结果为289。甚至0 / ROW_SIZE的计算结果为289。为什么会发生?有人请解释。 预先感谢

4 个答案:

答案 0 :(得分:2)

发生了什么

uint32_t num_rows = pager->file_length / ROW_SIZE;

扩展为

uint32_t num_rows = pager->file_length / ID_SIZE + USERNAME_SIZE + EMAIL_SIZE;

因此num_rows的值为0 + ID_SIZE + USERNAME_SIZE + EMAIL_SIZE,而不是零。考虑在您的定义中添加括号:

#define ROW_SIZE (ID_SIZE + USERNAME_SIZE + EMAIL_SIZE)

答案 1 :(得分:1)

宏扩展是基于令牌的替换。换句话说,

pager->file_length / ROW_SIZE

扩展到

pager->file_length / ID_SIZE + USERNAME_SIZE + EMAIL_SIZE

我相信您同意上述数值不一定为零,尤其是在USERNAME_SIZEEMAIL_SIZE非零的情况下。

要解决此问题,请在宏定义中的表达式两边加上括号:

#define ROW_SIZE (ID_SIZE + USERNAME_SIZE + EMAIL_SIZE)

答案 2 :(得分:0)

您必须记住,预处理器宏基本上在源代码中被查询替换。

如果您有

uint32_t num_rows = pager->file_length / ROW_SIZE;

编译器在进行预处理后会看到什么

uint32_t num_rows = pager->file_length / ID_SIZE + USERNAME_SIZE + EMAIL_SIZE;

由于普通operator precedence等于

uint32_t num_rows = (pager->file_length / ID_SIZE) + USERNAME_SIZE + EMAIL_SIZE;

那当然不是您期望或想要的。因此,务必始终在宏中使用多余的括号,如

#define ROW_SIZE (ID_SIZE + USERNAME_SIZE + EMAIL_SIZE)

答案 3 :(得分:0)

应该这样写:

#define ROW_SIZE (ID_SIZE + USERNAME_SIZE + EMAIL_SIZE)