C语言博客作业03-函数
0.展示PTA总分
1.本章学习总结
1.1 学习内容总结
1.1.1函数
- 函数的定义:
函数首部由函数类型、函数名和形式参数表组成(函数首部后面不能加分号,它与函数体一起构成完整的函数定义)。
函数类型指的是函数结果返回的类型,一般与return语句中的表达式类型一致。
函数体体现函数的实现过程,由一对大括号内的若干语句组成,用于计算或完成特定的工作,并用return返回运算的结果。
函数定义的一般形式
函数类型 函数名(形式参数表)
{
函数实现过程
}
- 函数的调用
1.函数调用的一般形式
函数名(实际参数表)
2.赋值语句
如volume=cylinder(radius,height)
3.输出函数的实参
如printf("%f",cylinder(radius,height);
4.放在if语句中当条件
如if(IsPrime(number))
{
;
}
调用标准库函数时,只需要在程序最前面用#include命令包含相应的头文件;调用自定义函数时,程序中必须有与调用函数相对应的函数定义。
主调函数的参数称为实参,函数定义时位于其首部的参数被称为形参。参数传递过程中只允许实参把值复制给形参。实参和形参一一对应,数量应相同,顺序应一致。
函数原型声明是一条C语句,而函数定义时的函数首部不是语句,后面不能跟分号
函数声明的一般格式
函数类型 函数名(参数表)
函数结果返回时,一般表达式类型与函数类型一致,如果不一致则以函数类型为准。return语句的作用一个是结束函数的运行,一个是带着运算结果返回主调函数
函数返回结果的形式
return 表达式
- 不返回结果的函数
调用函数不是为了得到某个运算结果,而是要让它产生某些作用(例如屏幕输出)。
不返回结果的函数定义
void 函数名(形参表)
{
函数实现过程
}
函数类型为void,表示不返回结果,可以省略return。在不返回void的函数定义中void的不能省略,否则函数类型被默认定义为int。
-
结构化程序设计思想
自顶向下的分析问题的方法
模块化的设计 -
局部变量和全局变量
概念:定义在函数内部的变量称为局部变量,定义作用于复合语句中的局部变量又称临时变量。定义在函数外不属于任何函数的变量称为全局变量。
优先级:由于全局变量和局部变量的作用范围不同,允许同名,同名时,在该函数中全局变量不起作用,而又局部变量起作用。同理全局变量与复合语句中的局部变量同名时,以符合语句为准。
全局变量的作用:可以帮助解决函数多结果返回的问题,但更多的适用于多函数间的全局数据表示。
注意:全局变量虽然可以用于多个函数间的数据交流,但对于规模比较大的程序,为避免各函数间数据的相互干扰,应尽量使用局部变量。
- 变量生存周期和静态局部变量
注意:变量的作用范围和生存周期是两个不同的概念
概念: 局部变量是自动变量,函数被调用时,系统自动为其局部变量分配存储单元,一旦该函数调用结束,所有分配给该单元由系统自动回收。变量从定义开始分配存储单元到运行结束存储单元被回收,整个过程称为变量生存周期。而全局变量由于它与具体函数无关,所以它的生存周期为整个程序执行周期。
自动变量的定义形式:
auto 类型名 变量表;
在静态存储区内除了全局变量,还有一种特殊的局部变量——静态局部变量。一旦含有静态局部变量的函数被再次调用,则静态变量会被重新激活,上一次函数调用后的值仍然保留着,可供本次调用继续使用。
静态变量定义形式:
static 类型名 变量表;
赋值区别:自动变量如果没有赋初值,其存储单元中将是随机值。而静态变量,如果没有赋初值,系统将自动赋值0,并且赋初值只在函数第一次调用的时候起作用,以后的调用都按前一次调用保留的值使用。
1.2 本章学习体会及代码量学习体会
1.2.1 学习体会
学习了使用函数,感觉解析问题时也会更注重模块化,注重由上而下的分析。
在实践过程中尽可能的使编写的程序思路清晰明了(即通过封装函数,使主函数更加简洁)。同时为了使编写的函数可以重复利用,提高利用率
感觉函数确实是必不可少的,觉得对于后续的学习,学好函数是必要的。
1.2.2 代码累计
本次综合作业代码量:287行
1.综合作业
题目:小学生口算表达式自动生成系统
2.本次作业的函数关系图
3.函数功能及全局变量介绍
3.1.全局变量
int response和int answer在所有函数中意义相同,所以设置为全局变量。
3.2.函数 void Showlevel()
仅用于展示可选择的年级菜单
3.3函数 int IsContinue()
用于判断是否继续做题
3.4 int Judge()
用于判断正确和错误
4.运行结果截图,测试用例
一年级:
图中一年级的加法最大范围应为两位数的加法,红线画出部分满足一位数加两位数的加法。
二年级:
图中测试数据由上到下分别为 两位数初一一位数,整千数相减,1到9表内除法
三年级:
该数据从上到下分别为 三位数减两位数的减法,两位数除一位数的除法,三位数减三位数的减法,三位数减一位数的减法,两位数乘以两位数的乘法,同时包含了输入异常选择的测试。
- 调试碰到问题及解决办法
======================
问题:
编写提示是否继续的函数时,由于我所编写的条件是如果ch'Y'||ch'y',发现第一个问题结束后无论输出什么都是结束运行。
解决办法:
逐语句调试,观测ch变量的是否成功赋值。
发现ch赋值为\n,因此想起了之前所强调的字符型变量注意造吸收符的问题!
总结:
虽然说提过的问题有所印象,但是还不够深刻,还不够注意该问题,因此在实际编写中很可能犯该错误。特别若是在大作业中犯该种错误,有时错误很难寻找很麻烦,因此应当引起注意
问题:
当我运行完所有的题目时,发现最终仍有是否继续做题的提示,而此时无论是否回答继续,最终又都会结束。说明该部分在编写时考虑的不够到位。
解决办法:
一开始是直接利用if(IsContinue()0){break;}判断是否继续并直接跳出。而仔细回顾发现我的IsContinue语句中是直接输出提示的。
一开始考虑利用传递参数,在封装的函数中判断后考虑是否输出提示,显然太过麻烦。
最后就根据想做题数和已做题数的数量特点,利用if语句,在不是最后一个问题的条件下,嵌套if(IsContinue()0){break;}。
问题:
一开始书写判断是否继续的函数时是直接利用if(ch'Y'||ch'y‘)则返回值1,其余都返回0。在实际操作中发现,当不小心输入其他字母或数字时,同样结束程序,因此不能只是简单的if-else语句。
解决办法:
利用if-else if语句后,还需要考虑的是若为其他字符,应当人性化的提醒重新输入选择,并且再次判断。
由此造一个while(1)的恒真语句,输入字符,当为'y'||'Y'||'N'||'n'时可利用return结束函数直接返回值,否则就提示重新输入选择,直到输入正常的字符并判断结束为止。
6.大作业总结
1.首先思路还是不是很清晰,虽然老师强调不要一个年级一个年级的封装函数,但是每个年级的题细分很多,无从下手,所以最后还是选择了根据年级封装不同题集。
2.其次作业完成的还是较为粗糙,因为一开始去口算网观察一些题,觉得同个年级中有好多题目都是加大随机数范围而加大难度,因此认为只要总结同样题目的最大范围,按照最大范围编写随机数,即可概括全部情况。但是这样的话,在完成博客作业的测试数据部分,就很有可能遇不到需要的题型,于是我又尽力再分。
3.作业还不够完整,在每个年级中的混合和连加运算目前还不能做到,题集不能完全满足要求。