快速上手系列-C语言之位运算

很多时候我们都要处理二进制位的问题,如将两个数按位相加,将一个存储单元中的各二进制位左移或右移一位等等,这些问题是常常会遇到的。

C语言提供的位运算符:

有以下几个:

其中除~外其它的运算符均为双目运算,参加运算的两个数据,按二进制位展开,然后进行相应的运算,如:“&、或、异或、非”等。某些位运算符在特定的场景中比较适用,如:

& 常用来将一个单元清零、取一个数中的某些指定位、保留指定位操作| 常用来将一个数的某些位置1^ 判断两个位值,不同为1,相同为0,常用来使特定位翻转等~ 是一个单目(元)运算符,用来对一个二进制数按位取反,即将0变1用来配合其它位运算符使用的,用来设置屏蔽字移位运算

<< 将一个数的各位二进制位全部左移,高位左移后溢出,舍弃不起作用.例如:a =<<2 将a的二进制数左移2位,右补0若a=15,即二进制数00001111左移2位得00111100,(十进制数60)>>如果原来符号位为0(正数)则左边移入0.如果符号位为1(负数),则左边移入1还是0要取决于系统,移入0的称为“逻辑右移”,移入1的称为“算术右移”.例如:

a的值是八进制数113755:a:1001011111101101 (用二进制形式表示)a>>1: 0100101111110110 (逻辑右移时)a>>1: 1100101111110110 (算术右移时)在有些系统中,a>>1得八进制数045766,而在另一些系统上可能得到的是145766。Turbo C和其他一些C编译采用的是算术右移,即对有符号数右移时,如果符号位原来为1,左面移入高位的是1其实,改变一个或几个二进制位的值,通常使用位操作指令来实现,如通过&、|、 ^、~ 的组合来实现二进制按位赋值或改变其值。那么还有没有其他方式能够实现这种功能呢?

当然,还有其他的操作方式,在之前介绍结构体的时候说过“位域”,是的,也可以通过位域来实现对一个数的一个或多个二进制位赋值。在C语言中,允许在一个结构体中以位为单位来指定其成员所占内存长度,这种以位为单位的成员称为“位段”或称“位域” ( bit field);利用位域能够用较少的位数存储数据。

关于位段的定义与引用有几点重要说明:

位段成员的类型必须指定为unsigned或signed类型,其可以是char, unsigned char或short, unsigned short。就是不能使float来看个测试例子:

给位段成员赋值时,不要超出位域定义的范围,如上面例子中,段成员a定义为2位,最大值为3,即(11),所以data a =5,就会取5的低两位进行赋值,就得不得想要的值。一个位段必须存放在一个存储单元中,不能跨两个单元;如果第一个单元空间不能容纳下一个位段,则该空间不用,而从下一个单元起存放该位段来看一个例子:

我们假设可以跨位段,那上面的结果应该是8,可能是这样的:

实则不然,其实它是这样的:

位段的长度不能大于存储单元的长度

可以看出来报错了,因为char是占一个字节的存储单元,只有8位,而char a :9;a占9位超过了char存储单元的长度,因此出错。

不能定义位段数组

http://www.wu0553.com/news/37247.html
http://www.wu0553.com/news/37250.html
http://www.wu0553.com/news/37251.html
http://www.wu0553.com/news/37253.html
http://www.wu0553.com/news/37254.html
http://www.wu0553.com/news/37256.html
http://www.wu0553.com/news/37257.html
http://www.wu0553.com/news/37259.html
http://www.wu0553.com/news/37260.html
http://www.wu0553.com/news/37261.html
http://www.wu0553.com/news/37263.html
http://www.wu0553.com/news/37267.html
http://www.wu0553.com/news/37268.html
http://www.wu0553.com/news/37322.html
http://www.wu0553.com/news/37366.html
http://www.wu0553.com/news/37370.html
http://www.wu0553.com/news/37377.html
http://www.wu0553.com/news/37395.html
http://www.wu0553.com/news/37396.html
http://www.wu0553.com/news/37397.html
http://www.wu0553.com/news/37402.html
http://www.wu0553.com/news/37403.html
http://www.wu0553.com/news/37404.html
http://www.wu0553.com/news/37405.html
http://www.wu0553.com/news/37406.html
http://www.wu0553.com/news/37407.html
http://www.wu0553.com/news/37430.html
http://www.wu0553.com/news/37431.html
http://www.wu0553.com/news/37432.html
http://www.wu0553.com/news/37433.html
http://www.wu0553.com/news/37436.html
http://www.wu0553.com/news/37441.html
http://www.wu0553.com/news/37448.html
http://www.wu0553.com/news/37454.html
http://www.wu0553.com/news/37455.html
http://www.wu0553.com/news/37465.html
http://www.wu0553.com/news/37466.html
http://www.wu0553.com/news/37467.html
http://www.wu0553.com/news/37468.html
http://www.wu0553.com/news/37469.html
http://www.wu0553.com/news/37470.html
http://www.wu0553.com/news/37471.html
http://www.wu0553.com/news/37473.html
http://www.wu0553.com/news/37474.html
http://www.wu0553.com/news/37475.html
http://www.wu0553.com/news/37476.html
http://www.wu0553.com/news/37477.html
http://www.wu0553.com/news/37478.html
http://www.wu0553.com/news/37480.html
http://www.wu0553.com/news/37481.html
http://www.wu0553.com/news/37482.html
http://www.wu0553.com/news/37483.html

如一个段要从另一个字开始,可以定义:

unsigned a:1;unsigned b:2;unsigned :0;unsigned c:3;(另一个单元)由于用了长度为0的位段,其作用是使下一个位段从下一个存储单元开始存放;将a、b存储在一个存储单元中,c另存在下一个单元(“存储单元”视不同的编译系统而异).看个例子:

猜你喜欢

转载自www.cnblogs.com/cc888/p/11672039.html