C语言博客作业--结构体
一、PTA实验作业
函数题 题目1:结构体数组按总分排序
1.本题PTA提交列表
2.设计思路
void calc(struct student *p,int n)//计算每个人成绩总和的函数
struct student *pos
for pos=p to pos<p+n pos++
pos->sum=pos->score[0]+pos->score[1]+pos->score[2]
end for //计算每个人成绩的总和
void sort(struct student *p,int n)
struct student *min=p,temp;
int i,j,index;
for i=0 to i<n-1 i++
index=i;
for j=i+1 to j<n j++
if(p[index].sum<min[j].sum)
index=j;
end for//运用选择排序法,查找每次循环中总成绩最大学生的下标
temp=min[index];
min[index]=p[i];
p[i]=temp;
end for//查找完之后,该下标的学生的全体信息与前面下标为i的学生的全体信息进行互换
3.代码截图
4.本题调试过程碰到问题及PTA提交列表情况说明
-
问题:对选择排序法运用的还是不很熟练,最开始写选择排序的时候,在互换两结构成员信息的时候,自己粗心大意,
让p[i]=min[index],应该让p[i]=temp,一直认为是循环的问题,检查了半天都没检查出来,最后通过调试,发现经过这个部分学生信息的互换并没有达到预期的目的,所以此处出现了错误
-
解决方法:把p[i]=min[index]改为p[i]=temp,
答案正确
编程题--题目2.计算职工工资
1.本题PTA提交列表
2.设计思路
struct worker{/*定义结构*/
char name[10
float zbpay;
float fdpay;
float zc;
float sfpay;
};//该结构体表示员工的姓名,基本工资,浮动工资,支出,实发工资
int N,i,j;
scanf("%d",&N);
struct worker workers[N];//定义结构体数组
for i=0 to i<N i++
scanf("%s%f%f%f",workers[i].name,&workers[i].zbpay,&workers[i].fdpay,&workers[i].zc);
workers[i].sfpay=workers[i].zbpay+workers[i].fdpay-workers[i].zc;
end for//实现员工信息的输入,并计算实发工资
for j=0 to j<N j++)
printf("%s %.2f\n",workers[j].name,workers[j].sfpay)
end for//输出每个员工的姓名和实发工资
3.代码截图
4.本题调试过程碰到问题及PTA提交列表情况说明
- 问题:定义的数组被越界了,
一开始定义的结构体数组为 - 解决方法:首先我认为,一般的段错误大部分是数组越界的问题,所以我让输入的N作为结构体数组的数组长度,这样不管N多大都不会越界了,
编程题--题目3. 通讯录的录入与显示
1.本题PTA提交列表
2.设计思路
struct imformation{
char name[20];
char birthday[20];
char sex[2];
char imphone[19];/*im为固定英文immobilization的头两个字母*/
char mophone[19];/*mo为移动英文mobile的头两个字母*/
};//该结构体表示朋友的名字,出生日期,性别,固定电话,手机
int N,i,n,j,k;
scanf("%d",&N);
struct imformation friends[N];//定义结构体数组,数组长度为N,避免段错误
for i=0 to i<N i++
scanf("%s%s%s%s%s",friends[i].name,friends[i].birthday,friends[i].sex,friends[i].imphone,friends[i].mophone);
end for//输入结构体数组每个朋友的信息
scanf("%d",&n);//输入查询次数
int number[n];//定义一个普通数组
for j=0 to j<n j++
scanf("%d",&number[j])
end for //把要查询的编号存入普通数组
for i=0 to i<n i++
if(number[i]>=0&&number[i]<N) printf("%s %s %s %s %s\n",friends[number[i]].name,friends[number[i]].imphone,friends[number[i]].mophone,friends[number[i]].sex,friends[number[i]].birthday);
else printf("Not Found\n");
end for// 遍历普通数组,如果数组的元素(就是编号)在0到N-1之内则输出 ,否则输出Not Found
3.代码截图
4.本题调试过程碰到问题及PTA提交列表情况说明
- 问题:最开始定义结构体是这样的:
年月日是整型,所以输入的时候在年月日之间通过加上‘/'实现输入,输出的时候
通过加上‘/'实现输出,虽然答案正确但是这样的答案并不是PTA想要的 - 解决方法:,年月日与‘/’通过字符串输入,再通过字符串方式输出,发现答案正确,可能PTA就是想让‘/’与年月日一起输入输出,而不是通过在输入与输出语句中打出‘/’的方式,而‘/’为字符,所以也就需要把年月日定义为字符型,因此字符串是最好的选择。
二、截图本周题目集的PTA最后排名
三、阅读代码
1.本题要求实现函数,可以返回一个给定月份的英文名称
我的代码
- 优点:本代码使用了指针指向数组,先把月份英文名称存放进数组,根据输入的n判断月份再通过指针变量s来返回月份对应数组的首地址,比起我用switch语句来一个一个选择月份,少了许多的代码量,也方便理解,还不需要定义二维字符数组
- 学会了使用指针指向多个数组
2.请编写一个函数fun,函数的功能是:输入一个字符串,过滤此串,只保留串中的字母字符,并统计新生成串中包含的字母个数。
优点:巧妙运用指针,在第一个非字母元素前所有字母元素都保持原位,j++用于计算字母个数,也用于存放下一个字母元素。碰到非字母元素就跳过,接着继续遍历数组,寻找字母元素,找到就存放进(pre+j),同时j++,计算字母个数的同时,按顺腾出下一个位置存放字母元素,直到数组遍历完后,跳过了所有非字母元素,按顺序存放了所有字母元素,最后让(pre+j)为空字符,作为结束标志。- 学会了巧妙运用指针重新给自己赋值的方法,这种方法还可以试用其他类型相似的题目比如删除空格字符或者其它一些给定的字符。
四、本周学习总结
1.总结本周学习内容
1.1 结构体、共用体、枚举这种构造数据类型特点
- 结构体:结构体和数组一样都是构造型数据类型,和数组不同的是,结构体可以处理不同类型的数据,结构体里还可以有结构体类型、共用体的类型的数据。
struct a{
类项名 结构成员
类项名 结构成员
};
struct 结构名{
类型名 结构成员1
类项名 结构成员2
struct a 结构成员3
}结构体变量名表;
- 共用体:共用体是一种多变量共享存储空间的构造类型,它允许几种不同的变量共用同一存储空间,共用体空间等于最大成员占据的空间且共用体不能赋初值。
struct 结构名{
类型名 结构成员1
类项名 结构成员2
union 类项名{
类项名 结构成员3;
类项名 结构成员4;
类项名 结构成员5;
} 共用体变量名表;
}结构体变量名表;
- 枚举:1.枚举类型是指变量的值可以全部列出,定义一个枚举变量后,变量的值确定在定义之中。
2.枚举元素的类型是常量,只能在定义阶段赋值。
3.第一个枚举成员的默认值为整型的0,后续枚举成员的值在前一个成员上加1,也可以人为设定枚举成员的值,从而自定义某个范围内的整数。
4.枚举型是预处理指令#define的替代,类型定义以分号;结束。
举例:
enum DAY
{
MON=1, TUE, WED, THU, FRI, SAT, SUN
};
之后TUE=2, WED=3, THU=4, FRI=5, SAT=6, SUN=7
1.2递归函数原理
- 即函数自己不断的调用自己,任何递归函数都必须包含条件,来判断是否要递归下去,即要有递归出口与递归调用式子,一旦结束条件成立,递归克隆应该不再继续,以递归出口值作为函数结果,然后返回,结束一个递归克隆函数体。
最后通过一层层的返回,一层层的计算出值,得到最终答案。其实质是把问题简化成形式相同,但较简单一些的情况,程序中每经过一次递归,问题就得到一步简化,不断地简化下去,最终归结到一个初始值,就不必再往下递了,最后就是一层一层的归了
2.罗列本周一些错题
-
2.1
分析: 这一题中,题目要求把a中地址作为函数值返回主函数 所以第4个空格填p,而返回值必须与自定义函数的类型相同,由此可见,自定义的函数类型与p相同是指针
错因:粗心,没有考虑到函数返回值需要和函数的类型相同,所以应填struct student *。
-
2.2
分析:这题递归函数的问题,需要确定正确的递归出口和递归式子,而我没有确定正确的递归出口
错因:没有考虑到0!=1,所以应填n0||n1