C的三種基本程式結構-----詳解以及例子
目錄
對於一個程式來說,它的內在邏輯是非常重要的。只要肯靜下心來仔細推敲,找到它的關鍵邏輯。整個程式就已經完成了一大半,剩下的都是一些格式與規定。
我最感興趣的就是第四部分,習題部分找凶手的例題。看見題目的時候整個傻眼了,這個也能用程式碼編出來並找到凶手嗎?事實證明是可以的。
下面附上例題程式碼,結果及一些總結。希望對同時在學習C語言的你能有一些幫助,如果你是程式大神,那就不用細看我這篇文章啦~
一.順序結構
例1:
財務人員給員工發工資時經常遇到這樣一個問題,即根據每個人的工資額(以元作為單位)計算出各種面值的鈔票的張數,且要求總張數最少。例如,某職工工資為3436元,發放方案為:100元34張,20元1張,10元1張,5元1張,1元1張。
程式:
結果:
總結:
(1)因為要求總張數最少,所以最好先拿最大數額的錢來支付工資,則順序為100元→50元→20元→10元→5元→1元。
(2)每次只要能除以相關的數額得到的整數就是它的張數(m100=money/100),相除之後餘下的部分留給下一級數額再相除 (money%=100;m50=mone/50;),一直除到5,剩下的都是1元能解決的部分(...m5=money/5;money%=5;printf("m1=%d",money);)。
(3)m1只出現在了printf列印裡,且值該等於money%=5,所以不用對它進行定義。
(4)要處理的變數是金錢,所以資料型別是整型int,scanf與printf時加%d
(5)30行最後一個斜槓表示承接下一行。
例2:
從鍵盤輸入一個大寫字母,要求改用小寫字母輸出。
程式:
結果:
總結:
(1)涉及到的變數是大小寫字母,所以資料型別是字元型char。scanf與printf時加%s。
(2)判斷輸入的字元是否為大寫,是則進入小寫轉換,不是則提醒輸入錯誤。A~Z的ASCII值為65~90,不知道也沒關係,用字元型表示計算機自己知曉則有第9行的表示。&&間的兩個Ch的判斷加了括號是為了方便閱讀,不加也可以,因為>= ,<=(關係運算符)的優先順序比&&(與)的高。
(3)大寫轉換為小寫:第11行。A與a的ASCII值相差了32,所以也可以寫成ch = ch + 32 ;本程式中的11行為通用寫法,用於不清楚大寫之間的ASCII差值的時候。
二.選擇結構
1.if語句
例1:
輸入兩個實數a,b,如果a比b大,則將兩個數數值交換,按代數值由小到大次序輸出這兩個數。
程式:
結果:
總結:
(1)輸出時(16行)先輸出a再輸出b,且要求由小到大一次輸出,所以如果輸入時a的值比b大時就要進行交換(10~15行)。
(2)temp是用來交換a,b的中間載體,先將a中的內容給a,現在a是空的,緊接著就可以把b中的內容給a;現在b是空的,然後再把a放在temp中的內容給b(誰空給誰賦值),就實現了a與b的交換。注意順序不要寫錯,不可寫成:temp=a;b=temp;a=b。
例2:
輸入三個實數a,b,c,按代數值由小到大次序輸出這三個數。
程式:
結果:
總結:
(1)與上個例題差不多,只是判斷的數增加到了三個,再把不符合a<b<c的情況列出來進行值的交換即可。
(2)29行中%5.2f意思為:以寬度為5,顯示兩位小數的形式輸出。
(3)與上一個例題一樣都是涉及到實數,一個用的int,一個用了float。其實都可以,因為實數的定義如下:
有理數中整數部分是int型,分數(小數)部分是float型。
例3:
有一函式如下,編一程式,輸入一個x值,輸出y值。
-1 (x<0)
y= 0 (x=0)
1 (x>0)
程式:
結果:
總結:
(1)易錯點:14行else if 裡面不要寫成x = 0。平時書寫時是x=0,可在計算機中 = 是賦值運算子,==是關係運算子,與<,>一樣。
例4:
寫程式,判某一年是否閏年。
輸入:年(year)
計算:判是否閏年
輸出:閏年或非閏年(leap)
閏年條件:
能被4整除,但不能被100整除。
能被4整除,又能被400整除。
程式:
結果:
總結:
(1)外迴圈的選擇:因為條件是1.能被4整除,但不能被100整除。2.能被4整除,又能被400整除。都有能被4整除,所以最好放 在外迴圈。
(2)第2,3迴圈的選擇:由於能被400整除的數肯定能被100整除,但能被100整除的數不一定能被400整除,所以最好被100整除放在第2迴圈裡,能被400整除放在最內。
(3)flag為標誌位,用來判斷當前情況下是否為閏年,為1時輸出為閏年,由於為閏年的情況比不是閏年的要少,所以定義時給flag賦值為0,在很多個不是閏年的情況下就不再標註flag=0,使程式更簡潔。
2.switch語句:
格式:switch(表示式)
{
case 常量表示式1:語句序列1
case 常量表達式2:語句序列2
case 常量表達式i:語句序列i
case 常量表達式n:語句序列n
default: 語句序列n+1
}
執行過程為:當表示式的值等於常量表達式i的值,則從語句序列i開始執行到語句序列n+1為止 。若表示式的值不等於任何一個常量表達式的值,則只執行default後面的語句。
一般在每個語句序列之後加一個break語句,這樣在執行語句序列i之後,使流程跳出switch結構,實現多分支選擇結構。
例1:
編寫一個能進行兩個運算元加減乘除四則運算的計數器模擬程式
輸入:兩個運算元和運算子
計算:根據運算子確定運算
輸出:運算結果
程式:
結果:
總結:
(1)switch(op)不能寫成switch(‘op’)。
(2)做除法的時候要考慮被除數不能為0的情況。
(3)%5.2f指的是以寬度為5,顯示小數點後兩位來輸出。
例2:
給出一百分制成績,要求輸出成績等級‘A’、’B’、‘C’、‘D’、‘E’。90分以上為‘A’ ,80~89分為’B’ ,70~79分為‘C’,60~69分為’D’,其他為‘E’...
程式:用if寫
結果:
總結:
一個if之後,最好用else if,其他的用else。
if (條件句1)+執行句
elseif (條件句2)+執行句
else +執行句
如果條件句1成立,則執行if後面的執行句,如果條件句1不成立,然後條件句2成立,則執行elseif後面的執行句,如果條件句1和條件句2都不成立,則執行else後面的執行句。
程式:用switch寫
結果:
與上一個一致。
總結:
(1)因為case後接的是常量表達式,不能出現case:90~100,所以將分數除以10,用case:10,case:9...來表示。
(2)101~109除以10也是case:10的情況,會輸出A,所以加一個判斷語句:if(0 <= score && 100 >= score),過濾掉101~109之後再進行 score /= 10。
三.迴圈結構
1.while語句:支援“當型”迴圈控制結構的語句。
一般格式為:
while (表示式)
{
語句;
}
例1:
輸入:n
計算:1+2+3+L+n
輸出:計算的和
程式:
結果:
總結:
(1)while是先判斷再執行,給i賦初值為1,sum為0,第1次進入迴圈時sum=0+1,而程式要實現sum=0+1+2+...+n,且i也要由0自增到n,所以有while(i<=n)。
例2:
計算一條語句中的空格、字母、數字的個數。
程式:
結果:
總結:
(1)該程式是要輸入一條語句來計算字母,數字及空格的個數,用 while(ch != '\n')來判斷語句輸入結束(即按下空格之後將輸出對應個數)。
(2) if((ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z'))用來判斷是否是字母,包含大小寫。
(3)if(ch == ' ')用來判斷輸入的是否是空格,‘’單引號之間有空格。
2.do_while語句:“直到型”迴圈控制結構的語句。
一般格式為:
do
{
語句;
} while (表示式);
例1:
輸入:無
計算:1+2+3+L+100
輸出:計算的和
程式:
結果:
總結:
與while相比,do_while是先執行後判斷,它的賦初值和條件判斷都和while一致,只是順序不同。
3.for語句:比while語句更加靈活的迴圈控制語句。
一般格式為:
for (表示式1;表示式2;表示式3)
語句;
先求解表示式1;再解表示式2,若為真(非0)值,則執行語句,然後求解表示式3,再轉到求解表示式2。若為假(0)值,則結束for語句的執行。
例1:
輸入:無
計算:1+2+3+L+100
輸出:計算的和
程式:
結果:
總結:
(1)賦初值和條件判斷都一致,只是i的賦初值與i的自增都寫在for的固定表示式中了。
例2:
用for語句編寫一個計算1+3+5+ ...+(2*i-1)的程式,其中 i=1, 2, 3, ..., 100。
程式:
結果:
例3:
輸入:n
計算: 1!+2!+3!+ L+n!
輸出:計算的和
程式:
結果:
總結:
(1)計算的流程圖如下:
(2)由計算機制可給j賦初值為1,sum賦初值為0;也可因為 j 要進行乘運算所以初值最好為1,sum進行加運算,最好為0。
例4:
判斷數字m是否為素數(質數)。
程式:
結果:
總結:
(1)素數:一個大於1的正整數,如果除了1和它本身以外,不能被其他正整數整除。
(2)for迴圈中i從2開始直至小於它本身的那個數,即除了能被1和它本身除之外只要能被其他數整除不是素數,將這種情況定義一個標誌位flag=1。
(3) 1也是素數,且它進不了for迴圈,最好在迴圈外給flag賦0值,則輸入1時,會輸出0也是素數。
例5:
求100到200之間的素數。
輸入:無
計算: 求素數
輸出: 輸出素數 每4個一行 每個數佔4位
程式:
結果:
總結:
(1) 由於只用輸出素數,與上一個程式相比,只用輸出count為0時的情況。
(2)第22行%4d以寬度為4 。
4. break和continue語句
1.break語句:
在switch語句中使流程跳出switch結構。
在迴圈語句中使流程跳出當前迴圈。
例1:
將從鍵盤上輸入的若干個正整數求和,遇到負數則終止
程式,並且輸入的數不超過10個。
輸入:正整數
計算:求累加和
輸出:和
程式:
結果:
2.continue語句:
在迴圈語句中使本次迴圈結束,即跳過迴圈體中下面尚未執行的語句,接著進行下次是否執行迴圈的判斷。
例1:
把100~200之間的不能被3整除的數輸出。
程式:
結果:
四.習題
例1:
日本某地發生了一件謀殺案,警察通過排查確定殺人凶手必為4個嫌疑犯的一個。以下為4個嫌疑犯的供詞。
A說:不是我。
B說:是C。
C說:是D。
D說:C在胡說
已知3個人說了真話,1個人說的是假話。現在請根據這些資訊,寫一個程式來確定到底誰是凶手。
程式:
結果:
總結:
(1)因為已知3個人說了真話,1個人說的是假話。認為的可以判斷出凶手在C和D之間,但是電腦不會有這種想法,所以還是由這個已知條件來進行判斷。
(2)A~D依次設為說假話(假為0)(9~11行),sum裡放的是每個人說的話的真假,當sum為3時,說明其他三個人都說的是真話(真為1,所以有1+1+1=3)。
(3)sum實際上不是數與數的加法,而是真假情況的判斷結果:3個人說了真話,1個人說的是假話。
(4)A說:不是我。killer != 'A';B說:是C。killer == 'C';C說:是D。killer == 'D';D說:C在胡說(C的對立情況)。killer != 'D'
習題2:
題目:通過程式設計實現,統計0~n有多少個9
提示:n通過引數傳入