按位或運(yùn)算對(duì)兩個(gè)數(shù)的二進(jìn)制表示的每一位進(jìn)行邏輯 或操作:
- 規(guī)則:兩個(gè)對(duì)應(yīng)位有一個(gè)為1時(shí),結(jié)果就為1;只有兩個(gè)都為0時(shí)結(jié)果才為0
-
符號(hào):
| -
特點(diǎn):任何位與1相
或都會(huì)變成1,與0相或保持原值
運(yùn)算過程圖示
#include <stdio.h>
void print_binary_5bit(int number) {
for (int i = 4; i >= 0; i--) {
printf("%d", (number >> i) & 1);
}
}
int main() {
unsigned int a = 0b00111; // 十進(jìn)制 7
unsigned int b = 0b11100; // 十進(jìn)制 28
printf("按位或運(yùn)算示例:\n");
printf("a = 7 (二進(jìn)制: ");
print_binary_5bit(a);
printf(")\n");
printf("b = 28 (二進(jìn)制: ");
print_binary_5bit(b);
printf(")\n");
printf("\n逐位運(yùn)算過程:\n");
printf(" ");
print_binary_5bit(a);
printf("\n| ");
print_binary_5bit(b);
printf("\n -----\n ");
print_binary_5bit(a | b);
printf(" (十進(jìn)制 %d)\n", a | b);
return 0;
}
運(yùn)行結(jié)果:
按位或運(yùn)算示例:
a = 7 (二進(jìn)制: 00111)
b = 28 (二進(jìn)制: 11100)
逐位運(yùn)算過程:
00111
| 11100
-----
11111 (十進(jìn)制 31)
實(shí)用技巧詳解
1. 設(shè)置特定位為1(最常用)
#include <stdio.h>
void print_binary_5bit(int number) {
for (int i = 4; i >= 0; i--) {
printf("%d", (number >> i) & 1);
}
}
void set_last_bit_to_one(int number) {
printf("\n將數(shù)字 %d 的最末位設(shè)置為1:\n", number);
printf("原始數(shù)值: ");
print_binary_5bit(number);
printf(" (%d)\n", number);
printf("掩碼 1: 00001\n");
printf("按位或運(yùn)算:\n");
printf(" ");
print_binary_5bit(number);
printf("\n| 00001\n");
printf(" -----\n ");
print_binary_5bit(number | 1);
printf(" (%d)\n", number | 1);
printf("→ 最末位被強(qiáng)制設(shè)置為1\n");
}
void set_specific_bits() {
unsigned int flags = 0b10100; // 十進(jìn)制 20
unsigned int mask = 0b01011; // 十進(jìn)制 11
printf("\n設(shè)置特定位示例:\n");
printf("原始標(biāo)志位: ");
print_binary_5bit(flags);
printf(" (%d)\n", flags);
printf("設(shè)置掩碼: ");
print_binary_5bit(mask);
printf(" (要設(shè)置的位)\n");
printf("按位或運(yùn)算:\n");
printf(" ");
print_binary_5bit(flags);
printf("\n| ");
print_binary_5bit(mask);
printf("\n -----\n ");
print_binary_5bit(flags | mask);
printf(" (%d)\n", flags | mask);
printf("→ 掩碼中為1的位都被設(shè)置為1\n");
}
int main() {
set_last_bit_to_one(10); // 1010 → 1011
set_last_bit_to_one(15); // 1111 → 1111 (不變)
set_specific_bits();
return 0;
}
運(yùn)行結(jié)果:
將數(shù)字 10 的最末位設(shè)置為1:
原始數(shù)值: 01010 (10)
掩碼 1: 00001
按位或運(yùn)算:
01010
| 00001
-----
01011 (11)
→ 最末位被強(qiáng)制設(shè)置為1
將數(shù)字 15 的最末位設(shè)置為1:
原始數(shù)值: 01111 (15)
掩碼 1: 00001
按位或運(yùn)算:
01111
| 00001
-----
01111 (15)
→ 最末位被強(qiáng)制設(shè)置為1
設(shè)置特定位示例:
原始標(biāo)志位: 10100 (20)
設(shè)置掩碼: 01011 (要設(shè)置的位)
按位或運(yùn)算:
10100
| 01011
-----
11111 (31)
→ 掩碼中為1的位都被設(shè)置為1
2. 權(quán)限授予系統(tǒng)
#include <stdio.h>
void print_binary_4bit(int number) {
for (int i = 3; i >= 0; i--) {
printf("%d", (number >> i) & 1);
}
}
// 定義權(quán)限標(biāo)志
#define READ_PERM (1 << 0) // 0001 - 讀權(quán)限
#define WRITE_PERM (1 << 1) // 0010 - 寫權(quán)限
#define EXEC_PERM (1 << 2) // 0100 - 執(zhí)行權(quán)限
#define ADMIN_PERM (1 << 3) // 1000 - 管理員權(quán)限
void grant_permissions(unsigned int current_perm, unsigned int new_perm, const char* user) {
printf("\n為用戶 %s 授予權(quán)限:\n", user);
printf("當(dāng)前權(quán)限: ");
print_binary_4bit(current_perm);
printf("\n授予權(quán)限: ");
print_binary_4bit(new_perm);
printf("\n按位或運(yùn)算:\n");
printf(" ");
print_binary_4bit(current_perm);
printf("\n| ");
print_binary_4bit(new_perm);
printf("\n ----\n ");
unsigned int result = current_perm | new_perm;
print_binary_4bit(result);
printf(" (新權(quán)限)\n");
// 解釋權(quán)限含義
printf("權(quán)限說明: ");
if (result & READ_PERM) printf("讀 ");
if (result & WRITE_PERM) printf("寫 ");
if (result & EXEC_PERM) printf("執(zhí)行 ");
if (result & ADMIN_PERM) printf("管理");
printf("\n");
}
int main() {
printf("=== 權(quán)限管理系統(tǒng) ===\n");
// 初始用戶只有讀權(quán)限
unsigned int user_perm = READ_PERM;
grant_permissions(user_perm, WRITE_PERM, "張三");
grant_permissions(user_perm | WRITE_PERM, EXEC_PERM, "張三");
// 管理員一次性授予所有權(quán)限
grant_permissions(0, READ_PERM | WRITE_PERM | EXEC_PERM, "管理員");
return 0;
}
運(yùn)行結(jié)果:
=== 權(quán)限管理系統(tǒng) ===
為用戶 張三 授予權(quán)限:
當(dāng)前權(quán)限: 0001
授予權(quán)限: 0010
按位或運(yùn)算:
0001
| 0010
----
0011 (新權(quán)限)
權(quán)限說明: 讀 寫
為用戶 張三 授予權(quán)限:
當(dāng)前權(quán)限: 0011
授予權(quán)限: 0100
按位或運(yùn)算:
0011
| 0100
----
0111 (新權(quán)限)
權(quán)限說明: 讀 寫 執(zhí)行
為用戶 管理員 授予權(quán)限:
當(dāng)前權(quán)限: 0000
授予權(quán)限: 0111
按位或運(yùn)算:
0000
| 0111
----
0111 (新權(quán)限)
權(quán)限說明: 讀 寫 執(zhí)行
3. 組合配置標(biāo)志
#include <stdio.h>
void print_binary_8bit(int number) {
for (int i = 7; i >= 0; i--) {
printf("%d", (number >> i) & 1);
}
}
// 定義配置選項(xiàng)
#define OPTION_A (1 << 0) // 00000001
#define OPTION_B (1 << 1) // 00000010
#define OPTION_C (1 << 2) // 00000100
#define OPTION_D (1 << 3) // 00001000
#define OPTION_E (1 << 4) // 00010000
void build_configuration() {
printf("=== 構(gòu)建配置選項(xiàng) ===\n");
unsigned int config = 0;
printf("初始配置: ");
print_binary_8bit(config);
printf("\n\n");
// 逐步添加配置選項(xiàng)
config |= OPTION_A;
printf("添加選項(xiàng)A: ");
print_binary_8bit(config);
printf(" (A | 0)\n");
config |= OPTION_C;
printf("添加選項(xiàng)C: ");
print_binary_8bit(config);
printf(" (當(dāng)前 | C)\n");
config |= OPTION_E;
printf("添加選項(xiàng)E: ");
print_binary_8bit(config);
printf(" (當(dāng)前 | E)\n");
// 一次性添加多個(gè)選項(xiàng)
config |= (OPTION_B | OPTION_D);
printf("添加B和D: ");
print_binary_8bit(config);
printf(" (當(dāng)前 | (B | D))\n");
printf("\n最終配置: ");
print_binary_8bit(config);
printf(" (所有選項(xiàng)都已設(shè)置)\n");
}
int main() {
build_configuration();
return 0;
}
運(yùn)行結(jié)果:
=== 構(gòu)建配置選項(xiàng) ===
初始配置: 00000000
添加選項(xiàng)A: 00000001 (A | 0)
添加選項(xiàng)C: 00000101 (當(dāng)前 | C)
添加選項(xiàng)E: 00010101 (當(dāng)前 | E)
添加B和D: 00011111 (當(dāng)前 | (B | D))
最終配置: 00011111 (所有選項(xiàng)都已設(shè)置)
重要注意事項(xiàng)
關(guān)于"最末位變成0"的說明
原文中提到"對(duì)這個(gè)數(shù)or 1之后再減一",這實(shí)際上不是推薦做法。正確的方法是使用按位與來清除位:
// ? 不推薦的做法
int number = 0b1010; // 10
number = (number | 1) - 1; // 變成 1001 (9)
// ? 推薦的做法
int number = 0b1010; // 10
number = number & ~1; // 變成 1000 (8) - 清除最末位
總結(jié)
按位或運(yùn)算的核心用途:
-
設(shè)置特定位:將指定位強(qiáng)制設(shè)置為1
-
flags | mask設(shè)置mask中所有為1的位
-
-
權(quán)限授予:添加權(quán)限而不影響其他權(quán)限
- 用戶權(quán)限 = 當(dāng)前權(quán)限 | 新權(quán)限
-
配置組合:逐步構(gòu)建配置選項(xiàng)
- 配置 = 配置 | 新選項(xiàng)
合并標(biāo)志:將多個(gè)標(biāo)志合并為一個(gè)值
優(yōu)勢(shì):
- 非破壞性:只設(shè)置指定位,不影響其他位
- 可組合:可以一次性設(shè)置多個(gè)位
- 高效:?jiǎn)蝹€(gè)操作完成多個(gè)設(shè)置
按位或運(yùn)算是設(shè)置二進(jìn)制特定位的首選工具!