16
第第第 第第第

第十章 位运算

Embed Size (px)

DESCRIPTION

第十章 位运算. 本章主要内容. C 语言既是一种高级语言,广泛应用于应用软件的开发和程序设计,同时又是一种低级语言,可以用于系统软件的开发和程序设计,如自动控制系统中的过程控制、参数检测、数据通讯等控制程序,都可以综合利用 C 语言中的指针操作、位运算和位段技术来实现。 本章介绍位运算的基本形式和常用运算符 , 并简要介绍位段的概念。位运算的深入学习,应该在 《 计算机原理 》 和 《 汇编语言程序设计 》 课程中进行。. 一、位运算符和位运算. 位运算概述 所谓“位运算”,是指按二进制位进行运算。 位运算的特点: 运算按二进制逐位进行 —— 没有借位和进位。 - PowerPoint PPT Presentation

Citation preview

Page 1: 第十章 位运算

第十章 位运算

Page 2: 第十章 位运算

本章主要内容 C 语言既是一种高级语言,广泛应用于应用软件

的开发和程序设计,同时又是一种低级语言,可以用于系统软件的开发和程序设计,如自动控制系统中的过程控制、参数检测、数据通讯等控制程序,都可以综合利用 C 语言中的指针操作、位运算和位段技术来实现。

本章介绍位运算的基本形式和常用运算符 , 并简要介绍位段的概念。位运算的深入学习,应该在《计算机原理》和《汇编语言程序设计》课程中进行。

Page 3: 第十章 位运算

一、位运算符和位运算位运算概述所谓“位运算”,是指按二进制位进行运算。

位运算的特点:运算按二进制逐位进行——没有借位和进位。位运算量:整型( int,short,unsiged,long ) / 字符型(以补码 /ASCII 码形式存储),不可为实型。位运算符: & | ^ ~ << >>

Page 4: 第十章 位运算

一、位运算符和位运算 位运算符还可与赋值运算符相结合,进行

位运算赋值操作。如: a&=b 等价于 a=a&b

a>>=b 等价于 a=a>>b

注意:位运算时的数据类型为 char/int ,分析时要化为二进制形式,但在程序中书写及输出结果时仍为 char/int 。

Page 5: 第十章 位运算

位运算符的使用 按位与 & (均为 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,30a&b=20

Enter a and b: 12,20a&b=0

Page 6: 第十章 位运算

位运算符的使用 按位或 | (均为 0 时方为 0 ) 【例二】main( ){ unsigned char a,b; printf(“Enter a and b:”); scanf(“%o,%o”,&a,&b); printf(“a | b=%o\n”,a|b);}

Enter a and b: 20,30a | b=30

Enter a and b: 12,20a | b=32

计算 010 000 (a)

| 011 000 (b) 011 000

001 010 (a)

| 010 000 (b) 011 010

Page 7: 第十章 位运算

位运算符的使用 按位异或 ^ (二者相异方为 1 )

【例三】以下程序的功能是将 a 数据的低 4 位取反。#include <stdio.h>main(){ unsigned char a=0x39, b=0x0F; a=a^b; printf("%x\n", a);} 答案: 0x0f

计算 00111001 (a) ^ 00001111 (b)

00110110

Page 8: 第十章 位运算

位运算符的使用 按位取反 ~ (各位反转) 【例四】 main( ) { char a=3; int b=10; printf(“~a=%d,~b=%d\n",~a,~b); }

结果:~ a=-4 ,~ b=-11

计算~ a:补码 : 11111100原码 : 10000100

~ b:补码 :11110101原码 :10001011

Page 9: 第十章 位运算

位运算符的使用 左移运算 << 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

Page 10: 第十章 位运算

位运算符的使用 左移运算 <<

【例六】以下程序的运行结果是 。main(){ int a=12,b; b=0x1f5 & a<<3; printf("%d,%d\n",a,b);}

结果: 12 , 96

计算已知: 0x1f5 为 1 1111 0101且:∵ a 为 1100 ∴a<<3 为 1100000 111110101& 001100000

001100000 = 96

Page 11: 第十章 位运算

位运算符的使用 右移运算 >> a>>n 将 a 中各位右移 n 位,溢出则舍弃。左端——

a 为正数时(符号位为 0 ),填 0 ;a 为负数时(符号位为 1 ),填 0 或填 1 与系统有关

填 0 (逻辑右移) 填 1 (算术右移) TC 使用算术右移

Page 12: 第十章 位运算

位运算符的使用 右移运算 >>

【例七】以下程序的运行结果是 。main(){ int a=9,b=-9; printf("%d,%d",a>>2,b>>2);}

结果: 2 , -3 ( -9 的补码 : 1111111111110111 ,

右移后为 1111111111111101 )。

Page 13: 第十章 位运算

应用示例① 从整数 a 最右

端第 m 个位置开始取该位开始右面 n 位 。

算法如下: b=a>>(m-n+1)

c= ~ ( ~ 0<<n)

d=b&c

注:位自右向左从 0 开始编号

Page 14: 第十章 位运算

应用示例② 将一个整数a 循环右移 n 位。算法如下: b=a<<(16-n)

c=a>>n

c=c|b

Page 15: 第十章 位运算

二、位段 C 语言允许在一个结构体中以位为单位来

指定其成员所占内存长度。这种以位为单位的成员称为“位段”。

Page 16: 第十章 位运算

示例 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; /* 非位段 */ } ;