C语言位运算

合集下载

c语言位与运算

c语言位与运算

c语言位与运算C语言是一种非常常用的编程语言,具有强大的功能和灵活的特性。

在C语言中,位运算是一种非常重要的运算方式。

本文将介绍位与运算的概念、用法和应用场景。

一、概念位与运算是指对两个操作数进行二进制位的逐位比较,只有在相应的位都为1时,结果的相应位才为1,否则为0。

在C语言中,位与运算使用“&”符号表示。

二、用法1. 常规用法:位与运算常用于对数据的二进制位进行某种操作,例如判断某个数是否为偶数。

我们可以使用位与运算符将该数的二进制表示与1进行位与运算,如果结果为0,则该数为偶数,否则为奇数。

2. 掩码操作:位与运算还常用于进行掩码操作。

掩码是一种用于保留或屏蔽某些二进制位的技术。

我们可以通过位与运算将目标数据的某些位清零或保留。

例如,我们可以使用位与运算将一个字节的高4位清零,只保留低4位的值。

三、应用场景1. 位与运算常用于操作图像像素的颜色通道。

在某些情况下,我们需要提取图像中的红色通道、绿色通道或蓝色通道。

我们可以使用位与运算和合适的掩码来提取特定的颜色通道。

2. 位与运算还可以用于判断某些特定的状态或属性。

例如,我们可以使用位与运算来判断一个整数是否包含某个特定的标志位,或者判断一个字节是否为全零。

3. 位与运算还可以用于优化代码的性能。

在某些情况下,我们可以使用位与运算替代乘法或除法运算,以提高代码的执行效率。

四、示例代码下面是一些使用位与运算的示例代码:1. 判断一个数是否为偶数:```int isEven(int num) {return (num & 1) == 0;}```2. 提取图像的红色通道:```unsigned int getRedChannel(unsigned int pixel) {return (pixel & 0xFF0000) >> 16;}```3. 判断一个字节是否为全零:```int isZeroByte(unsigned char byte) {return (byte & 0xFF) == 0;}```以上代码仅为示例,实际使用时需要根据具体情况进行调整和优化。

C语言课件 位运算

C语言课件 位运算
位运算
主要内容
位运算符和位运算 位段 小结
位运算
系统软件中,用于检测和控制。 位运算—二进制位的运算。 运算符 优先级 含义
用途
&
8
按位与
定位清零、保留异或
定位翻转、保留
~
2
取反
补码
<<
5
左移
快速2乘法
>>
5
右移 快速2除法(逻辑/算术右移)
位运算
{
unsigned a:2;
unsigned b:6;
unsigned c:4;
int i;
}data;
位段成员类型必须为unsigned,int 类型; 位段长度不能大于存储单元; 可以定义无名段; 可以用整型格式输出。
小结
小结
位运算符和位运算:& | ^ ~ << >> 位段
举例:取整数的从右端开始的4-9位
void main()
{
unsigned a,b;
scanf(“%o”,&a);
结果:
b=(a>>4)&(~(~0<<6));
351
printf(“%o,%o\n”,a, b);
351,16
}
位段
位段:又称位域,在结构体中以位为单位的成员。 作用:减少存储数据的位数。 定义: struct packed_data

C语言中的位运算的技巧

C语言中的位运算的技巧

C语⾔中的位运算的技巧⼀、位运算实例1、⽤⼀个表达式,判断⼀个数X是否是2的N次⽅(2,4,8,16.....),不可⽤循环语句。

X:2,4,8,16转化成⼆进制是10,100,1000,10000。

如果减1则变成01,011,0111,01111。

两者做按位与运算,结果如果为0,则X是2的N次⽅。

2、统计⼀个整数的⼆进制中1的个数int count_number_of_one(int number){ int counter = 0; while (number) { counter++; number &= number - 1 ; } return counter;}⼆、位运算基础很多⾼级的动态规划题⽬或者⼀些基础的运算往往需要较⾼的执⾏效率和较低的空间需求,或者需要表⽰⼀些状态集合,⽽位运算刚好能满⾜这⼀切。

很多的时候,恰当的位运算使⽤也能使程序变得更加简洁和优美。

1、位运算法则位运算是各位互不影响的,⽐如A为1010⽽B为1100,那么有A&B=1000A|B=1110A^B=0110~A=11110101 (1的个数是取决于A的类型的,这⾥认为A的类型是8位整型)另外两种位运算是位移运算a<<b,a>>b。

前者表⽰将a的所有位向左移动b位,后者则表⽰将a的所有位向右移动b位。

对于⾮负整数(往往这也是我们最关⼼的),新空出的位将会被0取代。

⽐如A为1001,⽽B为3,那么A>>B则为1。

⼤多数情况下可以简单地认为左移b位就是乘以2b,⽽右移b位则是除以(整除)2b。

当然这是存在例外的——对于负数是不能这么简单认为的:⽐如在GNU GCC/G++ 编译条件下,若A=-1,你会发现对于任何位移运算A<<B,⽆论B的取值如何,其结果均为-1。

因此请注意,在位移运算下务必确保对⾮负整数进⾏运算,以免发⽣不必要的问题。

对于位移运算最常⽤的操作就是取⼀个特定的位——⽐如1< xx>2、对于集合的表⽰⼤多数时候,我们可以⽤⼀个整数来表⽰⼀个包含不超过32(当然如果使⽤64位整型变量也可以是64个)个元素的集合——对于每⼀个位,如果元素为1,则表⽰存在当前位所对应的集合成员,如果是0,则表⽰这个集合成员是不存在的。

