当前位置:
文档之家› C语言程序设计案例教程课件 第十二章 位的运算
C语言程序设计案例教程课件 第十二章 位的运算
12.2 位 段
#include<stdio.h> int main() {
struct cbit {
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;
相关概念
(1) 位段的定义与结构体的定义相仿;格式如下: struct 位段结构名 { 类型说明符1 位段名1:位段长度1; //最低位; 类型说明符2 位段名2:位段长度2; //次低位; 类型说明符3 位段名3:位段长度3; ...... 类型说明符N 位段名N:位段长度M; //最高位; };
return 0;
}
12.1.1 按位与运算符(&)
实例分析 设a=84(二进制为01010100),把其中从左边算起的 第3,4,5,7,8位保留下来。
12.1.2 “按位或”运算符(|)
基本形式 或运算的基本格式为:a | b
12.1.2 按位或运算符(|)
#include <stdio.h>
12.1.4 取反运算符(~)
#include <stdio.h> int main() {
int a=077; printf("%d",~a); return 0; }
程序运行结果如下: 192
12.1.5 左移运算符(<<)
基本形式
左移运算的基本格式为: a<<n
功能:左移运算符是用来将一个数的各二进制位左 移若干位,移动的位数由右操作数指定(右操作数必须 是非负值),其右边空出的位用0填补,高位左移溢出 则舍弃该高位。
pbit -> a = 0; pbit -> b &= 3; pbit -> c |= 1; printf("%d,%d,%d\n", pbit -> a, pbit -> b, pbit -> c); return 0; }
程序运行结果如下: 1,7,15 0,3,15
小型案例
问题: 对一无符号整数x进行右循环移y位后再取 其从右端开始的m—n位。
作业
1、教材第十二章课后习题。 2、作业集第十二章。
printf("请输入口令密码: "); scanf("%d",& code ); password =code>>2; printf("加密秘钥是:%d\n",password); system("PAUSE"); system("CLS"); printf("请输入登录口令: "); scanf("%d",&login); login==password?printf("正确,欢迎进入"):printf("不正确, 不能使用"); }
的按位运算。
12.1.1 “按位与”运算符(&)
基本形式 与运算的基本格式为:a & b
12.1.1 按位与运算符(&)
#include <stdio.h> int main( ) {
程序运行结果如下: a=84 b=59 c=16
int a=84,b=59,c;
c=a&b;
printf("a=%d\t b=%d\t c=%d\n",a,b,c);
(2) 如果相邻的两个位段字段的类型相同,且其位宽之和大于 其类型的sizeof()大小,则后面的位段字段将从下一个存储单元的 起始地址处开始存放,其偏移量恰好为其类型的sizeof()大小的整 数倍;
(3) 如果相邻的两个位段字段的类型不同,则各个编译器的具 体实现有差异,VC6采取不压缩方式,GCC和Dev-C++都采用压缩 方式;
12.2 位 段
相关概念 (2) 位段变量的说明与结构体变量的说明方式相同;可采用 两种方式:
先定义后说明、同时定义说明; (3) 位段变量的使用与结构体变量的使用法相同,有两 种形式:
变量: 位段变量名.位段名 指针: 位段指针名->位段名
12.2 位 段
位段的存储规则
(1) 如果相邻的两个位段字段的类型相同,且其位宽之和小于 其类型的sizeof()大小,则其后面的位段字段将紧邻前一个字段存 储,直到不能容纳为止;
➢相关知识 理解位运算:按位与、或、异或、取反、左移和右移
第12章 位运算
➢12.1 位的运算 ➢12.2 位段
学习目标
12.1 位的运算
掌握位运算符的概念 熟练应用常用的位运算
12.1 位的运算
运算符 名称
使用格式
运算符 名称
使用格式
&
按位与 表达式1&表达式2 ~
按位取反 ~表达式
|
按位或 表达式1|表达式2 <<
return 0;
}
12.1.3 异或运算符(∧)
实例分析 将八进制721与八进制52进行按位异或运算。
12.1.4 “取反”运算符(~)
基本形式 取反运算的基本格式为: ~ a
12.1.4 取反运算符(~)
实例分析 将八进制77进行按位取反运算。
先将77(8)化成二进制111111(2) 然后进行取反:~111111=000000
12.2 位 段
位段的存储规则 (4) 如果位段字段之间穿插着非位段字段,则不 进行压缩; (5)整个位段结构体的大小为其最宽基本类型成员 大小的整数倍; (6) 位段字段在内存中的位置是按照从低位向高 位的顺序放置的; (7) 取地址操作符&不能应用在位段字段上;
12.2 位 段
实例分析 编写程序输出各个位段的值。
12.1.6 右移运算符(>>)
#include<stdio.h>
int main() {
int a=-9, x=0;
程序运行结果如下: -9>>1=-5
x=a>>1;
printf("%d >>1=%d\n", a, x);
return 0;
}
12.2 位 段
学习目标 熟练位段的定义及使用方法
12.2 位 段
12.1.6 右移运算符(>>)
实例分析
编写程序实现对-9右移1位的功能。
分析:当对负数进行右移操作,左端补1不补0。-9右移一位的过程如下: ①-9的原码形式: 1000000000001001 最高位的1表示该数为负数 ②-9的反码形式: 1111111111110110 最高位不变,其余各位取反 ③-9的补码形式: 1111111111110111 对反码加1 ④右移1位-9>>1: 11111111111110111 挤掉右端1位,左端补1 ⑤求-9>>1的反码: 1111111111111010 对补码减1而得 ⑥求-9>>1的原码: 1000000000000101 反码最高位不变,其余取反 因此,-9>>1的值由-9变为-5。
int main( )
{
int a=060; int b=017; int c;
程序运行结果如下: a=48 b=15 c=63
c=a|b;
printf("a=%d\t b=%d\t c=%d\n",a,b,c);
return 0;
}
12.1.2 按位或运算符(|)
实例分析 将八进制60与八进制17进行按位或运算。
12.1.5 左移运算符(<<)
#include <stdio.h> int main() {
int a=15; printf("%d",a<<2); return 0; }
程序运行结果如下: 60
12.1.5 左移运算符(<<)
实例分析 若a=15,将a的二进制数左移2位。
说明:左移1位相当于该数乘以2,左移2位相当于 该数乘以2*2=4,15<<2=60,即乘了4。
12.1.6 右移运算符(>>)
基本形式
右移运算的基本格式为: a>>n 功能:右移运算符是用来将一个数的各二进制位 右移若干位,移动的位数由右操作数指定(右操作数 必须是非负值),移到右端的低位被舍弃,对于无符 号数,高位补0。对于有符号数,取决于所使用的系统 :高位补0的称为“逻辑右移”,高位补1的称为“算 术右移”。
小型案例
分析: 第一步:将无符号整数x进行右循环移y位。
无符号整数x右循环移y位后,x中原来左面(16-y)位右移y位, 原来右端y位移至最左面y位。现系统设用2个字节存放一个无 符号整数。
小型案例
分析: 第二步:取其从右端开始的m—n位。
代码:
小型案例
小型案例
第12章 位运算
【例】数据加解密文件。 #include <stdio.h> main() {int code ,password ,login;
C语言程序设计
课程回顾
1、标识符的定义规则? 2、C语言的基本数据类型有哪些? 3、运算符的类型及优先级。
任务 生成加密秘钥实例
➢任务描述 安全验证2.0版本,为了进一步提计算 机的安全性,希望程序员小王编写一 个加密口令验证模块,在进入计算机 系统前,两层保证用户的合法性。如 何实现呢?(利用位运算符)