西工大计算机学院计算机系统基础实验一(函数编写1~10)

还是那句话,千万不要慌,千万不要着急,耐下性子慢慢来,一步一个脚印,把基础打的牢牢的,一样不比那些人差。回到实验本身,自从​​​​​​按照西工大计算机学院计算机系统基础实验一(环境配置)-CSDN博客 这篇博客结束完成虚拟机平台VMware 17 Workstation Pro的安装,以及Ubuntu虚拟机的导入,还有实验包的导入之后,我们看到了如下图所示的实验压缩包content_1701767947881.tar,如 图1:查看被导入到Ubuntu虚拟机的实验包的压缩包content_1701767947881.tar 所示。接着我们解压缩这个包,如 图2:解压缩实验压缩包content_1701767947881.tar 所示。

图1:查看被导入到Ubuntu虚拟机的实验包的压缩包content_1701767947881.tar) 

 

图2:解压缩实验压缩包content_1701767947881.tar。使用"tar xvf content_1701767947881.tar"命令解压实验压缩包之后,得到了lab1-handout文件夹) 

接着进入到lab1-handout文件夹,并且查看该lab1-handout文件夹下有什么文件,如 图3:进入lab1-handout文件夹,查看该文件夹下的文件 所示。 但是千万不要急着,什么都不懂就开始做,先耐下性子来慢慢读一读README文件,了解清楚lab1-handout这个文件夹是用来干什么的,如 图4:使用less命令查看README文件 、图5:查看README文件的第一页图6:查看README文件的第二页 所示。这其中可能有很多大家不熟悉的命令,但千万不要排斥它,跟着作者一步一步来就可以。

