C-函数参数和“ <<”运算符

伊萨默特

我很抱歉没有特别的头衔,但我不知道它的名字。这是我的问题:在代码段中,定义了如下常量:

#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<<01<<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] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

C ++运算符“ <”和“>”

来自分类Dev

+ =运算符和新的运算符c#

来自分类Dev

C运算符的优势:增量运算符和逻辑运算符

来自分类Dev

C#运算符'is'参数

来自分类Dev

C#运算符'is'参数

来自分类Dev

函数调用运算符的C ++模板

来自分类Dev

函数的C ++运算符重载

来自分类Dev

C ++:使用运算符=调用多参数构造函数

来自分类Dev

用|在c函数中查询 参数中的运算符

来自分类Dev

C ++串联和分层运算符

来自分类Dev

<?=和>?的含义 C ++中的运算符

来自分类Dev

前缀和后缀运算符C ++

来自分类Dev

C ++赋值运算符和重载

来自分类Dev

C ++增量运算符和总和

来自分类Dev

设置(C ++)和运算符<重载

来自分类Dev

C ++中重载的==和!=运算符

来自分类Dev

运算符重载和非成员函数C ++

来自分类Dev

C ++:运算符new和default构造函数

来自分类Dev

C ++构造函数和运算符问题

来自分类Dev

C ++链表-构造函数和运算符重载

来自分类Dev

<=和>运算符作为函数参数

来自分类Dev

C ++:运算符重载:类内和类外。与预递增运算符的歧义

来自分类Dev

C运算符的优势:递增和逻辑运算符

来自分类常见问题

C和C ++关于++运算符的区别

来自分类Dev

C和C ++之间关于“ ^ =”运算符的区别

来自分类Dev

C#和C ++中的新运算符

来自分类Dev

重载运算符的参数太多,Visual Studio C ++

来自分类Dev

在C ++中将运算符作为参数发送

来自分类Dev

Postfix运算符重载中的虚拟参数的目的?C ++