C语言新教材PPT课堂课件第12章位运算

C语言新教材PPT课堂课件第12章位运算
| 1001 ────
1011=11 (3)主要用途:将1个数的某(些)位置1,其余各位不变。
3.按位异或── ^ (1)格式:x^y (2)规则:对应位相同时为0,不同时为1:3^9=10。 例如,3^9=1: 0011
^ 1001
────
1010=10 (3)主要用途:使1个数的某(些)位翻转(即原来为1的位变为0,为0 的变为1),其余各位不变。 4.按位取反── ~ (1)格式:~x (2)规则:各位翻转,即原来为1的位变成0,原来为0的位变成1: 在IBM-PC机中,~0=0xffff,~9=0xfff6。 (3)主要用途:间接地构造一个数,以增强程序的可移植性。 5.按位左移── << (1)格式:x<< 位数 (2)规则:使操作数的各位左移,低位补0,高位溢出:5<<2=20。
程序运行情况:
Input a integer number:1000 ←┘
result=0x3
程序说明:~ ( ~0 << 4)按位取0的反,为全1;左移4位后,其低4位为0,其 余各位为1;再按位取反,则其低4位为1,其余各位为0。这个整数正是我们 所需要的。
[例12.2] 从键盘上输入1个正整数给int变量num,按二进制位输 出该数。
printf("Input a integer number: ");
scanf("%d",&num);
num >>= 8;
/*右移8位,将8~15位移到低8位上*/
mask = ~ ( ~0 << 4);/*间接构造1个低4位为1、其余各位为0的整数*/
printf("result=0x%x\n", num & mask); }

c语言中位运算公式

c语言中位运算公式

c语言中位运算公式C语言中位运算公式在C语言中,位运算是对数据的二进制表示进行操作的一种运算。

位运算包括按位与(&)、按位或(|)、按位异或(^)、按位取反(~)以及左移(<<)和右移(>>)等操作。

这些运算符可以对整数类型的数据进行位级操作,具有高效、简洁的特点。

一、按位与运算(&)按位与运算符用来对两个操作数的二进制位进行与运算,即两个位都为1时结果为1,否则为0。

例如,对于两个整数a和b,a & b 的二进制位运算结果就是将a和b的二进制位对应的位进行与运算。

二、按位或运算(|)按位或运算符用来对两个操作数的二进制位进行或运算,即两个位只要有一个为1时结果为1,否则为0。

例如,对于两个整数a和b,a | b的二进制位运算结果就是将a和b的二进制位对应的位进行或运算。

三、按位异或运算(^)按位异或运算符用来对两个操作数的二进制位进行异或运算,即两个位相同为0,不同为1。

例如,对于两个整数a和b,a ^ b的二进制位运算结果就是将a和b的二进制位对应的位进行异或运算。

四、按位取反运算(~)按位取反运算符用来对操作数的二进制位进行取反运算,即将0变为1,1变为0。

例如,对于一个整数a,~a的二进制位运算结果就是将a的二进制位进行取反运算。

五、左移运算(<<)左移运算符用来将一个数的二进制位向左移动指定的位数,即在右边补0。

例如,对于一个整数a,a << n的二进制位运算结果就是将a的二进制位向左移动n位。

六、右移运算(>>)右移运算符用来将一个数的二进制位向右移动指定的位数,即在左边补0。

例如,对于一个整数a,a >> n的二进制位运算结果就是将a的二进制位向右移动n位。

位运算在C语言中具有很多应用场景。

其中,按位与运算常用于位掩码操作,按位或运算常用于设置标志位,按位异或运算常用于数据加密与解密,按位取反运算常用于数据反转等。

《C语言程序设计》第十章位运算(完)

《C语言程序设计》第十章位运算(完)
}
运行结果: a and b:0x81 a and b:0xbb a and b:0x3a
1 0 1 1 1 0 0 1 a:0xb9 a&b 1 0 0 0 0 0 1 1 b:0x83
1 0 0 0 0 0 0 1 结果:0x81
1 0 1 1 1 0 0 1 a:0xb9 a|b 1 0 0 0 0 0 1 1 b:0x83
unsigned char b=248 b>>2 1 1 1 1 1 0 0 0
补零
00111110
舍弃
不带符号的操作数右移位时,左端出现的空 位补零。
unsigned char b=248 b>>2 1 1 1 1 1 0 0 0
补零
00111110
舍弃
说明:
4) 每右移一位相当于操作数除2。 5) a>>2,b>>2形式的操作并不改变操作数a,b
b=a<<2 舍弃
0 0 0 1 1 0 1 1 a:0x1b
0 1 1 0 1 1 0 0 b:0x6c 补零
不带符号的操作数右移位时,左端出现的空 位补零。
带符号的操作数右移位时,左端出现的空位 按原最左端的位复制,无论什么操作数,移 出右端的位被舍弃。
例[10-4]:右移位操作。
void main(){ char a=-8; unsigned char b=248; printf("signed a right_shift 2 bit:%d\n", a>>2 ); printf("unsigned b right_shift 2 bit:%d\n", b>>2 ); }

C语言位运算符(附例题讲解)

C语言位运算符(附例题讲解)

