C语言位操作 | 按位运算符

2023-03-21 11:48:45 浏览数 (1)

二进制数、位、字节

PS:位运算详见计算机科学导论

前言:

C语言中可以单独操控变量中的位,例如:通常向硬件设备发送一两个字节来操控这些设备,每个位(bit)都有特定的含义,另外,与文件相关的操作信息经常被存储,通过特定的位表明特定的项。许多的压缩和加密操作都是直接除理单独的位。

高级语言一般不会处理这些级别的细节,C在提供高级语言便利的同时,还能在为汇编语言所保留的级别上工作。

二进制整数

C语言用字节(byte)表示存储系统字符集所需要的大小,所以C字节看可能是8位,9位,16位或者其他值。不过藐视存储芯片和数据率中所用的字节指的是8位字节。

假设一个字节为8位,每一位的编号对应2的相应指数,该字节能表示的最大数字是吧每一个位都设置为1:11111111这个二进制数的值就是128 64 32 16 8 4 2 1 = 255,二这个字节最小的二进制数是00000000,其值是0,因此1字节可以存储1~255范围内的数字,总共256个值。

或者不同的方式解释位组合,程序可以用1字节存储-128~ 128范围内的整数,总共还是256个值。

例如:

代码语言:javascript复制
unsigned char//用一个字节表示的范围是0~255
signed char//用一个字节表示的范围是-128~ 128

有符号整数

如何表示有符号整数取决于硬件,而不是C语言。

表示方法:表示有符号数最简单的方法是用1位存储符号,用剩下的7位来表示数字本身,用这种符号量表示法,10000001表示-1,00000001表示1.因此,其表示范围是-127~ 127

缺点:这种方法表示会出现两个0: 0和-0,这很容易混淆,而且两个位来存储同一个值也很浪费。

解决方法:二进制补码(详见计算机科学导论P32)简单概述:以1字节为例,

PS:二进制反码

二进制反码是指对一个二进制数,将每一位上的 0 改为 1,1 改为 0 得到的新数。

例如:对二进制数 1001,反码为 0110。

在计算机中,二进制反码经常用于表示补码,补码是对原码在最高位加上符号位的反码。在计算机中使用补码更方便实现负数的运算。

二进制浮点数

二进制小数

二进制小数是指在计算机科学中使用二进制表示的小数。在二进制下,一个小数可以分为整数部分和小数部分,并且小数部分由二进制位表示,每一位对应一个权重值,权重值以二进制的形式递减,从第0位到第1位分别对应 1/2,1/4,1/8……等。一个二进制小数可以通过将所有的二进制位的值乘上对应的权重值,并将所有的权重值相加得到。

浮点数表示方法

浮点数在计算机中使用IEEE 754标准进行表示。这种标准定义了一种二进制表示浮点数的方法,该方法将浮点数分成三个部分:符号位、指数位和尾数位。符号位表示该浮点数的正负性,指数位表示该浮点数的数量级,尾数位表示该浮点数的精度。

其他进制数

八进制

八进制(Octal)是一种数字进制,采用0~7这8个数字作为基数,表示数值的方法。在八进制中,每一个数字的位置都代表八进制中的某个数的权值。八进制的数值可以使用前缀0表示,例如数字053在八进制下表示为35。

十六进制

十六进制(Hexadecimal)是一种基数为16的数字系统。它的基数由十六个数字组成:0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E, F。A表示十进制的10,B表示十进制的11,以此类推。它通常用于计算机程序中的内存地址和颜色表示。在C 中,可以使用前缀”0x”表示一个数是十六进制。例如:0xFF表示十六进制的255,即十进制的255。

C按位运算符

按位运算符是 C 语言中的位运算符,它们可以在二进制级别操作整数。按位逻辑运算符包括 &(与)、|(或)、^(异或)和 ~(取反)。

掩码是一个二进制值,用于检索或修改整数的特定二进制位。例如,通过使用掩码并与整数的二进制值进行按位与运算,可以检索整数的特定二进制位。

