160 likes | 299 Views
第十章 位运算. 本章主要内容. C 语言既是一种高级语言,广泛应用于应用软件的开发和程序设计,同时又是一种低级语言,可以用于系统软件的开发和程序设计,如自动控制系统中的过程控制、参数检测、数据通讯等控制程序,都可以综合利用 C 语言中的指针操作、位运算和位段技术来实现。 本章介绍位运算的基本形式和常用运算符 , 并简要介绍位段的概念。位运算的深入学习,应该在 《 计算机原理 》 和 《 汇编语言程序设计 》 课程中进行。. 一、位运算符和位运算. 位运算概述 所谓“位运算”,是指按二进制位进行运算。 位运算的特点: 运算按二进制逐位进行 —— 没有借位和进位。
E N D
本章主要内容 • C语言既是一种高级语言,广泛应用于应用软件的开发和程序设计,同时又是一种低级语言,可以用于系统软件的开发和程序设计,如自动控制系统中的过程控制、参数检测、数据通讯等控制程序,都可以综合利用C语言中的指针操作、位运算和位段技术来实现。 • 本章介绍位运算的基本形式和常用运算符,并简要介绍位段的概念。位运算的深入学习,应该在《计算机原理》和《汇编语言程序设计》课程中进行。
一、位运算符和位运算 • 位运算概述 所谓“位运算”,是指按二进制位进行运算。 • 位运算的特点:运算按二进制逐位进行——没有借位和进位。 • 位运算量:整型(int,short,unsiged,long)/字符型(以补码/ASCII码形式存储),不可为实型。 • 位运算符:& | ^ ~ << >>
一、位运算符和位运算 • 位运算符还可与赋值运算符相结合,进行位运算赋值操作。如: a&=b 等价于 a=a&b a>>=b 等价于 a=a>>b • 注意:位运算时的数据类型为char/int,分析时要化为二进制形式,但在程序中书写及输出结果时仍为char/int。
位运算符的使用 • 按位与 &(均为1时方为1) 【例一】 main( ) { unsigned char a,b; printf(“Enter a and b:”); scanf(“%o,%o”,&a,&b); printf(“a&b=%o\n”,a&b); } 计算 010 000 (a) & 011 000 (b) 010 000 001 010 (a) & 010 000 (b) 000 000 Enter a and b: 20,30 a&b=20 Enter a and b: 12,20 a&b=0
位运算符的使用 • 按位或 |(均为0时方为0) 【例二】 main( ) { unsigned char a,b; printf(“Enter a and b:”); scanf(“%o,%o”,&a,&b); printf(“a | b=%o\n”,a|b); } 计算 010 000 (a) | 011 000 (b) 011 000 001 010 (a) | 010 000 (b) 011 010 Enter a and b: 20,30 a | b=30 Enter a and b: 12,20 a | b=32
位运算符的使用 • 按位异或 ^ (二者相异方为1) 【例三】以下程序的功能是将a数据的低4位取反。 #include <stdio.h> main() { unsigned char a=0x39, b=0x0F; a=a^b; printf("%x\n", a); } 计算 00111001 (a) ^ 00001111 (b) 00110110 答案:0x0f
位运算符的使用 • 按位取反 ~ (各位反转) 计算 ~ a: 补码: 11111100 原码: 10000100 ~ b: 补码:11110101 原码:10001011 【例四】 main( ) { char a=3; int b=10; printf(“~a=%d,~b=%d\n",~a,~b); } 结果:~a=-4,~b=-11
位运算符的使用 • 左移运算<< a<<n 将a中各位向左移n位,右端补0,高位溢出丢弃。 例: a= a<<n (可写为a<<=n),相当于a×2n(高位未溢出时) 【例五】以下程序的运行结果是 。 main() { unsigned int a=0x3ef,b; b=a<<2; printf("%x,%x\n",a,b); } A)3ef,fb B) 3ef,fbc C) fbc,3ef D) fbc,fbc 结果:B
位运算符的使用 计算 已知:0x1f5为1 1111 0101 且:∵a为1100 ∴a<<3为1100000 111110101 & 001100000 001100000 = 96 【例六】以下程序的运行结果是 。 main() { int a=12,b; b=0x1f5 & a<<3; printf("%d,%d\n",a,b); } • 左移运算<< 结果:12,96
位运算符的使用 • 右移运算>> a>>n 将a中各位右移n位,溢出则舍弃。 左端—— • a为正数时(符号位为0),填0; • a为负数时(符号位为1),填0或填1与系统有关 填0(逻辑右移) 填1(算术右移) TC使用算术右移
位运算符的使用 【例七】以下程序的运行结果是 。 main() { int a=9,b=-9; printf("%d,%d",a>>2,b>>2); } • 右移运算>> 结果:2,-3 (-9的补码 :1111111111110111, 右移后为1111111111111101)。
应用示例 ① 从整数a最右端第m个位置开始取该位开始右面n位 。 算法如下: b=a>>(m-n+1) c=~(~0<<n) d=b&c 注:位自右向左从0开始编号
应用示例 ② 将一个整数a循环右移n位。 算法如下: b=a<<(16-n) c=a>>n c=c|b
二、位段 • C语言允许在一个结构体中以位为单位来指定其成员所占内存长度。这种以位为单位的成员称为“位段”。
示例 struct data { int i; /*非位段*/ unsigned int a:3; /*占3位*/ unsigned int b:5; /*占5位*/ unsigned int :3; /*无名位段——不可用*/ unsigned int c:2; /*占2位*/ unsigned int :0; /*到下一字节起始处*/ unsigned int d:3; /*占3位*/ unsigned int :0; /*到下一字节起始处*/ float f; /*非位段*/ } ;