我在一个头文件中定义了两个带有掩码的#define:
myheader.h
#define MASK_A IPC_CREAT | IPC_EXCL | 0666
#define MASK_B 0666
void myfunction(int mymask);
myfile.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
中定义的MASK_A事件,之后是MASK_B的事情,但我不知道为什么,两次程序都通过MASK_A方式
投射
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
文字和整数比较的更好方法吗?
提前致谢。
答案 0 :(得分:4)
它不起作用,因为比较运算符(==)的优先级高于按位或(|)。 所以当你这样做时
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)
答案 1 :(得分:2)
建议始终将宏括起来
#define MASK_A (IPC_CREAT|IPC_EXCL|0666)
特别是涉及&
和|
,C&#39的优先规则
可能令人困惑:
#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&amp; 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)
稍后添加了短小的,合乎逻辑的&&
和||
,但保留了|
和&
的原始优先顺序。
答案 2 :(得分:1)
C语言中的一个已知缺陷是|
和&
的优先级低于==
(Dennis Ritchie在某些时候承认了这一点)。这是您的代码不起作用的实际原因。
通过正确编写宏来解决这个问题:
#define MASK_A (IPC_CREAT | IPC_EXCL | 0666)
任何体面的C编程书都将解决这样的问题,并展示如何用括号正确编写宏。