C 规范与标准库

概述

参考:

位移运算符

可以在 Linux 网络设备 中对 /sys/class/net/${NetDeviceName}/flags 文件含义的解释,找到位移运算的典型示例

1<<01<<1 等是位移运算符的表达方式,在许多编程语言(如 C、C++、Go、Python 等)中都有使用。它们表示“位移”操作,这个位移操作需要先将 1 转为 二进制,然后让所有数字向左移动指定的位数,移动后空的位置用 0 补齐。

  • 1<<0 表示将 1 (i.e. 二进制 1)向左移动 0 位,仍然是 1。
  • 1<<1 表示将 1 (i.e. 二进制 1)向左移动 1 位,结果是 10,值为 2。
  • 1<<2 表示将 1 (i.e. 二进制 1)向左移动 2 位,结果是 100,值为 4。
  • 3<<2 表示将 3 (i.e. 二进制 11)向左移动 2 位,结果是 1100,值为 12

位移的用途

利用数字 1 进行位移运算的这种位移操作,通常用于设置标志位。通过将特定位设置为 1 或 0,可以高效地表示多个布尔值(true/false)信息,i.e. 高效设置、存储和处理多个状态标志,尤其是在底层代码和系统编程中广泛使用。它在提高代码效率、节省存储空间、简化状态管理方面非常有用。

  1. 位掩码(Bitmask)操作:可以用来对一组位进行操作,常见于标志位的组合使用。通过设置、清除或检测某些位,代码可以很高效地处理多个状态。
  2. 高效存储:用一组位来表示多个布尔值时,比使用单独的变量更节省内存。一个整数可以用 32 位或 64 位来存储多种状态。
  3. 按位操作:可以方便地进行某些特定的操作,比如对位进行取反、与、或等运算,从而控制状态位或进行权限管理等。

例如:

#define FLAG_A (1 << 0)  /* 0001 */
#define FLAG_B (1 << 1)  /* 0010 */
#define FLAG_C (1 << 2)  /* 0100 */

这些标志位可以用位或 (|) 运算符组合成一个整数,表示多个状态的组合。

int flags = FLAG_A | FLAG_B; /* 结果为 0011,表示 FLAG_A 和 FLAG_B 都启用 */
/* 然后利用与运算检查哪些状态是启用的 */
if (flags & FLAG_A) { /* FLAG_A 已启用 */ }
if (flags & FLAG_C) { /* FLAG_C 已启用 */ } else { /* FLAG_C 未启用 */ }

在 Go 和 Python 中的使用

在 Go 和 Python 中,也可以使用类似的位移操作。

Go 示例

package main

import "fmt"

func main() {
    // 定义一些标志位
    const (
        FLAG_A = 1 << 0  // 0001
        FLAG_B = 1 << 1  // 0010
        FLAG_C = 1 << 2  // 0100
    )

    flags := FLAG_A | FLAG_B
    fmt.Printf("Flags: %b\n", flags) // 输出二进制格式

    // 检查 FLAG_A 是否被设置
    if flags&FLAG_A != 0 {
        fmt.Println("FLAG_A is set")
    }
}

Python 示例

# 定义标志位
FLAG_A = 1 << 0  # 0001
FLAG_B = 1 << 1  # 0010
FLAG_C = 1 << 2  # 0100

flags = FLAG_A | FLAG_B
print(f"Flags: {bin(flags)}")  # 输出二进制格式

# 检查 FLAG_A 是否被设置
if flags & FLAG_A:
    print("FLAG_A is set")

最后修改 October 12, 2024: devops change dir, QUIC (5119fbe6)