说三道四技术文摘-感悟人生的经典句子
说三道四 > 文档快照

位运算-C语言教程

HTML文档下载 WORD文档下载 PDF文档下载
前面介绍的各种运算都是以字节作为最基本位进行的。 但在很多系统程序中常要求在位(bit)一级进行运算或处理。C语言提供了位运算的功能,这使得C语言也能像汇编语言一样用来编写系统程序。
前面介绍的各种运算都是以字节作为最基本位进行的。 但在很多系统程序中常要求在位(bit)一级进行运算或处理。C语言提供了位运算的功能,这使得C语言也能像汇编语言一样用来编写系统程序。
12.1 位运算符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
   |00000101
    00001101        (十进制为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
    ^00000101  
     00001100       (十进制为12)
【例12.3】
main(){    int a=9;    a=a^5;    printf("a=%d\n",a);}
12.1.4 求反运算
求反运算符~为单目运算符,具有右结合性。其功能是对参与运算的数的各二进位按位求反。
例如~9的运算为:
    ~(0000000000001001)结果为:1111111111110110
12.1.5 左移运算
左移运算符“<<”是双目运算符。其功能把“<< ”左边的运算数的各二进位全部左移若干位,由“<<”右边的数指定移动的位数,高位丢弃,低位补0。
例如:
    a<<4
指把a的各二进位向左移动4位。如a=00000011(十进制3),左移4位后为00110000(十进制48)。
12.1.6 右移运算
   右移运算符“>>”是双目运算符。其功能是把“>> ”左边的运算数的各二进位全部右移若干位,“>>”右边的数指定移动的位数。
例如:
设  a=15,
a>>2
表示把000001111右移为00000011(十进制3)。
应该说明的是,对于有符号数,在右移时,符号位将随同移动。当为正数时,最高位补0,而为负数时,符号位为1,最高位是补0或是补1 取决于编译系统的规定。Turbo C和很多系统规定为补1。
【例12.4】
main(){    unsigned a,b;    printf("input a number:   ");    scanf("%d",&a);    b=a>>5;    b=b&15;    printf("a=%d\tb=%d\n",a,b);}
请再看一例!
【例12.5】
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);}
12.2 位域(位段)
有些信息在存储时,并不需要占用一个完整的字节,而只需占几个或一个二进制位。例如在存放一个开关量时,只有0和1两种状态,用一位二进位即可。为了节省存储空间,并使处理简便,C语言又提供了一种数据结构,称为“位域”或“位段”。
所谓“位域”是把一个字节中的二进位划分为几个不同的区域,并说明每个区域的位数。每个域有一个域名,允许在程序中按域名进行操作。这样就可以把几个不同的对象用一个字节的二进制位域来表示。
1. 位域的定义和位域变量的说明
位域定义与结构定义相仿,其形式为:
    struct 位域结构名
       { 位域列表 };
其中位域列表的形式为:
    类型说明符 位域名:位域长度  
例如:
    struct bs
     {
       int a:8;
       int b:2;
       int c:6;
     };
位域变量的说明与结构变量说明的方式相同。 可采用先定义后说明,同时定义说明或者直接说明这三种方式。
例如:
    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
     }
    在这个位域定义中,a占第一字节的4位,后4位填0表示不使用,b从第二字节开始,占用4位,c占用4位。
2) 由于位域不允许跨两个字节,因此位域的长度不能大于一个字节的长度,也就是说不能超过8位二进位。
3) 位域可以无位域名,这时它只用来作填充或调整位置。无名的位域是不能使用的。例如:
    struct k
     {
      int a:1
      int  :2          /*该2位不能使用*/
      int b:3
      int c:2
     };
从以上分析可以看出,位域在本质上就是一种结构类型,不过其成员是按二进位分配的。
2. 位域的使用
位域的使用和结构成员的使用相同,其一般形式为:
  位域变量名•位域名
  位域允许用各种格式输出。
【例12.6】
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("%d,%d,%d\n",pbit->a,pbit->b,pbit->c);}
上例程序中定义了位域结构bs,三个位域为a,b,c。说明了bs类型的变量bit和指向bs类型的指针变量pbit。这表示位域也是可以使用指针的。程序的9、10、11三行分别给三个位域赋值(应注意赋值不能超过该位域的允许范围)。程序第12行以整型量格式输出三个域的内容。第13行把位域变量bit的地址送给指针变量pbit。第14行用指针方式给位域a重新赋值,赋为0。第15行使用了复合的位运算符"&=",该行相当于:
    pbit->b=pbit->b&3
