一、PTA实验作业
题目1:结构体数组中查找指定编号人员
1. 本题PTA提交列表
2. 设计思路
struct student fun(struct student *std, char *num)
{
定义struct student p用来保存返回人员的数据
定义变量i,j,flag用来控制循环
for i=0 to N-1
{
flag赋值为1
for j=0 to 5
{
if std->num[j]与num[j]不相等
那么让flag变成0,std++,停止内循环
}
经过上面的循环如果 flag还是为1,说明制定编号人员存在,立即停止外循环
}
将*std的数据复制到p上
if flag不等于0
返回 p
}
3.代码截图
4.本题调试过程碰到问题及PTA提交列表情况说明。
直接让p赋上std的数据,编译错误,后来才发现是忘记加星号(*)。改用一个一个数据复制的方法赋值。
题目2:时间换算
1. 本题PTA提交列表
2. 设计思路
struct Time{
int hour;
int min;
int sec;
}time;//该结构体表示时间的小时数,分钟数,秒数
定义变量n表示增加的秒数;
输入时间和秒数;
给原秒数做加法运算time.sec+n;
if time.sec不小于60{
分钟数增加,秒数减去60
if time.min不小于60{
小时数增加,分钟数减去60
if time.hour不小于24
小时数变为0
}
}
if time.hour<10
输出0 /*如果时间不足两位要补0*/
输出 小时数:
if time.min<10
输出0
输出 分钟数:
if time.sec<10
输出0
输出 秒数
3.代码截图
4.本题调试过程碰到问题及PTA提交列表情况说明。
这道题问题不大,思路清楚,就是最后输出时如果时间是个位数前面要输出0,我的处理方法感觉比较麻烦,要进行三次判断。
题目3:通讯录的录入与显示
1. 本题PTA提交列表
2. 设计思路
struct communication{
char name[11];
char birthday[11];
char sex;
char tel[17];
char mob[17];
};//该结构表示通讯录人员的姓名,生日,性别,固定和手机号码
定义变量i,j来控制循环
定义N,k表示通讯录人员总数和要查询的编号个数
定义通讯录人员数组struct communication person[N]
for i=0 to N-1
录入成员信息
输入要查询的编号个数k
定义数组count[k]用来保存要查询的编号
for j=0 to k-1
录入编号
for j=0 to k-1
if 0<=count[j]<N
输出该编号人员的信息
else
输出"Not Found"
3.代码截图
4.本题调试过程碰到问题及PTA提交列表情况说明。
仔细检查自己思路没问题,后来发现电话号码不超过15位但还要算上加号,所以存放号码的数组大小至少为17,否则会溢出。
二、截图本周题目集的PTA最后排名。
三、阅读代码
1.时间换算:本题要求编写程序,以hh:mm:ss的格式输出某给定时间再过n秒后的时间值(超过23:59:59就从0点开始计时)。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
int all[10]={0},i=0;
void tosex(int n) //转换为60进制
{
if(n>59) tosex(n/60);
all[i]=n%60;
i++;
return 0;//原代码有return 0,如果要在dev上测试,需要删除
}
int main()
{
int h,m,s,n,stamp,j;
scanf("%d:%d:%d\n%d",&h,&m,&s,&n);
stamp=s+m*60+h*3600+n; //时间戳
tosex(stamp);
all[i-3]=all[i-3]%24; //小时是24进制的
for(j=i-3;j!=i;j++)
{
if(all[j]<10) printf("0");
printf("%d",all[j]);
if(j<i-1) printf(":");
}
return 0;
}
这是本周PTA的一道题,我们使用结构体来做,然而上面的代码采用了递归的做法,方法更加巧妙。
先算出总的秒数,利用递归函数和数组all来计算保存换算后的时间,最后逆序输出。
2.角谷定理:输入一个自然数,若为偶数,则把它除以2,若为奇数,则把它乘以3加1。经过如此有限次运算后,总可以得到自然数值1。求经过多少次可得到自然数1。
#include<stdio.h>
//定义递归函数,参数为数字和步骤数
int jg(int n,int step)
{
if(n!=1)
{
if(n%2 == 0)
{
printf("%d ", n);
n = n / 2;
}
else if (n % 2 == 1)
{
printf("%d ", n);
n = 3 * n + 1;
}
return jg(n, step + 1);
}
else
{
printf("%d ", n);
step++;
}
printf("\nSTEP=%d\n",step);//输出步骤数
}
//主函数
int main()
{
int s=0;
int num;
printf("请输入一个数:");
scanf("%d",&num);//输入数字
jg(num,s);
return 0;
}
可以利用递归解决一些复杂的数学问题,找出递归出口和递归式子就可以完成,可以试着挑战一些题目,主要是要发现其中的共同规律。
四、本周学习总结
1.总结本周学习内容。
嵌套函数
(1)在一个函数中再调用其他函数,可以使问题解决过程局部化,避免功能之间的相互干扰。
(2)对于一个具体问题设计方法的原则一般如下:
(i)自顶向下
(ii)逐步求精
(iii)函数实现
(3)在设计函数时应注意:
(i)限制函数的长度
(ii)避免函数功能间的重复
(iii)减少全局变量的使用
(4)递归函数
(i)递归函数即自己调用自己的函数
(ii)递归函数的两个要点:递归出口和递归式子
(iii)注意运算式子不能这样写:fact(n)=n*fact(n-1);
结构体、共用体、枚举这种构造数据类型特点
· 结构体的特点
(i)结构体和数组一样都是构造型数据类型,和数组不一样的是,结构体可以处理不一样类型的数据,但是数组中的元素必须是同一数据类型
(ii)结构体变量所占的内存长度为所有成员所占内存的长度之和
(iii)结构体数组每个元素都是一个结构体类型的数据(定义数据时要注意)
· 共用体的特点
(i)共用体变量所占的内存长度等于最长的成员的长度
(ii)同一段内存可以存放几种不同类型的成员,但是每一瞬间,只能存放一种,其他成员都不起作用
(iii)共用体变量中起作用的成员是最后一次存放的成员
(iv)共用体变量的地址和其成员地址都是同一地址,&a, &a.i都一样
(v)不能对共用体变量名赋值,不能引用共用体变量名来得到一个值,不能在定义共用体变量时对它进行初始化
(vi)不能将共用体变量作为函数参数,不能使函数返回共用体变量,但可以使用指向共用体变量的指针
(vii)共用体使用了内存覆盖技术,同一时刻只能保存一个成员的值,如果对新的成员赋值,就会把原来成员的值覆盖掉。
· 枚举的特点
(i) 枚举类型是指变量的值可以全部列出,定义1个枚举变量后,变量的值确定在定义之中。
(ii)枚举和结构体、共用体的区别在于,枚举元素是常量,只可以在定义阶段赋值。
(iii)枚举定义的量属于全局常量,在其他地方不能再有与之重名的量。
(iv)变量的值只限于列举出来的值的范围内
递归函数原理
(i)递归通常用来解决结构自相似的问题。所谓结构自相似,是指构成原问题的子问题与原问题在结构上相似,可以用类似的方法解决。具体地,整个问题的解决,可以分为两部分:第一部分是一些特殊情况,有直接的解法;第二部分与原问题相似,但比原问题的规模小。实际上,递归是把一个不能或不好解决的大问题转化为一个或几个小问题,再把这些小问题进一步分解成更小的问题,直至每个小问题都可以直接解决。
(ii)递归函数的内部执行过程
一个递归函数的调用过程类似于多个函数的嵌套的调用,只不过调用函数和被调用函数是同一个函数。为了保证递归函数的正确执行,系统需设立一个工作栈。具体地说,递归调用的内部执行过程如下:
(1)运动开始时,首先为递归调用建立一个工作栈,其结构包括值参、局部变量和返回地址; (2)每次执行递归调用之前,把递归函数的值参和局部变量的当前值以及调用后的返回地址压栈; (3)每次递归调用结束后,将栈顶元素出栈,使相应的值参和局部变量恢复为调用前的值,然后转向返回地址指定的位置继续执行。
(参考自递归函数工作原理)
2.罗列本周一些错题。
课堂派C语言复习作业--结构体
(1)
输入数据时,要在前面加上&。
(2)