图3:进入lab1-handout文件夹,查看该文件夹下的文件) 

 (图4:使用less命令查看README文件

 (图5:查看README文件的第一页

 

 (图6:查看README文件的第二页

在这里不要害怕怎么读,不要害怕说因为它是英文,所以就感到害怕。不要害怕,耐下性子慢慢读,就可以读出来一二的。在这里它的大概意思是,我们需要编写bits.c文件中的几个函数的函数体,接着使用dlc可执行文件检查bits.c文件中我们所写的函数是否满足运算符等的要求,然后使用make clean命令清除掉上一次已生成的可执行文件,再使用make btest文件生成可执行文件,最后运行生成的可执行文件价差我们所写的函数的正确性。你可能听不懂这段话是什么意思,不要怕,你跟着作者做,后面都会详细的讲到的。接着使用同样的方法,我们来查看bits.c文件,如 图7:查看bits.c文件(上)图8:查看bits.c文件(下) 所示。

图7:查看bits.c文件(上)

 (图8:查看bits.c文件(下)

 bits.c文件开头的一大段注释给我们三个要点信息:

要点1:不要使用"#include <stdio.h>",我们可以得到要点2与要点3:

要点2:对于整型数,只能使用& ^ | + << >> ! ~这八个运算符,只能定义并使用int型的局部变量以及函数参数变量,只能使用0x0到0xFF的int型常量;

要点3:对于浮点数,只能使用& ^ | + << >> ! ~这八个运算符,可以定义并使用int型或unsigned int型的局部变量以及函数参数变量,可以使用任意有符号整型与无符号整型常量,可以使用循环与条件判断。

大家记住它就好,不要深究,考虑到有些同学的Ubuntu没有内置VS code,而且vim编辑器对于初学者来说难度也有点大,所以我们选择Ubuntu内置的文本编辑器,开始编辑bits.c中的第一个函数,如 图9:使用Ubuntu内置的文本编辑器,开始编辑bits.c中的第1个函数 所示。如果文本编辑器的大小过小,可以按照 图10:调大文本编辑器显示文字的大小(上) 、图11:调大文本编辑器显示文字的大小(下) 所示。

 (图9:使用Ubuntu内置的文本编辑器,开始编辑bits.c中的第1个函数

图10:调大文本编辑器显示文字的大小(上)) 

图11:调大文本编辑器显示文字的大小(下)) 

定位到第174行,我们开始编写第一个函数bitXor,如 图12:定位到第174行,开始编写第1个函数bitXor 所示。

图12:定位到第174行,开始编写第1个函数bitXor

bitXor的意思是什么呢?意思是,需要我们只使用取反和位与运算,来实现异或操作。即只使用~与&,来实现^操作。那么该怎么实现这个功能呢?根据异或操作的定义,相同为0,不同才为1。也就是说,0^0=0,0^1=1,1^0=1,1^1=0。观察这个例子,我们发现,只要其中有并且只有1个为1即可。即~x&y和x&~y一个需要为1,一个需要为0,可以写成(~x&y)|(x&~y),但是不允许使用位或操作,那么我们应该怎么做呢?再思考下去就很麻烦了。我们不妨换一种思路,当x&y与~x&~y都为0时,这时只对应着两种情况,0^1=1与1^0=1,然后对x&y和~x&~y取反,得到~(x&y)和~(~x&~y),这时只有当0^1=1与1^0=1这两种情况下,~(x&y)和~(~x&~y)才都为1,进而~(x&y)&~(~x&~y)才为1,所以只需要写一个语句 "return ~(x&y)&~(~x&~y)"即可。如 图13:编写完成第1个函数bitXor 所示。接着保存对bits.c文件的修改,然后在包含bits.c文件的文件夹中打开命令行,如 图14:在包含bits.c文件的文件夹中打开命令行 所示。接着使用命令"./dlc -e bits.c"查看运算符的数量是否满足要求以及是否满足其它的要求。如果除了对各个函数所使用到的运算符进行计数之后就没有其它的输出,那么表明满足运算符和其它的要求。接着使用"make clean"命令清除掉上一次遗留的旧的文件,如 图15:使用命令"./dlc -e bits.c"和命令"make clean" 所示。接着再使用命令"make btest"生成新的文件,生成btest这个新的可执行文件之后,使用命令“./btest -f bitXor”来检验我们所写的第一个函数bitXor的正确性,其中"-f"选项制定了需要被检验的函数名,在这里需要被检验的函数名是bitXor。如 图16:使用命令"make btest"和命令“./btest -f bitXor” 所示。我们已成功编写了bitXor函数。

图13:编写完成第1个函数bitXor) 

图14:在包含bits.c文件的文件夹中打开命令行) 

图15:使用命令"./dlc -e bits.c"和命令"make clean" 。使用命令"./dlc -e bits.c"查看运算符的数量是否满足要求以及是否满足其它的要求。如果除了对各个函数所使用到的运算符进行计数之后就没有其它的输出,那么表明满足运算符和其它的要求。接着使用"make clean"命令清除掉上一次遗留的旧的文件) 

 

 (图16:使用命令"make btest"和命令“./btest -f bitXor”

 接着第二个函数,isZero,当x为0时,返回1,当x不为0时,返回0,所以只需要简单的写"return !x"即可,如 图17:编写第2个函数isZero图18:重复编写第1个函数时的操作 所示。

图17:编写第2个函数isZero

 (图18:重复编写第1个函数时的操作。使用命令"./dlc -e bits.c"统计各个函数使用到的运算符的个数,使用命令"make clean"清除掉上一次遗留下来的旧的可执行文件,使用命令"make btest"生成新的btest可执行文件,使用命令"./btest -f isZero"检验所写函数isZero的正确性)

第三个函数,thirdBits,要我们自己产生一个int型的数,保证它从最低有效位开始,每第三个比特位被设置为1,即期望我们返回的数是:0100 1001 0010 0100 1001 0010 0100 1001B。但是根据要点二中的一句话:只能使用0x0到0xFF的int型常量,即我们不能直接返回它。那么应该怎么产生这个数呢?我们发现,可以先产生一个小于0xFF的int型常量,让它既满足从最低有效位开始,每第三个比特位被设置为1,又满足小于0xFF,而这个数就是0x49,它的二进制表示形式为0100 1001。接着让0x49左移9位,得到了1001 0010 0000 0000,左移9位的目的就是为了让其既能保证,除了低9位以外,从最低有效位开始,每第三个比特位被设置为1,又是0x49左移所能完成这个任务的极限。接着将0x49与0x49<<9拼凑在一起,得到了0000 0000 0000 0000 1001 0010 0100 1001,它结合了0x49和0x49<<9的优点,保证了最大程度上从最低有效位开始,每第三个比特位被设置为1。但是,最高的16个比特位还没有被处理,而这可以简单的通过((0x49<<9)+0x49)<<18来实现。最后将0x49、0x49<<9与((0x49<<9)+0x49)<<18拼凑起来,即为最终的答案。而为了节省运算符,我们使用int型变量t来保存((0x49<<9)+0x49),接着"return t+(t<<24)"即可。具体的五个步骤为:

  1. 期望的输出: 0100 1001 0010 0100 1001 0010 0100 1001

  2. 第一个步骤: 0000 0000 0000 0000 0000 0000 0100 1001 0x49

  3. 第二个步骤: 0000 0000 0000 0000 1001 0010 0000 0000 0x49<<9

  4. 第三个步骤: 0000 0000 0000 0000 1001 0010 0100 1001 (0x49<<9)+0x49

  5. 第四个步骤: 0100 1001 0010 0100 0000 0000 0000 0000 ((0x49<<9)+0x49)<<18

  6. 第五个步骤: 0100 1001 0010 0100 1001 0010 0100 1001 (((0x49<<9)+0x49)<<18)+(0x49<<9)+0x49

图19:编写第3个函数thirdBits 所示。

 (图19:编写第3个函数thirdBits

第4个函数anyOddBit,如果x中,只要有一个第奇数个比特位被设置为了1,那么就返回1,否则返回0,比如7是0111,其第0、1、2个比特位为1,满足第1个比特位被设置为1,返回1;比如5是0101,第0、2个比特位为1,不满足第奇数个比特位被设置为1,也就是第1个比特位没有被设置为1,所以返回0,注意这里特别容易混淆,作者因为搞混了这一点,废了好多功夫。我们的思路就是,先产生1010 1010 1010 1010 1010 1010 1010 1010,这个数是0xAAAAAAAA,它第1、3、5、7、9、11... ...31个比特位都被设置为了1,然后将0xAAAAAAAA与x做位与操作,这样子获取x的所有奇数比特位,如果x中存在一个奇数比特位被设置为1,那么位与的结果就不为0,此时连用两个逻辑非!,即可得到1,如果x中所有奇数比特位都是0,那么位与的结果就是0,此时连用两个逻辑非!,即可得到0。那么我们该如何得到0xAAAAAAAA呢?可以按照下面的五个步骤来得到0xAAAAAAAA。为了节省运算符,引入int a=0xAA,int b=0xAA<<8,int c=a+b,int d=(c<<16)+c,这时d即为0xAAAAAAAA。然后编写第四个函数anyOddBit,如 图20:编写第4个函数anyOddBit 所示。

  1. 期望的输出: 1010 1010 1010 1010 1010 1010 1010 1010 0xAAAAAAAA

  2. 第一个步骤: 0000 0000 0000 0000 0000 0000 1010 1010 0xAA

  3. 第二个步骤: 0000 0000 0000 0000 1010 1010 0000 0000 0xAA<<8

  4. 第三个步骤: 0000 0000 0000 0000 1010 1010 1010 1010 (0xAA<<8)+0xAA

  5. 第四个步骤: 1010 1010 1010 1010 0000 0000 0000 0000 ((0xAA<<8)+0xAA)<<16

  6. 第五个步骤: 1010 1010 1010 1010 1010 1010 1010 1010 (((0xAA<<8)+0xAA)<<16)+((0xAA<<8)+0xAA)

图20:编写第4个函数anyOddBit) 

第5个函数,isEqual,如果两个int型数相等,那么返回1,否则返回0,我们直接!(x^y)即可。如 图21:编写第5个函数isEqual 所示。

图21:编写第5个函数isEqual) 