C语言提供了六种位运算符:& 按位与| 按位或^ 按位异或~ 取反<< 左移>> 右移12.1.1按位与运算按位与运算符"&"是双目运算符。

其功能是参与运算的两数各对应的二进位相与。

只有对应的两个二进位均为1时,结果位才为1,否则为0。

参与运算的数以补码方式出现。

例如:9&5可写算式如下:00001001 (9的二进制补码)&00000101 (5的二进制补码)00000001 (1的二进制补码)可见9&5=1。

按位与运算通常用来对某些位清0或保留某些位。

例如把a 的高八位清0 ,保留低八位,可作a&255运算( 255 的二进制数为0000000011111111)。

【例12.1】main(){int a=9,b=5,c;c=a&b;printf("a=%d\nb=%d\nc=%d\n",a,b,c);}12.1.2按位或运算按位或运算符“|”是双目运算符。

其功能是参与运算的两数各对应的二进位相或。

只要对应的二个二进位有一个为1时,结果位就为1。

参与运算的两个数均以补码出现。

例如:9|5可写算式如下:00001001|0000010100001101 (十进制为13)可见9|5=13【例12.2】main(){int a=9,b=5,c;c=a|b;printf("a=%d\nb=%d\nc=%d\n",a,b,c);}12.1.3按位异或运算按位异或运算符“^”是双目运算符。

其功能是参与运算的两数各对应的二进位相异或,当两对应的二进位相异时,结果为1。

参与运算数仍以补码出现,例如9^5可写成算式如下:00001001^0000010100001100 (十进制为12)【例12.3】main(){int a=9;a=a^5;printf("a=%d\n",a);}12.1.4求反运算求反运算符~为单目运算符,具有右结合性。

C语言中的位运算

C语言中的位运算
那么,sLowBits1 与 sLowBits2 有什么区别?
注意了,sLowBits1 和 sLowBits2 都是 short 型(而不是 unsigned short), 所以在这里,sLowBits1 代表一个正数值,而 sLowBits2 却代表了一个负数值(因 为 8 即是二进制 1000,sLowBits2 最高位是 1)。
///////////////////////////////////////////////// int main() { short sHighBits1 = 0x7fff; short sHighBits2 = 0x8f12; unsigned short usHighBits3 = 0xff12; short sLowBits1 = 0x7bcd; long lResult = 0;
[sHighBits1 + sLowBits1] lResult = 7fff7bcd lResult = 8f127bcd lResult = ff127bcd
嗯,运行很正确嘛……于是我们就放心的在自己的程序中使用起这个函数来 了。
可是忽然有一天,我们的一个程序无论如何结果都不对!经过 n 个小时的检 查和调试,最后终于追踪到……CatenateBits16() !?它的返回值居然是错的!!
前一次还好好的,后一次就 ffff 了?X 档案?
[X 档案的真相]:
注意那两个我们用来当作低 16 位值的 sLowBits1 和 sLowBits2。
已知: 使用 sLowBits1 = 0x7bcd 时,函数返回正确的值; 使用 sLowBits2 = 0x8bcd 时,函数中发生 X 档案。
lResult = CatenateBits16(sHighBits2, sLowBits1); printf("lResult = %08x ", lResult, lResult);

c语言中的位运算

c语言中的位运算

c语言中的位运算位运算是计算机中常用的一种运算方式,它直接对二进制数的每一位进行操作。

在C语言中,位运算有多种操作符,包括位与(&)、位或(|)、位异或(^)、位取反(~)等。

本文将介绍位运算的基本概念和常见应用。

一、位与运算(&)位与运算是对两个操作数的每一位进行与操作,只有在两个操作数的对应位都为1时,结果的对应位才为1,否则为0。

位与运算常用于屏蔽某些位、清零某些位的操作。

例如,假设有一个8位的二进制数11101110,我们想将第4位和第5位清零,可以使用位与运算符来实现:```unsigned char num = 0xEE; // 二进制数11101110unsigned char mask = 0xCF; // 二进制数11001111 unsigned char result = num & mask; // 二进制数11001110```通过将原数与一个掩码进行位与运算,可以将指定位置零,得到结果11001110。

二、位或运算(|)位或运算是对两个操作数的每一位进行或操作,只要两个操作数的对应位中有一个为1,结果的对应位就为1,否则为0。

位或运算常用于设置某些位、将某些位置1的操作。

例如,假设有一个8位的二进制数00110011,我们想将第3位和第4位置1,可以使用位或运算符来实现:```unsigned char num = 0x33; // 二进制数00110011unsigned char mask = 0x0C; // 二进制数00001100 unsigned char result = num | mask; // 二进制数00111111```通过将原数与一个掩码进行位或运算,可以将指定位置1,得到结果00111111。

三、位异或运算(^)位异或运算是对两个操作数的每一位进行异或操作,当两个操作数的对应位相同时,结果的对应位为0,否则为1。

位异或运算常用于数据加密、数据校验等操作。

c的位运算

c的位运算

c的位运算
C的位运算是C语言中的一种操作,它主要用于对二进制数字进行运算。

C语言中的位运算符包括位与(&),位或(|),位异或(^),左移(<<),右移(>>)和取反(~)等。

这些位运算符可以用于对整数进行位操作,从而得到一些特定的结果。

