c语言博客做业05--指针

1.本章学习总结


1.1 思惟导图

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

1.2.1 学习体会

  • 学习体会:这两周的学习进度“咻”一下加快,总的来讲仍是比较吃力的,从数组过渡到指针再过渡到文件,总体的学习节奏都比以前快上不少。新的概念与新的函数(文件里概念性的东西有点多)等须要静下来消化的东西变得更加多了。发现一个问题,从最基本的概念上仍是不够熟练与清晰。具体表如今——课堂派的复习做业作起来有点像预习做业……处于一个会与不会,可能会大概会的一个模糊的区间范围内,这也致使了一种上课时的一种“我是谁,我在哪,我在干什么”的状态。对于新内容的接收和学习速度不够,课后也没有及时的巩固,进而致使了一种恶性死循环。趁着博客做业对于指针的内容进行了一个梳理。指针的pta题目仍是相对少一些嘛……对于返回多个值的函数,指针可以起到的做用就比较大,在字符串的一些程序编写上,用指针也更加便捷,要学会习惯指针的用法,普及化酱,多学多练吧。qaq
  • 该作的事:指针的运用仍是比较普遍,不只在字符串还有后面要学到的链表知识,因此仍是要一些代码量,对于一些比较经典的运算方法进行一个分析,方便深刻掌握指针的使用。
  • 对于老师的建议:qaq 虽然文件对于课设有比较大的帮助,可是直接跳跃讲文件,其中再参杂一些尚未巩固牢靠的指针知识会使原本不那么复杂的文件显得有些遥远和难以接纳(emmmm不知道是否是我本身的感受……就是:使人头大鸭酱)课堂派里常出现一些须要devc进行调试的题目也经常是“老师已经开启禁止黏贴功能”,建工程由于对指针概念的不够熟悉也变成了老师博客代码的搬运工。但愿老师能够救救孩子,日常能够挑一些课堂派上的经典代码进行分析合理化课堂派的功能巩固一下指针知识……oxo辛苦老师……

1.2.2 代码累计


2.PTA总分

2.1

2.2 个人总分:

  • 总分:110

3.PTA实验做业

3.1 PTA题目1

7-2 说反话-增强版 
给定一句英语,要求你编写程序,将句中全部单词的顺序颠倒输出。git

3.1.1 算法分析

定义数组 a[500001];
定义 flag=0,len 字符串长度i,j,ret,count=0 单词长度
    gets(a);
    len=strlen(a);
    for i=len-1 To 0            //倒序判断
        if a[i]!=' '
            ret=1;count++;
        end if
        if a[i]=' '&&ret=1      //一个单词结束
            if flag=1 已输出过单词 先空格
            end if
            for j=i+1 To i+count
            逐个输出字符
            flag=1;
            end for
            所有初始化
        end if
        if i=0&&ret=1           //第一个单词单独判断
            同理输出
        end if       
    end for

3.1.2 代码截图

3.1.4 PTA提交列表及说明

#include<stdio.h>
#include<string.h>
int main()
{
    char a[100][100];
    int i,j;
    int flag=0;
    char sentense[10000];
    gets(sentense);
    int m=0,n=0;
    for(i=0;sentense[i];i++)
    {
        if(sentense[i]!=' ')
        {
            a[m][n]=sentense[i];
            m++;                           //单词长度累加 
        }
        if(m!=0&&sentense[i]==' ')
        {
            a[m][n]='\0';
            n++;m=0;                       //有单词累计,遇到空格 
        }
    }
    for(i=n;i>0;i--)
    {
        for(j=0;a[j][i];j++)
        {
            printf("%c",a[j][i]);flag=1;
        }
        if(flag==1) printf(" ");
    } 
    for(j=0;a[j][0];j++)
    printf("%c",a[j][i]);
    return 0;
}
  • Q:运行时间超长,致使最后一个测试点过不去
  • A:以上是以前第一次写这道题目时的代码,利用二维数组对于出现的单词进行标号统计,最后倒序输出。(我jio得这样比较直观 小声bb)这种状况会出现最后一个测试点过不去,运行时间超长。先进行总统计,再输出。因此就采用倒序判断,边判断边输出,节省了运行时间。第二种方法比较通用,可是我的是以为第一种方法灵活度更高,顺便还能够指定输出指定位置的单词。但这道题对于运行时间的要求比较高,所以仍是要采用便判断边输出的方式。

4.大做业

4.1.改造函数介绍

函数1 computerExp 随机生成表达式

int computerExp(char grade,int *gradeNum)
定义i,j=0,step,n                      //控制生成的随即位数&计算步数
定义exp[30], op[5]={'+','-','*','/'};                      //枚举
    switch(grade)
        A:一位两步
        B:两位一步
        C:三位一步
    for j=0 To step-1
        for j To (i+1)*n-1
            exp[j]=rand()%10+'0';             //生成随机数转字符录入
        end for
        exp[j]=op[rand()%*gradeNum];           //对应加减/加减乘除
    end for;
    exp[i]='\0';
    输出表达式


