我很抱歉没有特别的头衔,但我不知道它的名字。这是我的问题:在此代码段中,定义了如下常量:
#define WS_NONE 0
#define WS_RECURSIVE (1 << 0)
#define WS_DEFAULT WS_RECURSIVE
#define WS_FOLLOWLINK (1 << 1) /* follow symlinks */
#define WS_DOTFILES (1 << 2) /* per unix convention, .file is hidden */
#define WS_MATCHDIRS (1 << 3) /* if pattern is used on dir names too */
并且有一个这样定义的函数:
int walk_recur(char *dname, regex_t *reg, int spec)
他使用“ |”发送常量(WS_DEFAULT和WS_MATCHDIRS)以起作用:
walk_dir(".", ".\\.c$", WS_DEFAULT|WS_MATCHDIRS);
这是他使用参数的方式:
if ((spec & WS_RECURSIVE))
walk_recur(fn, reg, spec);
if (!(spec & WS_MATCHDIRS)) continue;
如果WS_RECURSIVE传递给函数,则首先if语句为true。我不知道<<操作符如何工作以及(spec&WS_RECURSIVE)语句如何返回true。他如何用“ |”发送不同的常量?并且他可以使用“ spec”值,该值必须等于传递的常量,这怎么可能?
对不起,我的英语不好。
将单个整数值视为单个位的集合是一个非常常见的习惯用法。C没有直接支持位数组,因此我们使用按位运算符来设置和清除位。
该<<
运算符是左移运算符。例如:
1 << 0 == 1
1 << 1 == 2
1 << 2 == 4
1 << 3 == 8
1 << n
因为任何非负数n
(在范围内)都是2的幂。整数值中的每个位都表示2的幂。任何整数值都可以视为2的幂的唯一和。
|
是按位或运算符;用于将多个1位值(1的幂)组合为一个整数值:
(1 << 0) | (1 << 3) == 1 | 8
1 | 8 == 9
在这里,我们将位0(代表值1
)和位3(代表值8
)组合为一个值9
。(我们本可以使用+
而不是|
在这种情况下使用,但是通常使用|
2的幂次不只一次时可以避免问题。)
现在我们可以使用bitwise和operator来测试是否设置了位&
:
int n = (1<<0) | (1<<3);
if (n & (1<<3)) {
printf("Bit 3 is set\n");
}
else {
printf("Bit 3 is not set\n");
}
现在,我们可以定义宏,这样我们就不用写1<<0
和1<<3
所有的地方:
#define WS_RECURSIVE (1 << 0)
...
#define WS_MATCHDIRS (1 << 3)
int n = WS_RECURSIVE | WS_MATCHDIRS;
// n == 9
if (n & WS_RECURSIVE) {
// the WS_RECURSIVE bit is set
}
if (!(n&WS_MATCHDIRS) {
// the WS_MATCHDIRS bit is *not* set
}
你也可以定义宏,以简化设置和测试位(SET_BIT()
,IS_SET()
,等),但大多数C程序员也懒得这样做。位值的符号名称对于代码的可读性很重要,但是一旦您了解了按位运算符的工作原理,更重要的是,如何编写设置,清除和测试位的常用习惯,原始运算符就足够可读。
通常最好使用无符号而不是有符号的整数类型。在某些情况下,有符号类型上按位运算符的行为可能很棘手。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句