例如,左移(<<)操作可以将一个数的二进制表示向左移动指定的位数,右移(>>)操作可以将一个数的二进制表示向右移动指定的位数,位与(&)操作可以将两个数的二进制表示中相应位置上的值进行逻辑与运算等。

这些位运算在编写一些特定的算法和系统程序时非常有用,可以提高程序的效率和性能。

- 1 -。

C语言位运算

C语言位运算
x 1011 1010 & 0000 0000 结果 0000 0000
取指定位 x = x & 0xf0 ; (高4位)
x 1011 1010 & 1111 0000 结果 1011 0000 保留指定位 x 01010100 & 00111011 结果 00010000
2.“按位或” 运算符 ( | )
(2) 用途: 与其它位运算配合使用。 a=a&~1——将最后一位置0
例如:main()
{ unsigned char a,b; a=0x9d; b=0xa5; printf(“~a: %x\n”, ~a); printf(“a&b: %x\n”,a&b); printf(“a | b: %x\n”,a | b); printf(“a^b: %x\n”,a^b);
}
输出结果: ~a: 62 a&b: 85 a | b: bd a^b: 38
5.“左移运算” 运算符 (<< ) (1)规则:
二进制数的各位依次左移,高位移走作废,低位补0
D7 D6 D5 D4 D3 D2 D1 D0
0
(2) 用途:对于一个无符号整数,若左移若干位后不溢 出(<=65535), 则每左移一位相当于原值乘2
x.c);
(1) 规则:两个运算量的相应位之间进行运算,两个
对应位中只要有一个为“1”时,结果就为“1”,
否则结果为“0”
0010 1010
| 1010 0011
(2) 用途:
结果 1010 1011
将数据中某些位置为1
x=x | 0x0f; (低4位置1)
x 1010 0101 | 0000 1111

c语言位运算

c语言位运算
12
8 2 只能被存 储为00000000),因此一0的补码也是0 0000000。可知,+0和一0的补码表示是 相同的。或 者说0的补码是唯一的。 用补码进行运算,减法可以用加法来实现,十7 一6应得1。可以将十7的补码和一6的 补码相加,就得到结果值的补码。 十7的补码: 0000011 1 一6的补码: 11111010 -----------------------------------------------(相加) 100 0 0 0 0 0 进位被舍去。后面8位00000001就是1的 补码。
6
12 11 10 9 ------8 7 6 1 2 3 4 5
9一5=4 (向后拨5个字) 9+7=16(向前拨7个字) 从图上可见,向前拨7个字也能指向4。这是由于 钟是圆的,12点的
7
下一个小时是1点。时钟是12进制的,可以把1 2点看成0点,13点 就是:1点,其实是进位后得到了十二进制数11 ,其中第一个1是进 位,即高位,第二个1是低位。高位不保留,只保 留低位,因此,16点 用十二进制数表示为14,高位不保留,在时钟上 就是4点,用十进制数可表示为:16一12=4 。 对十进制数,如果想从9得到结果值5,可以 用减法: 9一4=5 已知4的补数为10一4=6,即4与6互补。因 此9一4可以改写为加法: 9+6 =15 再去掉高位1,得5。
2
二、原码 只将最高位作符号位(以0代表正,1代表负) ,其余各位代表数值本身的绝对值(以二 进制表示)。如: +7的原码为: 00000111 ^ | 代表'正'' ' 一7的原码为: 10000 1 1 1 ^ | 代表,'负' 二进制的111代表十进制的7,为简化起见,我 们只用一个字节存放一个整数,如果用两个

c语言位运算详解