函数2 Calculation 运算

定义 former latter i,j,pos;
for j=0 To j<n-1
    former=10*former+exp[pos]-'0';    //转数字
    pos++;
end for;
for i=0 To i<step-1
    for j=0;j<n-1
        latter=10*latter+exp[pos]-'0';       //转数字
        pos++;
    end for
end for
switch op            //运算
    case +:
    case -:
    case *:
    case /:     if latter=0,跳过此题
return latter;


4.3 与原有函数代码比较

等级选择

former

void Calculation(char x)
{
    switch(x)
    {
    case 'A':
        while(correctNum<10)//若是想一直答下去,就把它修改为while(1),而后输入6666照样能够退出循环w
        {
            printf("当前挑战等级:青铜\n");
            printf("当前答对题数:%d\n",correctNum);
            printf("tips:输入6666提早结束游戏\n\n\n");
            x = rand() % 10; /* generate 1-digit random number */
            y = rand() % 10; /* generate another 1-digit random number */
            kind=rand()%4;
            randomOperation(kind,x,y);
        }
        break;
    case 'B':
        while(correctNum<10)
        {
            printf("当前挑战等级:钻石\n");
            printf("当前答对题数:%d\n",correctNum);
            printf("tips:输入6666提早结束游戏\n\n\n");
            x = rand() % 90+10; /* generate 1-digit random number */
            y = rand() % 90+10; /* generate another 1-digit random number */
            kind=rand()%2;
            randomOperation(kind,x,y);
        }
        break;
    case 'C':
        while(correctNum<10)
        {
            printf("当前挑战等级:王者\n");
            printf("当前答对题数:%d\n",correctNum);
            printf("tips:输入6666提早结束游戏\n\n\n");
            x = rand() % 900+100; /* generate 1-digit random number */
            y = rand() % 900+100; /* generate another 1-digit random number */
            kind=rand()%2;//decide to minus or plus
            randomOperation(kind,x,y);
        }
        break;
    }
}

latter