第6个函数,leastBitPos,可以理解为,找到从左到右最后一个1的位置,然后其它位置都设为0。对于96来说,96可以写成0110 0000,最低位的1是从右往左第5个,所以返回0010 0000;对于104来说,104可以写成0110 1000,从左到右最后一个1的位置是第3个,所以返回0000 1000。那么我们该怎么做呢?发现可以将x各位取反然后加1,并将这个结果与x进行位与,这时返回的结果即为我们期望中的结果。比如对于96,也就是0110 0000来说,各位取反得到了1001 1111,再加1得到了1010 0000,然后将这个数与0110 0000进行位与操作,得到了0010 0000,正好是我们想要的结果,所以我们"return ((~x)+1)&x;"即可,如 图22:编写第6个函数leastBitPos 所示。

图22:编写第6个函数leastBitPos

接着第7个函数,isPositive, 如果x大于0的话返回1,如果x不大于0的话返回0。该怎么做呢?只需要判断符号位即可。该怎么获取符号位呢?可以将x右移31位,因为一方面针对int型变量的右移都是算术右移,另外一方面实验也规定了所有的右移都是算术右移,所以我们将x右移31位,这样所有的比特位都和符号位是一样的取值了。这时得到!(x>>31),如果x为正,则符号位为0,x>>31为0,逻辑非后为1;如果x为负,则符号位为1,x>>31为0xFFFFFFFF,逻辑非后为0。另外考虑到当x为0时,本想让其返回0,结果此时!(x>>31)的结果也是1,所以需要修正,修正的结果为!(x>>31)&!!x,进而可以写成!(!x|x>>31)。当x为0时,!x为1,!x|x>>31直接为1,!(!x|x>>31)为0;当x为负数时,!x为0,x>>31为0xFFFFFFFF,!(!x|x>>31)为0;当x为正数时,!x为0,x>>31也为0,进而!(!x|x>>31)为1,按照这个思路,我们写出了"return !(!x|x>>31)",如 图23:编写第7个函数isPositive 所示。

