C语言博客作业05——指针
1.本章学习总结
1.1思维导图
1.2本章学习体会及代码量
1.2.1学习体会
可能因为之前数组那块儿的作业拖得太久了,以至于我觉得指针学的好快,还没反应过来就教完了,然后一开始做题的时候,就是一脸懵逼得状态。然后前段时间也都在不数组的作业,指针也没好好看看书,也就上课的时候听听老师讲课,然后后面做题,一不会就去翻书,一来二去的虽然还是不很明白指针到底怎么回事,但是大概的题目也都会做了。然后现在我把指针跟结构体的题目集都刷完了,也该好好补补指针的知识点了。
1.2.2代码累计
2.PTA总分
2.1截图PTA中指针题目集的排名得分
2.2我的总分
PTA总分:110
3.PTA实验作业
3.1PTA题目1
反话-加强版
给定一句英语,要求你编写程序,将句中所有单词的顺序颠倒输出。
3.1.1算法分析
定义整型变量:i、j、k=0、count=0、length、temp
定义字符型指针:ch
ch=(char *)malloc(500001*sizeof(ch));//通过malloc把较大的数组放到堆区,防止爆栈
输入字符串ch
通过strlen函数得到字符串ch的长度
temp=length-1 //解决末尾为空格的情况
while length-- do
while ch[k]为空格 do //解决前面有连续空格的情况
k++
end while
if length=0 且 ch[0]!=' ' then
for j=0 to count do
putchar(*(ch+j)) //输出开头不为空格时的单词
end for
end if
if ch[length] 不为空格 then
count++
else if ch[length]为空格 且 ch[length+1]不为空格 且 length不是字符串尾 then
for i=1 to count do
putchar(*(ch+length+i))
end for
if length+1!=k then
printf(" ")
end if
count=0
else if ch[length]为空格 且 ch[length+1]为空格 或者 ch[length]为空格 then
continue
end if
end while
3.1.2代码截图
3.1.3PTA提交列表及说明
- Q:一开始直接用printf输出,然后输出的都是这样子的
- A:运行之前,我一直把printf认为是跟scanf一样的,遇到空格就停下来,结果是我太天真了…然后当时可能脑子有点抽了,一直想不到除了printf和puts()还有什么输出方式,然后又用循环和printf一个一个字符的输出,结果…不知道为什么输出了一堆乱七八糟的东西。然后过了好久好久才想到了putchar()这个家伙,运行了一下结果对了,就提交了。
- Q:兴致冲冲的提交完之后他告诉我:部分正确…
- A:然后看了一眼测试点,三个没过:一个词,末尾有空格、最小词,前有空格、只有空格,然后经过一番改动,自认为可以过了,结果一提交,还是部分正确…再看一眼,最小词,前有空格这个点还是没过,我想着我已经把开头第一个是空格的情况加进去了,怎么会还错,然后一调试,发现当开头是连续空格的时候,我的输出是错的,输出多了空格。突然想起来大作业里消除非法字符串的做法,想想这里的情况也差不多,就用了一个while解决了开头的连续空格的问题。
4.大作业
题目:实现小学四则运算。
在函数那章,我们已经实现小学四则运算这份作业,现在要求大家把之前设计函数升级改造,原来的函数大家都是用全局变量实现不同函数参数传递,这次作业要求改地址传递,减少全局变量的使用。
题目要求:
题目有3个难度级别,分别为:
- 第一级是1位数的一步加减乘除计算
- 第二级是2位数的2步加减运算
- 第三级是3位数的2步加减运算
4.1改造函数介绍
1.构造字符数组存放算术表达式
*char CreateExp(char exp,char level);
- 伪代码
定义整型变量num、op(获取随机数)、i,字符型数组str[10](用于整型转字符型存放)
srand(time(NULL)) //获取随机数种子
if level=='1' then
i=3 //一级运算数及运算符的总和
while --i do
if i为偶数 then
num=rand()%10;
itoa(num,str,10)//将整型变量num转化为字符型变量存入数组str中
strcat(exp,str);//将str数组中的字符串接在exp数组后
else
op=rand()%4;
switch(op)//随机获取运算符,并接在数组exp后
case 0: strcat(exp,"+");;break;
case 1: strcat(exp,"-");break
case 2: strcat(exp,"*");break;
case 3: strcat(exp,"/");break;
end if
end while
else//当level为2或3时
i=5 //二(三)级运算数及运算符的总和
while --i do
if i为偶数 then
if level=='2' then
num=rand()%100
else
num=rand()%1000
end if
itoa(num,str,10)//将整型变量num转化为字符型变量存入数组str中
strcat(exp,str);//将str数组中的字符串接在exp数组后
else
op=rand()%4;
switch(op)//随机获取运算符,并接在数组exp后
case 0: strcat(exp,"+");;break;
case 1: strcat(exp,"-");break
end if
end while
end if
strcat(exp,"=")//将等号接在表达式后
if 表达式合法 then
输出表达式
else
返回CreateExp(exp,level)函数,重新创建表达式
return *exp//返回指针*exp
- 函数代码
char CreateExp(char *exp,char level)//构造字符数组存放算术表达式
{
int num,i;
int op;
char str[10];
srand(time(NULL));
if(level=='1')
{
i=3;//运算数及运算符的总和
do
{
if(i%2)
{
num=rand()%10;
itoa(num, str, 10);
strcat(exp,str);
}
else
{
op=rand()%4;
switch(op)
{
case 0: strcat(exp,"+");;break;
case 1: strcat(exp,"-");break;
case 2: strcat(exp,"*");break;
case 3: strcat(exp,"/");break;
}
}
}while(--i);
}
else
{
i=5;//运算数及运算符的总和
do
{
if(i%2)
{
if(level=='2')
num=rand()%100;
else
num=rand()%1000;
itoa(num, str, 10);
strcat(exp,str);
}
else
{
op=rand()%2;
switch(op)
{
case 0: strcat(exp,"+");break;
case 1: strcat(exp,"-");break;
}
}
}while(--i);
}
strcat(exp,"=");
if(IsExp(exp,level))//判断表达式是否合法
printf("\n\t\t\t\t%s",exp);
else
return CreateExp(exp,level);//表达式不合法时返回CreateExp(exp,level)函数,重新创建表达式
return *exp;
}
2.表达式是否合法
*int IsExp(char exp,char level);
- 伪代码
if 等级为二、三级 then //二三等级不含除法,即不存在表达式不合法情况
return 1;
定义整型变量m=0,sum=0,i=0、字符型变量c=exp[i],oldc='+'
while c!='=' do
c=exp[i]
if c为数字 then
m=10*m+c-'0'//将字符型数字转化为整型数字
else
if oldc=='+' then
sum+=m
else if oldc=='/' then
if m==0 或者 sum%m!=0 then //不合法情况,即除数为零、不能整除
return 0
end if
end if
m=0//初始化 ,用于下一轮转化整型变量
oldc=c
end if
i++
end while
return 1
- 函数代码
int IsExp(char *exp,char level)//表达式是否合法
{
if(level=='2'||level=='3')//二三等级不含除法,即不存在表达式不合法情况
return 1;
int m=0, sum=0,i=0;
char c, oldc='+';
do
{
c = exp[i];
if( c<='9'&&c>='0' )
m = 10*m + c - '0';
else
{
if( oldc == '+' )
sum += m;
else if(oldc == '/')
{
if(m==0 || sum%m!=0)//不合法情况,即除数为零、不能整除
return 0;
}
m = 0;
oldc = c;
}
i++;
} while(c!='=');
return 1;
}
3.表达式运算
*int ComputeExp(char exp);
- 伪代码
定义整型变量m=0,sum=0,i=0、字符型变量c=exp[i],oldc='+'
while c!='=' do
c=exp[i]
if c为数字 then
m=10*m+c-'0'//将字符型数字转化为整型数字
else
if oldc是+ then
sum+=m
else if oldc是- then
sum-=m
else if oldc是* then
sum*=m
else if oldc是/ then
sum/=m
end if
m=0//初始化
oldc=c
end if
i++
end while
return sum
- 函数代码
int ComputeExp(char *exp)//表达式运算
{
int m=0, sum=0,i=0;
char c, oldc='+';
do
{
c = exp[i];
if( c<='9'&&c>='0' )
m = 10*m + c - '0';//将字符型数字转化为整型数字
else //计算表达式
{
if( oldc == '+' )
sum += m;
else if(oldc == '-')
sum -= m;
else if(oldc == '*')
sum*=m;
else if(oldc == '/')
sum/=m;
m = 0;//初始化
oldc = c;
}
i++;
} while(c!='=');
return sum;
}
4.3与原有函数代码比较
- 函数的功能上
因为上一回做大作业的时候时间有点赶,代码功能不够齐全,函数的设计上自我感觉也不够理想,于是这次的大作业是我在上回大作业的思路的基础上重新打的,与原来默认每轮只做十道题相比,多了一个题数选择的功能。 - 函数分装上
将原来void Screen();//提示界面 、void Menu();//显示菜单这两个函数整合成一个函数void Screen();//提示界面 - 创建表达式上
· 原代码
void NumberGet()
{
if(levelChoice=='1')
{
srand(time(NULL));
number1=rand()%10;
number2=rand()%10;
}
else if(levelChoice=='2')
{
srand(time(NULL));
number1=rand()%100;
number2=rand()%100;
number3=rand()%100;
}
else
{
srand(time(NULL));
number1=rand()%1000;
number2=rand()%1000;
number3=rand()%1000;
}
}
void OperatorGet()
{
if(levelChoice=='1')
{
srand(time(NULL));
operator_ch1=rand()%4;
switch(operator_ch1)
{
case 0:ch1='+';break;
case 1:ch1='-';break;
case 2:ch1='*';break;
case 3:ch1='/';break;
}
}
else
{
srand(time(NULL));
operator_ch1=rand()%2;
operator_ch2=rand()%2;
switch(operator_ch1)
{
case 0:ch1='+';break;
case 1:ch1='-';break;
}
switch(operator_ch2)
{
case 0:ch2='+';break;
case 1:ch2='-';break;
}
}
}
//函数void GameBegin()中的一部分
if(levelChoice=='1')
{
NumberGet(); //获取随机数
OperatorGet(); //随机获取运算符
printf("%.0f %c %.0f = ",number1,ch1,number2);
scanf("%lf",&yourAnswer);
rightAnswer=Calculate();
if(yourAnswer==rightAnswer)
{
printf("\n\t\t\t\tGood job!^_^\n");
i++;
}
else
{
printf("\n\t\t\t\t回答错误!>_<\n");
printf("\n\t 正确答案是:%.0f %c %.0f = %.2lf\n",number1,ch1,number2,rightAnswer);
j++;
}
}
else
{
NumberGet(); //获取随机数
OperatorGet(); //随机获取运算符
printf("%.0f %c %.0f %c %.0f = ",number1,ch1,number2,ch2,number3);
scanf("%lf",&yourAnswer);
rightAnswer=Calculate();
if(yourAnswer==rightAnswer)
{
printf("\n\t\t\t\tGood job!\n");
i++;
}
else
{
printf("\n\t\t\t\t回答错误!>_<\n");
printf("\n\t\t\t\t正确答案是:%.0f %c %.0f %c %.0f = %.0lf\n",number1,ch1,number2,ch2,number3,rightAnswer);
j++;
}
}
· 改造后的代码(如上char CreateExp(char *exp,char level);函数)
1.原函数中,随机数与随机运算符的获取分装为两个函数,表达式的输出也只是由一个简单的printf()输出
而改进后的代码,将随机数与随机运算符的获取再加上表达式的整合放在同一个函数中,使代码更加简洁
2.原代码中,多次调用随机数和随机运算符的获取函数,在效率上拖慢了程序的运行,而改进后的代码则不存在多次重复调用的情况出现
- 在判断表达式是否合法上
在原来的程序中,我并没有设置判断表达式是否合理的函数,而是针对除法不能整除时,令结果保留两位小数(代码如下)
而为了解决除数为0的情况,我直接将除数的取值范围定在1到9之间,就不存在除数为0的情况了
指针版的大作业中老师明确要求了,将除法不能整除和除数为0的情况设为不合法表达式,受老师博客中计算字符串表达式代码的影响,我的判断表达式是否合法的函数如下
然后其余的函数基本都大同小异
4.4改进大作业总结
- 其实两次大作业做下来,都有一个让我很闹心的地方,就是我在函数调用上出了点小问题,我的主函数中只有void GameBegin();这一个子函数。在做指针版的大作业时,我在主函数中已经打好框架了,(就是void GameBegin();函数中的内容)但是在我的所有函数都补充完了之后,我想要做一个每轮结束之后再次进入程序的函数,但是不能用 return main
所以我只好将主函数中的所有内容都放到一个函数中,再将这个函数放入主函数中,这样就导致了我的主函数中只有一行代码(让我自己看的很难受,但是又不知道怎么解决)
- 老师在课上提到了整型数字转化为字符型数字有专门的函数时,我就回去百度了一下,然后按照先获取整形随机数,再将其转化为字符型数字的思路做了。
- 然后顺着老师提供的如何计算字符串表达式的方法,我在想反正不合法表达式只存在与一级题目的除法运算中,那这种方法也可以用来判断表达式是否合法。
- 其实从总体上看,我这次大作业更多的是依赖于老师博客上提供的思路与做法进行改进的,自我感觉并没有太多的自己思考的地方。
- 老师博客上提供的算法其实是之前课堂派上的一道题目,让我知道其实我们可以多多学习平常课堂派中题目的思路。
C语言博客作业05——指针的更多相关文章
- C语言|博客作业05
这个作业属于哪个课程 C语言程序设计II 这个作业的要求在哪里 https://edu.cnblogs.com/campus/zswxy/CST2019-1/homework/9825 我在这个课程的 ...
- C语言Ⅰ博客作业05
这个作业属于那个课程 C语言程序设计II 这个作业要求在哪里 https://edu.cnblogs.com/campus/zswxy/CST2019-3/homework/9827 我在这个课程的目 ...
- C语言博客作业05
这个作业属于哪个课程 C语言程序设计II 这个作业要求在那里 https://edu.cnblogs.com/campus/zswxy/CST2019-3/homework/9827 我在这个课程的目 ...
- C博客作业05—指针
1.本章学习总结 1.1思维导图 1.2本章学习体会及代码量学习体会 1.2.1 学习体会 理解了指针在代码中的使用方法,学会使用指针进行参数操作 学会了结构体的定义方式与结构体的使用 经过持续一个周 ...
- C语言博客作业6---结构体&文件
C语言博客作业6---结构体&文件 1.本章学习总结(2分) 1.1思维导图 请以思维导图总结本周的学习内容.如下图所示: 1.2.学习体会 描述本周学习感受,也可以在这里提出你不理解地方.对 ...
- C语言博客作业5--指针
C语言博客作业5--指针 1.本章学习总结(2分) 1.1思维导图 请以思维导图总结本周的学习内容,如下图所示: 1.2本章学习体会及代码量学习体会 1.2.1学习体会 描述本周学习感受,也可以在这里 ...
- C语言I-博客作业05
这个作业属于那个课程 C语言程序设计II 这个作业要求在哪里 C语言1博客作业05 我在这个课程的目标是 学会运用函数编代码 这个作业在那个具体方面帮助我实现目标 写C语言作业的时候,编代码的实践中 ...
- C语言博客作业06——结构体&文件
C语言博客作业06--结构体&文件 1.本章学习总结 1.1思维导图 1.2.本章学习体会 在本周的学习中,我们学习了关于结构体和文件的内容.结构体的本身并不难,但以结构体为基础的链表还是让我 ...
- C语言博客作业4--数组
C语言博客作业4--数组 1.本章学习总结 1.1思维导图 请以思维导图总结本周的学习内容,如下图所示: 1.2本章学习体会及代码量学习体会 1.2.1学习体会 描述本周学习感受,也可以在这里提出你不 ...
随机推荐
- Makefile 编译时虽然加上了-g 选项 但是还是无法调试
make 编译时默认的命令是all,不能写成其他的
- Lists.newArrayListWithExpectedSize( int estimatedSize)
Lists.newArrayListWithExpectedSize( int estimatedSize) 构造一个期望长度为estimatedSize的ArrayList实例. 源码: publ ...
- SQLSERVER 查询系统中的所有表的数量
SELECT a.name, b.rows FROM sysobjects AS a INNER JOIN sysindexes AS b ON a.id = b.id WHERE (a.type = ...
- SQL-递归查询在Ora与Mssql
今天在工作中,有同事“请教”从 Sql Server 移植数据到 DM DB 的改写问题,本以为难度不大,结果发现 Sql Server 数据库的语法.架构上,与 Oracle / DM 数据库差异还 ...
- 用Python绘制一个感兴趣是数学公式图
下面是函数sin,cos函数的图像: 代码如下: import numpy as np import pylab as pl import matplotlib.font_manager as fm ...
- Docker介绍及使用
什么是容器? 容器就是在隔离的环境运行的一个进程,如果进程停止,容器就会销毁.隔离的环境拥有自己的系统文件,ip地址,主机名等,kvm虚拟机,linux,系统文件 程序:代码,命令 进程:正在运行的程 ...
- 剑指offer:反转链表
问题描述 输入一个链表,反转链表后,输出新链表的表头. c++代码 /* struct ListNode { int val; struct ListNode *next; ListNode(int ...
- mybatis第一次搭建出错
### Error building SqlSession. ### The error may exist in com/test/pojo/UserMapper.xml ### Cause: or ...
- 廖雪峰 JavaScript 学习笔记(函数)
JavaScript中,定义函数的方式如下: function abs(x) { if (x >= 0) { return x; } else { return -x; } } 上述abs()函 ...
- Activiti 工作流之所学所感(基本配置) DAY1
由于公司需求,最近在研究工作流,在此记录一下所学所感以备往后使用时候可以方便查询,有不足之处请各位大牛提点,下面直接进入主题. 下载activiti 所需资料 可以直接在官网上下载,也可以在我的网盘 ...