C语言博客作业--函数嵌套调用
一、实验作业
1.1->PTA题目(6-5)
(1)设计思路
void printdigits( int n ){
if n小于9(确定数字范围)
//输出n的值;
else if n大于0
printdigits(n/10);//调用自身
//输出换行符
//输出n的个位数
end else if
}
(2)代码截图
(3)本题调试过程碰到问题及PTA提交列表情况说明
- 输入除0和1的单个数字,输出错误的结果,原因在于只判断了n是0或1 的情况,没有想到其他数的结果。
- 只需要判断n大于0且n小于等于9的情况:即只有一个数的情况。
1.2->学生成绩管理系统
1.2.1->画函数模块图,简要介绍函数功能。
- cal()函数:控制台功能,实现调用相应功能函数
- void in_students():写入学生信息的功能函数
- void out_students():输出学生信息的功能函数
- void modify():输入相应学号实现修改特定学生信息的功能函数
- void search_student():输入相应学号实现查找特定学生信息的功能函数
- void delet_student():输入相应学号和相应课程号实现删除特定学生的特定信息的功能函数
- void sort():简单的按学号排序的函数
- void resort():按总分重新排序的函数
- int inch():判断所输入的学号到底存在与否的函数
1.2.2->截图展示你的工程文件
1.2.3->函数代码部分截图
本系统代码总行数:463
头文件:
插入学生信息及学生成绩信息代码:
删除学生成绩信息代码:
修改学生成绩信息代码:
总分排序代码:
1.2.4->调试结果展示
输入&插入:五个学生,三门课程:分三次输入,第一次一个,第二次两个,第三次一个,第四次一个(为需要排序的)
查询:当没有学生信息存放时,当有学生信息但输错学号或输入学号正确时
-
当有学生信息但输错学号:(接上的输入)
-
当正确输入时:
排序并输出提示:
输出显示所有学生成绩信息:
输出按总分排序的成绩信息:
输入学号和课程删除学生成绩信息:(由于命令描述比较模糊,我认为是把该课程号下的成绩归0,并且在平均分中不计该删去的课程)
-
删除前:
-
删除后:
再排序输出
输入学号和课程号修改学生成绩信息:
-
修改前:
-
修改后:
一些其他自己加的:
- 在主菜单里有加上的输入[2018]返回主菜单,前面演示过
- 在修改和删除时添加更多选项,猜测。
1.2.5->调试碰到问题及解决办法。
- 把学号从double类型改成char类型之后有些输入的语句和调用的语句没有改,导致的程序崩溃。
- 只修改了调用的语句,没有注意到另外的一些地方也要修改。
- 程序异常退出,调试时无法进入cal函数,并且弹窗提示段错误,查了网上的信息,可能是未正确引用导致,再运行程序,返回value 3221225725,遂在网上查过,大概是内存空间不足的意思,于是就修改定义在cal函数里的students数组大小,正常运行。
二、截图本周题目集的PTA最后排名。
PTA排名
三、阅读代码
//全排列:从n个不同元素中任取m(m≤n)个元素,按照一定的顺序排列起来,叫做从n个不同元素中取出m个元素的一个排列。当m=n时所有的排列情况叫全排列。
#define SWAP(a,b,t) ((t)=(a),(a)=(b),(b)=(t)) //宏定义用来交换两个元素的功能
void permutation(char *ch, int min, int max) //min和max确定了需要排序的元素区间 min-max
{
int i;
char temp;
if (min == max) //边界条件
{
printf("%s\n", ch);
}
else
{
for (i = min; i<= max; i++)
{
SWAP(ch[i], ch[min], temp); //先交换在调用
permutation(ch, min+1, max); //min逐渐逼近max
SWAP(ch[i], ch[min], temp); //再交换
}
}
}
- 优点:宏定义实现交换元素功能,比用一个新的功能函数实现更简单;用递归的方式逐个输出排列可能,是一个如何用递归来解决这类问题的有参考价值的代码。
四、本周学习总结(3分)
1.介绍本周学习内容
1、宏
- 宏是预处理命令。
- 使用宏进行一些运算时要注意运算的元素之间的优先度,宏展开并不加入括号。
- 宏可以用来定义一些简单的功能函数(一行里完成)。
- 宏只需定义一次,可以多次使用,所以使用宏能增强程序的易读性和可靠性。
- 传给宏的参数慎用自增运算符|自减运算符
2、链表
- 是动态地进行存储分配的一种结构,它可以根据需要开辟内存单元。
- 链表中每一个元素称为“结点”,每个结点都应包括两个部分:一为用户需要用的实际数据,二为下一个结点的地址。
- “表尾”的地址部分放一个“NULL”(表示“空地址”),链表到此结束。
- 删除:将下一结点的地址指向要删除的结点的下一结点的地址,即先链接后删除,再释放结点的内存空间
- 插入新结点:找到要插入的结点,将其下一结点地址指向一个新的结点,再把新的结点的下一结点地址指向插入结点的下一结点地址
- 结点在内存中可以不连续存在
3、申请动态内存
- void *malloc(size_t size);用来申请,在头文件stdlib里
- 对于成功的申请需要给返回的指针指定类型
- void free(void *ptr);用来释放申请的内存空间,在申请的内存空间不用之后要释放。
2.学习体会。
- 链表的学习让我发现学生成绩管理系统的新写法。
- 学会申请动态内存,就可以精确的使用内存空间,而且在指不定要多少内存空间的情况下大有用处。
- 宏的使用要尤其谨慎,该加括号的一定要加上,不然可能会出现自己意料之外的小问题(而且可能很隐蔽)。
- 写工程文件时如果修改一个数据的类型,要注意同时修改用到这一数据的地方,善用搜索功能。
- 在写工程文件作业时,发现比起可见的错误(编译器提示)来说,段错误(数组下标越界、修改数据类型后要修改的一系列如%d于%s之类)反而是我更经常犯的错误,对于这类问题,编译器直接通过,出错就相当难以检查。