图23:编写第7个函数isPositive) 

第8个函数,ezThreeFourths,开始慢慢变复杂了,我们需要完美复现C语言表达式x*3/4,那么该怎么做呢?首先计算x*3,x*3可以用位运算表示为(x<<1)+x,接着计算x/4,这里并不能简单的((x<<1)+x)>>2。为什么呢?因为如果简单的这样做以后,会存在当x为负数时舍入的问题,比如当x=-1、-2、-3、-5、-6、-7... ...时,((x<<1)+x)>>2会比x*3/4小1,而当x=-4、-8、-12时,((x<<1)+x)>>2才会与x*3/4相等。所以为了解决这个问题,进行修正,设a=(x<<1)+x,修正为(a+(a>>31)&0x3)>>2,这样子就可以啦!如 图24:编写第8个函数ezThreeFourths 所示。

(图24:编写第8个函数ezThreeFourths)

第9个函数,isLessOrEqual。首先从大方向上来看,存在一个或的情况,也就是说,当x等于y时也返回1,所以大框架为:

(                                                       ) | (    !(x^y)    )

这样子解决了或的问题,下一步就应该要解决isLess的问题。怎么解决这个问题呢?第一反应是通过计算x-y=x+~y+1,根据结果的符号位来判断是否小于。但问题在于,虽然一般情况下这种方法是对的,但如果是一个很小的负数减去一个很大的正数,或者一个很大的正数减去一个很小的负数,这时int类型就无法表示相减的结果,甚至无法表示1-0x8000 0000的结果。所以就需要根据int类型能不能放得下相减的结果,来进行分类讨论。那么如何判断int类型能不能放得下相减的结果呢?我们发现,只有当x与y异号时才存在溢出的问题,所以我们可以将x与y是否同号作为分类依据,这样子大框架进一步细分为:

((    (x^~y)&(            )    |    (        )   ) >>31)&1 | (    !(x^y)    )

当x与y同号时,x与~y异号,x^~y的符号位为1,此时x-y的符号位为即为我们想返回的结果,所以直接返回x-y即可,这时大框架即为:

((    (x^~y)&(x+~y+1)    |    (        )   ) >>31)&1 | (    !(x^y)    )

而当x与y异号时,x与~y同号,x^~y的符号位为0,此时选择x&~y,如果x符号位为0,那么x一定大于y,最终应该返回0,而x&~y恰好就是0;如果x符号位为1,那么x一定小于y,最终应该返回1,而x&~y恰好就是1。利用这个性质,最终的大框架即可完成:

((    (x^~y)&(x+~y+1)    |    (     x&~y   )   ) >>31)&1 | (    !(x^y)    )

而如果只选择直接看x的符号位是否为1,而不是选择x&~y的话,有可能出现x与y同号并且x-y符号位为0并且x符号位为1,这时(x^~y)&(x+~y+1)符号位为0,x符号位为1,0|1为1,返回1,但我们想要其返回0,这就出现了冲突。为了避免这个冲突,就需要保证当x与y同号,x^~y的符号位为1时,我们选择的表达式一定为0,所以这才选择了x&~y。有些同学会问,那我们最开始的时候,为什么不写成(           !!(x^y)&()                                            ) | (    !(x^y)    ),是不是也是这个道理呢?对。因为当!(x^y)为1,即x==y时,!!(x^y)&()中的()一定为0,所以我们才选择省略了!!(x^y)。最终,如 图25:编写第9个函数isLessOrEqual 所示。

