這幾周學習了指針,指針是C語言的一個重要的概念,也是特點之一。它能夠經過對地址的訪問來改變值,因此它的用處也不少,例如交換數就能夠經過指針來完成。但是運用指針,大多時候都要經過運行看能不能經過編譯來判斷是否要加*或者不加* 。作指針題集時,函數題還有些用到指針,可是編程題就沒有用到了,仍是用以前的老方法作(不大會用指針)。知道指針是很重要的一部分,等到掌握得更熟練再回來從新作一遍吧。還學習了字符串處理的一些函數,以前賦值都是直接用等號,判斷用大於小於,可是字符串的判斷就要調用函數了,剛開始用還真是很容易出錯。PTA的題目,將以前對數據的處理變成了對字符串的處理,能夠對這些函數多些運用吧
求子串在母串中最後一次出現的地址 給定程序中函數fun的功能是:求出在字符串中最後一次出現的子字符串的地址,經過函數值返回,在主函數中輸出今後地址開始的字符串;若未找到,則函數值爲NULL。 函數接口定義: char *fun (char *s, char *t ); 其中 s和t 是用戶傳入的參數。函數求 t指針所指的字符串在s指針所指的字符串中最後一次出現的地址,並返回,若未找到,則函數值爲NULL。
定義整型變量i,j,k,n,用來判斷是否出現子串的flag=0 定義字符指針變量p for 從i=0到t數組爲空字符 do i++ 將i的值賦給n end for for 從i=0到s數組爲空字符 do for 從i=j,k=0開始到s數組結束,而且s數組和t數組中的字符同樣時 do if t數組最後一個字符不爲空字符 do 指針p指向s數組中第j-n個字符即最後一次出現t串時的位置減去t串的長度 flag=1 end if end for end for if flag==0 返回 p 爲空指針 不然返回 p
Q1:一開始沒有定義指針讓它來指向要輸出的數組,直接把s數組return回去了,調試過程當中發現它並無按我所想的狀況發展
A1:加了個字符指針,讓它指向要輸出的首地址,最後把這個指針返回回去就能夠了算法
定義存放隨機數num1,num2,num3,隨機運算符operation_1,operation_2 operation_1=rand()%4 operation_2=rand()%2//產生範圍內的隨機數,用於switch switch(level)//level是主函數傳參進來的數 case 1: num1=rand()%10 num2=rand()%10 itoa(num1,exp,10)//將整型數據轉化爲字符數據並存在數組中char *itoa( int value, char *string,int radix); 原型說明:value:欲轉換的數據。string:目標字符串的地址。radix:轉換後的進制數,能夠是 10進制、16進制等。 switch(operation_1) case 0:strcat(exp,"+");break;//將符號接到數組裏 ...... end switch strcat(exp,itoa(num2,exp+3,10))//將第二個數也接到數組裏,由於前一個數和運算符佔了2個字節,因此exp從第3個開始存放進去 break; case 2: ....... case 3: ....... //等級二,等級三均同理可獲得一個式子 end switch strcat(exp,"=")//接上等於號 輸出exp
void CreateExp(char *exp,int level) { int num1,num2,num3; int operation_1,operation_2; srand(time(NULL)); operation_1=rand()%4; operation_2=rand()%2; switch(level) { case 1: srand(time(NULL)); num1=rand()%10; num2=rand()%10; itoa(num1,exp,10); switch(operation_1) { case 0:strcat(exp,"+");break; case 1:strcat(exp,"-");break; case 2:strcat(exp,"*");break; case 3:strcat(exp,"/");break; } strcat(exp,itoa(num2,exp+3,10)); break; case 2: num1=rand()%100; num2=rand()%100; num3=rand()%100; itoa(num1,exp,10); switch(operation_2) { case 0:strcat(exp,"+");break; case 1:strcat(exp,"-");break; } strcat(exp,itoa(num2,exp+4,10)); switch(operation_2) { case 0:strcat(exp,"+");break; case 1:strcat(exp,"-");break; } strcat(exp,itoa(num3,exp+7,10)); break; case 3: num1=rand()%1000; num2=rand()%1000; num3=rand()%1000; itoa(num1,exp,10); switch(operation_2) { case 0:strcat(exp,"+");break; case 1:strcat(exp,"-");break; } strcat(exp,itoa(num2,exp+5,10)); switch(operation_2) { case 0:strcat(exp,"+");break; case 1:strcat(exp,"-");break; } strcat(exp,itoa(num3,exp+9,10)); break; }strcat(exp,"="); puts(exp); }
將exp和level傳入該函數裏面 if 等級爲1而且是除號 while 除數爲0 清屏//將非法式子清除 調用函數CreateExp if 不是除號或者除數不爲0 跳出while end if end while while num1取餘num2不爲0//即不能整除屬於非法式子 清屏 調用函數CreateExp if num1取餘num2爲0 跳出while end if end while end if
int IsExp(char *exp,int level) { srand(time(NULL)); if(level==1&&exp[1]=='/') { while(exp[2]=='0') { system("cls");//調用清屏函數將非法函數去掉 CreateExp(exp,level); if(exp[1]!='/'||exp[2]!='0') break; } while((exp[0]-'0')%(exp[2]-'0')!=0) { system("cls"); CreateExp(exp,level); if((exp[0]-'0')%(exp[2]-'0')==0) break; } } }
定義整型變量m來存放數據,sum作整個式子的結果,i 定義字符型變量oldc爲+ do if exp數組的第i個數據是大於0而且小於9 m=10*m+exp[i]-'0'//將字符數據轉化爲數字數據 else if oldc爲加號 sum+=m else if oldc爲減號 sum-=m else if oldc爲乘號 sum*=m else sum/=m end if i++//字符數組exp日後移 while 最後一個數據時不爲= return sum//將sum的值返回到主函數
int ComputeExp(char *exp) { int m=0, sum=0,i=0; char oldc='+'; do { if(exp[i]<='9'&&exp[i]>='0' ) m=10*m+exp[i]-'0'; else { if(oldc=='+' ) sum += m; else if(oldc=='-') sum -= m; else if(oldc=='*') sum*=m; else sum/=m; m = 0; oldc =exp[i]; } i++; }while(exp[i-1]!='='); return sum; }
void Number() { switch(level) { case 1: srand(time(NULL)); num1=rand()%9+1; num2=rand()%9+1; break; case 2: srand(time(NULL)); num1=rand()%90+10; num2=rand()%90+10; num3=rand()%90+10; break; case 3: srand(time(NULL)); num1=rand()%900+100; num2=rand()%900+100; num3=rand()%900+100; break; } } void Operation() { int operation_1,operation_2; srand(time(NULL)); operation_1=rand()%4; operation_2=rand()%2; if(level==1) { switch(operation_1) { case 0:ch1='+';break; case 1:ch1='-';break; case 2:ch1='*';break; case 3:ch1='/';break; } } else { switch(operation_2) { case 0:ch2='+';ch3='+';break; case 1:ch2='-';ch3='-';break; } } } void GameBegin() { int response; if(level==1) { printf("你的題目是%.0f %c %.0f =\n",num1,ch1,num2); } else if(level==2) { printf("你的題目是%.0f %c %.0f %c %.0f =\n",num1,ch2,num2,ch3,num3); } else { printf("你的題目是%.0f %c %.0f %c %.0f =\n",num1,ch2,num2,ch3,num3); } }
改造前用了三個函數來完成得出隨機的式子,一個函數用來產生隨機數,一個函數用來產生隨機運算符,另外一個用來將它們鏈接而且輸出 改造後的代碼將這三個函數共同完成的內容併到同一個裏面來完成,就不用定義那麼多全局變量,讓不一樣函數共用一個變量。並且代碼量也少了,看起來比較簡潔
改造前獲得隨機數時直接使用rand()%9+1,這樣就不會獲得0,因此就沒有判斷除數爲0的狀況。可是以前的除法都認爲不能整除也是正常的式子,因此還要考慮用戶輸入的答案和計算機給出的答案會不一致,考慮的就比較多 改造後將式子都控制在能夠整除的狀況下,因此在下一個計算結果的函數就能夠比較輕鬆了
double Gameresult() { double result; switch(ch1)//一級難度的一步運算i { case '+': result=num1+num2;break; case '-': result=num1-num2;break; case '*': result=num1*num2;break; case '/': result=num1/num2+0.005; result=1.0*((int)(result*100))/100; break; } switch(ch2)//二,三級難度的兩步運算 { case '+':result=num1+num2;break; case '-':result=num1-num2;break; } switch(ch3) { case '+':result=result+num3;break; case '-':result=result-num3;break; } return result; }
改造前一級難度和二三級難度在計算結果時分開討論,由於一級是一步運算,而二三級是兩步運算 改造後不用判斷是一級難度仍是二三級難度了,能夠共有一個代碼來完成,提升了代碼的效率