C语言博客作业03--函数

0.展示PTA总分(0----2)

1.本章学习总结(2分)

1.1 学习内容总结

函数的定义与调用

  • 函数定义:函数包括库函数和自定义函数两种,库函数由C语言系统提供定义,我们可以直接调用,而自定义函数则需要我们自己定义方可调用。
    • 一般形式为:
函数类型 函数名(形式参数表)     /*函数首部*/
{
函数实现过程              /*函数体*/
}
- **特别注意**:
     1.函数首部后不能加分号,它需要和函数体一起构成完整的函数定义。
     2.每个形参都需要把它的类型写出来,不能只写一个类型来定义多个变量,如```int x,y```,这是错误的。
     3.形参必须是变量,用于接受实参传递的值。
     4.如果函数定义在主函数后,需要在主函数前加上函数声明,<span style="color:red">函数声明需要加分号</span>。
  • 函数调用:一般来说,在程序执行时,第一个被执行的应该是main函数,若有遇到函数调用,则主函数暂停,执行调用的函数,执行完后返回主函数继续执行。
    • 一般形式:函数名(实际参数)
    • 关于参数的传递,只能由实参传递给形参,而不能反过来。实参可以是常量、变量或表达式。
    • 关于结果的返回:return语句只能返回一个值。如若想要返回多个值,可以考虑用全局变量,但要注意避免让变量名称与局部变量的相同,否则可能会导致程序出错。
      举个栗子:
      c05-函数-7-1 求组合数

我们可以很清楚地看到,主函数部分变得简洁,思路更清晰,可读性更好了。所以说,当我们遇到极为繁琐的函数题时,可以将它分为多个部分,定义多个函数,每一个函数解决一类问题,这样不仅不容易让思路混乱,还减少了我们调试的工作量。一个函数,我们如果确定调试成功,再加上其他部分的时候,我们就不需要再次对这个函数进行调试了,这可以大大减少我们的调试时间。

局部变量与全局变量

  • 局部变量:定义在函数内部的变量叫做局部变量,它的作用范围只在函数内部。(形参是局部变量)
  • 全局变量:定义在函数外且不属于任何函数的变量称为全局变量,它的作用范围是从定义开始到程序所在的文件结束,它对作用范围内的所有函数都起作用。
  • 特殊的局部变量——静态变量:它的特殊之处在于,它不会像普通的局部变量一样,因为函数调用结束就被系统收回,它的生存周期会持续到程序结束。要注意的是,静态变量的赋值只在第一次调用时起作用,而且,如果没有给它赋值,系统默认为0。我们可以利用这一点,对一些需要赋值为0的变量进行定义,比如数组中的运用。c07-一维数组-7-5 有重复的数据I


1.2 本章学习体会及代码量学习体会

1.2.1 学习体会

学完函数,我的主函数部分就剩下了输入输出,刚刚开始的时候简直被震惊到了,主函数居然可以那么短?!只剩下输入输出了,思路简直是一目了然,函数的可读性一下子就增强了。虽然知道要可以用函数,但是我现在还不是很习惯用函数去实现那些功能,我总是把那些代码都堆在主函数里,然后就显得我的代码特别长,对读者,特别不友好。>.<我会尽快改过来的,尽量让主函数部分只放输入和输出部分。我觉着,这部分需要注意的,还是全局变量和局部变量的运用。特别是知道可以利用静态变量去实现赋值的时候,我其实有点惊讶,脑袋里就只剩下一个想法:“什么?还可以这样?!”真的,每次学到新的东西,就感觉被刷新了认知,也许我应该习惯的,但是每次自己想很久没想出来的东西被一下子解决的时候,还是忍不住惊叹它的神奇。

1.2.2 代码累计

c05-函数的代码有298行。
本次综合作业代码量:408行

2.综合作业(8分)

题目:小学生口算表达式自动生成系统
口算题参考网站

功能要求:
1.完成1-3年口算题自动出题系统
2.注意每个年级运算数要求,运算数和运算符要随机生成
3.用户每选择一个难度级别后必须输入题目数量,能统计用户的正确率。用户每算一题,若错误,给出正确答案。 用户中途退出,不继续做题,需要有个提示操作可中途退出。

注意:
软件界面必须友好,多加文字提示,能让用户自己当前做什么,接下来怎么做,每步操作可以退到主菜单界面。
-注意异常数据处理,如除0错误、不合法数据、临界数据,系统保证运行时候不崩溃。
注意函数封装,不管是几位数的加减乘除运算,相同功能的代码应该都封装都一函数,通过参数传递实现代码覆盖。也可以考虑数据输入、输出等函数封装,尽量不要把代码都放main中。各种异常情况也可以单独封装函数处理,让程序的扩展性更强。
扩展功能:
可以设置答题时间,用户超过答题时间,提示不能继续做题,重新选抽题。请查阅C的时间函数。
扩展难度级别,比如出现2步加减乘除,然后乘除优先计算。比如2+3*4运算
2.本次作业的函数关系图

3.函数功能及全局变量介绍

3.1.全局变量

全局变量:

3.2.ListMenu()函数

  • 功能:用于列出所有题目类型
  • 思路:不同类型不同编号
  • 截图:

3.3 main()函数

  • 功能:实现输入输出。
  • 思路:引导用户输入,根据输入结果调用不同函数。
  • 截图:

你看!主函数就这么短!

3.4random(int n)函数(这个是原先定义的,后来发现这样会引起其他问题,就没有调用它了,就放在那里当公式了。)

  • 功能:根据不同需要,取不同类型的随机数。
  • 思路:把每种不同类型的随机数编号,调用时根据读入的编号n来决定随机数类型,再返回随机数。
  • 截图:

3.5void one()函数

  • 功能:用于包括符号1年级水平的所以题目
  • 思路:根据输入的题型编号,来跳到对应的题目库
  • 截图:

注:2、3年级的函数与1年级的函数定义类似,稍有修改。

3.6two()函数

  • 功能:用于包括符号2年级水平的题目
  • 思路:根据输入的题型编号,来跳到对应的题目库
  • 截图:

3.7three()函数

  • 功能:用于包括符号3年级水平的题目
  • 思路:根据输入的题型编号,来跳到对应的题目库
  • 截图:

3.8AddAndSubtract()函数

  • 功能:随机生成加减法的题目。
  • 思路:根据输入的不同题目类型,利用随机数,确定两个运算数的值,再输出题目。
  • 截图:




注:乘除法的及混合运算的函数与加减法函数类似,稍作修改。

3.8MultiplicationAndDivision()函数

  • 功能:随机生成乘除法的题目。
  • 思路:根据输入的不同题目类型,确定两个运算数的值符合题目类型,输出题目。
  • 截图:



4.运行结果截图,测试用例。

一年级:

整十数加一位数的加法:

注:数据:D:整十数和一位数加减法

整十数减整十数的减法:

注:数据:E:整十数和整十数加减法

10以内三个数连加:

注:数据:G:10以内三个数加减法

100以内连加连减混合运算:

注:数据: I:100以内加减法

二年级:

1-9以内的表内乘除法:

注:数据:O:表内乘除法

整十数加整十数的加法(进位的):

注:数据: L:整十的加减法

尾数是0三位数加法(和在一千以内的):
随机太多了,我随机了很久,没碰到,我的整10的数,是在万以内的,这个随机,得看运气的,我可能比较,非。害。

整百数加减法(和超过一千的,退位的):

注:数据:M:整百的加减法

三年级:

三位数加三位数的加法(含连续进位的):

注:数据: S:三位数的加减法

一位数乘一位、二位、三位数:

注:数据:V:一位数与两位数的乘除法


注:数据:W:一位数与三位数的乘除法

整十数乘整十数:

注:数据:T: 整十与整十的乘除法

万以内的加减法:

注:数据:R:万以内的加减法

5. 调试碰到问题及解决办法

  • 1.如何取不同位数的随机数?
    • 比如一位数,原本我的代码是rand()%10,但是这样的话,会存在0,对九九乘法表的运算数来说,不应该有0,那怎么办呢?后来我改写了一下,改为random()%9+1,取9的余数,得到的结果范围是08,再加1的话,范围就是19,就是我们需要的范围啦!
    • 二位数的做法相类似:rand() % 90+10
  • 2.调试的时候发现自己随机出来的都是加法的运算?!
    • 刚刚开始以为是真的随机都是加号,次数多了就觉得不对,然后发现,我随机符号的时候,switch语句后面没有跟break,所以它一直执行到最后一个case语句,而最后一个case语句是令符号为加号。所以发现错误之后,我就立刻改正了。
  • 3.输入出错?
    • 在调试的时候,会遇到无法输入的情况。因为我的题目类型typle是字符型变量,缓冲区有一个换行符,因此读取下一个符号的时候,需要清除那个换行符。我是在输入输出的时候,加上一个getchar()来吸收换行符。
  • 4.随机数的除数为0?
    • 本来没意识到,后来调试的时候才发现忘记考虑这个了。因为是系统出的题,所以如果出的题不合法,就要重新出。我就给总体的出题函数套了个while(1),s得到随机数后,判断它是否为0,若为0,执行continue语句,即重新开始循环,重新输出,若合法,则输出题目,当然输出后面要加break,不然就会无限循环输出。我才不会告诉你我之前死循环了呢
  • 5.取随机数
    • 前面提到了,我本来是图方便,虽然后面发现也没有多方便定义了一个取随机数的函数,但是后来发现,如果我取的随机数是相同范围的时候,得到的两个数会相同,所以后面我就想着,反正都很麻烦,干脆之间用随机函数好了,然后就很粗暴完美地解决了这个问题。

6.大作业总结

  • 这个作业的话,就是慢慢写完的。先是列了个大框架,把需要的函数写出来,分配一下需要的功能,比如加减法、乘除法、混合运算、取随机数什么的。
    分配完了,再将各个部分填充完,把函数写完整。我自己的话,是把加减放在一起,乘除放在一起,这样可能会有点复杂,其实也可以把四则运算拆成4个函数,可能会更清楚吧。我写一半的时候意识到了这一点,但是写都写了,就不想重新改,因为改动的话,就是大篇幅的改了,我怕我把自己的思路弄乱,虽然本来可能就有点乱所以就继续按着原来的想法做了。因为种种原因,我的大作业可能还不是很细致,有一些题目没有办法做到,比如四则运算混合什么的。但是回顾整个过程,其实大部分还是不难的,就是比较繁琐,要写很多,要考虑很多,函数也是一层套一层,就需要更加细致地思考。说起来,我觉着函数的变量定义是很重要的,还有变量的命名,最好是能够区别开所以的变量,不论是局部变量还是全局变量,我的代码有一个不好的地方就是,我没有办法根据大写字母就知道它代表的题目类型是什么,我还需要和最前面的题目编号相对照。(如果读者有什么好的建议,可以在下面评论。)要我自己评价的话,我的代码可能还有很多需要改进的地方,比如输入输出提示可以多样化什么的,还有实现一些其他功能,比如计算正确率,根据正确率分析需要提高计算能力的部分习题啊什么的,说起来,能拓展的也很多。(就是有的我没什么思路,害)
原文地址:https://www.cnblogs.com/yubing----/p/11718856.html