c语言位运算详解
右移3位 00 00 1 1 1 1 00 00 0 0 0 1
图11.2 15右移3位得到1
右移1位相当于该数除以2,右移n位相当于该数除以2 n , 因此,将15右移3位,相当于15/2 3 = 1(C语言规定整数相 除商为整数)。
右移时应注意符号问题。对于无符号数,右移时左端补0。 对于有符号数,若符号位为0(该数为正),则右移时左端 补0,同无符号数的处理。若符号位为1(该数为负),则右 移时左端是补0还是补1,取决于所用的计算机系统。有的系 统左端补0,称逻辑右移;左端补1,称算术右移。显然,两 种方式所得的结果是不一样的。Turbo C采用的是算术右移。
scanf (”%u” , & a ) ;
b=a >> 4 ; b=b & 0x000F; printf (” \na=%u b=%u ”, a , b ) ; } 运行情况如下: 115
a=115,b=7
例 2 循环移位。要求将一个无符号数进行左循环移位。如 图11. 4所示。将a左移1位,并将移出位补到右端,输入′e ′结束。
(4)重复以上步骤,直到有键按下。程序如下:
# include <stdio. h> main( ) { unsigned a ; int flag ; scanf (”%u” , & a ) ; while (getchar( ) !=’ e ’ )
{
flag=a & 0x8000 ; a=a<<1 ;
关于位段数据,注意以下几点: (1)一个位段必须存储在同一存储单元(即字)之中,不能跨两 个单元。如果其单元空间不够,则剩余空间不用,从下一个 单元起存放该位段。 (2)可以通过定义长度为0的位段的方式使下一位段从下一存 储单元开始。 (3)可以定义无名位段。 (4)位段的长度不能大于存储单元的长度。

C语言位操作运算详解

C语言位操作运算详解

位运算程序中的所有数在计算机内存中都是以二进制的形式储存的。

位本文会以C语言的交互环境来做代码演示常见的二进制位的变换操作and运算 &•判断奇偶数对于除0以外的任意数x,使用x&1==1作为逻辑判断即可if (x&1==1){}•判断某个二进制位是否为1比如第7位, 0x40转到二进制是0100 0000,代表第7位是1.if (n&0x40){//TODO:添加你要处理的代码}•字节读取(x >> 0) & 0x000000ff /* 获取第0个字节*/(x >> 8) & 0x000000ff /* 获取第1个字节*/(x >> 16) & 0x000000ff /* 获取第2个字节*/(x >> 24) & 0x000000ff /* 获取第3个字节*/•判断一个数是不是 22 的指数bool isPowerOfTwo(int n) {if (n <= 0) return false;return (n & (n - 1)) == 0;}•取余//得到余数int Yu(int num,int n){int i = 1 << n;return num&(i-1);}•指定二进制位数截取比如说16位二进制数A:1001 1001 1001 1000,如果来你想获A 的哪一位的值,就把数字B:0000 0000 0000 0000的那一位设置为1.比如说我想获得A的第三位就把B的第三位数字设置为1,则B为0000 0000 0000 0100,设置完之后再把A、B求与,其结果若为0,说明A的第三位为0,其结果为1,说明A的第三位为1.同理:若要获得A的第五位,就把B设置为0000 0000 0001 0000,之后再求与。

通常在我们的程序中,数字B被称为掩码,其含义是专门用来测试某一位是否为0的数值。

C语言第12章位运算法则

C语言第12章位运算法则
本章要求 1、位运算及其特殊用途。 2、信息的位段表示。
第 12 章 位运算 1/5
第 12 章 位运算
位运算: 是指对二进制按位进行运算。如:将一个二进制的位左移或右移,两个二进制数相加 等。
12.1 位运算
C 语言提供的位运算符: & 按位与 | 按位或 ∧ 按位异或 ~ 取反 << 左移 >> 右移
b=a<<(16-n);
c=a>>n;
cபைடு நூலகம்c|b;
printf(“%o\n%o”,a,c);
}
12.3 位域(位段)
信息可以用 1 字节、2 字节、4 字节、8 字节表示。 例如,用 1 字节表示一个英文字符,2 字节表示一个汉字字符,4 字节表示一个实数,....等。
第 12 章 位运算 4/5
|=, 例:a|=b 相当于 a=a|b
>>=, 例:a >>=b 相当于 a=a>>b
<<=, 例:a<<=b 相当于 a=a<<b
∧=, 例:a∧=b a = a∧b
12.2 位运算举例
例[12.1] 取一个整数 a 从右端开始的 4~7 位。 比如,
第 12 章 位运算 3/5
0000,0000,1101,1001(16 位二进制) 方法: (1) 先使 a 右移 4 位,使要取出的几位移到最右端。a>>4 (2) 设置一个低 4 位全为 1,其余为 0 的数
二、“按位或”运算符 规则: 参加运算的两个运算量,如果两个对应位中有 1,则 该位结果值为 1,否则为 0。 例如 X=10001001 Y=11101110

C语言中的位操作与位运算

C语言中的位操作与位运算

C语言中的位操作与位运算位操作和位运算是C语言中常用的编程技术,它们通过直接操作变量的位来实现一些特定功能和优化程序性能。

本文将介绍C语言中的位操作与位运算,并探讨其在实际编程中的应用。

一、位操作概述位操作是通过改变变量中的独立的二进制位来实现特定功能的操作。

在C语言中,位操作主要包括位与(&)、位或(|)、位异或(^)、位取反(~)等操作符。

1. 位与(&)操作符位与操作符用于将两个操作数的对应位进行与运算,只有当两个位都为1时,结果位才为1,否则结果位为0。

例如,当我们需要提取一个变量的特定位时,可以通过使用位与操作符来屏蔽其他位,只保留我们需要的那一位。

2. 位或(|)操作符位或操作符用于将两个操作数的对应位进行或运算,只要两个位中有任意一个为1,结果位就为1。

位或操作通常用于设置一个或多个特定位的值为1,或者将多个变量的特定位合并为一个变量。

3. 位异或(^)操作符位异或操作符用于将两个操作数的对应位进行异或运算,当两个位不相同时,结果位为1,否则结果位为0。

位异或操作通常用于交换两个值、翻转指定位的值等。

4. 位取反(~)操作符位取反操作符用于将操作数的每个位取反,即1变为0,0变为1。

位取反操作通常用于取反一个变量的所有位。

二、位运算概述位运算是通过对二进制数进行逻辑操作来实现特定功能的运算。

在C语言中,常用的位运算包括左移运算(<<)、右移运算(>>)、按位取反(~)运算。

1. 左移运算(<<)左移运算符用于将操作数中的各个位向左移动指定的位数。

左移时,低位补0。

左移运算通常用于实现对变量进行乘以2的n次方的操作。

2. 右移运算(>>)右移运算符用于将操作数中的各个位向右移动指定的位数。

右移时,高位补0(对于无符号数)或补符号位(对于有符号数)。

右移运算通常用于实现对变量进行除以2的n次方的操作。

3. 按位取反(~)按位取反运算符用于将操作数的每个位取反。

c语言位运算

c语言位运算

c语言位运算C语言是一种多用途、面向过程的编程语言,位运算是C语言中非常重要的一种运算形式。

在这里,我们将介绍C语言中位运算的基本内容。

1. 位运算的概念位运算是对数据的每一位进行逻辑运算的一种方式,其中包括位逻辑运算和位移运算。

位运算的逻辑操作符一般由 & 、 | 、 ^ 、 ~符号表示,而位运算的移位操作符一般由 << 、 >>符号表示,它们分别表示左移、右移操作。

2. 位逻辑运算位逻辑运算是基于位操作的一种逻辑运算,对给定的两个比特串进行操作,如果比特串中有一位为1,那么逻辑运算结果就是1,如果比特串中所有位都为0,那么逻辑运算结果就是0。

C语言中最常用的位逻辑运算符有&(与)、|(或)、^(异或)、~(取反),它们的运算规则如下:(1)&(与运算):两个比特位均为1,结果才是1,否则结果为0。

(2)|(或运算):只要有一个比特位为1,结果即为1,否则结果为0。

(3)^(异或运算):两个比特位不同时,结果才是1,相同时结果为0。

(4)~(取反运算):对比特位求反,0变1,1变0。

3. 位移运算位移运算是一种特殊的位运算,它是指将数据在二进制表示中进行左右移动操作。

在C语言中,位移运算符一般用 << 、 >>示,其中表示左移,>>示右移。

左移运算是将数据的二进制表示整体向左移动,左边的位被舍弃,右边补0,而右移运算是将数据的二进制表示整体向右移动,右边的位被舍弃,左边补0。

4. 位运算的优势位运算具有速度快、效率高、不消耗资源等优势,所以在硬件领域以及一些操作系统方面的实时程序编程中,位运算是不可或缺的。

位运算的优势在于:(1)位运算不受数据类型的限制,可以对任何数据进行操作;(2)位运算的操作速度极快,它们的运行速度都比传统的基数运算要快,也比其他类型的运算要快;(3)位运算只需要使用少量的计算资源,因此可以有效减少计算机系统中消耗的电路数量,这是电路节省的重要手段;(4)位运算比较容易实现,它只需要逻辑电路,少量的门电路即可实现特定的运算功能,因此可以有效的提高硬件的性能。

c语言位运算

c语言位运算

C语言位运算详解位运算是指按二进制进行的运算。

在系统软件中,常常需要处理二进制位的问题。

C语言提供了6个位操作运算符。

这些运算符只能用于整型操作数,即只能用于带符号或无符号的char,short,int与long类型。

C语言提供的位运算符列表:运算符含义描述& 按位与如果两个相应的二进制位都为1,则该位的结果值为1,否则为0 | 按位或两个相应的二进制位中只要有一个为1,该位的结果值为1 ^ 按位异或若参加运算的两个二进制位值相同则为0,否则为1 ~ 取反~是一元运算符,用来对一个二进制数按位取反,即将0变1,将1变0 << 左移用来将一个数的各二进制位全部左移N位,右补0 >> 右移将一个数的各二进制位右移N位,移到右端的低位被舍弃,对于无符号数,高位补0 1、“按位与”运算符(&)按位与是指:参加运算的两个数据,按二进制位进行“与”运算。

如果两个相应的二进制位都为1,则该位的结果值为1;否则为0。

这里的1可以理解为逻辑中的true,0可以理解为逻辑中的false。

按位与其实与逻辑上“与”的运算规则一致。

逻辑上的“与”,要求运算数全真,结果才为真。

若,A=true,B=true,则A∩B=true 例如:3&5 3的二进制编码是11(2)。

(为了区分十进制和其他进制,本文规定,凡是非十进制的数据均在数据后面加上括号,括号中注明其进制,二进制则标记为2)内存储存数据的基本单位是字节(Byte),一个字节由8个位(bit)所组成。

位是用以描述电脑数据量的最小单位。

二进制系统中,每个0或1就是一个位。

将11(2)补足成一个字节,则是00000011(2)。

5的二进制编码是101(2),将其补足成一个字节,则是00000101(2)按位与运算:00000011(2) &00000101(2) 00000001(2) 由此可知3&5=1 c语言代码:#include <stdio.h> main() { int a=3; int b = 5; printf("%d",a&b); } 按位与的用途:(1)清零若想对一个存储单元清零,即使其全部二进制位为0,只要找一个二进制数,其中各个位符合一下条件:原来的数中为1的位,新数中相应位为0。

C语言位运算

C语言位运算

位运算一、基本概念:1、概念:C语言提供了对二进制数中的某个位或某几位进行操作的运算符,称为位运算。

2、特点:不再将数据作为一个整体进行运算,而是对数据中的某个或某几个二进制位进行的运算。

3、用途:可直接用于编写系统程序,常用在检测和控制领域。

4、无符号数适用于只有正数和0的场合。

(可表示范围:0~2n-1)5、有符号纯整数的二进制表示有3种形式:(原码、反码、补码)(1)原码:如果用n位二进制表示一个数,用最高位表示符号,最高位为1表示负数,最高位为0表示正数,剩下的n-1位表示数值,数值部分用其绝对值表示,这种表示方法称为原码。

二进制原码的表示范围:-2n-1<x<2n-1。

例:十进制55D转换为二进制为:00110111B。

十进制-55D转换为二进制为:10110111B。

(2)反码:用n位二进制表示数据,仍然用最高位表示符号,1表示负,0表示正,剩下的n-1为表示数值(正数不做任何变换,保持不变,负数符号位不变其余各位按位取反(0变为1,1变为0)),这种表示方法称为反码。

(表示的数据范围与原码相同)例:十进制55D转换为二进制为:00110111B十进制-55D转换为二进制为:11001000B。

(3)补码:利用有模运算表示数据的一种方式。

如果用n位二进制表示数据,则系统的模是2n。

对任意一个范围在-2n-1≤x<2n-1的数X,其补码表示为:=2n+X。

[X]补例:十进制55D转换为二进制为:100000000+00110111=00110111B 十进制-55D转换为二进制为:100000000-00110111=11001000B二、位运算逻辑位运算符移位位运算符符号含义符号含义~按位取反(单目)<<左移(双目) &按位与(双目)|按位或(双目)>>右移(双目)∧按位异或(双目)1、按位与的作用:(1)全部清零:将一个需要全部清零的数与零做按位与运算。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

第8章位运算C语言是为描述系统而设计的,与其它高级语言相比,它的一个重要特点是具有汇编语言的功能,这主要表现在C语言提供了特有的位运算功能。

8.1 位运算概念C语言的位运算是指在C语言中能进行二进制位的运算。

位运算包括位逻辑运算和移位运算,位逻辑运算能够方便地设置或屏蔽内存中某个字节的一位或几位,也可以对两个数按位相加等;移位运算可以对内存中某个二进制数左移或右移几位等。

为了表示数值,可以采用不同的方法,一般有:原码、反码和补码。

计算机内部是以补码形式存放数值的。

8.2 位运算符C语言提供了六种位运算,如表8-1所示。

表8-1 位运算符及含义说明:1.位运算量a,b只能是整型或字符型的数据,不能为实型数据。

2.位运算符中除按位取反运算符~为单目运算符外,其它均为双目运算符,即要求运算符的两侧各有一个运算量。

8.2.1位逻辑运算符假设a,b为整型的数据,并且设a=123(等于二进制数00000000001111011),b=152(等于二进制数00000000010011000)1.“按位与”运算符&运算规则:参加运算的两个运算量,如果两个数相应位的值都是1,则该位的结果值为1,否则为0。

即:0 & 0 =0;0 & 1 =0;1 & 0 =0;1 & 1 =1。

【例8-1】a的补码:00000000001111011b的补码:00000000010011000& ————————结果的补码:00000000000011000即:a&b=0x18。

2.“按位或”运算符|运算规则:参加运算的两个运算量,如果两个数相应位的值都是0,则该位的结果值为0,否则为1。

即:0 | 0 =0;0 | 1 =1;1 | 0 =1;1 | 1 =1【例8-2】a的补码:00000000001111011b的补码:00000000010011000| ————————结果的补码:00000000011111011即:a|b=0xfb。

3.“按位异或”运算符^运算规则:参加运算的两个运算量,如果两个数的相应位的值不同,则该位的结果值为1,否则为0。

即:0 ^ 0 =0;0 ^ 1 =1;1 ^ 0 =1;1 ^ 1 =0【例8-3】a的补码:00000000001111011b的补码:00000000010011000^ ————————结果的补码:00000000011100011即:a^b=0xe3。

4.“按位取反”运算符~运算规则:对一个运算量的每一位都取反,即将1变为0,0变为1。

【例8-4】a的补码:00000000001111011~ ————————结果的补码:1111111110000100即:~a=0xff84。

以上位逻辑运算规则如表8-2所示,表中是以两个运算量中相应某一位为例。

5.位逻辑运算符的一些用途(1)判断一个数据的某一位是否为1。

如判断一个整数a(2个字节)的最高位是否为1,可以设一个与a同类型的测试变量test,test的最高位为1,其余位均为0,即int test=0x8000。

根据“按位与”运算规则,只要判断位逻辑表达式a&test的值就可以了:如果表达式的值为test本身的值(即0x8000),则a的最高位为1;如果表达式的值为0,则a的最高位为0。

【例8-5】0100010011111110&1000000000000000=0 说明最高位为0;1100010011111110&1000000000000000=1000000000000000 说明最高位为1;(2)保留一个数据中的某些位。

如果要保留整数a的低字节,屏蔽掉其高字节,只需要将a和b进行按位与运算即可,其中b的高字节每位置为0,低字节每位置为1,即int b=0xff。

【例8-6】00101010 01010010&00000000 11111111=00000000 01010010。

(3)把一个数据的某些位置为1。

如果把a的第10位置为1,而且不要破坏其它位,可以对a和b进行“按位或”运算,其中b的第10位置为1,其它位置为0,即int b=0x400。

【例8-7】00100000 01010010|00000010 00000000=00100010 01010010。

(4)把一个数据的某些位翻转,即1变为0,0变为1。

如要把a的奇数位翻转,可以对a和b进行“按位异或”运算,其中b的奇数位置为1,偶数位置为0,即int b=0xaaaa。

【例8-8】00000000 01010010^01010101 01010101=01010101 00000111。

(5)交换两个值,不用临时变量。

【例8-9】a=3,b=4。

想将a和b的值互换,可以用以下三条赋值语句实现:a=a^b;即:a=3^4=7b=b^a;即:b=4^7=3a=a^b;即:a=7^3=48.1.2移位运算符1.左移运算符<<运算规则:对运算符<<左边的运算量的每一位全部左移右边运算量表示的位数,右边空出的位补0。

【例8-10】a<<2表示将a的各位依次向左移2位,a的最高2位移出去舍弃,空出的低2位以0填补。

例:char a=0x21;则a<<2的过程 00100001〈〈2=10000100即 a<<2的值为0x84。

左移1位相当于该数乘以2,左移n位相当于该数乘以2n。

如a=0x21(相当于十进制数的33),a<<2的值为0x84(相当于十进制数的132),132相当于33乘以22=4的值。

但是,a<<4:0010 00010000舍弃补0即a<<4的值为0x10(相当于十进制数的16),这是因为在进行左移时发生了溢出,即移出的高位中含1被舍弃。

因此,左移n位相当该数乘以2n只适合于未发生溢出的情况,即移出的高位中不含有1的情况。

2. 右移运算符>>运算规则:对运算符>>左边的运算量的每一位全部右移右边运算量表示的位数,右边低位被移出去舍弃掉,空出的高位补0还是补1,分两种情况:(1)对无符号数进行右移时,空出的高位补0。

这种右移称为逻辑右移。

【例8-11】unsigned char a=0x8a;a: 10001010 等于十进制数138a>>1: 01000101 0 等于十进制数69补 0 舍弃(2) 对带符号数进行右移时,空出的高位全部以符号位填补。

即正数补0,负数补1。

这种右移称为算术右移。

【例8-12】char a=0x8a;a: 10001010 等于十进制数-118a>>1: 11000101 0 等于十进制数-59补 1 舍弃又如:char a=0x76;a: 01110110 等于十进制数118a>>1: 00111011 0 等于十进制数59补0 舍弃从上面例子中可以看出,右移1位相当于除以2,同样,右移n位相当于除以2n。

8.2.3位赋值运算符位运算符与赋值运算符结合可以组成位赋值运算符。

C语言提供的位赋值运算符如表8—3所示,它们都是双目运算符。

8.2.4不同长度的数据进行位运算如果两个数据长度不同(例如long型和int型)进行位运算时(如a&b,而a为long 型,b为int型),系统会将二者按右端对齐。

如果b为正数,则左侧16位补满0。

若b为负数,左端应该补满1.如果b为无符号整数,则左侧添满0。

8.3 位段本书前面章节介绍了结构体的数据类型包括了基本类型、数组、指针、结构体与共用体等等,这些数据都是以字节为单位存储的。

实际上,存储一个数据有时只需占用字节中的一位或几位就可以了,例如,“真”或“假”用0或1表示,只需1位即可表示,这样,可以用一个字节存放几个数据。

尽管通过位运算符可以实现对这种数据的存储和访问,但这种方法比较麻烦。

C语言提供了位段结构来解决这个问题。

位段结构是指结构体成员可以是以位为单位定义存储长度的结构体。

位段结构的定义形式如下:struct 结构类型名{类型成员 1:长度;类型成员2:长度;…………}其中,冒号“:”左面的成员称为位段,它是一种特殊的结构成员,冒号右面的长度表示存储位段需要占用字节的位数。

【例8-13】 struct device :{ unsigned a:1;unsigned b:2;unsigned c:4;int x;float y;} data;定义了结构体变量data,它包含5个成员,它们分别是a,b,c,x,y。

其中,a,b,c为位段,分别占用1个位、2个位、4个位,即a,b,c共占用7个位。

这样,用一个字节就可以存储这三个位段,x、y为基本类型的成员,分别需要2个、4个字节存储。

因此,结构体变量data需要占用7个字节的内存单元,其每个成员在内存中的分配情况如图8-1所示。

1 42 1 16 32图8-1 结构变量data的内存分配情况说明:1.位段在一个存储单元中是从高位到低位分配内存还是从低位到高位分配内存因机器而异,在Turbo C中是从低位向高位分配内存,例中第7位未用,空闲。

2.位段的数据类型必须用unsigned或int类型不能用char和其它类型。

有的C编译系统只允许用unsigned型。

3.对位段的访问与其它结构体的访问方法一样,可以采用圆点运算符和指向运算符。

但必须注意不能对位段进行取地址运算,也不能使用超过位段最大值的数据。

例如:&data.a 是错误的。

因为内存地址是以字节为单位的,无法指向位。

下面的用法也是不合理的:data.b=6;因为data. b只占内存的2位,而数据6需要3位存放,因此,data.b实际上只存储了6的二进制110的低2位10即整数2。

4.位段的长度不能超越整型边界。

【例8-14】struct{unsigned a:18;/*错误,data.a长度是18位,超出了2个字节*/unsigned b:12;/*正确,data.b长度为12位,*/} data;5.如果某个位段要从下一个字节开始存放,可以采用:struct{unsigned a:1;unsigned :0;unsigned b:2;} data;这里,data的第二个成员为无名位段,长度为0,表示本位段后面定义的位段应从下一个字节开始存放。

如图8-2所示。

空闲跳过6 27 1图8-2 长度为0的无名位段占用内存情况这样,data需占用内存2个字节。

如果无名位段后面的长度不为0,则表示跳过不用的位数。

【例8-15】struct{unsigned a:1;unsigned :2;unsigned b:2;} data;各位段在内存的分配情况如图8-3所示,data只需占用内存1个字节。

相关文档
最新文档