C语言位运算符详解(图文并茂,附带实例)

2025-05-14 21:56:54

在 C语言中,位运算符是一组用于执行二进制数(通常表示为整数)的位级操作的运算符。这些运算符直接操作整数的二进制位,因此通常具有非常高的速度和效率。

位运算符能够深入操作数的内部,并根据非 0 值或 0 值将二进制位视为真或假,然后进行逻辑运算。

以下是 C语言中的位运算符:

位逻辑与 &;

位逻辑或 |;

位逻辑异或 ^;

位逻辑非 ~。

为了更好地理解这些位逻辑运算符的特性,我们选取两个整数 170 和 102,并使用自定义的 printBinary() 函数输出它们的二进制表示形式。

void printBinary(unsigned char dec)

{

// 数组初始化为 0

char bits[8] = {0};

int count = 0;

int quotient;

int remainder;

while(dec > 0)

{

remainder = dec % 2;

quotient = dec / 2;

dec = quotient;

bits[count] = remainder;

count++;

}

// 逆序输出所有二进制位

for (int i = 8 - 1; i >= 0; i--)

printf("%d", bits[i]);

putchar('\n');

}

printBinary(170);

printBinary(102);

将十进制数 170 作为 printBinary() 函数的参数,它将输出 170 对应的二进制数 10101010。将十进制数 102 作为 printBinary() 函数的参数,它将输出 102 对应的二进制数 01100110。

接下来,我们对这两个数值分别进行各种位逻辑运算,以观察其运算结果。

C语言位逻辑与&

尝试对 170 和 102 进行位逻辑与运算:

printf("%hhu\n", 170 & 102);

printBinary(170 & 102);

运行结果为:

34

00100010

表达式 170&102 的结果为十进制 34,二进制 00100010。让我们来分析为何得到这个结果。

位逻辑与 & 操作会深入字节内部,并对二进制位进行逻辑与运算。如果两个位同时为真(1),则运算结果为真(1);否则,运算结果为假(0)。

查看下图,从左至右两个操作数的第 1 个二进制位分别为 1 和 0。1 & 0 结果为假,因此得到结果 0。

图 1 1&0

查看下图,从左至右两个操作数的第 2 个二进制位分别为 0 和 1。0 & 1 结果为假,因此得到结果 0。

图 2 0&1

查看下图,从左至右两个操作数的第 3 个二进制位分别为 1 和 1。1 & 1 结果为真,因此得到结果 1。

图 3 1&1

查看下图,从左至右两个操作数的第 4 个二进制位分别为 0 和 0。0 & 0 结果为假,因此得到结果 0。

图 4 0&0

以此类推,后面 4 个二进制位的运算与前面一致,最终的结果为 00100010。

接下来,将最终的二进制结果 00100010 转换为十进制,从最高位开始:

第 1 位权值为 2^7,该位为 0,积为 0。

第 2 位权值为 2^6,该位为 0,积为 0。

第 3 位权值为 2^5,该位为 1,积为 2^5。

第 4 位权值为 2^4,该位为 0,积为 0。

第 5 位权值为 2^3,该位为 0,积为 0。

第 6 位权值为 2^2,该位为 0,积为 0。

第 7 位权值为 2^1,该位为 1,积为 2^1。

第 8 位权值为 2^0,该位为 0,积为 0。

将所有乘积累加起来,得到其十进制表示:

2^5 + 2^1 = 32 + 2 = 34

因此,位逻辑与运算 170 & 102 得到的十进制结果为 34,二进制结果为 00100010。

C语言位逻辑或|

尝试对 170 和 102 进行位逻辑或运算:

printf("%hhu\n", 170 | 102);

printBinary(170 | 102);

运行结果如下图所示:

238

11101110

表达式 170 | 102 的十进制结果为 238,二进制结果为 11101110。接下来分析为什么会得到这个结果。

位逻辑或 | 运算将深入字节内部,对二进制位进行逻辑或运算。如果两个位同时为假(0),则运算结果为假(0);否则,运算结果为真(1)。

查看下图,从左至右两个操作数的第 1 个二进制位分别为 1 和 0。1 | 0 结果为真,因此得到结果 1。

图 5 1|0

查看下图,从左至右两个操作数的第 2 个二进制位分别为 0 和 1。0 | 1 结果为真,因此得到结果 1。

图 6 0|1

查看下图,从左至右两个操作数的第 3 个二进制位分别为 1 和 1。1 | 1 结果为真,因此得到结果 1。

图 7 1|1

查看下图,从左至右两个操作数的第 4 个二进制位分别为 0 和 0。0 | 0 结果为假,因此得到结果 0。

图 8 0|0

以此类推,后面 4 个二进制位的运算与前面一致,最终的结果为 11101110。

接下来,将最终的二进制结果 11101110 转换为十进制,从最高位开始:

第 1 位权值为 2^7,该位为 1,积为 2^7。

第 2 位权值为 2^6,该位为 1,积为 2^6。

第 3 位权值为 2^5,该位为 1,积为 2^5。

第 4 位权值为 2^4,该位为 0,积为 0。

第 5 位权值为 2^3,该位为 1,积为 2^3。

第 6 位权值为 2^2,该位为 1,积为 2^2。

第 7 位权值为 2^1,该位为 1,积为 2^1。

第 8 位权值为 2^0,该位为 0,积为 0。

