北京大学计算概论-:第10讲-复合数据结构-数组与结构ppt课件_第1页
北京大学计算概论-:第10讲-复合数据结构-数组与结构ppt课件_第2页
北京大学计算概论-:第10讲-复合数据结构-数组与结构ppt课件_第3页
北京大学计算概论-:第10讲-复合数据结构-数组与结构ppt课件_第4页
北京大学计算概论-:第10讲-复合数据结构-数组与结构ppt课件_第5页
已阅读5页,还剩69页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、第十讲:复合数据结构数组与结构北京大学 信息科学技术学院2019年11月:内容题要 复合数据结构 数组 构造 常见问题与错误 常见问题 编译错误 运行调试:数组:数组 是 什么?数组 是 一组变量数组 是 一组 具有编号 的 变量:如何声明 一个数组int sz10; 数组的类型数组名数组中变量的数目必须是一个常量:数组 中 变量 的 编号int sz10; 数组中变量的编号 从 0 开场; 到 数组的长度1 终了0 1 2 3 4 5 6 7 8 9:如何访问 数组 中 的 变量int sz10;sz0 = 1;sz1 = 3;sz2 = 7;sz8 = 16;sz9 = 12; sz2;

2、数组名变量编号:数组变量赋值 的 一种特殊方式 声明时赋值int sz5 =12, 3, 7, 28, -2; :#include int main()int sz10;int i;for( ; ; ) ;for(i = 0; i 10; i+)printf(%d , szi);return 0;程序填空;要求:1.接收用户输入的10个数字2.存放在数组sz中:#include int main()int sz10;int i;for( i=0 ; i 10 ; i+)scanf(%d, &(szi);for(i = 0; i 10; i+)printf(%d , szi);retur

3、n 0;:数组 的 遍历经过 循环结构:正向 遍历int szLEN; for(int i = 0; i = 0; i-) szi :通过遍历 实现 对 数组变量 的 控制台赋值int szLEN; for(int i = 0; i LEN; i+)scanf(“%d”, &(szi);:通过遍历 实现 对 数组变量 的 控制台输出int szLEN; for(int i = 0; i LEN; i+)printf(“%dn”, szi);:数组 的 应用示例当程序要处理一组类型相同、含义类似的数据时,应该使用数组:游戏:过年抽奖 一个村庄,有128个村民 村长对村民说: 今年村里出现

4、了财政盈余M元; M是20003000之间的一个整数 准备通过抽奖的方式把钱发给村民 游戏规则如下: 每个村民上报一个在20003000元之间的整数 如果有人上报的数字和M相等,就把钱发给这些人 如果只有一个村民猜对,就把M元钱全部发给他 如果有多个人村民猜对,就把M元钱平均分配给这些村民村长邀请我们编写一个程序, 实现村里财政盈余的自动分配:编程的基本思路 定义一个数组 存放所有村民上报的数据 定义一个数组 存放获奖者的编号幸运者数组) 定义一个整数 存放获奖者人数 对村民从0开始编号最后一个编号是127) 村民按照编号顺序上报数字;程序将村民上报的数字存放在对应编号的数组变量中。 遍历村民

5、上报的数字,若上报数字与幸运数相等,那么 将村民编号添加到幸运者数组中; 并将获奖者人数加1 最后,打印出获奖者编号和获得的奖金数额:#define LUCKY_M 2345#define LUCKY_M 2345 /财政盈余财政盈余#define POPULATION 128 #define POPULATION 128 /村民数量村民数量int main( )int main( ) int peoplePOPULATION; / int peoplePOPULATION; /记录所有村民上报数字的数组记录所有村民上报数字的数组 int luckyPeoplePOPULATION; / in

