我在一个头文件中定义了两个 #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 An");
/* Do some things... */
} else {
printf("My mask is Bn");
/* 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 An");
/* Do some things... */
} else {
printf("My mask is Bn");
/* Do other things...*/
}
}
它工作正常,但看起来不是很漂亮。 请问有人知道管理#define
文字和整数比较的更好方法吗?
提前谢谢。
它不起作用,因为比较运算符 (==( 的优先级高于按位 Or (|(。 所以当你这样做时
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)
建议始终将宏括起来
#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("%xn", 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("%xn", (0xAA|0xBB00) == mask);
//prints 1 — parentheses force the intended grouping
}
正如该语言的作者丹尼斯·里奇(Denis Ritchie(在第一个K&R中所说的那样,
"一些运营商的优先级错误;某些部分 语法可以更好。
他在文章中解释了|
和&
的这些优先顺序, C语言的发展*,他解释说|
和&
用于B
,而不是短路,逻辑||
和&&
(B没有,史前C也没有(,因此|
和&
的优先规则是这样的:
if (a==b & c)
将被解析为
if ((a==b) & c)
后来添加了简短的逻辑&&
和||
,但保留了|
和&
的原始优先级。
C语言中一个已知的缺陷是|
和&
的优先级低于==
(Dennis Ritchie在某个时候承认了这一点(。这是代码不起作用的实际原因。
通过正确编写宏来解决此问题:
#define MASK_A (IPC_CREAT | IPC_EXCL | 0666)
任何一本像样的 C 编程书籍都会解决这样的问题,并展示如何正确编写带有括号的宏。