打开位是将某二进制位从 0 改为 1 的过程。

关闭位(清空位)是将某二进制位从 1 改为 0 的过程。

切换位是将某二进制位从 0 改为 1 或从 1 改为 0 的过程。

检查位的值是检查某二进制位是否为 1 的过程。

移位运算符是 <<(左移)和 >>(右移)。它们可以将整数的二进制位整体移动,以便快速地进行乘除运算。

按位逻辑运算符

用法:掩码

用法:打开位

用法:关闭位(清空位)

用法:切换位

用法:检查位的值

移位运算符

示例

代码语言:javascript复制
#include <stdio.h>

int main()
{
    int num = 15;
    int mask = 1;
    int result;

    // 检查num的第3位是否为1
    result = num & (mask << 3);
    if (result)
        printf("The 3rd bit of num is 1n");
    else
        printf("The 3rd bit of num is 0n");

    // 关闭num的第3位
    num &= ~(mask << 3);
    printf("num after clearing 3rd bit: %dn", num);

    // 切换num的第3位
    num ^= (mask << 3);
    printf("num after toggling 3rd bit: %dn", num);

    return 0;
}

以上代码通过位运算符检查了num的第3位是否为1,并对它进行了关闭、切换操作。

位字段

位字段是一种在C语言的结构体和联合体中定义结构化数据的方法,允许把一个字节或多个字节的内存空间划分为几个不同的二进制位域。每个位域代表一个独立的二进制位,用于存储特定的数据,可以节省内存空间和提高效率。位字段可以通过定义结构体或联合体以及通过在结构体或联合体中定义每个位域的大小来实现。

示例

位字段是C语言提供的一种结构体的数据结构,通过把比特位分配到结构体的成员变量中来存储一些小数据。以下是一个简单的示例:

代码语言:javascript复制
struct Packed {
   unsigned int a:3;
   unsigned int b:5;
   unsigned int c:4;
};

struct Packed data;

data.a = 3;
data.b = 17;
data.c = 11;

在这个示例中,结构体Packed有三个成员变量:abc。其中,变量a占用3个比特位,变量b占用5个比特位,变量c占用4个比特位。因此,结构体的总比特位数为3 5 4 = 12比特位。

比特位是一个二进制位,它可以是0或1.

比特位在计算机编程中有很多用途,主要是在存储和处理数据时的状态表示。比如,可以使用一个比特位来表示一个特定的选项是否开启或关闭,或者在内存的一个字节中的多个比特位上的组合来表示特定的状态。

比特位还可以用来压缩数据,因为它们占用的空间很小。例如,使用比特位来表示大量的布尔数据可以节省存储空间。

总而言之,比特位是计算机编程中非常重要的一个概念,因为它是所有计算机数据的基础。

位字段和按位运算符

位字段是一种数据类型,它把数据存储在一个二进制位的集合中,这些二进制位都有着自己的名字和宽度。每一位的宽度指的是其在二进制位集合中的位数。

按位运算符是一种运算符,它把数据进行位级运算。这些运算符可以分别完成:与(&)、或(|)、异或(^)、取反(~)等运算。使用按位运算符和位字段,我们可以非常灵活地对数据进行组合和处理,特别是在计算机硬件和嵌入式系统开发中非常有用。

对齐特性(C11)

对齐特性(C11)是指在C11标准中对于内存对齐的规定,对齐是指按照一定规则调整内存中某个对象的地址,使得它们更容易被访问。在C11中,内存对齐的规则由编译器决定,但可以使用C11提供的_Alignas(alignment)关键字来手动指定对齐方式。举个例子,在以下代码中,变量x被指定为8字节对齐:

代码语言:javascript复制
#include <stdio.h>
#include <stdlib.h>

int main(void)
{
    _Alignas(8) int x;
    printf("%ldn", __alignof(x));
    return 0;
}

输出的结果是8,说明变量x确实被按照8字节对齐。

0 人点赞