代码之家  ›  专栏  ›  技术社区  ›  Alejandro Galera

如何在“if”比较中使用定义掩码

c
  •  4
  • Alejandro Galera  · 技术社区  · 8 年前

    我已经在一个头文件中定义了两个使用掩码定义:

    我的标题.h

    #define MASK_A IPC_CREAT | IPC_EXCL | 0666
    #define MASK_B 0666
    
    void myfunction(int mymask);
    

    我的文件.c

    #include "myheader.h" 
    
    ... 
    
    void myfunction(int mymask) {
       if (MASK_A == mymask) {
          printf("My mask is A\n");
          /* Do some things... */   
       } else {
          printf("My mask is B\n");
          /* Do other things...*/   
       } 
    }
    
    void main() {   
    
        myfunction(MASK_A);
        myfunction(MASK_B); 
    }
    

    据我所知,用这个简单的程序应该先屏蔽在 myfunction 在那之后,掩盖一些事情,但我不知道为什么, 两次程序都通过一种方式 .

    铸件 if ((int)MASK_A == mymask) 不起作用。

    看起来define mask_a和mask_b不是整数,因为:

    如果我将函数重新定义为:

    void myfunction(int mymask) {
       int _maskA=MASK_A;
       if (_maskA == mymask) {
          printf("My mask is A\n");
          /* Do some things... */   
       } else {
          printf("My mask is B\n");
          /* Do other things...*/   
       } 
    }
    

    它很好用,但看起来不太漂亮。 谁都知道更好的管理方法 #define 文字和整数比较?

    事先谢谢。

    3 回复  |  直到 8 年前
        1
  •  4
  •   Code Name Jack    8 年前

    它不起作用,因为比较运算符(==)的优先级高于按位或()。 所以当你这样做的时候

     if (MASK_A == mymask) 
    

    结果是,

    if (IPC_CREAT | IPC_EXCL | 0666==mymask)
    

    最终执行有点像,

    if (IPC_CREAT | IPC_EXCL |( 0666==mymask))
    

    尝试将宏定义为

    #define MASK_A (IPC_CREAT | IPC_EXCL | 0666)
    
        2
  •  2
  •   Petr Skocik    8 年前

    建议 总是 用括号括起宏

    #define MASK_A (IPC_CREAT|IPC_EXCL|0666)
    

    尤其是当涉及到 & 和 | ,C的优先规则 可能会令人困惑:

    #include <stdio.h>
    #include <assert.h>
    int main()
    {
        int mask = 0xAA|0xBB00; assert(mask==0xBBAA);
    
        printf("%x\n", 0xAA|0xBB00 == mask);
        //prints aa because 0xAA|(0xBB00==mask /*false==0*/)  equals 0xAA
        //IOW, == has a higher precedence than |  
        //ans so 0xAA|0xBB00==mask is equivalent to 0xAA|(0xBB00==mask) 
    
        printf("%x\n", (0xAA|0xBB00) == mask);
        //prints 1 — parentheses force the intended grouping
    }
    

    正如该语言的作者丹尼斯·里奇(Denis Ritchie)在第一个K&R中所说,

    "Some of the operators have the wrong precedence; some parts of the syntax could be better."

    γ 和 & 在他的文章中, The Development of the C Language* 他解释的地方 γ 和 & 用于 B 而不是短路,逻辑 || 和 && (B没有,史前C也没有)以及 γ 和 & 是这样的:

      if (a==b & c)
    

    将被解析为

     if ((a==b) & c)
    

    短路,合乎逻辑 && 和 γ 后来又增加了,但最初的先例是 γ 和 & 被保留了下来。

        3
  •  1
  •   Lundin    8 年前

    这是C语言的一个已知缺陷 | 和 & 优先级低于 == (丹尼斯·里奇在某个时候承认了这一点)。这就是代码不起作用的实际原因。

    通过正确编写宏来解决此问题:

    #define MASK_A (IPC_CREAT | IPC_EXCL | 0666)
    

    任何一本像样的C编程书都会解决这样的问题,并展示如何用括号正确地编写宏。