void Choice(char x,int *correctNum,int *incorrectNum,int *gradeNum)//选择
{
    int answer,end;
    while(*correctNum<10)//若是想一直答下去,就把它修改为while(1),而后添加一个跳出循环条件就好啦w
    {
 again:
        switch(x)
        {
        case 'A':printf("当前挑战等级:青铜\n");*gradeNum=4;break;
        case 'B':printf("当前挑战等级:钻石\n");*gradeNum=2;break;
        case 'C':printf("当前挑战等级:王者\n");*gradeNum=2;break;
        }
        printf("当前答对题数:%d\n",*correctNum);
        printf("tips:输入任意大于6666可直接结束游戏\n\n\n");
        answer=computerExp(x,gradeNum);
        if(answer==5555)//除数为0
        {
            fflush(stdin);//清空输入缓冲区
            system("cls");//empty
            goto again;
        }
        end=Judgement(answer,correctNum,incorrectNum);
        if(end)break;
        Pause();
    }
  • former:函数重复的内容比较多,函数的内容比较单一。
  • latter:由于表达式是另外输出,因此简化了这一块的代码,其余的部分放在computerExp中完成,直接生成一串字符。

计算

former

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int kind;//choose to minus or plus etc.
int flag=0;//控制是否输出正确提示语
int END=0;//控制跳出循环
int Num=0;//sum
char grade;//choose one to play
int wrongTimes=0;//the number of wrong times
int correctNum=0;//the number of correct times
int incorrectNum=0;//the number of incorrect times
int x,y;
void Calculation(char x);
void Menu(void) ;
void plus(int x,int y);
void divide(int x,int y);
void minus(int x,int y);
void multiply(int x,int y);
void correctMessage( void );
void incorrectMessage( void );
int randomOperation(int kind,int x,int y);
void Ending(void);//ending message

latter

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
void  Pause(void);
char Menu(void) ;
int    Calculation(char exp[],int step,int n);
int    Judgement(int answer,int *correctNum,int *incorrectNum);
int    computerExp(char grade,int *gradeNum);
void  Ending(int *correctNum,int *incorrectNum);//ending message
void  correctMessage( int *correctNum );
void  incorrectMessage(int *wrongTimes,int *incorrectNum,int answer);
void  Choice(char x,int *correctNum,int *incorrectNum,int *gradeNum);
int Calculation(char exp[],int step,int n)
{
    int former=0,latter=0;
    int i,j,pos=0;
    for(j=0;j<n-1;j++)
    {
        former=10*former+exp[pos]-'0';
        pos++;
    }
    pos++;                //jump the op position
    for(i=0;i<step-1;i++)
    {
        for(j=0;j<n-1;j++)
        {

            latter=10*latter+exp[pos]-'0';//change into number
            pos++;
        }
            switch(exp[i*n+n-1])
            {
                case '+':former+=latter;latter=0,pos++;break;
                case '-':former-=latter;latter=0;pos++;break;
                case '*':former*=latter;latter=0;pos++;break;
                case '/':if(latter==0) return former=5555;
                             former/=latter;latter=0;pos++;break;
            }
    }
    return former;
}
  • former:简单抛个头文件。先前的代码只是生成两个随机数,分+-*/模块分别去计算,致使代码的赘余,功能的重复。以前仍是用了比较多的void类型函数
  • latter:对计算上进行了一个优化,利用switch将整个计算封装在一块儿,使代码简化不少。

4.4 改进大做业总结

  • qaq!!!总算写到这里了。此次的大做业仍是进行了比较大规模的改动。前后看错好几回要求……刚开始仍是基于上一次的代码,进行修改,只是简单地把全局变量修改为指针。后来发现题目要求是将表达式储存到字符数组中,再整串输出。所以这边仍是进行了一个比较大的改动。刚开始的代码大概长这样。
switch (grade)//等级
    {
    case 'A':n=1;break;
    case 'B':n=2;break;
    case 'C':n=3;break;
    }
    for(i=0; i<3*n; i++)num[i]=rand()%10;                 //生成随机数
    for(i=0; i<n; i++)x=10*x+num[i];                    //生成第一个随机数
    for(i=n; i<2*n; i++)y=10*y+num[i];                    //生成第二个随机数
    for(i=2*n; i<3*n; i++)z=10*z+num[i];                    //生成第三个随机数
    for(i=0;i<3*n+3;i++)                  //录入字符数组
    {
        if (i==n)
        {
            exp[i]=randomOp();
            if(exp[i]=='/'&&y==0)
            {
                do
                {
                    for(i=n;i<2*n;i++)
                    {
                        num[i]=rand()%10;
                        y=10*y+num[i];
                    }
                }while(y);
            }
            else if(exp[i]=='*'||exp[i]=='/')
            {
                mark1=1;
            }
        }
        else if(i==2*n+1)
        {
            exp[i]=randomOp();
            if(exp[i]=='/'&&z==0)
            {
                do
                {
                    for(i=2*n;i<3*n;i++)
                    {
                        num[i]=rand()%10;
                        z=10*z+num[i];
                    }
                }while(!z);
            }
            else if(exp[i]=='*'||exp[i]=='/')
            {
                mark2=1;
            }

        }
        else if (i==3*n+2)exp[i]='=';
        else
        {
            exp[i]=num[j]+'0';
            j++;
        }
    }
    exp[i]='\0';//加上终止符
  • 仍是在迎合题目要求,进行固定步数的计算,可是这种比较固定的模式,就比较好考虑运算优先级,这串代码改动上意义不大。不过在刚写完的时候仍是比较满意的。固定位置的固定符号,整个程序都比较固化,没什么弹性。
  • 后来是老师评论了个人博客的时候,我才开始考虑,计算与表达式分离的好处,在这边请教了老师。而后就从表达式的随机生成开始进行修改,在这方面就相对灵活些。写函数我会倾向于先写一个最简单的程序,验证程序是否能正常得出结果,便于调试——由于大做业里面的函数已经涉及到的东西仍是比较多。而后就写出了一个能够自定义生成随即表达式的程序。大概长这样
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main()
{
    if (grade=='A')gradeNum=4;else gradeNum=2;
    int i,step,j=0,n;
    printf("你想挑战的位数:");scanf("%d",&n);n++;
    printf("你想挑战的步数:");scanf("%d",&step);step++;
    char exp[30];
    char op[5]={'+','-','*','/'};
    for(i=0;i<step;i++)
    {   
        for(j;j<(i+1)*n-1;j++)
            exp[j]=rand()%10+'0';
        if(i!=step-1)exp[j]=op[rand()%gradeNum];
        else exp[j]='=';j++;
    }
    exp[j]='\0';
    printf("%s",exp);
}
  • 这样的写法比以前的写法要灵活些,之后要是想修改条件也比较便利。由于以前判断优先级的时候,是对固定位置的符号进行判断,若是符合条件进行优先运算酱。可是通过这样的改动以后,暂时就没有一个比较可行的方法来进行优先级的比较。若是最近可以找到一个比较合适的方法,我会在博客下面进行补充。
  • 因此如今的程序仍是比较笨一点。
  • 此次的大做业在参数的传递上,仍是时常出现问题的。时常出现一级指针二级指针并行的状况。老师推荐去看范华同窗的代码qaq!!!但仍是比较不容易吸取一些,因此就先按照本身熟悉的字符数组来写,后期会再尝试模仿范华同窗的代码,对于指针的运用再增强练习一下。
  • 写此次大做业比较大的收获,是已经能够相对熟悉地运用字符数组,而后可以尝试着用一些指针,return语句的灵活运用在处理除数为0的状况时也起到了比较大的做用。嘛。但愿在文件版大做业的修改上面能够效率高一点,思考问题考虑通式,思惟不定时酱。
  • 此次还简化了一些函数,代码量上大概简略了100行酱。

相关文章
相关标签/搜索