6、t luckyPeoplePOPULATION; /幸运者数组,记录获奖者编号幸运者数组,记录获奖者编号 int nLucky=0; / int nLucky=0; /获奖者人数获奖者人数 int i; / int i; /循环变量循环变量 for (i=0; iPOPULATION; i+) for (i=0; iPOPULATION; i+) scanf(“%d”, &(peoplei); / scanf(“%d”, &(peoplei); /读入村民报的数字,数组下标就是村民的编号读入村民报的数字,数组下标就是村民的编号 for (i=0; iPOPULATION; i+

7、) for (i=0; iPOPULATION; i+) if ( peoplei = LUCKY_M ) if ( peoplei = LUCKY_M ) luckyPeoplenLucky = i; luckyPeoplenLucky = i; nLucky +; nLucky +; / /输出获奖者编号及所获奖金数额输出获奖者编号及所获奖金数额 for (i=0; inLucky; i+) for (i=0; inLucky; i+) printf(%d %dn, luckyPeoplei, LUCKY_M / nLucky); printf(%d %dn, luckyPeoplei,

8、LUCKY_M / nLucky); return 0; return 0; :构造: 结构的概念结构的概念 通常,一个学生的个人信息,包括:学号、姓名、性别、年龄、各门功课的成绩等数据,这些数据都与一个学生相关联,类型各不相同。如果将这些数据定义为各独立的简单变量: Number、Name、Sex、Age、Course1、Course2、 这样就难以反映它们之间的内在联系。应该把它们组织成一个组合项,把它们当作一个有机的整体。这个组合项就是结构Structure)21:结构类型及其定义 把多个紧密关联的变量分量顺序组织在一起,定义成一个新的复合数据类型结构类型 定义一个结构类型 struct

9、 结构类型名 类型1 分量名1; 类型2 分量名2; . ; 结构分量的类型可以相同,也可不同 同一个结构内的分量名不可相同22struct point float x; float y;:结构类型变量的定义 结构类型只是定义了一种新的数据类型 系统并不为这个新类型分配内存空间。 可以使用新的结构类型来声明变量结构类型变量。 结构类型变量定义的两种形式: 用已定义的结构定义变量,例如:struct point point1;struct point point2; 定义结构的同时定义结构类型的变量,例如:struct city float x, y; int population; city1

10、, city2; 系统会为结构类型变量分配内存空间23:结构类型变量中分量的访问 结构类型变量的值由其各个分量构成 对分量的访问一般通过“变量名.分量名完成 结构赋值及访问的例子: float dx, dy; struct point float x, y; p1, p2, points2; p1.x = p1.y = 3.5f; p2.x = p2.y = 1.5f; dx = p1.x - p2.x; dy = p1.y - p2.y;24结构变量本身可以作为一个整体来使用结构变量本身可以作为一个整体来使用points0 = p1; points1 = p2;:25结构类型中的分量 结构类

11、型中分量的类型可以是任何类型 基本数据类型的分量 struct point float x, y; ; 其他类型的分量:结构类型、数组类型 分量的类型不能是未定义的结构类型 分量的类型不能是正在定义的结构类型struct city char name32; struct city city1;x;struct city struct point float x, y; location; int population; char name32;city1;struct city struct point location; int population; char name32;city1;

12、(city1.location).x:26结构变量的内存布局 结构中各分量在内存中顺序存放 struct square struct point int x, y; p1, p2; sq1; sq1.p1.x = 10; sq1.p1.y = 20; sq1.p2.x = 100; sq1.p2.y = 200;主存储器sq1.p1.x1020100200*sq1.p1.ysq1.p2.xsq1.p2.y:结构变量所占内存的大小 结构变量所占内存的大小并不完全等于于各分量所占字节数的总和 struct char_frequency char c; int frequency; ; sizeof

13、(strcut char_frequency)通常为8,而非5 这是编译器在编译时的一个特殊要求。27:结构应用示例1救援 洪水淹没了很多房子,只有屋顶还是安全的。被困的人们都爬上了屋顶。现在救生船每次都从大本营出发,到各屋顶救人,救了人之后将人送回大本营。 救生船每次从大本营出发,以速度50米/分钟时向下一个屋顶,达到一个屋顶后,救下其上的所有人,每人上船1分钟,船原路返回,达到大本营,每人下船0.5分钟。 假设大本营与任意一个屋顶的连线不穿过其它屋顶。 输入:第一行是屋顶数n,其后n行,每行是每个屋顶的坐标和人数 输出:第一行是所有人都到达大本营并登陆所用的时间,其后n行,每行是每个屋顶的

14、坐标和人数28:29NiiiipspeedyxtotalTime122)5 . 01 (2(图中原点是大本营,每个点代表屋顶,每个屋顶由其位置坐标和其上的人数表示。:30#include #include #include #define MAX_ROOF_NUM 1000#define SPEED 50.0#define UP 1.0#define DOWN 0.5int main() int roof_num; / 屋顶数屋顶数. scanf(%d, &roof_num); / 输入屋顶数输入屋顶数. struct roof float x, y; / 屋顶坐标屋顶坐标. int

15、p; / 屋顶上的人数屋顶上的人数. rfsMAX_ROOF_NUM; double totalTime = 0; / 救援总时间救援总时间. int i; / 循环控制变量循环控制变量. /用循环处理每一个屋顶,输入屋顶位置及人数数用循环处理每一个屋顶,输入屋顶位置及人数数. for (i=0; iroof_num; i+):31 /用循环处理每一个屋顶,输入屋顶位置及人数用循环处理每一个屋顶,输入屋顶位置及人数. for (i=0; iroof_num; i+ scanf(%f%f%d,&(rfsi.x), &(rfsi.y), &(rfsi.p); / 用循环处理

16、每一个屋顶,计算救援时间用循环处理每一个屋顶,计算救援时间 . for (i=0; iroof_num; i+) / 首先计算从大本营到屋顶的双程航行时间,并累加到总救援时间中首先计算从大本营到屋顶的双程航行时间,并累加到总救援时间中 . totalTime += 2 * sqrt(rfsi.x*rfsi.x + rfsi.y*rfsi.y) / SPEED; / 然后计算被求人员上船和下船所耗费的总时间,并累加到总救援时间中然后计算被求人员上船和下船所耗费的总时间,并累加到总救援时间中 . totalTime += rfsi.p * (UP + DOWN); / 打印出救援总时间打印出救援总

17、时间. printf(Total Time is: %.2lfn, totalTime); / 依次打印出各屋顶的位置及人数依次打印出各屋顶的位置及人数. for (i=0; iroof_num; i+) printf(Roof ID: %d %.2f %.2f %dn, i+1, rfsi.x, rfsi.y, rfsi.p); return 0;:32结构应用示例2学生成绩统计n定义一个结构,包含学生的所有信息。nstruct student n int number;n char name8;n char sex;n int age;n float course8; n;nstruct

18、student class1160;:33单个变量、数组和结构 数组和结构:多个变量的集合 数组 通过数组可定义大量类型相同的变量 数组元素通过“变量下标”形式访问 静态数组的大小数组元素的个数是预先确定的,即数组定义中数组个数必须是整数常量 构造 结构把一组密切相关的变量类型可以不同组织成一个整体 结构的分量通过变量. 分量形式访问:单个变量、数组和结构34n更加复杂的数据定义更加复杂的数据定义n结构中的数组结构中的数组n结构中的结构结构中的结构n结构数组结构数组:复杂结构示例:教师、学生、班级struct teacher_s / 教师结构教师结构 char name32; / 姓名姓名 c

19、har title16; / 职称职称 int age; / 年龄年龄;struct student_s / 学生结构学生结构 char name32; / 姓名姓名 char sex; / 性别性别 int age; / 年龄年龄;struct class_s / 班级结构班级结构 struct teacher_s teacher; / 教师教师 struct student_s students180; / 所有学生所有学生 int student_num; / 学生人数学生人数;:上机中的问题 和 错误:上机编写程序 的 基本流程第一步:按照题目要求, 在VC中编写、调试程序第二步:把调

20、试成功的程序 提交到编程网格中:问题:为什么 在VC的一个项目里面, 只能有一个main函数?VC的一个项目代表了一个C程序一个C程序只能具有一个main函数VC的一个项目里只能有一个main函数:问题:为什么 main函数需要返回一个int值?int main( ) return 0;用于表示:用于表示:在程序运行过程中是否发生了错误在程序运行过程中是否发生了错误返回值为返回值为0 0,表示:没有发生错误表示:没有发生错误在这们课程在这们课程涉及的程序涉及的程序中,返回值中,返回值固定为固定为 0 0 !:错误: include 语句前没有 # include include int mai

21、n( ) int main( ) return 0; return 0; #include #include int main( ) int main( ) return 0; return 0; :关于关系运算表达式int a, b, c;if(abc)int a, b, c;If(ab)&(bc):分支结构中的花括号if(ab)print(“%d”, a);print(“%d”, b);if(ab)print(“%d”, a);print(“%d”, b);if(ab)print(“%d”, a);print(“%d”, b);=:在任何情况下,scanf函数调用中都 不要出现 n

22、 scanf(“n”, ); :程序 的 书写风格int main() int result; int num; int i = 1; while(i result) result = num; i+; printf(“%dn”, result); return 0;int main()int result; int num; int i = 1; while(i result) result = num; i+; printf(“%dn”, result); return 0;:程序 的 书写风格风格1:每一行 最多 只写 一条语句 e = a; a = b; b = e; e = a; a

23、 = b; b = e; :程序 的 书写风格风格2:同一层次的语句 具有 相同的缩进#includeint main()int a, b, e;scanf(“%d %d”, &a, &b);if(a b)e = a; a = b; b = e;printf(“%d %dn”, a, b);return 0;缩进1缩进2缩进3:程序 的 书写风格if else 语句 的 书写风格if(a b)a += b;printf(“a b”); else b += a;printf(“a = b”);:程序 的 书写风格while语句 的 书写风格while(i 100)sum += i

24、;i+;:程序 的 书写风格for语句 的 书写风格for(int i = 0; i 100; i+)if(i%2 = 0)continue;sum += i;:程序 的 书写风格风格3:成对地 输入 左右花括号while(i 100)while(i 100)while(i 100)sum += i;i+;while(i 100)sum += i;i+;while(i 100)sum += i;i+;while(i 100)step 1step 2step 3step 1step 2step 3:编译出现错误时,请从第一个错误开始分析!:程序的调试程序的调试u 语法错误:编译语法错误:编译(

25、(组建组建) )错误错误u 不要惊慌,编译结果输出窗口已经为你指明不要惊慌,编译结果输出窗口已经为你指明了程序的出错行及错误原因,可以据此来修了程序的出错行及错误原因,可以据此来修改程序错误。改程序错误。u 改错时,应从出错信息中的第一条开始,用改错时,应从出错信息中的第一条开始,用鼠标双击该条信息,程序源文件窗口就将定鼠标双击该条信息,程序源文件窗口就将定位到出错行。位到出错行。u 很多时候,程序编译后会出很多错误,但很很多时候,程序编译后会出很多错误,但很可能是由第一个错误衍生而来的,改完第一可能是由第一个错误衍生而来的,改完第一个错误后,再编译时其他错误就不再出现了个错误后,再编译时其他

26、错误就不再出现了。所以,应该每修改完一个错误后就编译一。所以,应该每修改完一个错误后就编译一次。次。:二、关于程序的错误修改及调试二、关于程序的错误修改及调试 这里少了一个这里少了一个“”。双击第一行,定位错误及了解双击第一行,定位错误及了解错误原因!错误原因!这里的一堆错误,都是由于上这里的一堆错误,都是由于上面少了一个面少了一个“”引起的!引起的!:程序调试!程序调试!程序运行不正确,怎么办?:u运行结果错:程序跟踪调试运行结果错:程序跟踪调试u由于程序算法及其他原因,执行结果不正由于程序算法及其他原因,执行结果不正确,这时从源程序表面上就很难发现错误确,这时从源程序表面上就很难发现错误。

27、u跟踪调试:可以手动一步一步执行程序语跟踪调试:可以手动一步一步执行程序语句,在每条语句执行后,可以查看相关变句,在每条语句执行后,可以查看相关变量的值,以判断和预期结果是否相符;也量的值,以判断和预期结果是否相符;也可以了解程序的执行顺序,看它是否和预可以了解程序的执行顺序,看它是否和预期的程序流程相符。期的程序流程相符。u断点设定:在跟踪调试前,还需要确定一断点设定:在跟踪调试前,还需要确定一下程序可能从哪里出错,设置一个断点,下程序可能从哪里出错,设置一个断点,让程序在此停止自动运行,由我们手动一让程序在此停止自动运行,由我们手动一步一步发出程序执行命令。如果不能确定步一步发出程序执行命

28、令。如果不能确定程序是从哪里出错,则可以将断点设置在程序是从哪里出错,则可以将断点设置在程序的第一条语句处。程序的第一条语句处。程序的调试程序的调试:设置程序设置程序断点断点:跟踪方式跟踪方式执行程序执行程序查看变量值查看变量值当前程序执行当前程序执行停留在此行停留在此行程序手动执行程序手动执行 进入函数进入函数 一步一步执行一步一步执行 从函数中执行出来从函数中执行出来 执行到光标所在行执行到光标所在行:课堂参与请一个同学上来调试下面程序的问题所在/有一分数序列: 2/1, 3/2, 5/3, 8/5, 13/8, 21/13, . 求出这个数列的前n项之和。 #include int ma

29、in() int a, b, e, m, n, i, j;double sum=0.0;a=1;b=2;scanf(%d,&m);for(j=0;jm;j+)scanf(%d, &n);for(i=0;in;i+)sum += b/a;e = a;a = b;b = e+b;printf(%.3lfn,sum);return 0;:课堂练习课堂练习:练习1:接收用户输入的3个数字, 输出其中的最小值 程序输入 3个数字 程序输出 3个数字中的最小值课堂参与请一位同学上台, 编写上述程序:课堂参与练习2:判断一个整数能否被7整除 程序输入 一个整数 程序输出 如果这个整数能被7整

30、除,输出字符串 true; 否则,输出字符串false;请一位同学上台, 编写上述程序:练习3:判断一个整数的某个数位上是否存在数字7 问题描述 给定一个4位整数,判断这个数字的个位数、十位数、百位数和千位数这4个数字中是否存在数字7 程序输入 一个4位整数 程序输出 如果某个数位上的数字是7,输出字符串 true 否则,输出字符串 false课堂参与请一位同学上台, 编写上述程序:练习4:判断某一年是否是闰年 程序输入 一个表示年份的整数如,2019) 程序输出 如果这个年份是闰年,程序输出 true; 否则,程序输出false;闰年的充分必要条件是:“年份能被400整除”或者“年份能被4整

31、除,但不能被100整除”课堂参与请一位同学上台, 编写上述程序:1.接收从控制台输出的两个整数2. (假设是两个正整数)3.输出这两个数的最大公约数:#include int main() int a, b, t; scanf(%d%d, &a, &b); / a和b的最大共数也是b和a%b的最大公约数 t = a % b; while (t != 0) a = b; b = t; t = a % b; printf(%dn, b); return 0;:1.接收从控制台输出的一组整数 (假设输入n个整数,n = 100)2.按输入相反的顺序输出这组整数:#include #d

32、efine MAX 100int main() int aMAX, i, j, n, t; scanf(%d, &n); for (i = 0; i n; i+) scanf(%d, &ai); for (i = 0, j = n-1; i j; i+, j-) t = ai; ai = aj; aj = t; for (i = 0; i n; i+) printf(%dn, ai); return 0;:#include #define MAX 100int main() int aMAX, i, j, n, t; scanf(%d, &n); for (i = 0; i n; i+) scanf(%d, &ai); for (i = 0, j = n-1; i j; i+, j-) t = ai; ai = aj; aj = t; for (i = 0; i n; i+) printf(%dn, ai); return 0

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论