zoukankan      html  css  js  c++  java
  • C博客作业03--函数

    这个作业属于哪个班级 C语言--网络2011/2012
    这个作业的地址 C博客作业03--函数
    这个作业的目标 学习如何设计函数、C语言基本数据类型
    名字 黎钊涵

    展示PTA总分

    本章学习总结

    1.1 函数

    在C语言中,函数与编程是密切相关的,比如平常用到的printf、scanf,其实都是函数,他们是已经被编辑好的函数,放在了头文件中,如果我们想使用一个函数,就需要给它定义和声明,才能调用,使用函数可以使代码更加简洁规范,增强可读性,便于读者理解

    1.1.1 定义

    一个函数的定义其实需要三部分内容:函数返回值类型、函数名称、函数参数

    • 函数名称

    函数名实际上就是一个标识符,以字母或_(下划线)开始,后接任意数量的字母或数字或_(下划线)的组合,例如:lzhdsg 而不能表示为 lzh-dsg

    • 函数返回值

    函数的返回值则与函数所定义的类型密切相关,一般来说,函数返回的类型就是函数定义的类型,比如我们定义了一个函数类型为int,则它的返回值类型也为int,而如果定义函数类型为void,则此函数没有返回值

    • 函数参数

    函数参数分为实参和形参,实参就是拥有数据、实际上传输数据的参数,而形参就是没有实际数据要等待接受数据的参数;当我们调用之前所定义、声明的函数时,此函数传入的参数和函数体内接收到的参数其实并不是同一个变量,它们的值有可能相等,也可能不相等,如果对形参做出一个动作指令,实参可能不受影响;同时实参可以是常量、变量、表达式、函数等,形参与实参相对应,形参只能位于函数内部,它是在被调用时分配内存,一旦调用结束就立刻释放内存;除此之外,函数中的数据传递方向是单向的,只能由实参传递给形参,而不能把形参的值反向地传递给实参,也正因此,我们才说实参不因为形参的改变而改变,在函数调用过程中,形参的值发生改变并不会影响实参

    一般定义形式:

    函数类型  函数名(形参)
    {
       函数体
    }
    

    1.1.2 声明

    在调用某函数前应该对被调用函数进行声明,类似于使用变量前对变量进行说明,声明目的是使编译器系统知道被调函数返回值的类型,从而按照此类型做出相应的处理

    一般在文件头声明

    #include <stdio.h>
    
    int MAX(int x, int y);
    int MIN(int x, int y);
    
    ...
    

    也可以在函数头声明

    #include <stdio.h>
    
    int main(void)
    {
        int a = 2;
        int b = 5;
    
        int MAX(int x, int y);
        int MIN(int x, int y);
    
        ...
    

    1.1.3 调用

    声明之后,可以在需要的位置对函数进行调用

    ...
     printf("%d
    ", MAX(a,b));
     printf("%d
    ", MIN(a,b)); 
    ...
    

    1.1.4 代码总览

    int function( int x, int y );//函数声明
    int main()
    {
    m=function(j);
    }//函数调用
    int function( int x, int y )//函数定义
    {
    ...
    return a;//返回a的值给function,若函数头为void则无返回
    }
    

    1.1.5 小知识点

    在以下几种情况时可以省去对被调函数的函数说明(https://zhuanlan.zhihu.com/p/94377668)

    • 如果被调函数的返回值是整型或字符型时,可以不对被调函数作说明,而直接调用。这时系统将自动对被调函数返回值按整型处理

    • 当被调函数的函数定义出现在主调函数之前时,在主调函数中也可以不对被调函数再作说明而直接调用

    • 如在所有函数定义之前,在函数外预先说明了各个函数的类型,则在以后的各主调函数中,可不再对被调函数作说明。

    • 对库函数的调用不需要再作说明,但必须把该函数的头文件用include命令包含在源文件前部

    1.2 全局变量、局部变量、静态局部变量

    1.2.1 全局变量

    • 全局变量:定义在函数外而不属于任何函数的变量,生存周期贯穿整个程序执行过程

    • 存在意义:解决多个函数间的变量共用,它对作用范围内的所有函数都起作用

    • 作用范围:从定义开始到程序所在的文件结束

    • 定义位置:程序头部,两函数中间或程序尾部,只要在函数外部即可,一般位于程序的最前面,即第一个函数的前面

    • 例:

    #include<stdio.h>
    
    int x;                     //定义全局变量x
    
    int f();
    
    int main(void)
    {
      int a = 1;
      x = a;                   //对全局变量x赋值
      a = f();                 //a的值为4
      {
         int b = 2;
         b = a + b;            //b的值为6
         x = x + b;            //全局变量运算
      }
      printf("%d %d", a, x);
      return 0;
    }
    
    int f()
    {
      int x = 4;               //x为局部变量,在本函数中,全局变量x不起作用
      return x;
    }
    

    1.2.2 局部变量

    • 局部变量:定义在函数内部的变量,随着函数调用的结束而被系统回收

    • 存在意义:避免各个函数之间的变量相互干扰,便利结构化程序设计

    • 作用范围:所在函数内部

    • 定义位置:一般位于函数或复合语句的开始处,标准C规定不能定义在中间位置

    • 例:

    int main(void)
    {
     int a = i;          //主函数的局部变量
      {                  //复合语句开始
        int b = 2;       //复合语句内的局部变量
        ...
      }                  //复合语句结束
     printf("%d", a);
     return 0;
    }
    

    1.2.3 静态局部变量

    • 静态局部变量:一种特殊的局部变量,存放在静态存储区,不会像普通函数一样因为函数调用的结束而被系统回收,它的生存周期和全局变量一样,会持续到程序结束, 如果定义没有赋初值,系统将自动赋0,若赋初值也只在第一次调用时起作用,从第二次调用开始,都按前一次调用保留的值使用

    • 存在意义:拥有能力与局部变量相同,生存周期与全局变量相同,有点二者取优结合的意思

    • 作用范围:只能用于所定义函数,不能用于其他函数(包括主函数)

    • 定义格式:static 类型名 变量名

    • 例:

    ...
    static double f = 1;    //定义静态变量,第一次赋值为1
    f = f * n;              //上一次调用的值再乘n
    ...
    

    1.3 C数据类型及注意点

    注意数据类型以及取值范围

    1.3.1 整型变量

    • int类型
      取值范围(16位):-32768~32767(-2^15— 2^15-1)
      转换说明:%d

    • short类型
      取值范围(16位):-32768~32767(-2^15— 2^15-1)
      转换说明:%d

    • long类型
      取值范围(16位):取值范围(16位)-2147483648~2147483648(-2^31— 2^31-1)
      转换说明:%ld

    1.3.2 浮点型变量

    • 单精度float
      取值范围:10^-37 —10^37
      转换说明:%f

    • 双精度double
      取值范围:(2^63— 2^63-1)
      转换说明:%f

    1.4 C运算符

    • 逻辑运算符

      • “与” :“&&”
      • “或”:“||”
    • 关系运算符

      • “等于”:==
      • “小于”;<
      • “大于”;>
      • “小等于”:<=
      • “大等于”;>=
      • “不等于”;!=

    注意“等于”是“==”不是“=”,“=”为赋值,将右边的值赋给左边

    • 算术运算符

      • 加:+
      • 减:-
      • 乘:*
      • 除:/
      • 取余:%
      • 自加:++
      • 自减:--

    注意“乘”是“*”不是“×”

    综合作业(6分):小学生口算表达式自动生成系统

    2.1.模块流程图



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

    2.2.1.全局变量

    int GatValue1();//生成一位随机数
    int GatValue2();//生成两位随机数
    char GetSymbol();//生成二则运算符
    char GetSymbo2();//生成四则运算符
    void Expression(int num1, char op, int num2);//生成随机表达式
    void Rewards();//奖励小朋友的话
    void Encouragements();//鼓励小朋友的话
    

    2.2.2 菜单相关函数

    void OperateMenu();//游戏操作界面
    void GradeOneMenu();//一年级
    void GradeTwoMenu();//二年级
    void GradeThreeMenu();//三年级
    
    • 主菜单
    int main(void)
    {
    	OperateMenu();//游戏操作界面	
    	return 0;
    }
    void OperateMenu()//游戏操作界面
    {
    	char option;
    	int temp;
    	system("cls");//清屏
    
    	do
    	{
    		system("cls");
    		printf("******************************************
    ");
    		printf("1.一年级口算
    ");
    		printf("2.二年级口算
    ");
    		printf("3.三年级口算
    ");
    		printf("4.退出系统
    ");
    		printf("******************************************
    ");
    		printf("请输入您的选择:");
    		scanf(" %c", &option);
    		switch (option)
    		{
    		case '1':
    			system("cls");
    			GradeOneMenu();//一年级函数调用
    			break;
    		case '2':
    			system("cls");
    			 GradeTwoMenu();//二年级函数调用
    			break;
    		case '3':
    			system("cls");
    			GradeTwoMenu();//三年级函数调用
    			break;
    		case '4':
    			printf("
    谢谢您的参与!
    ");
    			Sleep(500);
    			exit(0);
    		default:
    			printf("您输入不对,只能输入1,2,3,4,请重输!
    ");
    			Sleep(500);
    		}
    	} while (!(option >= '1' && option <= '4'));
    }
    
    • 一年级操作系统
    void GradeOneMenu()//一年级
    {
    
    	while (1)
    	{
    		system("cls");//清屏
    		printf("*********************一年级小朋友好!********************************
    ");
    		printf("系统将随机生成一个口算式,如果您会做,则输入y,输入结果。
    ");
    		printf("**如果您不想做,输入n退回主菜单。
    ");
    		printf("***************************************************************
    ");
    
    		/*1.生成操作数函数*/
    		int num1, num2;
    		srand(time(0));
    		num1 = GatValue1();
    		num2 = GatValue1();
    	
    		/*2.生成随机运算符函数*/
    		char op;
    		op = GetSymbol();
    		/*3.根据年级判断生成的表达式是否合理的函数(选做)*/
    		int temp;
    		if (op == '-' && num1 < num2)
    		{
    			temp = num1;
    			num1 = num2;
    			num2 = temp;
    		}
    		/*4.生成表达式函数,并输出展示*/
    
    		Expression(num1, op, num2);
    		printf("是否继续答题
    ");
    		char ch = 0;
    		scanf("
    %c", &ch);
    		if (ch == 'y')//选择答题
    		{
    			/*答题模块*/
    			int yourNumber, result;
    			int right = 0, wrong = 0;
    			int count = 0;
    			switch (op)
    			{
    			case'+':result = num1 + num2;
    				break;
    			case'-':result = num1 - num2;
    				break;
    			}
    			printf("请你输出你滴回答哟:");
    			scanf("%d", &yourNumber);
    			if (yourNumber == result)
    			{
    				Rewards();
    				right++;
    			}
    			else
    			{
    				Encouragements();
    				printf("正确答案是:
    ");
    				printf("%d", result);
    				wrong++;
    			}
    			count++;
    			printf("是否继续答题
    ");
    			scanf("
    %c", &ch);
    			if (ch == 'n')
    			{
    				printf("小朋友你的成绩为:答对题数:%d 答错题数:%d 共答题数:%d ", right, wrong, count);
    				right = 0;
    				wrong = 0;
    				count = 0;
    			}
    
    		}
    		else
    			OperateMenu();//返回主菜单
    	}
    	return;
    }
    
    • 二年级操作系统
    void GradeTwoMenu()//二年级
    {
    	
    	while (2)
    	{
    		char op=0;
    		system("cls");//清屏
    		printf("*********************二年级小朋友好!********************************
    ");
    		printf("系统将随机生成一个口算式,如果您会做,则输入y,输入结果。
    ");
    		printf("**如果您不想做,输入n退回主菜单。
    ");
    		printf("***************************************************************
    ");
    
    
    		/*生成随机操作数*/
    		int num1, num2;
    		srand(time(0));
    		num1 = GatValue2();
    		num2 = GatValue2();
    		
            op= GetSymbol();//生成二则运算符
    		
    
    		/*3.根据年级判断生成的表达式是否合理的函数(选做)*/
    		int temp;
    		
    		if (op == '-' && num1 < num2)
    		{
    			temp = num1;
    			num1 = num2;
    			num2 = temp;
    		}
    		/*4.生成表达式函数,并输出展示*/
    		Expression(num1, op, num2);
    		printf("是否继续答题
    ");
    		char ch = 0;
    		scanf("
    %c", &ch);
    		if (ch == 'y')//选择答题
    		{
    			/*答题模块*/
    			int yourNumber, result;
    			int right = 0, wrong = 0;
    			int count = 0;
    			switch (op)
    			{
    			case'+':result = num1 + num2;
    				break;
    			case'-':result = num1 - num2;
    				break;
    			}
    			printf("请你输出你滴回答哟:");
    			scanf("%d", &yourNumber);
    			if (yourNumber == result)
    			{
    				Rewards();
    				right++;
    			}
    			else
    			{
    				Encouragements();
    				printf("正确答案是:
    ");
    				printf("%d", result);
    				wrong++;
    			}
    			count++;
    			printf("是否继续答题
    ");
    			scanf("
    %c", &ch);
    			if (ch == 'n')
    			{
    				printf("小朋友你的成绩为:答对题数:%d 答错题数:%d 共答题数:%d ", right, wrong, count);
    				right = 0;
    				wrong = 0;
    				count = 0;
    				Sleep(800);
    
    			}
    
    		}
    		else
    			OperateMenu();//返回主菜单
    	}
    	return;
    }
    
    • 三年级操作系统
    void GradeThreeMenu()//三年级
    {
    	char op;
    	int num1;
    	int num2;
    	int N;
    	int temp;
    	while (3)
    	{
    		system("cls");//清屏
    		printf("*********************三年级小朋友好!********************************
    ");
    		printf("系统将随机生成一个口算式,如果您会做,则输入y,输入结果。
    ");
    		printf("**如果您不想做,输入n退回主菜单。
    ");
    		printf("***************************************************************
    ");
    
    
    		/*2.生成随机运算符函数*/
    		op = GetSymbo2();
    		/*1.生成操作数函数*/
    		if (op == '*' || op == '/')//三年级小朋友需要1位数乘2位数,2位数除以1位数
    		{
    			num1 = GatValue2();
    			num2 = GatValue1();
    			N = num1 * num2;
    		}
    		else
    		{
    			num1 = GatValue2();
    			num2 = GatValue2();
    		}
    
    		/*3.根据年级判断生成的表达式是否合理的函数(选做)*/
    		if (op == '-' && num1 < num2)
    		{
    			temp = num1;
    			num1 = num2;
    			num2 = temp;
    		}
    
    		/*4.生成表达式函数,并输出展示*/
    		Expression(num1, op, num2);
    		printf("是否继续答题
    ");
    		char ch = 0;
    		scanf("
    %c", &ch);
    		if (ch == 'y')//选择答题
    		{
    			/*答题模块*/
    			int yourNumber, result;
    			int right = 0, wrong = 0;
    			int count = 0;
    			switch (op)
    			{
    			case'+':result = num1 + num2;
    				break;
    			case'-':result = num1 - num2;
    				break;
    			case'*':result = num1 * num2;
    				break;
    			case'/':result = num1 / num2;
    				break;
    			}
    			printf("请你输出你滴回答哟:");
    			scanf("%d", &yourNumber);
    			if (yourNumber == result)
    			{
    				Rewards();
    				right++;
    			}
    			else
    			{
    				Encouragements();
    				printf("正确答案是:
    ");
    				printf("%d", result);
    				wrong++;
    			}
    			count++;
    			printf("是否继续答题
    ");
    			scanf("
    %c", &ch);
    			if (ch == 'n')
    			{
    				printf("小朋友你的成绩为:答对题数:%d 答错题数:%d 共答题数:%d ", right, wrong, count);
    				right = 0;
    				wrong = 0;
    				count = 0;
    				Sleep(800);
    
    			}
    
    		}
    		else
    			OperateMenu();//返回主菜单
    	}
    	return;
    }
    

    2.2.2 出题相关函数

    int GatValue1()//随机生成一个操作数
    {
    	int num;
    	num = 1 + rand() % 9;//一年级1到10
    
    	return num;
    }
    int GatValue2()//随机生成2个操作数
    {
    	int num;
    	num = 1 + rand() % 100;//一年级1到100
    	return num;
    }
    
    
    char GetSymbol()//生成二则运算符
    {
    	char op;
    	int num;
    	srand(time(0));
    	num = rand() % 2;
    	switch (num)
    	{
    	case 0:op = '+';
    		break;
    	case 1:op = '-';
    		break;
    	}
    	return op;
    }
    char GetSymbo2()//生成四则运算符
    {
    	char op=0;
    	int num;
    	switch (num)
    	{
    	case 0:op = '+';
    		break;
    	case 1:op = '-';
    		break;
    	case 2:op = '*';
    		break;
    	case 3:op = '/';
    		break;
    	}
    	return op;
    }
    
    
    void Expression(int num1, char op, int num2)//生成随机表达式
    {
    	printf("%d %c %d =
    ", num1, op, num2);
    }
    void Rewards()//奖励小朋友的话
    {
    	int a;
    	srand(time(0));//随机种子
    	a = 1 + rand() % 3;
    	switch (a)
    	{
    	case 1:printf("对啦!太棒了小朋友!
    ");
    		break;
    	case 2:printf("哇哦!又对了!
    ");
    		break;
    	case 3:printf("对了对了又对了!
    ");
    		break;
    	case 4:printf("厉害了小朋友!
    ");
    		break;
    	}
    	printf("
    ");
    }
    void Encouragements()//鼓励小朋友的话
    {
    	int a;
    	srand(time(0));//随机种子
    	a = 1 + rand() % 3;
    	switch (a)
    	{
    	case 1:printf("没关系的
    ");
    		break;
    	case 2:printf("哎呀又错啦!没关系我们再来一次!
    ");
    		break;
    	case 3:printf("失败是成功之母,再来!
    ");
    		break;
    	case 4:printf("没事没事继续加油哦!
    ");
    		break;
    	}
    	printf("
    ");
    }
    

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

    • 以一年级为例

    一年级界面

    回答正确

    回答错误

    统计答题情况

    2.4.大作业中编程技巧总结

    2.4.1 随机数生成

    2.4.2 延迟界面

    知道了可以用Sleep(数字)来延迟界面,括号内数字为延迟的时间

    例:

    这样待会儿统计答题情况的时候就能延缓,让小朋友有充分的时间看清并记录自己的答题情况

    2.4.3 感悟思考

    • 首先,大作业本身是一道综合性很强的题目,看似简单的小学生运算系统设计,其中却掺杂着大量的程序设计知识以及现实生活知识。就程序设计而言,哪里需要设计函数,需要设计几个函数,如何正确设计函数,函数内又需要设计什么内容,如何定义变量,如何通过变量正确表达各种值和话语,种种问题都需要我们进行冷静地思考,深入的分析,理性地探究,大胆地实践,方能找到解决问题的方法;就现实生活而言,一年级的小学生学习范围是哪里,二年级三年级又分别覆盖了什么知识,是否还像我们小时候那样,哪些知识点有出现较大增删减改,题目难度又如何把控,究竟是“一视同仁”,难度确定,做完即止,还是“因人而异”,可以主动提升难度,体现区分度,这些问题其实都需要考虑进去,因为这道题目是一道现实应用题,与现实生活有密切联系,我们必须基于生活实际进行程序设计,这样设计出的程序才能更好地与现实接轨,应用于现实生活。

    • 其次,在编程过程中,我发现了很多问题,先说程序设计,比如对于随机数部分的设计,我发现我对于随机数的理解还很浅,并没有真正掌握它的用法,或许只是懂得有这么一个东西叫做随机数,但是到底是什么、怎么用就模糊不清;再比如对于操作系统设计的不理解,一开始特别蒙,完全不知道从哪里下手,还记得实验课的时候,老师提醒了两次,我依然一头雾水,真是丈二和尚摸不着头脑,好在最后终于敲下了熟悉的#include<stdio.h>,也算是从0到1的第一步正式迈出,这门课就是这样,一定要大胆实践,空想没有用,想不出来就先试试看,试试看说不定就出来了;再说现实生活,我一开始压根就没考虑到这一层面,根本没有这个意识,所以在课堂上老师提出的时候我一下子还没反应过来:what?还要考虑这个?转念一想,对啊,这是个现实问题啊,当然需要!今后考虑问题也会更多地从实际出发,从现实出发,充分考虑到各种现实因素对程序的影响,再进行程序设计。

    • 再者,对于C语言这门学科,我又有了新的理解。感觉它跟数学挺像的,逻辑性很强,前面是什么、后面是什么都很有条理,并且非常注重细节,别说一行代码、一个单词,哪怕是一个符号也不能错,我这次又出现了许多次的编译错误、格式错误,真是非常头疼,却也无可奈何,只能细心检查、耐心纠错,除此之外别无他法;它也和英语很像,注重语法,强调定义,不说种类繁多的命名法,单论各种变量的定义格式、各种函数的使用法则,都需要熟记于心,做到胸有成竹。死记硬背肯定不行,需要自己多实践多动手敲代码,自然能记熟、记牢。现在回过头再看老师常说的那句“代码量不够”,似乎不再是那么平淡,很多问题的根本原因就真的是代码量不够,因为代码量不够,所以会出现各种低级错误;因为代码量不够,所以遇到新的问题不懂如何设计程序;因为代码量不够,所以对C语言不熟,看不到问题本质,换个面就以为它是新的头,再费大量功夫死研究,到头来也没研究出个所以来。

    • 最后,再接再厉吧,现在已经感受到在这门学科上自己存在的诸多不足了, 但也逐渐摸清了C语言的学习正确学习方法,继续努力即可。它比想象中更难,也比想象中更简单。

  • 相关阅读:
    token是什么?和session什么区别,怎么用
    HashTable详解
    Cookie和Session的区别
    测试基础面试题
    什么是回归测试?回归测试的主要目的是什么?
    每天一个linux常用命令--ls 和 -ll 有什么区别?
    python中6个序列的内置类型分别是什么,列表和元组的异同有哪些
    今天去面试自动化测试,被几个问题问住了,记录下
    python排序算法-冒泡和快速排序,解答阿里面试题
    Myeclipse使用积累
  • 原文地址:https://www.cnblogs.com/jmlzh/p/14064163.html
Copyright © 2011-2022 走看看