实验6(2019.6.4)
Posted zys-0119
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了实验6(2019.6.4)相关的知识,希望对你有一定的参考价值。
Part 1 【实验结论】
一、结构体类型及编程应用。
1、对程序ex1-2.cpp的补足。
首先,老师在实验6.pdf中给出了提示:
先在结构体数组stu中查找最低分;然后,查找成绩与最低分相同的学生,将其信息保存在数组t中。
然后按照提示一步步来就行了。
①在结构体数组stu中查找最低分。所以利用循环扫描一遍数据,从而找出最低分,用min存放最低分的数值。
从而有:
for(i=0;i<n;i++){ if(s[i].score<min){ min=s[i].score; } }
②查找成绩与最低分相同的学生,将其信息保存在数组t中。那就再扫描一遍,利用之前一经找好的min,通过条件s[i].score==min寻找,用j存放最低分学生的个数,顺便记入数组t中。
从而有:
for(i=0;i<n;i++){ if(min==s[i].score){ t[j++]=s[i]; } }
③返回最低分学生个数。即:return j;
三步分析完,完整的代码就出来了:
1 #include <stdio.h> 2 3 const int N=5; 4 5 // 定义结构体类型struct student,并定义STU为其别名 6 typedef struct student { 7 long no; 8 char name[20]; 9 int score; 10 }STU; 11 12 // 函数声明 13 void input(STU s[], int n); 14 int findMinlist(STU s[], STU t[], int n); 15 void output(STU s[], int n); 16 17 int main() { 18 STU stu[N], minlist[N]; 19 int count; 20 21 printf("录入%d个学生信息\\n", N); 22 input(stu, N); 23 24 printf("\\n统计最低分人数和学生信息...\\n"); 25 count = findMinlist(stu, minlist, N); 26 27 printf("\\n一共有%d个最低分,信息如下:\\n", count); 28 output(minlist, count); 29 30 return 0; 31 } 32 33 // 输入n个学生信息,存放在结构体数组s中 34 void input(STU s[], int n) { 35 int i; 36 for(i=0; i<n; i++) 37 scanf("%ld %s %d", &s[i].no, s[i].name, &s[i].score); 38 } 39 40 // 输出结构体s中n个元素信息 41 void output(STU s[], int n) { 42 int i; 43 for(i=0; i<n; i++) 44 printf("%ld %s %d\\n", s[i].no, s[i].name, s[i].score); 45 } 46 47 // 在结构体数组s中,查找最低分学生的记录,将其存入结构体数组s中 48 // 形参n是结构体数组s中元素个数 49 // 函数返回最低分的学生人数 50 int findMinlist(STU s[], STU t[], int n) { 51 // 补足函数实现 52 // ××× 53 int i,j=0; 54 int min; 55 min=s[0].score; 56 for(i=0;i<n;i++){ 57 if(s[i].score<min){ 58 min=s[i].score; 59 } 60 } 61 for(i=0;i<n;i++){ 62 if(min==s[i].score){ 63 t[j++]=s[i]; 64 } 65 } 66 return j; 67 }
运行结果如下:
2、对程序 ex1-3.cpp的补足。
虽说老师没有在pdf中给出过多的提示,但还是拆分任务看看,问题主要出在对process子函数的编写上面,下面对process子函数进行拆分。
①计算总分。
这个没什么好注意的,逐项计算总分就行了,有:
for(i=0;i<n;i++){ s[i].sum=s[i].objective+s[i].subjective; }
②排序(从高到低)。
这里我使用了冒泡法排序,当然用选择法排序也可以。
那么有:
for(i=0;i<n-1;i++){ for(j=0;j<n-1-i;j++){ if(s[j].sum<s[j+1].sum){ t=s[j]; s[j]=s[j+1]; s[j+1]=t; } } }
这里的t,注意其定义是STU t,因为这是在结构体中进行冒泡排序操作,所以数组t也应该在结构体中。
这和上一个例子有所不同,上个例子t是在形参中定义的。所以这里需要在子函数内部进行定义。
③排定等级。
按照这个思路:i)第一名,即i=0时,为优秀。
ii)第二名至第五名,即i=1,2,3,4时,为合格。
iii)第六名至第十名,即i=5,6,7,8,9时,为不合格。
那么,就有:
strcpy(s[0].level,"优秀"); for(i=1;i<=4;i++){ strcpy(s[i].level,"合格"); } for(i=5;i<=9;i++){ strcpy(s[i].level,"不合格"); } }
注意:这里不能写成s[i].level=“合格”,因为这里的level是数组元素,所以需要用strcpy()函数。(这点很重要,但也很容易被遗忘)
整理一下,结合输入输出模块,可得完整代码:
1 #include <stdio.h> 2 #include <string.h> 3 const int N = 10; 4 5 // 定义结构体类型struct student,并定义其别名为STU 6 typedef struct student { 7 long int id; 8 char name[20]; 9 float objective; /*客观题得分*/ 10 float subjective; /*操作题得分*/ 11 float sum; 12 char level[10]; 13 }STU; 14 15 // 函数声明 16 void input(STU s[], int n); 17 void output(STU s[], int n); 18 void process(STU s[], int n); 19 20 int main() { 21 STU stu[N]; 22 23 printf("录入%d个考生信息: 准考证号,姓名,客观题得分(<=40),操作题得分(<=60)\\n", N); 24 input(stu, N); 25 26 printf("\\n对考生信息进行处理: 计算总分,确定等级\\n"); 27 process(stu, N); 28 29 printf("\\n打印考生完整信息: 准考证号,姓名,客观题得分,操作题得分,总分,等级\\n"); 30 output(stu, N); 31 32 return 0; 33 } 34 35 // 录入考生信息:准考证号,姓名,客观题得分,操作题得分 36 void input(STU s[], int n) { 37 // 补足代码 38 // ××× 39 int i; 40 for(i=0;i<n;i++){ 41 scanf("%ld %s %f %f",&s[i].id,s[i].name,&s[i].objective,&s[i].subjective); 42 } 43 } 44 45 //输出考生完整信息: 准考证号,姓名,客观题得分,操作题得分,总分,等级 46 void output(STU s[], int n) { 47 // 补足代码 48 // ××× 49 int i; 50 for(i=0;i<n;i++){ 51 printf("%ld %s %f %f %f %s\\n",s[i].id,s[i].name,s[i].objective,s[i].subjective,s[i].sum,s[i].level); 52 } 53 } 54 55 // 对考生信息进行处理:计算总分,排序,确定等级 56 void process(STU s[], int n) { 57 // 补足代码 58 // ××× 59 int i,j; 60 STU t; 61 //计算总分 62 for(i=0;i<n;i++){ 63 s[i].sum=s[i].objective+s[i].subjective; 64 } 65 //冒泡法排序 66 for(i=0;i<n-1;i++){ 67 for(j=0;j<n-1-i;j++){ 68 if(s[j].sum<s[j+1].sum){ 69 t=s[j]; 70 s[j]=s[j+1]; 71 s[j+1]=t; 72 } 73 } 74 } 75 //确定等级 76 strcpy(s[0].level,"优秀"); 77 for(i=1;i<=4;i++){ 78 strcpy(s[i].level,"合格"); 79 } 80 for(i=5;i<=9;i++){ 81 strcpy(s[i].level,"不合格"); 82 } 83 }
运行结果如下:
PS:库里球迷不要黑我。。。。。。因为他没系统的学过C语言,纯当是自学吧。。。。。。(拿总冠军更重要)
二、共用体类型及编程实例。
▲共用体与结构体类型的区别。
(PS:此处引用课外参考书的一段话,比我自己总结的要更专业、简练些)
1、共用体变量在定义的同时只能用第一个成员的类型值进行初始化。
2、因为共用体变量中的所有成员共享一段公共存储区,所以共用体变量所占内存字节数与其成员中所占字节数最多的那个成员相等;而结构体变量中的每个成员分别占有独立的存储空间,所以结构体变量所占内存字节数是其成员所占字节数的总和。(总之就是共用体占用内存空间比结构体少)
3、因为共用体变量中的所有成员共享存储空间,所以变量中所有成员的首地址相同,而且变量的地址也就是该变量成员的地址。
三、枚举类型及编程示例。
1、枚举类型用于描述整型常量。
2、枚举类型使用过程中的注意事项。
(1)枚举类型不能直接输入输出。
(2)枚举类型可以隐含转换为int类型,但int类型转换为枚举类型必须显式转换。
Part 2 【实验总结与体会】
具体的总结都在Part1 部分了,结构体这个东西就相当于由一些数组和数据组成的表格,还是建立在前几章的基础上。 在编写这次实验代码的过程中,遭遇了很多问题,也调试了很多次,总之还是因为前面的内容掌握的不好,还得多加复习。
一些套路,比如冒泡法排序、选择法排序、在结构体中找出最大的项目和最小的项目、找出/输出质数等,还需要总结与练习,考试可以往里面套。
--The End--
谢谢大家的阅读与评论。
以上是关于实验6(2019.6.4)的主要内容,如果未能解决你的问题,请参考以下文章
[NTUSTISC pwn LAB 7]Return to libc实验(puts泄露libc中gadget片段定位)