图25:编写第9个函数isLessOrEqual

 第10个函数,rotateLeft,将x旋转左移n位。比如0x87654321左移4位得到了0x76543218,该怎么得到0x76543218呢?我们发现,其由两部分组成,分别是0x76543210与0x8。0x76543210可直接由x<<4得到,0x8可有x>>28然后与0xF做位与得到。最终4可被n代替,28可被32+~n+1代替,那么如何得到0xF呢?最省运算符的方法是,~0+(1<<n)。所以按照这个思路,我们可写出表达式为"(x<<n)|((x>>(32+~n+1))&(~0+(1<<n)))",最终如 图26:编写第10个函数rotateLeft 所示。

图26:编写第10个函数rotateLeft

/* * bitXor - x^y using only ~ and & *   Example: bitXor(4, 5) = 1*   Legal ops: ~ &*   Max ops: 14*   Rating: 1*/
int bitXor(int x, int y) {return ~(x&y)&~(~x&~y);
}
/** isZero - returns 1 if x == 0, and 0 otherwise *   Examples: isZero(5) = 0, isZero(0) = 1*   Legal ops: ! ~ & ^ | + << >>*   Max ops: 2*   Rating: 1*/
int isZero(int x) {return !x;
}
/* * thirdBits - return word with every third bit (starting from the LSB) set to 1*   Legal ops: ! ~ & ^ | + << >>*   Max ops: 8*   Rating: 1*/
int thirdBits(void) {int t=0x49+(0x49<<9);return t+(t<<18);
}
/* * anyOddBit - return 1 if any odd-numbered bit in word set to 1*   Examples anyOddBit(0x5) = 0, anyOddBit(0x7) = 1*   Legal ops: ! ~ & ^ | + << >>*   Max ops: 12*   Rating: 2*/
int anyOddBit(int x) {int a=0xAA;int b=a<<8;int c=a+b;int d=c+(c<<16);return !!(x&d);
}
/* * isEqual - return 1 if x == y, and 0 otherwise *   Examples: isEqual(5,5) = 1, isEqual(4,5) = 0*   Legal ops: ! ~ & ^ | + << >>*   Max ops: 5*   Rating: 2*/
int isEqual(int x, int y) {return !(x^y);
}
/* * leastBitPos - return a mask that marks the position of the*               least significant 1 bit. If x == 0, return 0*   Example: leastBitPos(96) = 0x20*   Legal ops: ! ~ & ^ | + << >>*   Max ops: 6*   Rating: 2 */
int leastBitPos(int x) {return ((~x)+1)&x;
}
/* * isPositive - return 1 if x > 0, return 0 otherwise *   Example: isPositive(-1) = 0.*   Legal ops: ! ~ & ^ | + << >>*   Max ops: 8*   Rating: 2*/
int isPositive(int x) {return !(x>>31|!x);
}
/** ezThreeFourths - multiplies by 3/4 rounding toward 0,*   Should exactly duplicate effect of C expression (x*3/4),*   including overflow behavior.*   Examples: ezThreeFourths(11) = 8*             ezThreeFourths(-9) = -6*             ezThreeFourths(1073741824) = -268435456 (overflow)*   Legal ops: ! ~ & ^ | + << >>*   Max ops: 12*   Rating: 3*/
int ezThreeFourths(int x) {int a=(x<<1)+x;return (a+((a>>31)&0x3))>>2;
}
/* * isLessOrEqual - if x <= y  then return 1, else return 0 *   Example: isLessOrEqual(4,5) = 1.*   Legal ops: ! ~ & ^ | + << >>*   Max ops: 24*   Rating: 3*/
int isLessOrEqual(int x, int y) {
return ((((((x+~y+1)&(x^~y))|(x&~y))>>0x1f))&1)|!(x^y);
}
/* * rotateLeft - Rotate x to the left by n*   Can assume that 0 <= n <= 31*   Examples: rotateLeft(0x87654321,4) = 0x76543218*   Legal ops: ~ & ^ | + << >> !*   Max ops: 25*   Rating: 3 */
int rotateLeft(int x, int n) {return (x<<n)|((x>>(32+~n+1))&(~0+(1<<n)));
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/202647.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

YOLOv8改进 | TripletAttention三重注意力机制(附代码+机制原理+添加教程)

一、本文介绍 本文给大家带来的改进是Triplet Attention三重注意力机制。这个机制&#xff0c;它通过三个不同的视角来分析输入的数据&#xff0c;就好比三个人从不同的角度来观察同一幅画&#xff0c;然后共同决定哪些部分最值得注意。三重注意力机制的主要思想是在网络中引入…

C陷阱与缺陷——第6章 预处理器

在严格意义上的编译过程开始之前&#xff0c;C语言预处理器首先对程序代码做了必要的转换处理。预处理器的主要作用是&#xff1a; 我们有时需要将某个特定数量在程序中出现的所有实例统统加以修改大多数C语言实现在函数调用时都会带来重大的系统开销 1. 不能忽视宏定义中的空…

Kontakt v7.7.2(音频采样器)

Native Instruments Kontakt 7是一款强大的软件采样器&#xff0c;它允许用户从各种来源采样音频并进行编辑和处理。它包含大量预设采样库&#xff0c;包括乐器、合成器、鼓组和声音效果等。此外&#xff0c;Kontakt 7还允许用户创建自己的采样库&#xff0c;以便根据自己的需要…

电脑版的便签软件使用哪一款?

您会选择使用电脑便签软件吗&#xff1f;很多人在日常工作及生活中会选择用电脑便签来督促自己按时完成工作任务&#xff0c;而且选择电脑便签是一个难题&#xff0c;毕竟当前电脑便签类工具非常多&#xff0c;如果想要找一款功能比较强大且又简单易用的便签工具&#xff0c;那…

HarmonyOS学习--创建和运行Hello World

创建和运行Hello World 打开DevEco Studio&#xff0c;在欢迎页单击Create Project&#xff0c;创建一个新工程。根据工程创建向导&#xff0c;选择创建Application应用或Atomic Service元服务。选择“Empty Ability”模板&#xff0c;然后单击Next。关于工程模板的介绍和支持…

A股股票交易费用

A股股票交易费用如下&#xff1a; 经手费&#xff1a;&#xff08;上证/深证&#xff09;按成交额双边收取0.0487‰&#xff0c;交给交易所。 监管费&#xff1a;&#xff08;深证&#xff09;按成交额双边收取0.02‰&#xff0c;交易所代收&#xff0c;交给证监会。 证管费&…

QGraphicsView实现简易地图7『异步加载-多瓦片-无底图』

前文链接&#xff1a;QGraphicsView实现简易地图6『异步加载-单瓦片-无底图』 前一篇文章提到的异步单瓦片加载&#xff0c;是指线程每准备好一个瓦片数据后&#xff0c;立刻抛出信号让主线程加载。而本篇异步多瓦片加载是指线程准备好所有瓦片数据后&#xff0c;一起抛出信号让…

将文件夹中所有文件名取出

dir C:\Users\是啊\Desktop\实验五/b>C:\Users\是啊\Desktop\1111.xls C:\Users\是啊\Desktop\实验五&#xff08;这个是文件夹路径&#xff09; /b &#xff08;参数&#xff09; C:\Users\是啊\Desktop\1111.xls&#xff08;文件名输出的文件路径&#xff09;

用VR+科普点亮科技之光VR航天科普体验巡展

11月22日至26日&#xff0c;第十一届中国(绵阳)科技城国际科技博览会圆满闭幕。本届科博会以“科技引领创新转化开放合作”为主题&#xff0c;创新办展办会模式&#xff0c;搭建高能级科技合作交流平台&#xff0c;展示了国内外科技创新发展成就和最新成果&#xff0c;举办了多…

内核无锁队列kfifo

文章目录 1、抛砖引玉2、内核无锁队列kfifo2.1 kfifo结构2.2 kfifo分配内存2.3 kfifo初始化2.4 kfifo释放2.5 kfifo入队列2.6 kfifo出队列2.7 kfifo的判空和判满2.8 关于内存屏障 1、抛砖引玉 昨天遇到这样一个问题&#xff0c;有多个生产者&#xff0c;多个消费者&#xff0c…

【从零认识ECS云服务器 | 快速上线个人网站】二、使用ECS云服务器

第二章 使用ECS 2.1 获取ECS 方式一&#xff1a;通过试用中心免费领取ECS实例 满足以下全部条件的阿里云用户&#xff0c;可免费试用云服务器ECS&#xff1a; 阿里云注册会员用户并完成阿里云企业认证或个人认证用户。申请用户是云服务器ECS产品的新用户&#xff0c;可以申…

查询不用order by时结果默认怎么排序

总结: 如果在使用没有指定order by&#xff0c;那么基本上依赖于底层实现的&#xff0c;具体排序规则不定&#xff0c;所以排序的顺序也不固定&#xff0c;可能会随着时间发生变化。 在实际工作中&#xff0c;如果有查询列表展示数据的功能和需求&#xff0c;开发前一定要先确…

Linux 进程地址空间

文章目录 进程地址空间进程地址空间结构页表虚拟内存写时拷贝 进程地址空间 进程地址空间难以定义&#xff0c;因为它更像是一个中间件。 程序从磁盘中加载到内存&#xff0c;程序的执行需要硬件资源&#xff0c;所以每个程序启动时会创建至少一条进程&#xff0c;进程作为组…

HarmonyOS 修改App的默认加载的界面(ArkTS版本)(十七)

根据鸿蒙系统APP的应用生命周期结构&#xff08;鸿蒙4.0开发笔记之ArkTS语法基础之应用生命周期&#xff09;来看。 1、首先在roject/entry/src/main/ets/entryability/EntryAbility.ts文件中找到UI加载函数&#xff1a;onWindowStageCreate(…){…}&#xff0c;然后找到windo…

力扣100 相同的数(两种解法)

给你两棵二叉树的根节点 p 和 q &#xff0c;编写一个函数来检验这两棵树是否相同。 如果两个树在结构上相同&#xff0c;并且节点具有相同的值&#xff0c;则认为它们是相同的。 示例 1&#xff1a; 输入&#xff1a;p [1,2,3], q [1,2,3] 输出&#xff1a;true 示例 2&…

【数据分享】11个城市的出租车(网约车)数据(免费获取)

出租车&#xff08;网约车&#xff09;GPS数据是我们最常使用的交通大数据之一&#xff0c;但是出租车&#xff08;网约车&#xff09;GPS数据没有公开的获取渠道&#xff0c;有些学者可能能通过与相关机构合作拿到数据&#xff0c;但是对于绝大多数普通人是没有这个机会的&…

【理解ARM架构】中断处理 | CPU模式

&#x1f431;作者&#xff1a;一只大喵咪1201 &#x1f431;专栏&#xff1a;《理解ARM架构》 &#x1f525;格言&#xff1a;你只管努力&#xff0c;剩下的交给时间&#xff01; 目录 &#x1f35c;中断&#x1f368;GPIO中断代码实现 &#x1f35c;CPU&#x1f368;CONTROL…

2024王道考研计算机组成原理——存储系统

微信打开的时候会有一个人站在地球上&#xff0c;这个过程就是把程序从辅存转移到主存&#xff0c;数据只有调入主存当中才可以被CPU访问 cache&#xff1a;主存速度还是慢&#xff0c;为了进一步缓解CPU和主存之间的速度矛盾 在微信打视频聊天的时候&#xff0c;在这一段比较…

弘扬中华文化 感受戏曲魅力——安徽演艺小分队赴和田交流演出

为进一步弘扬中华优秀传统文化&#xff0c;促进皖和两地交往交流交融&#xff0c;12月2日&#xff0c;安徽省演艺小分队走进和田新夜市登台演出&#xff0c;黄梅戏、独唱、民乐演奏、杂技等丰富多样的表演&#xff0c;为观众们送上了一场文化盛宴。 安徽演艺小分队赴和田交流演…

一篇文章带你详细了解C++智能指针

一篇文章带你详细了解C智能指针 为什么要有智能指针内存泄漏1.什么是内存泄漏&#xff0c;它的危害是什么2.内存泄漏的分类3.如何避免内存泄漏 智能指针的使用及原理1.RAII2.智能指针的原理3.auto_ptr4.unique_ptr5.shared_ptr6.weak_ptr 为什么要有智能指针 C引入智能指针的主…