位域b中原有值为7,与3作按位与运算的结果为3(111&011=011,十进制值为3)。同样,程序第16行中使用了复合位运算符"|=",相当于:
pbit->c=pbit->c|1
其结果为15。程序第17行用指针方式输出了这三个域的值。
12.3 本章小结
1. 位运算是C语言的一种特殊运算功能, 它是以二进制位为单位进行运算的。位运算符只有逻辑运算和移位运算两类。位运算符可以与赋值符一起组成复合赋值符。如&=,|=,^=,>>=,<<=等。
2. 利用位运算可以完成汇编语言的某些功能,如置位,位清零,移位等。还可进行数据的压缩存储和并行运算。
3. 位域在本质上也是结构类型,不过它的成员按二进制位分配内存。其定义、说明及使用的方式都与结构相同。
4. 位域提供了一种手段,使得可在高级语言中实现数据的压缩,节省了存储空间,同时也提高了程序的效率。
C#取得Excel工作簿工作表名称 C#中用Automation自动化方式对Excel的操作 VB如何打开或保存为有密码保护的Excel sheets工作表 VB在Excel表格文件中搜索指定内容 VB复制Excel表到另外一个Excel中 Java实现生成网站快照缩略图片 php实现生成网站快照缩略图片 C#实现生成网站快照缩略图片 VB比较两个Excel表格的内容 VB实现Excel按列或行排序 VB删除EXCEL表格指定行 用vb.net写的验证码识别代码 VB删除EXCEL表格指定列 Oracle数据库Windows 2003环境自动备份批处理 VB通过ADODB连接EXCEL表格文件读取数据 使用VBScript卸载软件 Discuz X2用户注册过程SQL Android手机参数表 用jQuery改变图片(image src) 用std::atomic實現簡單的讀寫鎖 ChinaPay网上支付网关.NET开发 VOB生成IFO文件用nero刻录DVD详解 15款开源Android游戏引擎(安卓免费游戏引擎) 将MVC ASPX转换到Razor视图 Word设置目录简明教程 asp.net mvc页面javascript代码中如何使用razor Discuz X论坛数据表结构:用户数据表pre_common_member boost在windows平台下自带超强 IOCP 的ASIO Boost下载和编译安装简明指引 Windows和Linux环境中Boost下载安装编译配置使用指南 Android开发技巧:Android常用类库说明 在堆(heap)上与在栈(stack)上建立的对象有什么区别? 一个问题,在做元件时怎样建立TdateTimePicker 给大家看看我弟弟给我的信 求助,标题栏为“The police are investigating the robbery-"的是什么程序? 谁能将.CPP文件的代码翻译成DELPHI语言?? 有关于FLASH5.0的问题!!!请各位大吓指点! 一个问题,怎样在PC:PageControl上增加TabSheet1,TabSheet1,TabSheet1…. 标题栏为“The police are investigating the robbery-"的是什么程序? 一个弱弱的问题 一个问题,建立的 FB: TBevel没显示,好象根本没建立一样。 如何在 MDI CLIENT 中添加快捷方式??谢谢!! 55分,如何映射控件中子控件的消息? 如何选择书 关于文献数据库的一个问题-如何把一个字段和一个文件关联起来? 所有喜欢到水园来逛逛,但是从不回帖子或很少回帖子的人进来签到~~~~ 谁来救救我呀,我好惨呀。。。。 如何通过VC编程,随时关闭网络端口 诚寻对嵌入式linux感兴趣的网友 今天临走前,再灌一桶酒! 急!!!哪里可以下载到制作工具栏时用到的位图呀? 太原的在哪能买到程序员杂志 我的qq:10120129 谁找我??? xml 高手帮帮我,为什么我下面的文件,在IE5.0中什么也没有?? 请问高手:在uml类图中如何用关系表示一个实体类和一个接口间的关系。 Cathy进来~~ 请问高手们一个Delphi的一个应该是比较底层的东西。 mimi大酒店正式開業﹗先進來的有分啊﹗ 哪个高手完整地讲讲OpenWith菜单项的调用方法和函数等 关于非模态对话框中使用UpdateData(FALSE)函数的问题,朋友,帮个忙好吗? “记事本”小问题,大逻辑.大虾们,照顾照顾小弟呗. Linux下配置ISDN--期待所有的Linux高手到来?? 我是女生,哈哈 急,怎么样在打印表格时使较长的字段分两行显示,并字体变小。 在VB里做的用户控件为什么在VC不能调用啊! 不服不行(真没辙了)[不够可在加200分] 我的代理怎么了? 寻找能显示CAD图纸的delphi控件 偶要给lastlove(☆☆☆☆☆robin★★★★★)放高利贷了! 哪位做过读取网卡地址的动态链接库? c++builder与sql server 2000的sql语言兼容性问题 为什么TWaitThread的帮助在help里找不到? 有关WIN2K策略的设置? TREEVIEW中如何打印结构树? 急急急!opensheet(w_child,w_main,2,Original!)不好使了?为啥? 100分求教,存储过程的两个问题! 哪位大侠有MPEG数据帧格式的资料,望告之,谢了。 大家出个主意,怎么使这个查询速度最快??? 还有人么?再问个问题:) MM_mimi我走了~~~~~~~~~我好失望~~~~ 空心菜被mimi扔到风里了,偶只好另外改个名了 关于ORACLE8重要问题! 如图,已知正方形ABCD边长为1cm,点E在对角线BD上,BE=BC,P是CE上一动点,PF⊥BD,PG⊥BC,PF+PG的值为 解不等式组x-3(x-2)大于等于4 5分之2x-1小于2分之x-1 求未知数x 五分之四x=二分之一 x:3.2=4 七分之x=五分之二 x分之六=九分之八 这是怎么解出来v的 我写出来的始终是分数形式 i e或者l都约不了 解不等式 (3分之x-2)-(2分之3x+5)大于等于x-(3分之2-x) 阴影部分面积是150平方厘米,求图中未知数b.(提示:60°:360°=六分之一) 数学大神求救格式与方法 3-x分之1+3x小于等于2解不等式 饲养场有马,牛,羊共360头,马的头数是牛和羊的二分之一,牛的头数是马和羊的三分之一,饲养场有多少头羊 (1-3分之1)乘(1-4分之1)乘(1-5分之1)乘……乘(1-2009分之1)乘2009找规律,巧计算,求算式 同问 不等式组5大于2(1-x)和-三分之一x小于等于三分之二-x的整数解的和是 六分之x=四求未知数x 1/1乘3+1/3乘5+1/5乘7+.1/2007乘2009 求不等式组x小于3(x+1) (2-x/3)+1大于等于x 的整数解 13-x:2=15-x:6求未知数 24分之3乘以20等于多少 不等式组9x-a大于等于0 8x-b小于等于o X的整数解是1,2,3.适合的整数a,b的有序数对是(a,b) A17个 B64个 C72个 D81个 求未知数X,一,X=2.2:二,4分之1X-0.75=2分之1除以15分之6 816乘以3约等于多少 解不等式:x+1分之x-3小于或等于3 三乘三乘三乘三乘三等于几. 22度16分乘以5等于多少 X和0.8的比等于6分之5和2的比,求X 999乘100等于几 几乘以几等于28 5和8的比等于40和x的比. 999乘999等于多少 5/6乘以20/15再加上106/100等于几 当x=5时,代数式4x-8/3的值是4,当x=多少时,代数式4x-8/3的值是-1/3 (负3)减(负5)加(负7)减(负5)加三分之七等于多少? 已知7分之1等于0.142857循环,问:最少从小数点后面第几位开始,到第几位上的数字之和等于2000? 第一个 :当x取何值时,代数式【(5x-2)/8】-x的值比代数式【(x+11)/2】-3的值小1?第二个 :某同学在解方程3a-x=13时,误将-x看做+x,解得x=—2,则原方程的解是多少?第三个 :x=2是关于x的方程7+2 15分之1加10分之1等于多少 已知7分之1=0.142857循环,问:最小从小数点后第几位开始,到第几位上的数字和等于2000 当x为什么数时,代数式0.1x-2/0.2的值比代数式-1/6x+2/3的值大3? 50*27等于多少啊.如题 求救啊.50*27 到底等于多少啊.本人数学不及格 求救下. 已知七分之一等于0.142857,问小数点后面第100位上的数字是几?小数点后面前100位上的数学之和是多少 x为何值时代数式5/6x-1与代数式4+5/1x的值相等一元一次方程求求你们了(解题过程) 138×27÷69×50等于多少 已知7分之1=0.142857,142857的循环.问小数点后面第100位上的数字是几?小数点后面前100位上的数字之和是多少? x取什么值时,代数式2x-5大于代数式1/2(2-x)? 50+(-34)+40+(-27)等于多少 已知七分之一=0.142857(循环结0.142857的循环),问小数点后面第100位上的数字是几?小数点后面前100位上的数字之和是多少? 代数式5分之X+3的值是否能同时大于代数式2X+3和1-X的值?说明理由 50减去27等于? 0.3循环什三分之一吗?那0.3循环乘以3是1还是0.9循环? x取什么值时,代数式2x-5的值(1)不大于0(2)不小于-1(3)小于2分之1x+3(4)小于3分之2x-8说明理由 37乘18加27乘42怎么简算(用递等式) 判断题:1.如果甲数的三分之二大于乙数的四分之三(甲乙都不等于0),那么甲数小于乙数.(为什么错?)2.体积相等的两个长方体,他们的表面一定相等.为什么错?1.a是一个大于0,而不大于1的数, 6.8小时等于几小时几分? 当x等于多少时,代数式三分之二x与代数式负二分之一x减二的和为0 ..数学14、15、16题求讲解 4.8小时等于几小时几分? 二分之一X:四分之一=8 求未知数,根本就没教过七分之五=二分之一:X 一次数学小测验中,有一道这样的填空题:0.3= ————%.小丽在横线上填了30%,而老师却判小丽填错了,小丽不服,去找老师问个究竟.请聪明的你评评小丽答对了吗,为什么? 7+8等于几 求未知数X 4.X-2/7X=1/14 这题怎么写、、求数学大神 四个9怎么加等于1万 7x+8(x-2)[x是未知数]如何化简?如:15x+4x=19x[x是未知数]
备案号:鲁ICP备13029499号-2 说三道四 www.s3d4.cn