題目6-1 計算兩數的和與差
1 設計思路
(1)主要描述題目算法
第一步:psum為sum的地址,pdiff為diff的地址,形參op1、op2接受到實參a,b傳來的值。
第二步:根據題意進行賦值。
2.實驗代碼
void sum_diff( float op1, float op2, float *psum, float *pdiff ) { *psum=op1+op2; *pdiff=op1-op2; }
(2) 本題調試過程碰到問題及解決辦法
無。
題目6-2 拆分實數的整數與小數部分
1 設計思路
(1)主要描述題目算法
第一步:因為輸入的數據為浮點型,強制轉換x為整型,賦值給*intpart,*intpart的值為整數部分。
第二步:x減去*intpart為小數部分。
2.實驗代碼
void splitfloat( float x, int *intpart, float *fracpart )
{
*intpart=(int)x;
*fracpart=x-*intpart;
}
(2) 本題調試過程碰到問題及解決辦法
無。ps:原先定義了一個變量y用來存放強制轉換x后的值,發現是多此一舉。
題目6-3 在數組中查找指定元素
1 設計思路
(1)主要描述題目算法
第一步:定義變量flag=0用來標記,count用來存放指定元素的最小下標,用for循環和if語句一個一個的查找,找到了指定元素就令flag=1。
第二步:判斷flag是否為0(沒找到),真的就令count=-1。
第三步:返回count的值。
2.實驗代碼
int search( int list[], int n, int x ) { int count,j,flag=0; for(j=0;j<n;j++) { if(list[j]==x) { count=j; flag=1; } }
if(flag==0) count=-1;
return count; }
(2) 本題調試過程碰到問題及解決辦法
無。
3.流程圖
題目6-4 找最大值及其下標
1 設計思路
(1)主要描述題目算法
第一步:定義變量MAX,MAX存放數組第一個的值。
第二步:運用for循環比較,如果后一個的值大於MAX,就交換,下標存到指針b所指的變量里,進行下一次比較。
第三步:返回MAX的值。
2.實驗代碼
int fun(int *a,int *b,int n) { int j,MAX; MAX=a[0];
for(j=1;j<n;j++) { if(MAX<*(a+j)) { MAX=*(a+j); *b=j; } } return MAX; }
(2) 本題調試過程碰到問題及解決辦法
錯誤原因:寫這個程序時還不怎么會用指針,導致答案錯誤。
改正方法:去看了書上數組與指針那一章的幾個例題。
3.流程圖
題目6-5 最小數放前最大數放后
1 設計思路
(1)主要描述題目算法
第一步:運用for循環輸入數組的值。
第二步:運用for循環找出最小的數的下標,再用if語句判斷它是不是第一個數,不是就與第一個數進行交換。同理找出最大的數,然后交換。
第三步:輸出數組元素。
2.實驗代碼
void input(int *arr,int n) { int i; for(i=0;i<n;i++) { scanf("%d",arr++); } } void max_min(int *arr,int n) { int j,index=0,t,flag=0; for(j=1;j<n;j++) { if(*(arr+j)<*(arr+index)) index=j; } if(index!=0) { t=*arr;*arr=*(arr+index);*(arr+index)=t; } for(j=1;j<n;j++) { if(*(arr+j)>*(arr+flag)) flag=j; } if(flag!=0) { t=*(arr+n-1);*(arr+n-1)=*(arr+flag);*(arr+flag)=t; } } void output(int *arr,int n) { int k; for(k=0;k<n;k++,arr++) { printf("%3d",*arr); } }
(2) 本題調試過程碰到問題及解決辦法
無。
3.流程圖
題目6-6 指針選擇法排序
1 設計思路
(1)主要描述題目算法
第一步:用外循環控制趟數,n個數選n-1趟,假設當前趟的第一個數為最值,記在k中 。
第二步:再用for循環從下一個數到最后一個數之間找最值,若其后有比最值更大的,則將其下標記在k中。
第三步:若k不為最初的i值,就交換。
2.實驗代碼
void sort(int *x,int n) { int i,t,k,j; for(i=0;i<(n-1);i++) { k=i; for(j=i+1;j<n;j++) { if(*(x+j)>*(x+k)) { k=j; } } if(i!=k) { t=*(x+i); *(x+i)=*(x+k); *(x+k)=t; } } }
(2) 本題調試過程碰到問題及解決辦法
因為以前做過此題,所以沒有問題。
3.流程
題目6-7 判斷回文字符串
1 設計思路
(1)主要描述題目算法
第一步:用while循環語句判斷字符串數組有多少個字符。
第二步:定義變量j,從后往前與從前往后比較字符,不相等就跳出循環。
第三步:比較j和i的大小,j大於i返回真,j小於i返回假。
2.實驗代碼
bool palindrome( char *s ) { int i=0,j=0; while(*(s+i)!='\0') { i++; } i--; for(;j<=i;i--,j++) { if(*(s+i)!=*(s+j)) { break; } } if(j>i) return 1; else return 0; }
(2) 本題調試過程碰到問題及解決辦法
老師上課講過此題,所以並無問題。
3.流程圖
題目6-8 使用函數實現字符串部分復制
1 設計思路
(1)主要描述題目算法
第一步:用while循環語句判斷字符串數組有多少個字符。
第二步:判斷m是否超過輸入字符串的長度,是結果字符串應為空串,不是,定義一個變量i和j,i從m-1個字符開始賦值給j=0時的新字符數組。
第三步:令最后一個字符數組的值為'\0'。
2.實驗代碼
void strmcpy( char *t, int m, char *s ) { int i,j=0; while(*(t+i)!='\0') { i++; } i--; if((i+1)<m) *s='\0'; else { for(i=(m-1),j=0;*(t+i)!='\0';i++,j++) { *(s+j)=*(t+i); }
*(s+j)='\0';
}
}
(2) 本題調試過程碰到問題及解決辦法
1、如果不寫 void ReadString( char s[] ) 這個函數,在編譯器中運行不了,但是加上后PTA提交答案為錯誤。
解決辦法:在PTA的提交中不寫 void ReadString( char s[] ) 這個函數,
,題目中已說明可以不用表示,其實它寫的略去不表我想了半天。。。原來意思是不表示。。。
2、按照我的寫法寫,最后沒有寫
*(s+j)='\0' 程序會輸出亂碼。
原因:因為C通過判斷'\0'來辨識字符串的結束。系統讀取字符串,它只是從字符數組的開始,一直往后找,一直找到'\0'為止。如果不加,系統只好再往后找,一直找到'\0'為止。
3.流程圖
二. 總結
1、總結兩周里所學的知識點有哪些學會了?哪些還沒有學會?
這兩周主要學習了指針以及它的應用,知道了指針的作用(通過地址能找到所需的變量單元)和如何定義、使用它。我問題大的地方其實不是指針而是函數,可能時因為上學期對這一塊少加練習的緣故,不知道形參和實參它們之間是如何傳遞的,不知道在函數調用結束后,形參所占的內存單元會被釋放,形參發生改變不會改變主調函數實參的值。所以這幾次PTA的作業,讓我不光學習了指針還讓我重新復習了函數。
通過這幾次的PTA作業,我發現剛開始寫時,對指針的運用並不熟練,果然自己以為聽懂了和實際寫起來還是有很大的差別,這也說明了代碼光看是沒有用的。上個周末去參加了ACM的招新,有一道題已經完成了99%了,調試時總是輸出答案不對,在我冥思苦想時,時間已經到了。等到學長他們講思路時我終於發現了我的問題所在,就是一個小小的地方(重新計數時沒讓它的值等於0),非常后悔和可惜。雖然最后進了ACM,但是我覺得自己在寫代碼這塊思路還是不清晰,想到啥寫啥,代碼也不夠簡潔,最好的辦法還是多加練習,看書上的例題時最好開着編譯器自己動手打打。
2、Git地址:https://coding.net/u/FENGZX/p/PTA/git?public=true
3、點評3個同學的本周作業
4、學習進度表格