C语言博客作业03--函数
0.展示PTA总分
1.本章学习总结
1.1.1函数大概
① 包括库函数与自定义函数。
② 形参表中各个形参之间用逗号分隔,每个形参前面的类型必须分别写明,形参数目可以多个,或者没有。
③ 函数首部后面不能加分号。
1.1.2函数调用
格式:
函数名 (实际参数表)
① 调用自定义函数时,程序中必须有与调用函数相对应的函数定义。
② 任何C程序执行,首先从主函数main开始,遇到某个函数调用时,先执行调用函数,该函数执行完后返回主函数,从原先暂停的位置继续执行。
1.1.3参数传递
① 程序运行遇到函数时,实参的值依次传给形参,称为参数传递。
③ 形参必须是变量,实际参数可以是常量、变量和表达式。
④ 当实参是变量时,它与所对应的参数是不同的变量,但二者数量、顺序和类型应一致。
⑤ 实参是主调函数的,形参是自定义函数的。
1.1.4结果返回
格式:
return 表达式;
① 一般情况下表达式的类型与函数类型一致,若二者不一,以函数类型为准。
② return语句作用:一,结束函数的运行;二,带着运算结果(表达式的值)返回主函数。
③ return语句只能返回一个值,若函数产生多个运算结果,将无法通过return返回。
④ return语句之后的语句将不会被执行。
1.1.5函数声明
格式:
函数类型 函数名 (参数表);
① 先声明后定义。
② 声明后有分号,定义没有。
③ 函数声明-函数调用-函数定义
1.1.6不返回结果的函数
函数定义:
void 函数名 (形参表)
{
函数实现过程
}
① 函数类型为void,表示不返回结果,函数体中可以使用没有表达式的return 语句,也可省略return。
② 通常以屏幕输出体现。
③ Void不能省略,否则函数类型将被默认定义为int。
④ 若省略了return 语句,当函数中所有语句都执行完后,遇到最后的大括号即自动返回主调函数。
1.1.7局部变量
① 作用范围:局限在所在函数内。
② 作用:避免各个函数之间的变量相互干扰,解决函数多结果返回的问题。
③ 局部变量一般定义在函数或符合语句的开始处,标准C规定其不能定义在中间位置。
④ 也称自动变量,若无赋初值,则在储存单元中将是随机值。
1.1.8全局变量
① 作用范围:从定义开始到程序所在文件的结束,它对该范围内所有的函数都起作用。
② 作用:实现多个函数之间的变量共用。
④ 一般定义在程序的最前面。
⑤ 允许局部变量与全局变量同名,二者同名时,在局部变量所在函数中,全局变量不起作用;当函数局部变量与复合语句的局部变量同名时,以复合语句为准。
⑥ 生存周期:贯穿整个程序执行过程。
1.1.9静态变量
格式:
static 类型名 变量表;
① 作用范围:局限在所在函数。
② 若无赋初值,系统将自动赋0。
③ 赋初值只在第一次调用时起作用,以后调用都按前一次调用保留的值使用。
④ 生存周期:始于函数的第一次调用,贯穿于整个函数。
1.2 本章学习体会及代码量学习体会
1.2.1 学习体会
函数是个好东西,很妙,用起来感觉很高级。之前对函数的调用及返回这一块理解得不够透彻,但经过这次大作业的实践后,我渐渐明白了其中的道理,希望以后能多布置一些自由程度高的作业(前提是时间一定要给够啊,不然就跟没布置一样)。
1.2.2 代码累计
本次综合作业代码量:499
2.综合作业
2.1本次作业的函数关系图
3.函数功能及全局变量介绍
①void Face(); //界面函数
功能:显示欢迎界面
②double gradeOne(); //一年级函数
功能:生成符合一年级学生能力水平的题目
③double gradeTwo(); //二年级函数
功能:生成符合二年级学生能力水平的题目
④double gradeThree(); //三年级函数
功能:生成符合三年级学生能力水平的题目
⑤int judge(char button); //判断是否退出函数
功能:判断用户是否要退出测试
⑥int isReasonable(int number1, int number2, char op); //判断运算是否合理函数
功能:保证题目难度在用户的能力水平以内
⑦int isTrue(int answer, int yourAnswer, int trueCount); //判断结果是否正确函数
功能:判断用户的答案是否正确
3.1.全局变量
int testNumber; //题目总量
int i; //循环变量,实现多次出题
int flag; //判断两数之间的运算还是三个数之间的运算
int number1; //数1
int number2; //数2
int number3; //数3
int sum; //多数运算时,用sum储存前量两个数的结果
int temp; //交换变量
char operators[4] = { '*','/' ,'+','-' }; //所需运算符
int opNumber1; //用数字代表运算符1
int opNumber2; //用数字代表运算符2
char op1; //运算符1
char op2; //运算符1
int reasonable; //判断运算是否合理
int answer; //正确答案
int yourAnswer; //用户答案
int trueCount = 0; //答对次数
char button; //退出按钮
int judgement; //判断是否退出
double result; //成绩
3.2main函数
功能:调用界面函数、供用户选择年级并调用相关函数、计算用户正确率并输出。
思路:用switch语句实现年级函数的调用。
代码截图:
3.3.界面函数
功能:显示欢迎界面。
思路:输出一系列图案,拼凑成一个界面。
代码截图:
3.4一年级函数
功能:生成符合一年级学生能力水平的题目。
思路:用数组将运算符随机化,用“/”和“%”将随机数进行变形,使其达到用户要求。
代码截图:
3.5二年级函数
功能:生成符合二年级学生能力水平的题目。
思路:用数组将运算符随机化,用“/”和“%”将随机数进行变形,使其达到用户要求。
代码截图:
3.6三年级函数
功能:生成符合三年级学生能力水平的题目。
思路:用数组将运算符随机化,用“/”和“%”将随机数进行变形,使其达到用户要求。
代码截图:
3.7判断是否退出函数
功能:判断用户是否想退出测试
思路:设一个字符型变量button供用户输入 ,若用户输入g,先提示“是否退出”,当用户第二次输入g时,返回一个值使其退出测试。
代码截图:
3.8判断运算是否合理函数
功能:根据用户需求,判断题目是否合理
思路:把每次运算以“数1 运算符 数2”的形式传入该函数,判断是否存在运算结果为负、除法有余数、除数为0、除数大于被除数等等情况,若存在,则重新出题,若不存在,则程序继续。
代码截图:
3.9判断结果是否正确函数
功能:判断用户的作答是否正确
思路:先定义一个“正确次数”变量,将正确答案与用户答案传入该函数,若相同,则正确次数加一,并返回正确次数,若不同,输出正确答案。
代码截图:
4.运行结果截图
- 一年级运行结果截图:
- 二年级运行结果截图:
- 三年级运行结果截图:
5. 调试碰到问题及解决办法
5.1每次运行时生成的随机数都相同
- 问题分析:每次都用了同一个种子来产生随机数,每次运行时生成的随机数都相同。
- 解决办法:在程序前添加#include <time.h>,在生成随机数的语句前添加srand((unsigned)time(NULL));语句。
5.2显示正确率为0
- 问题分析:在计算正确率的语句result = trueCount / testNumber中忽略了C语言的除法不同于实际除法。
- 解决办法:将该语句修改为result = trueCount *1.0 / testNumber
5.3题目显示错误
- 问题分析:运算符号可能被修改,在排查过一遍程序后,终于找到了问题,在判断语句中出现if(op='/')的语法错误。
- 解决办法:将该语句改为if(op=='/'&&number2!=0)。
5.4退出按钮无用
- 问题分析:往button变量输入数据时,最后敲入的回车没有被吃掉,导致程序无法继续运行。
- 解决办法:在button的输入语句的下一行添加getchar()语句,解决了回车问题。
6.大作业总结
这可以说是第一个完全属于我的代码,虽然写得很慢很痛苦,但我不会像做PTA一样抓狂骂娘,毕竟这是自己的代码,所以当程序成功按照我的设想运行时,我由衷地感到高兴,在一次次的调试与构思中,我碰到过不少问题,多亏了百度,我才得以成功解决,我也从中学到了不少遍程新知识也巩固了函数旧知识点。
总结此次编写教训,有一个完善的而详细的思路显得格外重要,在刚开始写的时候我只设了四个函数(界面函数和三个年级函数),一个全局变量也没有,代码总量接近六百行,知道把三个年级函数分别提炼出来后才找出了可以设为全局变量的变量,并且将判断是否退出、判断运算是否合理和判断答案是否正确这三个功能分离出来,代码量也随之减少了。