C语言博客作业--结构体
一、PTA实验作业
题目1:6-4 结构体数组按总分排序
1. 本题PTA提交列表
2. 设计思路
void calc 函数部分(计算每位同学成绩总和)
i=0;
for i to n-1
总成绩=三科成绩总和
end;
void sort 函数部分 (通过比较每位同学成绩总和,对同学进行排序)
定义 i,j;
定义结构变量 temp
for i=1 to n
for j=0 to n-i
利用冒泡排序将同学的总分的从大到小排序
end;
3.代码截图
4.本题调试过程碰到问题及PTA提交列表情况说明。
计算总和时直接用sum=sum+score[i],发现运行后总和数并没有相加,是要用结构指针间接访问结构变量,后来改为p+i)->sum=(p+i)->score[0]+(p+i)->score[1]+(p+i)->score[2]可以计算成绩总和;开始时是用选择排序法,但发现发现过于复杂,后来换用冒泡排序,简单
题目2:7-5 有理数比较
1. 本题PTA提交列表
2. 设计思路
定义结构变量;
int flag;
char ch;
输入这两个有理数number1,number2
flag=number1.fenzi*number2.fenmu-number2.fenzi*number1.fenmu
判断flag的大小,从而确定ch的值
如若flag>0
ch='>';
若flag<0
ch='<'
否则
ch='='
输出两个有理数比较后的结果
end
3.代码截图
4.本题调试过程碰到问题及PTA提交列表情况说明。
开始时直接用两有理数相减,但发现分子,分母都是整型范围内整数,相除后不会保留小数;后来定义结构变量,分别定义分子,分母和分号;
再根据两有理数分子,分母的关系,判断ch的值就可以了
题目3:7-6 通讯录的录入与显示
1. 本题PTA提交列表
2. 设计思路
定义结构变量
定义结构变量表
输入n
for i=0 to n-1
输入姓名 生日 性别 固话 手机
输入k
for i=0 to k-1
输入查找编号num[i]
判断num[i]是否在0~10之间,若在,则输出相应的人员信息
若不在,则输出Not Found
3.代码截图
4.本题调试过程碰到问题及PTA提交列表情况说明。
这题部分正确的原因是输出错误,与原题要求的输出符号错了,其他没什么
二、截图本周题目集的PTA最后排名。
三、阅读代码
报数游戏
#include <stdio.h>
struct ele{
int no;
struct ele *link;
}
main()
{
int n,m,i;
struct ele *h,*u,*p;
clrscr();
printf("Please input n&m:\n");
scanf("%d%d",&n,&m);/*输入n和m*/
h=u=(struct ele *)malloc(sizeof(struct ele));/*形成首表元*/
h->no=1;
for(i=2;i<=n;i++)/*形成其余的n-1个表元*/
{
u->link=(struct ele *)malloc(sizeof(struct ele));
u=u->link;
u->no=i;/*第i个表元置编号i*/
}
u->link=h;/*末表元后继首表元,形成环*/
puts("\nThe numbers of who will quit the cycle in turn are:");
while(n)
{
for(i=1;i<m;i++)/*掠过m-1个表元*/
u=u->link;
p=u->link;/*p指向第m个表元*/
u->link=p->link;/*第m个表元从环中脱钩*/
printf("%4d",p->no);
free(p);/*释放第m个表元占用的空间*/
n--;
}
printf("\n\n Press any key to quit...\n");
getch();
}
```
>这是上周pta作业的报数游戏的题,当时做的时候感觉没什么思路,在网上找到这种做法;本代码使用结构体来做,并且定义了结构体指针,对其进行编号,用while循环语句,实现对其相应编号的人退出围成的环,直到第m个元素从环中脱离后,输出,并释放第m个表元占用的空间,避免空间浪费
#####用“结构”统计学生成绩
include <stdio.h>
define N 200
define SCORES 5
define NUMLEN 10
struct std_type{
char no[NUMLEN];/学号/
char name;/名字符串指针/
int scores[SCORES];/五门功课的成绩/
};
struct std_type students[N];
int order[N];
int total[N]; /[函数]输入一个学生信息函数/
int readastu(struct std_type spt)
{
int len,j;
char buf[120];/输入字符串的缓冲区/ printf("\nNumber : ");/输入学号/
if(scanf("%s",buf)1)
strncpy(spt->no,buf,NUMLEN-1);
else
return 0;/Ctrl+Z结束输入/
printf("Name : ");/输入姓名/
if(scanf("%s",buf)1)
{
len=strlen(buf);
spt->name=(char )malloc(len+1);/申请存贮姓名的空间/
strcpy(spt->name,buf);
}
else return 0;/Ctrl+Z结束输入/
printf("Scores : ");/输入成绩/
for(j=0;j<SCORES;j++)
if(scanf("%d",spt->scores+j)!=1)
break;
if(j==0)/一个成绩也未输入/
{
free(spt->name);/释放存贮姓名的空间/
return 0;
}
for(;j<SCORES;j++)/少数未输入的成绩用0分代之/
spt->scores[j]=0;
return 1;
} /[函数]输出一个学生信息的函数/
int writeastu(struct std_type spt)
{
int i; printf("Number : %s\n",spt->no);/输出学号/
printf("Name : %s\n",spt->name);/输出姓名/
printf("Scores : ");/输出成绩/
for(i=0;i<SCORES;i++)
printf("%4d",spt->scores[i]);
printf("\n\n");
} main()
{
int n,i,j,t; clrscr();
for(n=0;readastu(students+n);n++);
/采用冒泡法对学生信息数组排序/
for(i=0;i<n;i++)
{
order[i]=i;/预置第i个输入的学生/
for(t=0,j=0;j<SCORES;j++)/求第i个学生的总分/
t+=students[i].scores[j];
total[i]=t;
}
/冒泡排序/
for(i=0;i<n-1;i++)/共扫视n-1遍/
for(j=0;j<n-1-i;j++)
if(total[order[j]]<total[order[j+1]])
{/交换名次/
t=order[j];
order[j]=order[j+1];
order[j+1]=t;
}
for(j=0;j<n;j++)/输出/
writeastu(students+order[j]);
printf("\n Press any key to quit...\n");
getch();
}
```
本代码的功能是统计学生成绩,并按成绩对其排名;优势:本题代码调用多成函数实现对学生信息的输入和输出,并且程序中在输入前,有向系统申请存放空间,若输入成绩个数为0,则在将其空间释放,避免造成空间浪费,将其未输入的少数成绩记为0,这样就避免了输出错误;最后学生名次采用冒泡排序,结构简单;代码的注释很到位,值得我学习
四、本周学习结
1.总结本周学习内容。
结构体 共同体 枚举体
结构体:
概念:结构体时一种构造数据类型
用途:把不同类型的数据组合成一个整体
内存:各成员所占内存空间的累加
关键词:struct
#######一.结构体的声明与定义变量的方法一共有三种:
1.常规定义:
struct AA
{
int a;
int b;
}; //注意大括号后面有分号
变量定义:struct 机构体名 结构体变量名表
如: struct AA aa,bb;(前面的struct不能掉)
成员调用:aa.a; aa.b;
2.尾部定义。
struct CC
{
int a;
int b;
}aa,bb;
此时aa,bb就是已经定义好的CC类型的变量了,这种情况在声明时struct前就一定不能加typedef,如果加上了,aa,bb就成了和CC一样的结构体类型了,而不是变量了。
3.无名结构体
struct CC
{
int a;
int b;
}vip1,vip2;
此种情况除了vip1,vip2,不能再在其他地方定义新的变量,即定义了几个就只能用几个。
不能在结构体内部直接给成员赋值:
#include<stdio.h>
//直接带变量名Huqinwei
struct stuff{
// char job[20] = "Programmer";
// char job[];
// int age = 27;
// float height = 185;
}Huqinwei;
1
2
3
4
5
6
7
8
https://yq.aliyun.com/articles/10417
1
共用体:
构造数据类型,也叫联合体。
用途: 使几个不同类型的数据共占一段内存(相互覆盖)
关键词:union
特点:
1共用体变量任何时候只有一个变量存在。
2,共用体变量定义分配内存,长度=最长成员所在字节数
3,定义共用体变量的方式和结构体一样有三种:常规,尾部,无名。
4,当给一个成员重复赋值时或对多个成员赋值时,只承认最后一次的赋值。
枚举体
关键词:enum
用途:列举所有选项
举例:day = {Sunday,Monday,Tuesday,Wednesday,Thusday,Friday,Saturday};
结尾有分号,如果个枚举常量没有赋值,则默认值为其下标(参考一维数组),比如此时Tuesday = 2
#######递归函数的原理
递归(recursion)就是子程序(或函数)直接调用自己或通过一系列调用语句间接调用自己,是一种描述问题和解决问题的基本方法。
递归通常用来解决结构自相似的问题。所谓结构自相似,是指构成原问题的子问题与原问题在结构上相似,可以用类似的方法解决。具体地,整个问题的解决,可以分为两部分:第一部分是一些特殊情况,有直接的解法;第二部分与原问题相似,但比原问题的规模小。实际上,递归是把一个不能或不好解决的大问题转化为一个或几个小问题,再把这些小问题进一步分解成更小的问题,直至每个小问题都可以直接解决。因此,递归有两个基本要素:
(1)边界条件:确定递归到何时终止,也称为递归出口。
(2)递归模式:大问题是如何分解为小问题的,也称为递归体。递归函数只有具备了这两个要素,才能在有限次计算后得出结果
在递归函数中,调用函数和被调用函数是同一个函数,需要注意的是递归函数的调用层次,如果把调用递归函数的主函数称为第0层,进入函数后,首次递归调用自身称为第1层调用;从第i层递归调用自身称为第i+1层。反之,退出第i+1层调用应该返回第i层。
#######递归函数的内部执行过程
一个递归函数的调用过程类似于多个函数的嵌套的调用,只不过调用函数和被调用函数是同一个函数。为了保证递归函数的正确执行,系统需设立一个工作栈。具体地说,递归调用的内部执行过程如下:
(1)运动开始时,首先为递归调用建立一个工作栈,其结构包括值参、局部变量和返回地址;
(2)每次执行递归调用之前,把递归函数的值参和局部变量的当前值以及调用后的返回地址压栈;
(3)每次递归调用结束后,将栈顶元素出栈,使相应的值参和局部变量恢复为调用前的值,然后转向返回地址指定的位置继续执行。
2.罗列本周一些错题
1.输出应是s.score,应加上结构变量名 2.定义结构体指针,struct student *; 3.分数加一,应加上变量名,p->score[i]或p.score[i] 4.返回的是学生的所有相关信息,不止是成绩
1.定义结构体变量 struct worker s[10] 2.name[20]是地址,不用加&,其他的需加& 即&s[i].num, s[i].name ,&s[i].jbpay,&s[i]zwpay 3,max=i 4.min=i
fun()函数定义了一个数及数组,但D选项中fun(int n ,int a)不可以这么写,这样a是一个整型数,并不是一个数组