laiyuou 发表于 2021-11-17 00:05

第8天:关于c语言的位运算,以及初涉数据结构题目

位运算;很多的运算都是以字节作为最基本单位,但有些程序系统中也会要求在位(bit)一级进行运算或处理
&   按为与:只有两个二进制为1时结果才是1
|   按位或:只要对应的两个二进位有一个为1时,结果位就是为1.参与运算的两个数均以补码形式进行       
^   按位异或:只有对应的两个二进制为为相反的时候为1,即对应一个为0和对应的另个一为1时,结果才是1,否则都是为0
~   取反:对参与运算的数进行按位取反,即把每一个位0的变成1,把1的变成0;
<<左移:高位丢弃,低位补0;把所有的位进制数想左移
>>右移:左边的运算数的个二进位全部右移若干位

对于有符号数,向右移动时,符号位的将随同移动。当为正数时,最高位补0,当为负数时,符号位为1。

例子1:
```
int main()
{
        unsigned a, b;
        printf("input a number\n");//例如:输入10时候
        scanf_s("%d", &a);
        b = a >> 5;
        b = b & 15;
        printf("a=%d\tb=%d\n", a, b);//a=10,b=0
        return 0;

}
```
例子2:
```
int main()
{
        char a = 'a',b= 'b';
        int p, c, d;
        p = a;
        p = (p << 8) | b;
        d = p & 0xff;
        c = (p & 0xff00) >> 8;
        printf("a=%d\nb=%d\nc=%d\nd=%d\n", a, b, c, d);
        return 0;
}

```
位域:在信息存储时,并不需要占用一个完整的字节,而只需占几个或者一个二进制位。例如在存放一个开关量时,只有0和1两种状态
用以为二进制位就可以了,为了节省存储空间,并使处理简便,C语言又提供了一种数据结构,称为“位域”或者“位段”
位域:就是把一个字节中的二进位划分为几个不同区域,并说明每个区域的位数。每个域都有一个域名,允许在程序中按域名进行操作。这样就可以把几个不同的对象用一个字节的二进制位域来表示
1.位域的定义说明形式为:
struct 位域结构名{位域列表}其中位域列表的形式为:类型说明符 位域名:位域长度
struct bs {
        int a : 8;
        int b : 2;
        int c : 6;
}data;//说明data为bs变量,共占用两个字节。其中位域a占8位,位域b占2位,位域c占6位
对于位域的注意点:
1.一个位域必须存储在同一个字节中, 不能夸字节进行存储,如果一个字节的存储空间不够,则直接从下一个字节开始储存,
剩余不够的空间直接跳过不直接进行储存,也可以有意使某位域从下一单元开始。例如
```
struct bs
{
        unsigned a : 4;
        unsigned : 0;//当空域没有给予位域名的时候
        unsigned b : 4;
        unsigned c : 4;

};
```
2.由于位域不能跨过两个字节看,因此位域的长度不能大于一个字节的长度,也就是说不能超过8位二进制
3.位域可以没有域名,这时它只用来做填充或调整位置。无名的位域是不能使用的。
```
struct k
{
        int a : 1;
        int : 2;
        int b : 3;
        int c : 2;
};//可以看出,位域在本质上就是一种结构类型,不过其成员是按二进制位分配的。
```
位域的使用和结构成员的使用是相同,其一般形式为:
位域变量名.位域名    位域允许各种格式输出。
```
int main()
{
        struct bs {
                unsigned a : 1;
                unsigned b : 3;
                unsigned c : 4;
        }bit,*pbit;
        bit.a = 1;
        bit.b = 7;
        bit.c = 15;
        printf("%d,%d,%d\n", bit.a, bit.b, bit.c);
        pbit = &bit;
        pbit->a = 0;
        pbit->b &= 3;
        pbit->c |= 1;
        printf("a=%d\tb=%d\tc=%d\n", pbit->a, pbit->b, pbit->c);
        return 0;
}
```
数据结构题目:消失的数字,数组num包含从0到n的所有整数,但其中缺失了一个,请编写代码找出那一个缺失的整数。请优化在O(N)的时间复杂度之间完成。
//思路:num跟数组中数和之间进行异或,结果就是要找的数
//原理:相同的两个数异或是0,而数组中没有6,之间都有。。所以异或的结果就是缺失的6
//先思考几个小时,如果没有好思路再去看看别人的代码的思路,理解以后,后面不看他的再去实现。这样才能提高。
//OJ两种类型:1.IO型(牛客上的居多);2.接口型(leetcode居多)
```
int missingNumber(int* nums, int numsSize)
{
        int x = 0;//为什么是0?因为0和任何数异或都是它本身
        for (size_t i = 0; i < numsSize; ++i)
        {
                x ^= nums;//数组里面的值不是按顺序的,但是x和数组里面的值全部异或了一次,得到的x是一个异或出来的总值,所以但x再和一个顺序的数组
                //进行异或时,每异或一次就会消掉一个值,那么等到最后一个剩下的就是缺失的值
        }
        for (size_t i = 0; i <= numsSize; ++i)//这里一定要是i<= numsSize.一定要多一个等于,因为我们是要出排查缺失的数组,所有一定是会多比原来缺失的数组多一个。
        {
                x ^= i;
        }
        return x;
}

```

zoiitylj 发表于 2021-11-17 02:55

支持,想当年C语言我还是学得不错的,学过就去考2级C得了优,上机调试还是用turbo c2.0,不知现在还用不,只是非计算机专业,其他课业繁重就没有继续深入了

laiyuou 发表于 2021-11-17 09:13

RyanLi 发表于 2021-11-17 08:56
任何数与0异或等于它本身,有点没绕明白

任何数就相当于一个未知数x,与0进行异或就是还是等于x本身呀

chengfx 发表于 2021-11-17 02:24

值得鼓励

liuliu66 发表于 2021-11-17 08:23

每天跟着大佬一起学习,再会c语言

pierhu 发表于 2021-11-17 08:50

正准备考c语言,才看了一部分书

tlf 发表于 2021-11-17 08:51

RyanLi 发表于 2021-11-17 08:55

0异或1,应该等于1

RyanLi 发表于 2021-11-17 08:56

任何数与0异或等于它本身,有点没绕明白

3517277 发表于 2021-11-17 09:28

只要打开C语言的源代码,一看,好家伙,全都是这种位操作:lol
页: [1] 2
查看完整版本: 第8天:关于c语言的位运算,以及初涉数据结构题目