標籤:ble 能力 簡化 關係 代碼風格 很多 stdio.h prim 過多
一、PTA實驗作業題目1: 400~499 中4出現的次數1. 本題PTA提交列表
2. 設計思路
一、main函數
- 1.函式宣告int fun(int x)
- 2.定義變數i,k,i表示輸入的值,k存放4出現次數
- 3.重複以下步驟直到i>499
- 4.調用函數int fun(int x)計算i中k值
- 5.累加k值
- 6.輸出k值
二、函數int fun(int x)
- 1.k賦初值0
- 2.當x!=0時,重複下面步驟
- 3.計算個位元字x%10,如果x%10==4,k++
- 4.去除末位元字, x=x/10
- 5.返回k值
3.本題調試過程碰到問題及PTA提交列表情況說明。
k值輸出不對
調試
可以很清楚的看到m的值是i的個位元字,也就是說每次取個位元字後去除個位元字的語句沒有實現,導致k實際輸出的是個位元字為4的數字個數
改正:換do while語句為while語句,調試下看看有沒有實現去除個位元字
可以看到這次k記錄的數值就對了
小插曲:忽略main函數中的k+=fun(i)語句,看到k數值是1,2覺得沒實現累加,利用了靜態局部變數來實現對k進行累加,導致輸出一個幾千的數值。後改正
題目2:使用函數輸出水仙花數1. 本題PTA提交列表
2. 設計思路
一、main函數
- 1.定義整型變數m,n
- 2.輸入m,n
- 3.調用函數int narcissistic( number )判斷是否為水仙花數
- 4..如果 narcissistic( m )==1,printf("%d is a narcissistic number\n", m)
- 5.如果 narcissistic( n )==1,printf("%d is a narcissistic number\n",n)
- 6.調用函數void PrintN( int m, int n )選出(m,n)中的水仙花數,輸出這些水仙花數
二、函數int narcissistic(int number )
- 1.定義整型變數N,i,j,,number1,number2
- 2.給N賦初值0
- 3.定義整型變數sum,存放各個位元的數位N次方和 ,並賦初值
-
- number1=number,number2=number
- 5.如果number1不為0重複下面步驟
- 6.去個位元: number1=number1/10
- 7.N++,用來表示位元
- 8.i=1,當i小於N的值時,重複下面步驟
- 9.j=number2%10,sum=sum+pow(j,N)
- 10.如果sum==number,返回1,否則,返回0
三、函數void PrintN( int m, int n )
- 1.m++
- 2.當m<n時,重複下面步驟
- 3.如果narcissistic(m)==1,輸出這個數
- 4.m++;
3.本題調試過程碰到問題及PTA提交列表情況說明。
錯誤碼:
#include <stdio.h>int narcissistic( int number );void PrintN( int m, int n );int main(){ int m, n; scanf("%d %d", &m, &n); if ( narcissistic(m) ) printf("%d is a narcissistic number\n", m); PrintN(m, n); if ( narcissistic(n) ) printf("%d is a narcissistic number\n", n); return 0;}#include<math.h>int narcissistic( int number )//調用函數 { int N,i,j; int sum=0; while(number!=0){//如果number不為0執行迴圈體 j=number%10;//取個位元 N++;//累加N來計算水仙花數位元 number=number/10;//除去個位元得到新的number } for(i=1;i<=N;i++){ j=number%10; number=number/10; sum=sum+pow(j,N);//計算各個位元的數位N次方和 } if(sum==number){//如果各個位元數字N次方和等於這個數 return 1;}//返回1 return 0;//否則返回0 }void PrintN( int m, int n ){ int number; for(number==m;number<=n;number++){//當number在(m,n】範圍內執行迴圈體 if( narcissistic(number)==1){//如果為水仙花數 printf("%d\n",number);//輸出這個數 } } }
運行:
第二個函數沒有輸出,會不會是沒有進入這個函數?
135不是水仙花數,但是也輸出了,所以第一個函數調用是不是也有問題。。。。
變成輸出m到n所有數了,沒有實現判斷水仙花數
錯誤碼:
#include <stdio.h>int narcissistic( int number );void PrintN( int m, int n );int main(){ int m, n; scanf("%d %d", &m, &n); if ( narcissistic(m)) printf("%d is a narcissistic number\n", m); PrintN(m, n); if ( narcissistic(n))printf("%d is a narcissistic number\n", n); return 0;}#include<math.h>int narcissistic( int number )//調用函數 { int N,j,sum,i; N=0; sum=0; do{//如果number不為0執行迴圈體 number=number/10;//除去個位元得到新的number N++;//位元加一 } while(number!=0); for(i=1;i<=N;i++){ j=number%10;//取個位元 number=number/10;//去除個位元 sum=sum+pow(j,N);//計算各個位元的數位N次方和 } if(sum==number)//如果各個位元數字N次方和等於這個數 return 1;//返回1 return 0;//否則返回0 }void PrintN( int m, int n ){ while(m<n){ if( narcissistic(m)==1){//如果為水仙花數 printf("%d\n",m);}//輸出這個數 m++; }}
調試:
發現m,n不能輸入,還有sum一直為0
錯誤:忽略了number定義的類型是全域變數,所以在取個位的迴圈結束後number=0,並且影響到後面出現的number,根據全域變數特點,它們的值都為0了,導致錯誤
改正:用number1,number2來存放number的值,number1,number2分別用於倆個迴圈,這樣就不改變number的值了
提交:
新錯誤:運行逾時,沒有輸出
調試:
調試發現掉入迴圈出不去,仔細觀察發現迴圈條件是number1!=0,而我寫成number!=0,導致迴圈不能結束。
改正後:
不是很明白這個錯誤,但是知道錯誤是因為輸入範圍問題
再次閱讀題目,迴圈起點應該m+1而不是m,在迴圈開始前執行m++,提交正確
題目3:求組合數1. 本題PTA提交列表
2. 設計思路
一、main函數
- 1.定義倆個整型變數,m,n
- 2.定義倆個浮點型變數result,表示組合數結果
- 3.調用函數double fact(int n),計算result=fact(n)/(fact(m)*fact(n-m))
- 4.輸出result,控制輸出位元為0
二、函數double fact(int n)
- 1.定義整型變數i,存放迴圈次數
- 2.給fact賦初值 double fact=1.0
- 3.當i小於等於n時,重複下面步驟
- 4.fact=fact*i
- 5.i++
- 6.返回fact的值
3.本題調試過程碰到問題及PTA提交列表情況說明。
錯誤:沒有給 fact 賦初值
改正過程:嘗試使用double i,double(fact*i)但是運行還是一樣的錯誤,double型乘以int就是double型,錯誤點不在這。給fact賦值fact=1,運行還是顯示這個錯誤,改為1.0還是不行。錯誤上面解釋是希望輸出double型。所以嘗試改成double fact==1.0就對了
二、同學代碼結對互評1.同學互評照片。(我、沈夢婷)
2.My Code、互評同學代碼題目6-9 驗證哥德巴哈猜想
My Code:
#include <stdio.h>#include <math.h>int prime( int p );void Goldbach( int n );int main(){ int m, n, i, cnt; scanf("%d %d", &m, &n); if ( prime(m) != 0 ) printf("%d is a prime number\n", m); if ( m < 6 ) m = 6; if ( m%2 ) m++; cnt = 0; for( i=m; i<=n; i+=2 ) { Goldbach(i); cnt++; if ( cnt%5 ) printf(", "); else printf("\n"); } return 0;}int prime( int p ){ int k; for(k=1;k<=p/2;k++){//如果迴圈中滿足p%k==0,說明這個數不是素數,結束迴圈 if(p%k==0) break; } if(k>p/2&&p!=1)//如果迴圈正常結束,滿足該條件,就是素數 return 1; else return 0;}void Goldbach( int n ){ int x1,x2; for(x1=2;x1<n;x1++) for(x2=2;x2<n;x2++) if(prime(x1)==1&&prime(x2)==1&&x1<=x2){//調用素數函數判斷是否為素數 if(x1+x2==n)//判斷是否滿足哥德巴哈猜想 printf("%d=%d+%d",n,x1,x2); break; }}
沈夢婷的代碼:
#include <stdio.h>#include <math.h>int prime( int p );void Goldbach( int n );int main(){ int m, n, i, cnt; scanf("%d %d", &m, &n); if ( prime(m) != 0 ) printf("%d is a prime number\n", m); if ( m < 6 ) m = 6; if ( m%2 ) m++; cnt = 0; for( i=m; i<=n; i+=2 ) { Goldbach(i); cnt++; if ( cnt%5 ) printf(", "); else printf("\n"); } return 0;}int prime( int p ){ int i,n; if(p==1)//判斷p為1時不是素數 return 0; n=sqrt(p); for(i=2;i<=n;i++){ if(p%i==0){//判斷p是否為素數 return 0; } } return 1; } void Goldbach( int n ) { int p,q; for(p=2;p<=n;p++){ if(prime(p)!=0){//p是素數 q=n-p;//p與q的關係 if(prime(q)!=0){//q是素數 printf("%d=%d+%d",n,p,q); break; } } } }
3.我和同學代碼不同在哪裡?有哪些各自優勢?你更喜歡哪種代碼風格?如果同學代碼有錯的也請幫忙指出來哪裡出問題。
我預計是通過兩個迴圈,找到滿足哥德巴哈猜想的輸出,為了找到題目要求的一組就結束,還加了break,但是還是輸出所有情況,改了幾次也不行,覺得這種方法更適用於窮舉。而沈夢婷是通過找到最小的素數後,利用倆個數相加等於n的條件,將另一個數值表示出來,再判斷這個數是不是素數,如果是,則驗證了哥德巴哈猜想.沈夢婷的代碼思路清晰,也簡化了很多。相比較My Code中嵌套迴圈判斷要迴圈的次數比沈夢婷代碼迴圈次數多很多。所有我更喜歡她的代碼。
三、本周題目集的PTA最後排名。
四、本周學習總結1.你學會了什嗎?1.1 C語言哪些資料類型?
整型、字元型、實型
1.2 字元型資料需要注意地方?
(1)不僅可以寫成字元常量的形式,也可以用相應的ASSCII碼錶示,即可用整數表示。整數變數和字元型變數是可以互換的
(2)字元具有數值特徵,可以像整數一樣參加運算
(3)逸出字元只代表一個字元
(4)ASCII字元集中所有字元都能用逸出字元表示
1.3 自增自減運算子?
(1)使變數的值增1或減1
設n是一個整型變數並已賦值
++n和n++都相當於n=n+1
--n和n--都相當於n=n-1
(2)取變數的值作為運算式的值
++n的運算順序是:先執行n=n+1,再將n的值作為運算式++n的值
n++的運算順序是:先將n的值作為運算式n++的值,再執行n=n++
1.4 運算子優先順序?
(1)如果運算元兩側的運算子優先順序相同,則按結合方向決定計算順序
(2)運算子優先順序從高到低排列:邏輯運算子、算術運算子、關係運算子、邏輯運算子、條件運算式、賦值運算子、逗號運算子
(3)優先順序不同則按優先順序從高到低計算
1.5 C語言哪些運算式?
算術運算式、賦值運算式、關聯運算式、邏輯運算式、條件運算式和逗號運算式
課堂派哪裡做錯,做錯的請在這裡分析原因?
(1)int x=1,y=012;
printf("%d",y*x++);
正確答案:10
我的答案:20
分析:++的優先順序高於*,x++的值就是x,y是八進位,y=10,所以結果為10
(2)若a為int類型,且其值為3,則執行運算式a+=a-=a*a後,a的值
正確答案:-12
我的答案:-3
分析:a*a優先,所以a-=9.也就是a=a-9.a的值變為-6.所以a+=-6,即a=a-6,所以a=-12
1.6 其他內容?
(1)指定整型資料的輸出寬度:%md,若實際位元小於m,則左端補空格,若大於m,則按實際位元輸出
(2)double類型指定輸出寬度:%m.nf,保留n位小數,輸出寬度為m
(3)ch-‘a‘+‘A‘把小寫字元轉換成數字
ch-‘0‘把數字字元轉為數字
val+‘0‘把數字轉換為數字字元
(4)類型轉換
1.自動類型轉換
2.強制類型轉換
2.本周的內容,你還不會什嗎?
二進位的轉換和運算子的優先順序順序記憶不清。以及在PTA中忘記全域變數用於整個程式這一顯著特點,導致程式運行中更改了全域變數的值。主要是剛學的知識點不大熟,單拎出來會,放在題目中就忘了,需要一個加深印象的過程吧。
3.迴圈結構考試總結1.哪題做錯了,怎麼改?
第四題沒做,第五題錯了。
第四題中的二進位,課本上沒有,導致拿到題目自我暗示我沒學過,肯定不會寫。第五題的話還沒理出演算法,不知道如何寫代碼。
第四題的話可以先去瞭解下二進位,然後再做一遍。第五題要認真再想想。。。
2.考試結果滿意麼,怎麼改進?
不滿意。多多加強課本上一些比如素數判斷這類函數,題目中也挺常見的,太過依賴課本會覺得都懂這些簡單函數,但是自己寫的時候各種小細節問題就暴露出來了,浪費時間去找錯誤
3.其他總結。
1.時間不要浪費在簡單題上,導致佔用過多時間,所以一些常見的函數啊,語句啊,要記熟
2.書本上有提到但是沒有詳細介紹的知識點要儘快通過尋找資料補齊這部分知識,不能拖延,那就真沒時間看了。二進位對我來說就是血淋淋的例子
3.查錯能力很重要
C語言作業--函數