第四次博客作业
0.展示PTA总分
1.本章学习内容
1.1函数定义、调用、声明
1.1.1函数定义
- 自定义函数与库函数
函数是一个完成特定工作的独立程序模块,有库函数和自定义函数两种。库函数编程时只要直接调用即可,自定义函数需要用户自己定义。 - 自定义函数定义的一般形式
函数类型 函数名 (形式参数表) /*函数首部*/
{
函数实现过程 /*函数体*/
}
(1)函数首部由函数类型、函数名和形式参数表组成,在函数的第一行。
(2)函数名是函数整体的称谓,需要一个合法的标识符表示。
(3)函数类型指函数结果返回的类型,一般与return语句中表达式的类型一致。
(4)形式参数表中给出函数计算所要用到的相关已知条件,以类似变量定义的形式给出。
函数首部后面不能加分号,它和函数体一起构成完整的函数定义。
*形式参数表不能写成double r,h
。
1.1.2函数调用
- 调用函数
定义一个函数后,就可以在程序中调用这个函数。 - 调用标准库函数
调用标准库函数时,只需在程序的最前面用#include 命令包含相应的头文件。 - 调用自定义函数
调用自定义函数时,程序中必须有与调用函数相对应的函数定义。 - 函数调用过程
(1)任何C程序执行,首先从主函数main()开始,如果遇到某个函数调用,主函数被暂停执行,转而执行相应的函数,该函数执行完后将返回主函数,然后再从原先暂停位置的位置继续执行。
(2)通常把调用其他函数的函数称为主调函数,被调用的函数称为被调函数。 - 函数调用的形式
函数调用的一般形式为:函数名 (实际参数表)
。
实际参数可以是常量、变量和表达式。
1.1.3函数原型声明
- 函数声明
C语言要求函数先定义后调用,就像变量先定义后使用一样。如果自定义函数被放在主调函数的后面,就需要在函数调用前,加上函数原型声明。 - 函数声明目的
目的主要是说明函数的类型和参数的情况,以保证程序编译时能判断对该函数的调用是否正确。 - 函数声明一般形式
函数类型 函数名(参数表);
即与函数定义中的第一行(函数首部)相同,并以分号结束。
函数声明是一条C语句,而函数定义时的函数首部不是语句,后面不能有分号。
如果在调用函数前,既不定义,也不声明,程序编译时会出错。
1.2全局、局部变量,静态局部变量
1.2.1局部变量和全局变量
- 局部变量
(1)C语言中把定义在函数内部的变量称为局部变量,局部变量的有效作用范围局限于所在的函数内部。形式参数是局部变量。
(2)使用局部变量可以避免各个函数之间的变量相互干扰。
局部变量一般定义在函数或复合语句的开始处,标准C规定其不能定义在中间位置。 - 全局变量
(1)C语言中把定义在函数外而不属于任何函数的变量称为全局变量。它对作用范围内所有函数都起作用。
(2)全局变量的定义格式与局部变量完全一致,只是定义位置不在函数内,它可以定义在程序的头部,也可以定义在两个函数的中间或程序尾部,只要在函数外部即可。
一般情况下把全局变量定义在程序的最前面,即第一个函数的前面。
由于全局、局部变量的作用范围不同,允许它们同名。但是当某函数的局部变量与全局变量同名时,在该函数中全局变量不起作用,而由局部变量起作用。
(3)全局变量可以帮助解决函数多结果返回的问题,但全局变量更多地用于多函数间的全局数据表示。
1.2.2静态局部变量
(1)在静态存储区中,除了全局变量外,还有一种特殊的局部变量,即静态局部变量。
(2)它存放在静态存储区不会像普通局部变量那样因为函数调用结束而被系统回收,它的生存周期会持续到程序结束。
(3)一旦含有静态局部变量的函数被再次调用,则静态局部变量会被重新激活,上次函数调用后的值仍然保存着,可供本次调用继续使用。
(4)静态变量定义格式:static 类型名 变量表
1.3C数据类型及注意点
1.3.1整型与整型变量
- 整型
整型是指不存在小数部分的数据类型。除了基本整型int以外,为了处理不同取值范围的整数,C语言提供了扩展的整数类型,它们的表示方法是在int之前加上限定词short、long或unsigned。 - 整型常量
(1)整型变量即常说的整数。
(2)C语言中的整数有十进制、八进制和十六进制三种表现形式。
(3)十进制整数由正、负号和阿拉伯数字0~9组成,但首位数字不能是0。八进制整数由正、负号和阿拉伯数字0~7组成,首位数字必须是0。十六进制整数由正、负号和阿拉伯数字0~9、英文字符a~f或A~F组成,首位数字必须有前缀0x或0X。
1.3.2字符型与字符型变量
- 字符型
(1)每个字符型数据在内存中占用一个字节,用于储存它的ASCII码。
(2)C语言中的字符具有数值特征,不但可以写成字符常量的形式,还可以用相应的ASCII码表示,即可以用整数来表示字符。
(3)字符型变量的值可以是字符或整数,它就可以被定义成整型变量;同时整型变量的值也可以是字符型数据,他可以被定义成字符型变量。即整型变量和字符型变量的定义和值都可以互相交换。
互换整型变量和字符型变量的定义和值时,整型数据的取值范围是有效的ASCII码。 - 字符型常量
(1)字符型常量指单个字符,用一对单引号及其所括起的字符来表示。如‘a'、’X'、‘?’、‘ ’等都是字符型常量。
(2)C语言中的字符具有数值特征,可以像整数一样参加运算,此时相当于字符的ASCII码进行计算。 - 转义字符
(1)有一些字符,如回车符、退格符等控制码,它们不能在屏幕上显示,也无法从键盘输入,只能用转义字符来表示。
(2)转义字符由反斜杠加上一个字符或数字组成,它能把反斜杠后面的字符或数字转换成别的意义。
虽然转义字符形式上由多个字符组成,但它是字符常量,只代表一个字符,它的使用方法与其他字符常量相同。
1.3.3实型和实型常量
- 实型
(1)实数类型又称浮点型,指存在小数部分的数。
(2)浮点型数据有单精度浮点型(float)和双精度浮点型(double)两种,它们表示数值的方法是一样的,主要区别在于数据的精度和取值范围有所不同。与float型数据相比,double型数据的精度高,取值范围大。
实数在计算机中只能近似表示,运算中也会产生误差!!! - 实型常量
实型常量即常说的实数,又称为浮点数,可以用十进制浮点表示法和科学计数法表示。实型常量都是双精度浮点型。
浮点表示法:实数由正号、负号、阿拉伯数字0~9和小数点组成,必须要有小数点,并且小数点的前后至少一边要有数字。
科学计数法:实数由正号、负号、数字和字母e(或E)组成,e是指数的标志,在e之前要有数据,e之后的指数只能是整数。(实数的科学计数法又称实数的指数形式)
1.4C运算符
1.4.1算数运算符
- 单目、双目运算符
(1)算数运算符分为单目运算符和双目运算符两类,单目运算符只需要一个操作数,而双目运算符需要两个操作数。
(2)单目运算符有自增(++)、自减(--)、正值(+)、负值(-);双目运算符有加(+)、减(-)、乘(*)、除(/)、取余(%)。 - 自增、减运算符
++、--有两个功能:
(1)使变量的值增1或减1。
(2)取变量的值作为表达式的值。
++n的运算顺序是:先执行n=n+1,再将n的值作为表达式++n的值;
n++的运算顺序是:先将n的值作为表达式n++的值,在执行n=n+1。
要慎用自增、减运算,尤其不要用它们构造复杂的表达式。
1.4.2赋值运算符
- 赋值运算符
C语言将赋值作为一种运算,赋值运算符=的左边必须是一个变量,作用是把一个表达式的值符给一个变量。赋值运算符的优先级比算数运算符低,它的结合方向是从右到左。 - 复合算术赋值运算符
+=、-=、*=、/=、%=都是复合算术赋值运算符。
1.4.3关系运算符
- 关系运算符
(1)<、<=、>、>=、==、!=都是关系运算符。
(2)关系运算符的优先级低于算术运算符,高于赋值运算符和逗号运算符,它的结合方向是从左到右的。
关系表达式的运算结果是1或0,当关系成立时关系表达式的结果是1,否则为0。
1.4.4逻辑运算符
- 逻辑运算符
(1)单目:逻辑非(!)、双目:逻辑与(&&)、逻辑或(||)。
(2)C语言提供了三种逻辑运算符,逻辑运算对象可以是关系表达式或逻辑量,逻辑运算的结果也是一个逻辑量,与关系运算一样,用整数1表示“真”,0表示“假”。
1.4.5位运算
- 位运算符
位运算符有按位“与”(&)、按位“或”(|)、按位“异或”(^)、取反(~)、左移(<<)、右移(>>)。
(1)位运算符中除~是单目运算以外,其余均为双目运算。
(2)位运算符所操作的操作数只能是整型或字符型的数据以及它们的变体。
(3)操作数的移位运算不改变原操作数的值。
1.4.6其他运算
- 长度运算符
长度运算符sizeof是一个单目运算符,用来返回变量或数据类型的字节长度。 - 特殊运算符
(1)()括号:用来改变运算顺序。
(2)[]下标:用来表示数组元素。
(3)*和&:与指针运算有关。
(4)->和.:用来表示结构分量。
(ch = getchars ( ) ) != '\n'和ch = getchars ( ) != '\n'不等价。
2.综合作业:小学生口算表达式自动生成系统
2.1模块流程图
2.2函数功能
void GradeOneMenu()//一年级
{
int grade = 1;
int num1;//用于计算的数字1
int num2;//用于计算的数字2
char ch;//运算符号
int temp;//当num1<num2时防止相减为负数,用于交换num1与num2
int result;//表达式的正确结果
int resultPlayer;//使用者输入的结果
int all;//使用者想做的题数
int right=0;//正确的个数
int acount=0;//使用者做完的题个数
system("cls");
printf("*********************一年级小朋友好!********************************\n");
printf("系统将随机生成一个口算式,如果您会做,则输入y,输入结果。\n");
printf("**如果您不想做,输入n退回主菜单。\n");
printf("***************************************************************\n");
printf("输入你想做的题数:");
scanf("%d",&all);
while (1)
{
//随机生成两个数字
num1 = Num(grade);
srand(time(0));
num2 = Num(grade);
//如果数字1大于数字2,则交换两个数字
if (num1 < num2)
{
temp = num1;
num1 = num2;
num2 = temp;
}
//随机生成一个运算符号
ch = Ch(1);
//运算出正确结果
switch (ch)
{
case '+':
result = num1 + num2;
break;
case '-':
result = num1 - num2;
break;
case '*':
result = num1 * num2;
break;
case '/':
if (num2 == 0)//如果产生的随机数字2,即除数为0则除数变为2
{
num2 = 2;
}
for (num1; num1 % num2 != 0; num1++)//如果数字1除以数字2除不尽,则数字1加1
{
continue;
}
result = num1 / num2;
break;
}
printf("%d %c %d = ",num1,ch,num2);//输出表达式
scanf("%d",&resultPlayer);
if (result == resultPlayer)//使用者计算正确
{
right++;
acount++;
printf("正确!");
}
else//使用者计算错误
{
acount++;
printf("答案是%d哦,继续加油!",result);//输出正确结果
}
if (acount<all)//未完成使用者所给出的题数
{
printf("是否继续答题y/n:");
}
else//完成使用者所给题数
{
End(all,right);//结束语
break;
}
char ch;
scanf("\n%c", &ch);
if (ch == 'n')
{
OperateMenu(1);
return;
}
else
{
continue;
}
}
}
int Num (int grade)//随机数函数
{
int num;//返回的随机数字
switch (grade)
{
case 1:
num = 1 + rand()%20;//一年级生出1到20的数字
break;
case 2:
num = 1 + rand()%100;//二年级产生1到100的数字
break;
case 3:
num = 1 + rand()%100;//三年级产生1到100的数字
break;
}
return num;
}
char Ch (int grade)//产生随机运算符号函数
{
int num = rand()%12;//随机中介
char ch;//返回的符号
switch (grade)
{
case 1:
if (num > 5)
{
ch = '+';
}
else
{
ch = '-';
}
break;
case 2:
if (num < 3)
{
ch = '+';
}
else if(num < 6)
{
ch = '-';
}
else if (num< 9)
{
ch = '*';
}
else
{
ch = '/';
}
break;
case 3:
if (num < 3)
{
ch = '+';
}
else if(num < 6)
{
ch = '-';
}
else if (num< 9)
{
ch = '*';
}
else
{
ch = '/';
}
break;
}
return ch;
}
void End(int all,int right)//结束语函数
{
double end;
end = 1.0*right / all;//计算正确率
printf("你的正确率是:%.2f\n",1.0*right/all);
if (end <0.2)
{
printf("你可能需要多加练习,别灰心,加油!\n");
}
else if (end<0.6)
{
printf("差点就及格了,加油!");
}
else if (end<0.7)
{
printf("差点就良好了,冲冲冲!");
}
else if(end<0.9)
{
printf("还不错!不想全对吗?");
}
else
{
printf("你太棒了!!");
}
OperateMenu(1);
}
2.3运行结果
2.4编程技巧总结
- 随机符号
可以巧妙运用随机数,运用分支结构生产随机符号。 - 清屏
适当清屏可以是界面更加美观、简单。