1 / 38

第11单元 * 结构体与共用体 * 位运算

第11单元 * 结构体与共用体 * 位运算. 学习要求. 一般了解结构体变量的定义、引用 一般了解共用体变量的定义、引用 一般了解枚举类型 一般了解自定义类型 一般了解位运算符和位运算. 问题提出. 管理学生档案:假设每个学生信息包括学号、姓名、性别、年龄、成绩、地址。. 这些信息是一个整体,相互联系。在管理时如果以学生为一个管理单位,将这些数据组合在一起,将便于引用。这样的数据结构称为 “ 结构体 ” 。在其他高级语言中称为 “ 记录 ” 。. 解决办法. struct student{ // 声明结构体 struct student

tarala
Download Presentation

第11单元 * 结构体与共用体 * 位运算

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. 第11单元*结构体与共用体*位运算

  2. 学习要求 • 一般了解结构体变量的定义、引用 • 一般了解共用体变量的定义、引用 • 一般了解枚举类型 • 一般了解自定义类型 • 一般了解位运算符和位运算

  3. 问题提出 • 管理学生档案:假设每个学生信息包括学号、姓名、性别、年龄、成绩、地址。 • 这些信息是一个整体,相互联系。在管理时如果以学生为一个管理单位,将这些数据组合在一起,将便于引用。这样的数据结构称为“结构体”。在其他高级语言中称为“记录” 。

  4. 解决办法 struct student{ //声明结构体struct student int num; char name[20]; char sex; int age; float score; char addr[40]; }; struct student stu1={10010,"Liping",'M',19,87.5,"Bejing"};//定义结构体变量 printf(“%s,%s”,stu1.name,stu1.addr); //引用结构体变量的成员

  5. 概述 • 基本数据类型包括整型、实型、字符型。 • 数组属于构造类型数据,数组中各元素属于同一基本类型。 • 结构体就是将各种类型的数据组合成一个有机的整体。结构体的成员可以是不同的数据类型。

  6. 声明结构体 • 形式: • struct 结构体名{ • 成员表列 • }; • 说明: • 成员表列的每个成员都应进行类型说明 • 格式:类型名 成员名; 分号不能少!

  7. 例:声明一个日期结构体 • 日期包含年月日,可以这样声明 struct date{ int year; int month; int day; };

  8. 还可以直接定义,不出现结构体名 定义结构体变量 • 先声明结构体,再定义结构体变量。如: struct student stu1,stu2; struct date birthday; • 在声明结构体的同时定义变量。如: struct date{ int year; int month; int day; }birthday; struct student{ int num; char name[20]; char sex; int age; float score; char addr[40]; }stu1,stu2;

  9. 结构体类型的几点说明 • 类型与变量是两个概念。在编译时类型不分配空间,只对变量分配空间,可以对变量进行读写。 • 结构体中的成员,又称为域(field),可以单独使用。地位与变量相当。引用方法: • 结构体变量名.成员名 • 例:birthday.month • 例:stu1.age

  10. 结构体成员可以是结构体 struct date{ int year; int month; int day; }; struct student{ int num; char name[20]; char sex; struct date birthday; float score; char addr[40]; }stu1,stu2; struct student结构 引用name: stu1.name 引用day: stu1.birthday.day

  11. 结构体变量的引用 • 只能引用结构体变量的成员,与变量一样使用(赋值、计算、输出、求地址)。不能整体引用结构体变量。 • stu1.num=10010; • scanf(“%s”,stu1.name); • sum=stu1.score+stu2.score; • stu1.age++; • printf(“%c”,stu1.sex); • struct student *p=&stu1; //stu1首地址 • char *q=&stu1.name; //stu1成员name的首地址

  12. 结构体变量的初始化 • 可以象变量或数组一样,在定义时初始化。 void main() { struct student{ int num; char name[20]; char sex; int age; float score; char addr[40]; } stu1={10010,"Lining",'M',19,87.5,"Bejing"}; ; struct student stu1={10010,"Liping",'M',19,87.5,"Bejing"};

  13. 结构体数组 • 一个结构体变量可以放一组数据(一个学生的信息);若干个学生的信息可以用结构体数组存放。 请思考如何定义数组、初始化、输入、引用。 编程求平均成绩、输出成绩最好的学生信息。

  14. 结构体数组的定义和引用 • 声明结构体同时定义数组: • struct student {……} stu[10]; • 先声明结构体,再定义结构体数组: • struct student {……}; • struct student stu[10]; • 可以定义并同时初始化: • struct student stu[10]={{10010,"Liping",'M',19,87.5,"Bejing"},{},……}; • 引用: • stu[i].score

  15. p p++ *指向结构体指针 struct student • 结构体变量的指针(地址)就是该结构体变量所占据的内存段的起始地址。可以通过指针变量指向结构体变量。 • 注意结构体指针的+1运算指针怎么移动?

  16. *学生例题改用指针解决 • 定义一个指向结构体的指针变量: • sturct student *p; • 指向数组: • p=stu; • 引用: • (*p).score //注意必须加括号 • 指针移动: • p++

  17. *几点说明 • 定义指向结构体的指针变量p,可以将结构体变量的起始地址赋给p。 • (*p)指向结构体变量,(*p).成员名指向结构体变量的成员。注意:必须加括号。*p.成员名相当于*(p.成员名)。 • 指向成员也可用形式: • p->成员名 • 结构体变量.成员名== (*p).成员名==p->成员名 等效 等效

  18. 例题:投票统计 • 有3个人,张三,李四,王五,10个人参加投票,得票最高的当选。 • 声明一个结构体,包括姓名和票数两个成员 • struct person{ • char name[20]; • int count; • }; • 定义一个struct person的数组,三个数组元素 • struct person leader[3]={{“张三”,0}, {“李四”,0},{“王五”,0}}; • 用循环进行投票(输入姓名),统计相应得票数 • 找出得票最多的那个人

  19. **共用体 • 使几个不同的变量共同占用一段内存地址的结构称为“共用体”类型的结构。 • 定义共用体类型变量的形式: • union 共用体名{ • 成员表列 • }变量表列; • 引用共用体变量: • 共用体变量名.成员名

  20. **共用体 引用: a.i=10; printf(“%c”,a.ch); 不能整体引用共用体变量 定义: union data{ int i; char ch; float f; }a,b,c; 或定义好union data后,再 union data a,b,c;

  21. **共用体与结构体区别 • 共用体所占内存字节数是最大的成员的字节数;结构体所占内存字节数是所有成员的字节数和。 • 共用体某个时刻只有一个成员在起作用;结构体每个成员都有自己的空间,各自独立存在。 • a.i=10; • a.ch=‘a’; • a.f=1.5; //前面两条语句失去意义,a.i和a.ch不能再引用 • 共用体所有成员的地址相同;结构体每个成员地址不同。 • 不能把共用体变量作为函数参数,结构体可以。

  22. **枚举类型 • 如果一个变量只有几种可能,可以定义为枚举类型。 • “枚举”:将变量的值一一列举出来。变量的值只限于列举出来的值。 • 声明枚举类型用enum开头。 • 例:enum weekday {sun,mon,tue,wed,thu,fri,sat}; • 对于编译系统,将枚举元素作为常量处理,按定义顺序使它们的值为0,1,…… • 定义枚举类型的变量: • enum weekday workday; • workday=mon; • printf(“%d”,workday); //打印出1

  23. **用typedef定义类型 • 用typedef声明新的类型名来代替已有的类型名。 • 例: • typedef int INTEGER; • typedef float REAL; • INTEGER a,b; //等效 int a,b; • REAL x,y; //等效 float x,y; • typedef并不创建新的类型,只是创建了便于使用的标签。 • typedef与#define不同:typedef解释由编译器,#define是预处理。 typedef给出的符号仅限于类型,#define是文本替代。

  24. *位运算 • 位运算是指对二进制位的运算。 • 系统软件的编写、计算机的检测和控制都要用到位运算。 • 可以向远程设备发送一两个字节来控制该设备,其中的每一位都有特定的含义。 • 可以使用代表特定项目的特定位来存储操作系统的关于文件的信息。 • 许多压缩和加密操作都对单独的位进行操作。

  25. *位运算符和位运算

  26. 00000011 & 00000101 00000001 *位运算实例 计算:3&5 =1 可以利用按位与运算取二进制的某些(个)位: 设计一个数,将需要保留的这些位上置1,其余位置0,进行按位与运算。 思考:有个数01010101(84),想保留左起1、2、4位? 实例: IP地址:10.11.168.69 子网掩码:255.255.255.0 进行位与运算,找出网段

  27. 00000011 | 00000101 00000111 *位运算实例 计算:3|5 =7 可以利用按位或运算使二进制的某些(个)位置1: 设计一个数,将需要置1的这些位上置1,其余位置0,进行按位或运算。 思考:有个数00110000,将高4位保留,低4位全部置1?

  28. ~ 00000011 11111100 *位运算实例 计算:~3 = -4 思考:要使某个整数a的最低位为0,其余各位保留。怎么实现?(要保证算式对于2字节或4字节系统都正确) 对于2字节:a&0177776 对于4字节:a&037777777776 统一:a&~1

  29. 00000011 ^ 00000101 00000110 *位运算实例 可以利用按位异或运算,使特定位翻转(1变0,0变1): 设计一个数,将需要翻转的位置1,其余置0,进行按位异或运算。 思考:将01111010低4位翻转? 计算:3^5 = 6 思考:假设 int a=3,b=4; 执行:a=a^b;b=b^a;a=a^b; 问a,b值? 前2:b=b^(a^b)=b^b^a=0^a=a 第3:a=a^b^a=a^a^b=0^b=b 不要中间变量交换两个变量的值

  30. *位运算实例 • a=15,计算a<<2=? • 00001111左移2位=00111100,答案为60。 • 左移1位运算相当于乘以2 • a=64,计算a>>2=? • 01000000右移2位=00010000,答案为16。 • 右移1位运算相当于除以2

  31. *位运算实例 • 取一个整数右端开始的4~7位。 • 右移4位,使这4位为最低4位; • 取最低4位为1、其余各位为0的数(表示为~(~0<<4)) ,进行按位与运算;

  32. *位运算实例 • 循环移位:将16位整数a右循环移动n位。 • 将a右端n位放到b中的高n位(a左移16-n位); • 将a右移n位; • 将a与b进行按位或运算; a

  33. 实验指导 • 定义一个结构体变量(包括年、月、日)。输入一个日期,计算该日在本年中是第几天? • 提示: • 用数组表示每个月的天数 • int a[12]={31,28,31,30,31,30,31,31,30,31,30,31}; • 注意闰年的判断:如果是闰年,a[1]=29; • 计算第几天,将这个月之前的月份天数相加再加上日子。

  34. 实验指导 • 设计一个函数print,输出一个学生的成绩数组,该数组中有3个学生的数据记录,每个记录包括编号num、姓名name、成绩数组score[3],用主函数输入这些记录,用print函数输出这些记录。 • 定义结构体:必须在程序开始的位置定义,不能在main中定义 struct student{ int num; char name[20]; int score[3]; }; • 定义函数: void print(struct student p){ printf("%d,%s,%d,%d,%d\n",p.num,p.name,p.score[0], p.score[1],p.score[2]); }

  35. 实验指导 • 有3个学生,每个学生的数据包括学号、姓名、3门课程的成绩。从键盘输入这3个学生的数据,然后打印出3门课程的总平均成绩,以及最高分的学生的数据。 • 在上一题的基础上完成。 • 引用分数: • stu[i].score[k] //表示第i个学生的第k门课程成绩 • 计算每人的平均分 • 找最高平均分是谁

  36. **实验指导 • 实现从一个整数a中取出自右端开始的n~m位。 • 选做:参考课件。

  37. **实验指导 • 实现对一个整数进行左右循环移位。要求要循环位移的数a是一个八进制数,同时,移动位数n小于0时表示左移;大于0时表示右移。 • 选做:参考课件。

  38. **实验指导 • 实现在任意给出一个数的原码时,能够得到该数的补码。 • 选做。 • 提示: • 正数补码:与原码相同 • 负数补码:高位外取反+1

More Related