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行醬。

相關文章
相關標籤/搜索