代码之家  ›  专栏  ›  技术社区  ›  Cyber Gh

在C语言中用#来定义奇怪的行为

  •  -2
  • Cyber Gh  · 技术社区  · 8 年前

    #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 提前谢谢

    4 回复  |  直到 8 年前
        1
  •  2
  •   Joker_vD    8 年前

    发生了什么事

    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)
    
        2
  •  1
  •   Angew is no longer proud of SO    8 年前

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

    pager->file_length / ROW_SIZE
    

    扩展到

    pager->file_length / ID_SIZE + USERNAME_SIZE + EMAIL_SIZE
    

    我相信你同意以上不一定是零,特别是如果 USERNAME_SIZE 或 EMAIL_SIZE

    要解决此问题,请在宏定义中的表达式周围放置括号:

    #define ROW_SIZE (ID_SIZE + USERNAME_SIZE + EMAIL_SIZE)
    
        3
  •  0
  •   Some programmer dude    8 年前

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

    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)
    
        4
  •  0
  •   asdf    8 年前

    应该这样写:

    #define ROW_SIZE (ID_SIZE + USERNAME_SIZE + EMAIL_SIZE)