将所有乘积累加起来,得到其十进制表示:

2^7 +2^6 + 2^5 +2^3 + 2^2 + 2^1 = 128 + 64 + 32 + 8 + 4 + 2 = 238

因此,位逻辑或运算 170 | 102 得到的十进制结果为 238,二进制结果为 11101110。

C语言位逻辑异或^

尝试对 170 和 102 进行位逻辑异或运算。

printf("%hhu\n", 170 ^ 102);

printBinary(170 ^ 102);

运行结果为:

204

11001100

表达式 170 ^ 102 的十进制结果为 204,二进制结果为 11001100。接下来分析为什么会得到这个结果。

位逻辑异或 ^ 运算将深入字节内部,对二进制位进行逻辑异或运算。若两个位不同时,运算结果为真(1);否则,运算结果为假(0)。

查看下图,从左至右两个操作数的第 1 个二进制位分别为 1 和 0。1 ^ 0,两个位不同,结果为真,因此得到结果 1。

图 9 1^0

查看下图,从左至右两个操作数的第 2 个二进制位分别为 0 和 1。0 ^ 1,两个位不同,结果为真,因此得到结果 1。

图 10 0^1

查看下图,从左至右两个操作数的第 3 个二进制位分别为 1 和 1。1 | 1,两个位相同,结果为假,因此得到结果 0。

图 11 1^1

查看下图,从左至右两个操作数的第 4 个二进制位分别为 0 和 0。0 | 0,两个位相同,结果为假,因此得到结果 0。

图 12 0^0

以此类推,后面 4 个二进制位的运算与前面一致,最终的结果为 11001100。

接下来,将最终的二进制结果 11001100 转换为十进制,从最高位开始:

第 1 位权值为 2^7,该位为 1,积为 2^7。

第 2 位权值为 2^6,该位为 1,积为 2^6。

第 3 位权值为 2^5,该位为 0,积为 0。

第 4 位权值为 2^4,该位为 0,积为 0。

第 5 位权值为 2^3,该位为 1,积为 2^3。

第 6 位权值为 2^2,该位为 1,积为 2^2。

第 7 位权值为 2^1,该位为 0,积为 0。

第 8 位权值为 2^0,该位为 0,积为 0。

将所有乘积累加起来,得到其十进制表示。

2^7 + 2^6 + 2^3 + 2^2 = 128 + 64 + 8 + 4 = 204

因此,位逻辑异或运算 170 ^ 102 得到的十进制结果为 204,二进制结果为 11001100。

C语言位逻辑非~

前面介绍了几个双目位逻辑运算符,它们会对运算符左右两边的运算对象进行计算,并得到一个结果。

接下来将介绍的位逻辑非是一个单目运算符,它仅对其右侧的运算对象进行计算。现在,让我们尝试对 170 和 102 进行位逻辑非运算。

printf("%hhu\n", ~170);

printBinary(~170);

printf("%hhu\n", ~102);

printBinary(~102);

运行结果为:

85

01010101

153

10011001

表达式 ~170 的结果是十进制数 85,二进制数 01010101。表达式 102 的结果是十进制数 153,二进制数 10011001。接下来,我们来分析为什么会得到这样的结果。

位逻辑非 ~ 会深入字节内部,并对二进制位执行逻辑非运算。如果二进制位为真(1)时,则运算结果为假(0);如果二进制位为假(0)时,则运算结果为真(1)。

换句话说,位逻辑非运算会翻转运算对象的所有二进制位。查看下图,二进制位 1 变为 0,二进制位 0 变为 1。

图 13 翻转二进制位

接下来,将 ~170 最终的二进制结果 01010101 转换为十进制,从最高位开始:

第 1 位权值为 2^7,该位为 0,积为 0。

第 2 位权值为 2^6,该位为 1,积为 2^6。

第 3 位权值为 2^5,该位为 0,积为 0。

第 4 位权值为 2^4,该位为 1,积为 2^4。

第 5 位权值为 2^3,该位为 0,积为 0。

第 6 位权值为 2^2,该位为 1,积为 2^2。

第 7 位权值为 2^1,该位为 0,积为 0。

第 8 位权值为 2^0,该位为 1,积为 2^0。

将所有乘积累加起来,得到其十进制表示:

2^6 + 2^4 + 2^2+ 2^0 = 64 + 16 + 4 + 1 = 85

因此,位逻辑非运算 ~170 得到的十进制结果为 85,二进制结果为 01010101。

接下来将 ~102 最终的二进制结果 10011001 转换为十进制,从最高位开始:

第 1 位权值为 2^7,该位为 1,积为 2^7。

第 2 位权值为 2^6,该位为 0,积为 0。

第 3 位权值为 2^5,该位为 0,积为 0。

第 4 位权值为 2^4,该位为 1,积为 2^4。

第 5 位权值为 2^3,该位为 1,积为 2^3。

第 6 位权值为 2^2,该位为 0,积为 0。

第 7 位权值为 2^1,该位为 0,积为 0。

第 8 位权值为 2^0,该位为 1,积为 2^0。

将所有乘积累加起来,得到其十进制表示:

2^7 + 2^4 + 2^3 + 2^0 = 128 + 16 + 8 + 1 = 153

因此,位逻辑非运算 ~102 得到的十进制结果为 153,二进制结果为 10011001。

问道十大人物(问道十大顶级人物)
角色系统