| 这个作业属于哪个班级 | C语言--网络2011/2012 |
| ---- | ---- | ---- |
| 这个作业的地址 | C博客作业03--函数 |
| 这个作业的目标 | 学习如何设计函数、C语言基本数据类型 |
0.展示PTA总分
1.本章学习总结
1.1 函数定义、调用、声明
- 函数的定义:函数类型 函数名 ( 形参表 ) //函数头
{
执行语句 //函数体
return 语句 //结束函数,函数返回值
} - 函数的调用:函数名( 实参 )
* 注:若函数没有需要传入的参数,也需要圆括号来表示这是一个函数。
* 注:函数在调用之前必须要先有定义。
* 注:一般调用之前要有函数的声明。若函数定义在调用地方的上面,则不进行声明,也能编译成功,但不推荐使用。 - 函数的声明:函数类型 函数名 ( 参数表 );
* 注:函数的声明即为函数头加上分号 - 注意事项:
- 函数的参数是单向传递的,两个函数中,相同变量名的局部变量没有关系。
1.2 全局、局部变量、静态局部变量
- 全局变量:
- 在函数外定义的变量,不属于任何一个函数
- 作用范围:从定义开始,到源文件结束(在各个函数中均可使用)
- 局部变量:
- 1.在函数内定义的变量,包含函数的形参
- 2.在复合语句内定义的变量
- 备注:
- 若全局变量和局部变量同名,局部变量优先
- 在较大的程序中,过多地使用全局变量,可能导致不同函数之间的相互干扰
- 应尽量使用局部变量,避免不同函数间的相互干扰,提高代码质量
- 全局变量适用于某些变量值其它函数共享的情况
- 静态、动态变量
- 动态变量:
自动变量、普通局部变量
* auto int number; 其中"auto"可省略
* 动态变量若没有赋初值, 存储单元中将会是随机值
* 函数调用时,定义变量,分配存储单元
——>函数调用结束,收回存储单元 - 静态变量:
全局变量、静态局部变量
* 静态局部变量:static int number;
* 静态变量若没有赋初值,系统将自动赋0。(注意: 赋初值只在函数第一次调用时起作用,以后调用都按照前一次调用的值保留)
* 从变量定义开始,到程序结束,始终存在。(注意:虽然始终存在,但是静态局部变量仍受到变量作用范围限制,不能作用于其它函数(包括主函数))
- 动态变量:
1.3 C数据类型及注意点
- 无符号数据类型:没有符号位
- 有符号数据类型:最左边一位表示符号位
- 短整型: short (int) ———>2个字节
- 整型: int ———>4个字节
- 长整型: long int (备注:VS中long 仅有4个字节,而 long long 才有8个字节。输出时,printf("%lld",number);
- 浮点型(实型):
- 单精度浮点型: float ———>4个字节
- 双精度浮点型: double ———>8个字节
- 字符型:
- 字符型:char ———>1个字节
- 备注:
- double 类型的表数范围比long long类型的大
- 实数类型的变量有浮点误差,所以实数一般直接判断相等,而是如判断number等于5:
fabs(number - 5)<0.000001
--
- 整数的表示
- 十进制:0~9
例如:99 - 八进制:0~7,且首位为0
例如:077 - 十六进制:09,af,A~F,且首位为0X或0x
例如:0x2ad
- 十进制:0~9
- 实数的表示
- 浮点表示:12.0 12. .12
- 科学计数法:6.02-E27 1.2e+37 1E+5
(指数只能是整数。E前要有数字) - 指数型输入float(%e),double(%le)。指数型输出(%e)
--
- 格式说明
十进制 八进制 十六进制 int %d %o %x long %ld %lo %lx unsigned %u %o %x unsigned long %lu %lo %lx
--
1.4 C运算符
- 位运算符:
运算符 | 说明 |
---|---|
& | 按位与 |
^ | 按位异或 |
~ | 按位取反 |
<< | 左移 |
>> | 右移 |
- 位运算符
- &:按位与,一位为0,则为0;全部为1才为1;
- |:按位或,全部为0,才为0;一位为1就为1;
- ^:按位异或,(双目运算符),相同则为1,不同则为0;
- ~:按位取反,就是取反
- <<:左移,(双目运算符)(例子:number << 3),将数值向左移3位,空出的位用零填补
- >>: 右移,(双目运算符)
- 备注:
* 左(右)移一位相当于乘(除以)2
* 左(右)移动不改变原本操作数的数值
- 算术运算符:
-
单目:+、-、++、--
同优先级时:右结合(从右向左) -
双目:+、-、*、/、%
同优先级时:左结合(从左向右)、(加减优先级比乘除低) -
备注:
* 单目运算符仅需要一个操作数
* 双目运算符的两个操作数如果数据类型不同,将进行自动类型转换后再进行计算
* % 的两个操作数都必须是整数
* 赋值运算的优先级很低,从右向左 -
其它运算符:sizeof()
* 计算变量或数据类型的字节长度
* sizeof(int)
* int number;
sizeof(number); -
复合运算符:
-
复合算术赋值运算符 | 复合位赋值运算符 |
---|---|
+= | &= |
-= | |= |
*= | |
/= | |
%= |
- 逻辑运算符:&&、||、!
- 优先级:!>&&>||
- 逗号表达式:
- 表达式1,表达式2,......,表达式n
依次计算表达式1、2、3...... n 的值,并将表达式 n 的值作为逗号表达式的值 - 逗号运算符的优先级最低,左结合(从左向右)
- 表达式1,表达式2,......,表达式n
2.综合作业:小学生口算表达式自动生成系统
2.1.模块流程图
2.2.函数功能及全局变量介绍
- /Menu/
- void OperateMenu(); //游戏初始菜单
- void GradeOneMenu(); //一年级菜单
- void GradeTwoMenu(); //二年级菜单
- void GradeThreeMenu(); //三年级菜单
- void Encourage(double rate, int sumCount); //鼓励小朋友
- /Calculation/
- int RandomOperands(int grand); //随机操作数
- char RandomOperator(int grand); //随机运算符
- double FormulaAndAnswer(int grand); //生成算式
- /Judgement/
- double IsCorrect(int value1, int value2, char operate); //判断正确与否,计算正确率
- void IsChallenge(double rate, int level); //小朋友的挑战题目
2.2.1.全局变量
int sumCount = 0; //做题数
int correctCount = 0; //正确回答的题数
2.2.2 菜单相关函数
void GradeOneMenu(); //一年级菜单
void GradeTwoMenu(); //二年级菜单
void GradeThreeMenu(); //三年级菜单
- 功能:
- 实现人机交互。输出菜单,用户可以输入答案,也可以选择是否继续答题。
- 输出答题数、正答率,答题情况,增强用户的操作体验。
- 思路
- 输出是否答题界面,用户决定是否答题。
- 若用户选择答题,则输出算式,并在用户答错后输出正确答案。
- 若用户结束答题,计算并输出用户答题数、正答率。
- 判断正答率是否高于80%,若高于,则邀请用户进行“挑战”。
- 若用户意外输出不合法数值,请求用户重新输入。
- 代码:
--
void Encourage(double rate, int sumCount); //鼓励小朋友
- 功能:
- 根据小朋友的正答率、答题数,输出相应的随机语句。
- 增强人机交互的感觉,提高用户体验。
- 思路
- 将正答率分为(0,60)、60、(60,90]、(90,100]四个范围,根据不同范围,输出不同的话语。
- 若正答率为100,且答题数>9,则输出特殊的话语。
- 代码:
2.2.2 出题相关函数
int RandomOperands(int grand); //随机操作数
char RandomOperator(int grand); //随机运算符
double FormulaAndAnswer(int grand); //生成算式
-
功能:生成随机操作数、生成随机运算符、输出合理算式
-
思路:
随机操作数- 利用switch-case函数进入生成不同年级的操作数分支
- 利用rand()函数生成随机操作数,返回操作数的值
随机运算符 - 利用rand()函数随机生成1~4的值
- 根据switch-case进入不同年级分支
- 进入后,再利用switch-case,根据随机生成的1~4选择运算符,返回运算符
生成算式 - 先判断是否是减法、除法
- 如果是减法,判断操作数1是否大于操作数2,因为小朋友不会负数。若操作数1大于操作数2,则交换两个操作数
- 如果是除法,判断是否能整除,若不能整除,再重新调用函数生成随机数,直到能够整除
- 判断算式合理后,输出算式,同时将操作数、运算符传入判断正误的函数,得到正答率(正误判断函数中,定义全局变量总题数和全局变量正确答题数,每次均返回正答率,覆盖)
-
代码:
随机操作数:
随机运算符:
生成算式:
2.2.3 判断正误相关函数
double IsCorrect(int value1, int value2, char operate); //是否正确,计算正确率
- 功能:判断用户输入的答案是否正确,若错误,则输出正确的答案
- 思路:
- 为避免调皮的小朋友输入字符而不是数字,采用字符型输入,再转化为数值
- 若用户输入非法数值,输出错误提醒,让用户重新输入
- 利用switch - case根据运算符进入不同的运算分支,得出正确答案
- 将正确答案与用户的答案比对,若正确,则恭喜答对。并将正答数、总题数加1
- 若答案不符,提示答错,输出正确答案。并将总题数加1
- 因为总题数和正答数为全局变量,所以,计算正答率 rate,并返回。随着答题的进程,rate不断更新
- 代码:
2.3.运行结果截图,测试用例
2.4.大作业中编程技巧总结
- 睡眠函数的使用
#include <windows.h> //头文件
Sleep(1000) //1000为1000毫秒
- 清屏函数的使用
#include <stdlib.h> //头文件
system("cls"); //清屏
- 将输入的字符型的数字,转化为整型的数字
while (1)
{
scanf("%c", &ch);
if (ch >= '0' && ch <= '9')
{
ch = ch - '0';
personNum = personNum * 10 + ch;
flag = 1;
}
else
{
if (ch != '\n')
{
printf("输入有误,请输入数字\n");
Sleep(1000);
personNum = 0;
flag = 0;
}
}
if (ch == '\n' && flag == 1)
{
break;
}
}
- 定义函数,利用switch-case,根据年级生成随机操作数、随机运算符