




版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領
文檔簡介
1程序設計基礎C/C++語言程序設計案例教程2本章將介紹C語言的主要語句和程序設計的三種基本結構——順序結構、選擇結構和循環結構。把C語言的基本數據類型、運算符、順序結構、選擇結構、循環結構等知識貫穿到案例中,以幫助讀者建立程序設計的基本概念和思想3案例一計算圓的周長和面積1.問題描述已知圓的半徑,求圓的周長和面積。2.問題分析圖3.1計算圓的面積和周長的流程圖程序?=?數據結構?+?算法,所以,要編寫程序,通常要進行算法分析和數據分析,依據算法分析和數據分析畫出傳統流程圖或者N-S流程圖,最后根據流程圖編寫程序。(1)算法分析:所謂“算法”,指為解決一個問題而采取的方法和步驟,或者說是解題步驟的精確描述。對同一個問題,可以有不同的解題方法與步驟。在本題中l?=?2πr,s?=?πr2,屬于三種控制結構中的順序結構。(2)數據分析:主要分析有哪些輸入數據,輸出數據,中間數據,分別為什么類型比較合適。例如本題中r為輸入數據,l、s為輸出數據,都為float類型。(3)畫出流程圖,如圖3.1所示。4圖3.1計算圓的面積和周長的流程圖53.?C語言代碼#include<stdio.h>#definePI3.1415926voidmain(){floatr,l,s; /*數據定義部分,簡單語句*/r=2.0; /*給變量r賦值為2.0*/l=2*PI*r; /*計算周長l*/s=PI*r*r; /*計算面積s*/printf("l=%f,s=%f\n",l,s); /*輸出周長l和面積s,以上4條全部為執行語句*/}4.程序運行結果l=12.566370,s=12.56637063.1算?法?與?流?程
3.1.1算法的特性算法(algorithm)是指解題方案的準確而完整的描述,是一系列解決問題的清晰指令。算法具備以下特性:(1)有窮性:指算法在執行有限步驟后,自動結束而不會出現死循環,并且每個步驟在可接受的時間內完成。(2)確定性:算法中的每一個步驟都應當是確定的,而不是含糊的、模棱兩可的。也就是說不應該產生歧義。(3)有0個或多個輸入:所謂輸入是指算法執行時從外界獲取必要信息(外界是相對算法本身的,輸入可以是人工鍵盤輸入的數據,也可以是程序其他部分傳遞給算法的數據)。(4)有1個或多個輸出:算法的輸出就是指該算法得到的結果。算法必須有結果,沒有結果的算法沒有意義(結果可以是顯示在屏幕上或打印的,也可以是將結果數據傳遞給程序的其他部分)。(5)可行性:算法的每一步都必須是可行的,即都可通過執行有限次數完成。73.1.2算法的表示形式
常用的算法表示方法有自然語言、傳統流程圖、結構化流程圖(N-S流程圖)、偽代碼、計算機語言等。本書將重點講述傳統流程圖和N-S流程圖,在后面的程序算法描述中采用傳統流程圖,如果讀者感興趣的話,可以將它們轉化成為N-S流程圖。傳統流程圖是用一些約定的幾何圖形來描述算法。用某種圖框表示某種操作,用箭頭表示算法流程。下面的圖例就是美國標準化協會ANSI規定了一些常用的流程圖符號,如圖3.2所示,它已為世界各國程序工作者普遍采用的標準。8圖3.2常用的流程圖符號9下面分別介紹流程圖各圖符的作用和含義。起止框:表示算法的開始和結束。一般內部只寫“開始”或“結束”。輸入輸出框:表示算法請求輸入需要的數據或算法將某些結果輸出。一般內部常常填寫“輸入…”“打印/顯示…”等內容。菱形框(判斷選擇框):作用主要是對一個給定條件進行判斷,根據給定的條件是否成立來決定如何執行其后的操作。它有一個入口,兩個出口。處理框:表示算法的某個處理步驟,一般內部常常填寫賦值操作或計算表達式。連接點:用于將畫在不同地方的流程線連接起來。同一個編號的點是相互連接在一起的,實際上同一編號的點是同一個點,只是畫不下時才分開來畫。使用連接點,還可以避免流程線的交叉或過長,使流程圖更加清晰。注釋框:注釋框不是流程圖中必須的部分,不反映流程和操作,它只是對流程圖中某些框的操作做必要的補充說明,以幫助閱讀流程圖的人更好地理解流程圖的作用。10N-S流程圖比文字描述直觀、形象、便于理解;比傳統流程圖緊湊易畫,尤其是它廢除了流程線,整個算法是由各個基本結構按順序組成的。N-S流程圖的上下順序就是執行時的順序,寫算法和看算法都是從上到下,十分方便。用N-S流程圖表示的算法都是結構化算法,它由幾種基本結構順序組成,基本結構之間不存在跳轉,流程的轉移只存在于一個基本結構范圍之內。113.1.3C語言語句概述
C語言的語句分類如圖3.3所示。圖3.3C語言數據操作語句12案例二格式輸入輸出函數1.問題描述定義不同類型的數據,在運行界面按指定的數據格式輸入數據,完成數據賦值。2.問題分析程序大部分都是由輸入、處理、輸出組成的,輸入是大部分程序不可或缺的一部分,在編程時將數據的值以正確的形式輸入,賦予變量,是編程的一個基本任務,格式化輸入函數主要是scanf(),它要求在程序運行界面以指定的格式進行輸入。133.C語言代碼#include"stdio.h"/*預處理命令*/voidmain(){inta,b,c;longm;floatx;doubley;printf("inputa,b,c,m:");scanf("%d%o%x%ld",&a,&b,&c,&m);/*將變量a,b,c,m的值分別以十進制整型、八進制、十六進制和長整型的形式輸入,中間用空白符隔開,空白符常用空格,本章將用□表示一個空格,其他章節則省略*/printf("a=%d,b=%d,c=%d,m=%ld\n",a,b,c,m); /*輸出a,b,c,m的值*/printf("inputx,y:");scanf("%f%lf",&x,&y);/*將變量x,y的值以單精度形式和雙精度形式輸入,中間用空白符隔開*/printf("x=%f,y=%lf\n",x,y); /*輸出x,y的值*/}144.程序運行結果inputa,b,c,m:10□012□0x1a□100a=10,b=10,c=26,m=100inputx,y:6.8□1.2345x=6.800000,y=1.234500153.2數據的輸入與輸出3.2.1printf()函數1.?printf()函數printf()函數的一般格式為:printf("格式控制字符串",輸出項表);函數功能:將輸出項表中的各個對象的值按格式控制字符串中對應的格式顯示在標準輸出設備(顯示器)上。例如:printf("sumis%d\n",sum);16說明:(1)調用printf()函數時必須至少給出一個實際參數,即格式控制字符串。格式控制字符串是用雙引號括起來的字符串,可以包含兩類字符:①普通字符,是作為輸出提示的文字信息,將會進行原樣輸出。例如:printf("thisisanapple!");輸出的結果為:thisisanapple!②格式說明,由“%”和用來控制對應表達式的輸出格式字符組成,如%d,%c等。它的作用是將內存中需要輸出的數據由二進制形式轉換為指定的格式輸出。(2)輸出項表是需要輸出的數據對象。每個輸出的數據是一個值為基本類型或指針類型的表達式,稱為實參表達式。輸出項表中的各輸出項要用逗號隔開。輸出數據項的數目任意,但是格式說明的個數要與輸出項的個數相同,使用的格式字符也要與它們一一對應且類型匹配。17例如,對于printf("%d,%s",n,s);語句,其中?"%d,%s"?是格式控制字符串,n,s是輸出項表。格式字符d與輸出項n對應,格式字符s與輸出項s對應。2.格式字符每個格式說明都必須用“%”開頭,以一個格式字符作為結束,在此之間可以根據需要插入“寬度說明”、左對齊符號“-”、前導零符號“0”等。允許使用的格式字符及其說明如表3.l所示。18表3.1printf()函數使用的格式字符及其說明格式字符說明d或i輸出帶符號的十進制整數(正數不輸出符號)o以八進制無符號形式輸出整數(不帶前導0)X或x以十六進制無符號形式輸出整數(不帶前導0x或0X)。對于0x用小寫形式abcdef輸出;對于0X,用大寫形式ABCDEF輸出u按無符號的十進制形式輸出整數c輸出一個字符s輸出字符串中的字符,直到遇到'\0',或者輸出由精度指定的字符數f以[-]mmm.dddddd帶小數點的形式輸出單精度和雙精度數,d的個數由精度指定。隱含的精度為6,若指定的精度為0,小數部分(包括小數點)都不輸出E或e以[-]m.ddddddE±xxx或[-]m.dddddde±xxx的指數形式輸出單精度和雙精度數。d的個數由精度指定,隱含的精度為6,若指定的精度為0,小數部分(包括小數點)都不輸出G或g由系統決定采用%f格式還是采用%e格式,以使輸出寬度最小%輸出一個%19說明:(1)?%d格式符:輸出帶符號的十進制整數。①?%d是按實際長度進行輸出。如:printf("x=%d,y=%d",83,35);結果為:x=83,y=35②%md是按照m指定的寬度進行輸出,且數據右靠齊,不夠位左端補空格。如果實際寬度大于m,則按數據的實際寬度進行輸出。如:x=1234;y=123456;printf("x=%5d,y=%5d",x,y);結果為:x=□1234,y=123456注意:由于格式字符的控制在輸出時會出現空格。20③%-md按照m指定的寬度進行輸出,只是如果數據的位數小于m,則數據在寬度內左靠齊,右端補空格。如:x=1234;y=123456;printf("x=%-5d,y=%-5d",x,y);結果為:x=1234□,y=123456④%ld輸出長整型數據。如:x=76543;printf("x=%ld,x=%d",x,x);結果為:x=76543,x=76543⑤%mld是按照m指定的寬度輸出長整型數據,且數據右靠齊。如果實際寬度大于m,則按數據的實際寬度進行輸出。如:x=76543;printf("x=%7ld,x=%4ld",x,x);結果為:x=□□76543,x=7654321(2)?%o格式符:以八進制數形式輸出(無符號)整數。如:inta=-1;printf("%d,%o",a,a);結果為:-1,37777777777又如:printf("%lo,%8o",0xFFFFF,-1);結果為:3777777,37777777777printf("%-12o",0xFFFFF);結果為:3777777□□□□□22(3)?%x格式符:以十六進制形式輸出整數。輸出的數據不帶符號。如:x=-1;printf("x=%x,x=%d",x,x);結果為:x=ffffffff,x=-1同樣,%x也可以使用l、m、-作為說明符。如:longx=0x9FFFF;printf("%8x,%lx,%8lx,%-8lx",x,x,x,x);結果為:9ffff,9ffff,□□□9ffff,9ffff□□□23(4)?%u格式符:用來以十進制形式輸出無符號數據。如:inti=-2;unsignedintj=65535;printf("i=%d,%o,%X,%u\n",i,i,i,i);printf("j=%d,%o,%X,%u\n",j,j,j,j);結果為:i=-2,37777777776,FFFFFFFE,4294967294j=65535,177777,FFFF,65535同樣,%u也可以使用l、m、-作為說明符。24(5)?%c格式符:用來輸出一個字符。在0~255范圍的一個整數,可以用字符形式輸出,結果為該整數作為ASCII碼所對應的字符;反之,一個字符也可以用整數形式輸出。如:printf("x=%c,y=%c",'A',66);結果為:x=A,y=B同樣,%c也可以使用m作為說明符。如:printf("x=%5c",66);結果為:x=□□□□B25(6)?%s格式符:用來輸出一個字符串。①?%s是按實際字符串長度進行輸出。如:printf("%s","china");結果為:china②?%ms是按照m指定的寬度進行輸出,且字符數據右靠齊。如果實際長度大于m,則按字符串的實際長度進行輸出。如:printf("%8s","china");結果為:□□□china26③?%-ms按照m指定的寬度進行輸出,只是如果字符串的實際長度小于m,則字符數據左靠齊,右端補空格。如:printf("%-8s%s","china","is□good");結果為:china□□□is□good④?%m.ns是按照m指定的寬度進行輸出,但是只輸出字符串從左端開始的n個字符。如果n小于m,則字符數據右靠齊,左端補空格;如果n大于m,則突破m的限制,保證n個字符正常輸出。如:printf("%7.2s,%.4s","china","china");結果為:□□□□□ch,chin⑤%-m.ns如果n小于m,則字符數據左靠齊,右端補空格。如:printf("%-5.3s","china");結果為:chi□□27(7)?%f格式符:用來輸出實數,以小數形式輸出。①?%f是整數部分全部輸出,小數部分保留6位,小數位不夠6位后面補足0,多了四舍五入,需注意有效位數?、?m.nf指定輸出的數據共占m位,小數部分為n位。此時,小數點也需占用1位。如果實際寬度小于m,則數據右靠齊,左端補空格。如果實際寬度大于m,則按數據的實際寬度進行輸出。③%-m.nf如果數據的實際寬度小于m,則數據左靠齊,右端補空格。如:floatf=123.456;printf("%f,%10f,%10.2f,%.2f,%-10.2f\n",f,f,f,f,f);結果為:123.456001,123.456001,□□□□123.46,123.46,123.46□□□□28(8)?e格式符:以指數形式輸出實數。①?%e是固定小數部分占6位,整數占1位,小數點占1位,"e"占1位,指數占3位,指數符號占1位。整體共占13位。即數值按規范化指數形式輸出,小數點前必須有且只有1位非零的有效數字。如:printf("%e",123.456);結果為:1.234560e+002②?%m.ne指定輸出的數據共占m位,小數為n位。如果實際寬度小于m,則數據右靠齊,左端補空格。如果實際寬度大于m,則按數據的實際寬度進行輸出。③?%-m.ne如果數據的實際寬度小于m,則數據左靠齊,右端補空格。如:floatf=123.456;printf("%e,%10e,%10.2e,%.2e,%-10.2e",f,f,f,f,f);結果為:1.234560e+002,1.234560e+002,□1.23e+002,1.23e+002,1.23e+002□29(9)?g格式符:自動選擇實數輸出列數最小的f或e格式,且不輸出無意義的零。如:f=123.456;printf("%f,%e,%g",f,f,f);結果為:123.456001,1.234560e+002,123.456(10)?%%格式符:作用是輸出一個%。如:printf("這個月的出勤率是96%%");結果為:這個月的出勤率是96%在使用printf()函數時還需注意:·除了X,E,G外,其他格式字符必須用小寫字母?!じ袷娇刂谱址校砂D義字符?!じ袷秸f明必須以“%”開頭?!び敵鲎址?”,則應在“格式控制字符串”中用連續兩個%表示?!げ煌南到y在實現格式輸出時,輸出結果可能會有一些小的差別。30各種附加格式說明符含義見表3.2。表3.2附加格式說明符(修飾符)修飾符功能m輸出數據最小域寬,數據長度?<?m,左補空格;否則按實際寬度輸出.n對實數,指定小數點后位數(位數多了四舍五入,少了后面補零)對字符串,指定實際輸出位數-輸出數據在域內左對齊(缺省右對齊)+指定在有符號數的正數前顯示正號(+)0輸出數值時指定左面不使用的空位置自動填0#在八進制和十六進制數前顯示前導0,0xl在d,o,x,u前,指定輸出精度為long型在e,f,g前,指定輸出精度為double型31例3.1字符型數據的輸出。#include"stdio.h"voidmain(){intn=97; /*定義基本整型變量n,并給其賦值*/charch='B'; /*定義字符型變量ch,并給其賦值*/printf("n:%d%c\n",n,n); /*n:原樣輸出,第一個%d表示將n以十進制整型的形式 輸出,第二個%c表示將n以字符形式輸出*/printf("ch:%d%c\n",ch,ch); /*第一個%d表示將ch以十進制整型形式輸出*/printf("%s\n","student"); /*將字符串student以字符串形式輸出*/printf("%10s\n","student"); /*將字符串student以字符串形式輸出,域寬為10*/printf("%-10s\n","student"); /*將字符串student以字符串形式左對齊輸出,域寬為10*/printf("%10.3s\n","student");/*10表示域寬,.3表示從字符串student中從左至右截取 三個字符輸出*/printf("%.3s\n","student"); /*.3表示從字符串student中從左至右截取三個字符輸出*/}32程序運行結果如下:n:97ach:66Bstudentstudentstudentstustu333.2.2scanf()函數1.?scanf()函數scanf()函數的一般格式為:scanf("格式控制字符串",輸入地址列表);其中,格式控制字符串和printf中的一樣,輸入地址列表中的各輸入項用逗號隔開,各輸入項只能是合法的地址表達式,即可以是變量的地址或字符串的首地址等。例如,對于scanf("%d%f",&n,&f);這個語句,"%d%f"是格式控制字符串,&n,&f是輸入項表,n,f是兩個變量,這些變量前的符號“&”是C語言中的求地址運算符,&n就是取變量n的地址,&f則是取變量f的地址。也就是說,輸入項必須是某個存儲單元的地址。同時要注意輸入時在兩個數據之間要用一個或多個空格分隔,也可以用回車鍵(用↙表示)、跳格鍵Tab。輸入時可以采用:8□9.2↙或8□□□9.2↙或8(按Tab鍵)9.2↙或8↙9.2↙342.格式說明每個格式說明都必須用“%”開頭,以一個“格式字符”作為結束。允許用于輸入的格式字符和它們的功能和printf()函數格式一致。說明:(1)?%o,%x用于輸入八進制、十六進制的數。例如:scanf("%o%x",&a,&b);
printf("%d,%d",a,b);若輸入為:12□12↙或012□0x12,則得到結果為:10,18。(2)在格式字符前可以用一個整數指定輸入數據所占的寬度,由系統自動截取所需數據。例如:scanf("%3d%3d",&x,&y);若輸入為:123456↙,則得到的結果為:x=123,y=456。系統自動截取前3位賦給變量x,繼續截取3位賦給變量y。35(3)可使用“l”格式控制長型數據的輸入,如長整型,雙精度類型:scanf("%ld%lo%lx",&x,&y,&z);scanf("%lf%le",&a,&b);而輸入短型數據應用“h”,例如:scanf("%hd%ho%hx",&x,&y,&z);(4)“*”表示空過一個數據。例如:scanf("%d%*d%d",&x,&y);若輸入為:3□4□5↙,則得到的結果為:x=3,y=5。(5)對于unsinged型的可以用%u,%d,%o,%x輸入皆可。(6)不可以規定輸入數據的精度,即不可以對實數指定小數位的寬度。例如:scanf("%7.2f",&x);若輸入為:1234567↙,從而想得到x=12345.67是完全錯誤的!363.使用scanf()時應注意的問題(1)輸入項表只能是地址,表示將輸入的數據送到相應的地址單元中;所以一定要寫“&”,而不能直接寫變量名。(2)當調用scanf()函數從鍵盤輸入數據時,最后一定要按下回車鍵(Enter鍵),scanf()函數才能接受從鍵盤輸入的數據。當從鍵盤輸入數據時,輸入的數據之間用間隔符(空格、跳格鍵或回車鍵)隔開,間隔符個數不限。(3)在“格式控制字符串”中,格式說明的類型與輸入項的類型應一一對應匹配。(4)在“格式控制字符串”中,格式說明的個數應該與輸入項的個數相同。若格式說明的個數少于輸入項的個數時,scanf()函數結束輸入,多余的數據項并沒從終端接受新的數據;若格式說明的個數多于輸入項的個數時,scanf()函數同樣也結束輸入。37(5)如果在“格式控制字符串”中插入了其他普通字符,這些字符不能輸出到屏幕上。但在輸入時要求按一一對應的位置原樣輸入這些字符。例如:scanf("%d,%d",&i,&j);則實現上面賦值的輸入數據格式如下:1,2↙1和2之間的是逗號,而不能是其他字符。例如:scanf("inputthenumber%d",&x);輸入形式為inputthenumber3才能使x得到3這個值。例如:scanf("x=%d,y=%d",&x,&y);輸入形式為x=3,y=4↙如果想在輸入之前進行提示,先用一條printf()輸出提示即可。例如:printf("Inputthenumber:\n");scanf("%d",&x);38(6)在用“%c”格式輸入字符時不能用分隔符將各字符分開。例如:scanf("%c%c%c",&c1,&c2,&c3);若輸入a□b□c↙,則得到:c1='a',c2='□',c3='b'。因為“%c”只要求輸入一個單個的字符,后面不需要用分隔符作為兩個字符的間隔??梢娍崭褡址?、轉義字符均為有效字符。(7)某一數據輸入時,遇到下列輸入則認為當前輸入結束。①遇到空格、回車鍵、Tab鍵時輸入結束。②到達指定寬度時結束,如%3d,則只取3列。③遇到非法輸入時,如下面的例子:scanf("%d%c%f",&x,&y,&z);若輸入為:1234k543o.22↙,則得到:x=1234,y='k',z=543。遇到o認為數據輸入到此結束。393.2.3字符輸入輸出函數
1.?putchar()函數此函數為字符輸出函數,其作用是輸出給定的一個字符常量或一個字符變量,與printf()函數中的%c相當。putchar()函數括號內必須有一個輸出項,輸出項可以是字符型常量或變量、整型常量或變量、整型或字符型表達式,但輸出結果只能是單個字符而不能是字符串。例如:putchar('A');輸出字母A。putchar(65);輸出整數65作為ASCII碼所對應的字符,結果也為字母A。putchar(x);這里x可以是整型或字符型變量。例3.2字符輸出函數putchar()舉例。#include<stdio.h> /*putchar()函數所需的頭文件*/
voidmain(){chara,b,c;a='C';b='A';c='T';putchar(a); /*將變量a的值以字符形式輸出*/putchar(b); /*將變量b的值以字符形式輸出*/putchar(c); /*將變量c的值以字符形式輸出*/}程序運行結果如下:CAT402.?getchar()函數此函數為字符輸入函數,其作用是運行時在運行界面輸入一個字符,該函數返回輸入字符的ASCII碼值。該函數無參數,只能接受一個字符。當調用getchar()函數時,系統會等待外部的輸入。用getchar()函數得到的字符可以賦給一個字符型變量或者整型變量,也可以不賦給任何變量,只是作為表達式的一部分。41例3.3字符輸入函數getchar()舉例。#include"stdio.h" /*getchar()函數所需的類文件*/voidmain(){charch;ch=getchar(); /*利用getchar()函數給ch賦值,getchar()函數為無參函數*/putchar(ch); /*利用putchar()函數輸出變量ch*/printf("\n");printf("%c%d\n",ch,ch);/*將ch的值分別以字符形式和十進制整型形式輸出*/printf("%c%d\n\n",ch-32,ch-32);/*將ch-32的值分別以字符形式和十進制整型形式輸出*/}如果輸入的數據是a,程序運行結果如下:aa97A6542案例三交換兩個整型變量的值
1.問題描述從鍵盤輸入兩個整型變量的值,交換它們的值并輸出。圖3.4交換兩個整型數的流程圖2.問題分析(1)算法分析:在計算機中交換兩個變量a和b,不能只寫a=b;b=a;正確的交換方法(借助中間變量):c=a;a=b;b=c。(2)數據分析:輸入數據:a,b,int型;輸出數據:a,b,int型;中間數據:c,int型。(3)該算法的流程圖如圖3.4所示。43圖3.4交換兩個整型數的流程圖443.?C語言代碼#include<stdio.h>voidmain(){inta,b,c;printf("\ninputa,b:");scanf("%d%d",&a,&b); /*以十進制整型形式輸入a和b的值*/printf("\nbeforeexchange:a=%db=%d\n",a,b); /*輸出交換前a和b的值*/c=a;a=b;b=c; /*交換a和b的值*/printf("afterexchange:a=%db=%d\n",a,b); /*輸出交換后a和b的值*/}454.程序運行結果inputa,b:35beforeexchange:a=3b=5afterexchange:a=5b=3463.3順序結構程序設計順序結構是程序設計語言最基本的結構,其包含的語句是按照書寫的順序執行的,其特點就是其中的語句或結構被連續按順序執行。順序結構的程序流程如圖3.5所示,程序按書寫順序執行。先執行A,再執行B。其中A、B可是一條或多條語句,甚至是一個復雜的結構。47圖3.5順序結構執行流程
48例3.4編寫程序計算圓周長、圓面積、圓球表面積、圓球體積、圓柱體積。(1)算法分析。l=2*PI*r;s=PI*r*r;sq=4*PI*r*r;vq=4.0/3.0*PI*r*r*r;vz=PI*r*r*h;(2)數據分析。輸入數據:半徑r和圓柱體的高h,float型;輸出數據:圓周長l、圓面積s、圓球表面積sq、圓球體積vq、圓柱體積vz,float型。(3)該算法的流程圖如圖3.6所示。49圖3.6計算球體表面積、體積等的流程圖50(4)?C語言代碼。#include"stdio.h"#include"math.h"#definePI3.14voidmain(){doubler,h,l,s,sq,vq,vz;printf("請輸入圓半徑r,圓柱高h的值\n");scanf("%lf%lf",&r,&h);/*r和h為雙精度,輸入時用%lf*/l=2*PI*r;/*計算周長l*/s=PI*r*r;/*計算面積s*/sq=4*PI*r*r;/*計算球體表面積sq*/vq=4.0/3.0*PI*r*r*r;/*計算球體體積*/vz=PI*r*r*h;/*計算圓柱體體積*/printf("圓周長為:l=%6.2f\n",l);printf("圓面積為:s=%6.2f\n",s);printf("圓球表面積為:sq=%6.2f\n",sq);printf("圓球體積為:sv=%6.2f\n",vq);printf("圓柱體積為:sz=%6.2f\n",vz);}51(5)程序運行結果。請輸入圓半徑r,圓柱高h的值2.13圓周長為:l=13.19圓面積為:s=13.85圓球表面積為:sq=55.39圓球體積為:sv=38.77圓柱體積為:sz=41.5452例3.5從鍵盤上輸入一個3位數,求該數各位上的數字和。(1)算法分析。設該數為n,百位上的數字為a,十位上的字為b,個位上的數字為c,則a=n/100,b=n/10%10,c=n%10。(2)數據分析。輸入數據:n,int型;輸出數據:d,用于存放個位、十位、百位上的數的和,int型;中間數據:a,b,c,int型。(3)?C語言代碼。#include"stdio.h"voidmain(){intn,a,b,c,d;printf("輸入三位數:");scanf("%d",&n);a=n/100; /*百位數*/b=n/10%10; /*十位數*/c=n%10; /*個位數*/d=a+b+c; /*百位、十位、個位上的數字和*/printf("百位、十位、個位上的數字和=%d",d);}53(4)程序運行結果。輸入三位數:256百位、十位、個位上的數字和=13圖3.7計算三角形面積的流程圖思考:如果是四位數或者五位數,又應該如何求解?54例3.6輸入三角形的三邊長,求三角形的面積。(1)算法分析。已知三角形的三邊長a,b,c,則由海倫公式計算三角形的面積為其中,s=(a+b+c)/2。(2)數據分析。輸入數據:三邊邊長a,b,c,float型;輸出數據為面積area,float型;中間數據為半周長s,float型。(3)此題為順序結構程序設計,按照輸入數據、計算、輸出的思路畫出該算法的流程圖如圖3.7所示。55圖3.7計算三角形面積的流程圖56(4)?C語言代碼。#include<stdio.h>#include<math.h>voidmain(){floata,b,c,s,area;scanf("%f,%f,%f",&a,&b,&c); /*輸入三邊長*/s=(a+b+c)/2; /*計算半周長s*/area=sqrt(s*(s-a)*(s-b)*(s-c)); /*計算面積area*/printf("a=%7.2f,b=%7.2f,c=%7.2f,s=%7.2f\n",a,b,c,s);printf("area=%7.2f\n",area);}57(5)程序運行結果。3.0,4.0,5.0a=3.00,b=4.00,c=5.00,s=6.00area=6.00由以上例題可知:順序結構程序設計的一般步驟包括:(1)定義所需要的輸入、輸出和中間變量;(2)讓輸入變量得到值(可以通過賦值、輸入函數和初始化等方法完成);(3)依據算法計算所需結果;(4)按合適的格式輸出結果。58案例四計算y=|x|1.問題描述從鍵盤上輸入x的值,計算其絕對值。2.問題分析(1)算法分析。①
y=x;②如果y?<?0,則執行y?=?-x,可以用單分支if語句。(2)數據分析。輸入數據:x,float型;輸出數據:y,float型。(3)此題為選擇結構程序設計,按照輸入數據,計算、輸出的思路畫出該算法的流程圖如圖3.8所示。59圖3.8求絕對值的流程圖603.?C語言代碼#include"stdio.h"voidmain(){floatx,y;printf("pleaseinputx:");scanf("%f",&x);y=x;if(y<0)y=-x;printf("y=%f\n",y);}4.程序運行結果pleaseinputx:-10.3y=10.300000613.4選擇結構的程序設計選擇結構也稱為條件結構或分支結構,通常是在兩個或兩個以上不同的操作中選擇其中的一個進行操作。例如在例3.6中,如果輸入的a,b,c不能構成三角形,則無法計算,所以需要在計算前判斷a,b,c能否構成三角形,這就需要用選擇結構來完成。在C語言中有兩種選擇控制語句:if語句和switch語句。623.4.1if語句及其三種基本形式
1.單分支選擇語句單分支選擇語句的形式為if(表達式)
語句執行單分支選擇語句時,首先判斷表達式的值,若為真(非0),則執行下面的語句;若為假(0),則跳過該語句。流程圖如圖3.9所示。圖3.9單分支選擇結構執行流程圖632.雙分支選擇語句圖3.10雙分支選擇結構執行流程圖雙分支選擇語句的形式為if(表達式)
語句組1else語句組2執行雙分支選擇語句時,首先判斷表達式的值,若為真(非0),則執行語句組1;否則執行語句組2。流程圖如圖3.10所示。圖3.10雙分支選擇結構執行流程圖64例3.7在案例四中,用雙分支選擇語句求x的絕對值,流程圖如圖3.11所示。C語言代碼如下:#include"stdio.h"voidmain(){floatx,y;printf("pleaseintputx:");scanf("%f",&x);if(x>0)y=x;elsey=-x;printf("y=%f\n",y);}圖3.11用雙分支選擇語句實現x的絕對值的算法流程圖
653.多分支選擇語句
多分支選擇語句的形式為if(表達式1)語句1elseif(表達式2)語句2elseif(表達式3)語句3…elseif(表達式m)語句melse語句n流程圖如圖3.12所示圖3.12多分支選擇語句執行流程圖66執行多分支選擇語句時,先判斷表達式1的值,若為真(非0),則執行語句1,然后跳到整個if語句之外繼續執行下一條語句;若為假(0),則執行下一個表達式2的判斷,若表達式2的值為真(非0),則執行語句2,然后同樣跳到整個if語句之外執行if語句之后的下一條語句;否則一直這樣繼續判斷,當出現某個表達式的值為真時,則執行其后對應的語句,然后跳到整個if語句之外繼續執行程序;若所有的表達式均為假,則執行語句n,然后繼續執行后續程序。67例3.8從鍵盤上輸入x的值,計算y的值。68(1)算法分析。此題有四種情況,可以采用多分支if語句。在設計時,如果有n個分支,一般將前(n-1)個分支用if或者elseif引出,而將最后一個分支用else來處理。(2)數據分析。輸入數據:x,float型;輸出數據:y,float型。(3)?C語言代碼。#include"stdio.h"voidmain(){floatx,y;printf("pleaseintputx:");scanf("%f",&x);if(x>3)y=x+20;elseif(x>0)y=x+3;elseif(x>-3)y=x-20;elsey=x-3;printf("y=%f\n",y);}(4)程序運行結果。pleaseintputx:2y=5.000000693.4.2if語句的嵌套結構
在上述三種if語句的結構中,當if(表達式)或else后面的語句本身又是一個if語句結構時,就形成了if語句的嵌套結構。例如if語句的兩層嵌套結構為if(表達式1)if(表達式1-1)
語句1_1else
語句1_2elseif(表達式2_1)
語句2_1else
語句2_270一般而言,如果嵌套的if語句都帶else子句,那么if的個數與else的個數總相等,加之良好的書寫習慣,則嵌套中出現混亂與錯誤的機會就會少一些。但在實際程序設計中常需要使用帶else子句和不帶else子句的if語句的混合嵌套,在這種情況下,嵌套中就會出現if與else個數不等的情況,很易于出現混亂的現象。else和if配對的原則是:缺省?{}?的情況下,else總是和上方未配過對的最近的if配對,同時配對的else和if之間連線不能出現交叉。例如:if(表達式1)if(表達式2)語句1else語句271從形式上看,編程者似乎希望程序中的else子句屬于第一個if語句,但編譯程序并不這樣認為,仍然把它與第二個if相聯系。對于這類情況,C語言明確規定:if嵌套結構中的else總是屬于在它上面的、最近的、又無else子句的那個if語句。盡管有這類規定,建議還是應盡量避免使用這類嵌套為好。如果必須這樣做,應使用復合語句的形式明顯指出else的配對關系。如可以這樣來處理:if(表達式1){if(表達式2) 語句1}else語句272例3.9比較兩個整數的關系,討論它們是大于,小于還是等于關系。(1)算法分析。此題有三種情況,可以采用多分支if語句或者if語句的嵌套,這里采用if語句的嵌套,可以這樣設計:總體是一個雙分支,一個分支處理不等于的情況,另一個分支處理等于的情況,然后在不等于這個分支下嵌套一個雙分支,判斷是大于還是小于關系。(2)數據分析。輸入數據:x,y,int型;輸出數據:字符串,不需要定義。(3)算法流程圖如圖3.13所示。圖3.13比較兩個整數關系的流程圖
73(4)?C語言代碼。#include<stdio.h>voidmain(){
intx,y;
printf("Enterintegerxandy:");scanf("%d%d",&x,&y);if(x!=y)if(x>y)printf("x>y\n");/*注意else和它匹配的if對齊*/elseprintf("x<y\n");elseprintf("x=y\n");}(5)程序運行結果。Enterintegerxandy:350x<y74例3.10例3.8的分段函數用嵌套的if語句實現,程序如下:#include"stdio.h"voidmain(){floatx,y;printf("pleaseintputx:");scanf("%f",&x);if(x>0)if(x>3)y=x+20;elsey=x+3;
elseif(x>-3)y=x-20;elsey=x-3;printf("y=%f\n",y);}753.4.3switch語句(開關語句)switch語句是C語言中提供的一種有效的、結構清晰的多分支選擇語句,也稱為開關語句。它根據給出的表達式的值,將程序控制轉移到某個語句處執行。使用它可以克服嵌套的if語句易于造成混亂及過于復雜等問題。C程序設計中常用它來實現分類、菜單設計等處理。switch語句的一般形式為switch(表達式){case常量表達式1:語句組1;case常量表達式2:語句組2;…case常量表達式n:語句組n;default:語句組n+1;}76執行switch語句時,首先計算表達式的值,然后逐個與case后的常量表達式值相比較,當表達式的值與case后面某個常量表達式的值相等時,即執行其后的語句,繼續執行后面所有case后的語句,直到遇到break語句或遇到switch結構右側的花括弧結束。如果表達式的值與所有case后的常量表達式值均不相同時,則執行default后的語句。例如,要求輸入一個數字(1~7),輸出其對應星期幾的英文單詞。switch(a){case1:printf("Monday\n");case2:printf("Tuesday\n");case3:printf("Wednesday\n");case4:printf("Thursday\n");case5:printf("Friday\n");case6:printf("Saturday\n");case7:printf("Sunday\n");default:printf("error\n");}77當輸入5之后,執行了case5以及以后的所有語句,輸出了Friday及以后的所有單詞。因為在switch語句中,“case常量表達式”只相當于一個語句標號,表達式的值和某標號相等則從該標號開始執行,不能在執行完該標號的語句后自動跳出整個switch語句,所以出現了繼續執行所有后面case語句的情況。這是與前面的if語句不同的,應該引起注意。為了避免上述情況,C語言還提供了一種break語句,用于跳出switch語句。我們將程序修改如下,在每一case語句之后增加break語句,使每一次執行之后均可跳出switch語句,從而避免輸出不應有的結果。78switch(a){case1:printf("Monday\n");break;case2:printf("Tuesday\n");break;case3:printf("Wednesday\n");break;case4:printf("Thursday\n");break;case5:printf("Friday\n");break;case6:printf("Saturday\n");break;case7:printf("Sunday\n");break;default:printf("error\n");}最后一個分支(default)可以不加break語句。79例3.11將百分制成績轉換成五分制成績,轉換原則如下:80(1)算法分析。此題有五種情況,可以采用多分支if語句或switch語句,解決這個問題的關鍵有兩個,第一,如何將像93.6,95.8,96等這些數值都對應到輸出A這種分支下,將一個兩位數s轉換成一位數,通常采用(int)(s/10)這種方法。第二,這五個分支如果用switch語句,通常可以將前四個分支用case來處理,而將最后一個分支用default來處理。(2)數據分析。輸入數據:s,表示百分制成績,float型;輸出數據為:g,表示五分制成績,char型。81(3)?C語言代碼。#include<stdio.h>voidmain(){floats;charg;printf("請輸入一個0至100之間的百分制成績:");scanf("%f",&s);switch((int)(s/10)){case10:case9:g='A';break;case8:g='B';break;case7:g='C';break;case6:g='D';break;default:g='E';}printf("百分制成績為:%f,五分制成績為:%c\n",s,g);}(4)程序運行結果。請輸入一個0至100之間的百分制成績:85.5百分制成績為:85.500000,五分制成績為:B82說明:(1)?switch后面“表達式”的類型和常量表達式的類型是整型、字符型。(2)每一個case的常量表達式的值必須互不相同。(3)在case后允許有多條執行語句,可以不用{}括起來。(4)各case和default子句的先后順序可以變動,而不會影響程序執行結果。default子句可以省略不用。(5)多個case可共用一組執行語句。如例3.11中,case10和case9后的語句一樣,只需要在case9后面寫上語句組就行。833.4.4選擇結構程序舉例例3.12從鍵盤上輸入三個數,計算以這三個數為邊長,圍成的三角形的面積。(1)算法分析。在順序結構程序設計中,我們設計過求三角形面積的程序,沒有考慮輸入的數據是否可以組成三角形。本例要考慮三角形的三邊關系,若a+b>c&&a+c?>?b&&b+c>a,則可以構成三角形,所以此題有兩個分支,若能夠構成三角形,則計算其面積,否則輸出數據錯誤,可以用雙分支if語句解決。(2)數據分析。輸入數據:三邊長a,b,c,float型;輸出數據:面積area,float型;中間數據:半周長s,float型。84(3)?C語言代碼。#include<stdio.h>#include<math.h>voidmain(){floata,b,c,s,area;printf("請輸入三個大于0的三角形邊長");scanf("%f,%f,%f",&a,&b,&c); /*輸入三邊長*/if(a+b>c&&a+c>b&&b+c>a) /*判斷能否構成三角形*/{s=(a+b+c)/2; /*計算半周長s*/area=sqrt(s*(s-a)*(s-b)*(s-c)); /*計算面積area*/printf("a=%7.2f,b=%7.2f,c=%7.2f\n",a,b,c);
printf("area=%7.2f\n",area);}elseprintf("輸入數據錯誤");}(4)程序運行結果。請輸入三個大于0的三角形邊長3.0,4.0,5.0a=3.00,b=4.00,c=5.00area=6.0085例3.13從鍵盤上輸入一個年份,編寫程序判斷該年是否是閏年。(1)算法分析。判斷一個用整數表示的年份是不是閏年的規則是該數滿足以下兩個條件之一則為閏年:①能被400整除;②能被4整除,但不能被100整除。根據上述規則,我們可用year表示年份,flag為標志變量。是閏年,設置flag=1,否則設置flag=0,最后根據flag的值進行輸出。在是與否的問題中經常設計標志變量。是閏年需滿足的條件是表達式(year%400==0)||(year%4==0&&year%100!=0)的值為真,所以此題可以用雙分支if語句解決。(2)數據分析。輸入數據:year,int型;輸出數據:year,int型;中間數據:flag,int型。86(3)?C語言代碼。#include"stdio.h"voidmain(){intyear,flag;printf("Pleaeinputayear:");scanf("%d",&year);if((year%400==0)||(year%4==0&&year%100!=0))flag=1;elseflag=0;if(flag==1)printf("%d年是閏年\n",year);elseprintf("%d年不是閏年\n",year);}(4)程序運行結果。Pleaeinputayear:20002000年是閏年87例3.14從鍵盤上輸入a,b,c三個數,求關于x的方程ax2+bx+c=0的根。(1)算法分析。如果a等于0,是一元一次方程,否則是一元二次方程,所以總體是雙分支,當是一元二次方程時,有三種情況,可以用if語句的嵌套完成。判別式d=b2-4ac。當d?=?0時,方程有兩個相等的實根:x1=x2=-b/(2*a)。當d?>?0時,方程有兩個不相等的實根:x1=(-b+sqrt(d))/(2*a),x2=(-b-sqrt(d))/(2*a)。當d?<?0時,方程有兩個虛根:x1=jp+ipi,x2=jp-ipi,實部jp=-b/(2*a),虛部ip?=?sqrt(-d)/(2*a)。(2)數據分析。輸入數據:a,b,c,,float型;輸出數據:x1,x2,jp,ip,float型;中間數據:d,float型。88(3)?C語言代碼。#include"math.h"#include"stdio.h"voidmain(){floata,b,c,d,x1,x2,jp,ip;scanf("%f%f%f",&a,&b,&c);printf("theequation");if(fabs(a)<1e-6)printf("isnotquadratic");else{d=b*b-4*a*c;if(fabs(d)<=1e-6) /*相等的實根*/{?printf("hastwoequalroots:\n");printf("x1=x2=%8.4f\n",-b/(2*a));}elseif(d>1e-6) /*不相等的實根*/{x1=(-b+sqrt(d))/(2*a);x2=(-b-sqrt(d))/(2*a);printf("hastworealroots:\n");printf("x1=%8.4f,x2=%8.4f\n",x1,x2);}else /*虛根*/{jp=-b/(2*a);ip=sqrt(-d)/(2*a);printf("hastwocomplexroots:\n");printf("x1=%8.4f+%8.4fi\n",jp,ip);printf("x2=%8.4f-%8.4fi\n",jp,ip);}}}89(4)程序運行結果。132theequationhastworealroots:x1=-1.0000,x2=-2.000090案例五
計算1~100的累計和1.問題描述編程實現計算1~100的累計和。圖3.14用while實現1~100的累加求和流程圖2.問題分析(1)算法分析。設保存和的變量為sum,每次加上去的數是i,計算機是這樣完成的sum?=?sum?+?1,sum?=?sum?+?2,sum?=?sum?+?3,…,sum?=?sum?+?99,sum?=?sum?+?100,當要加上去的數i是101時,算法結束,我們可以看到這些算式有一個共同的特點,可以總結為sum=sum+i,只不過每次加上去的i的值不同罷了,i每次自增1,所以可以總結出循環變量為i,循環體為sum?=?sum+i,i?=?i+1;循環條件為sum?<=?100。(2)數據分析。輸入數據:無;輸出數據:和sum,int型;中間數據:i,int型。(3)算法流程圖如圖3.14所示。91圖3.14用while實現1~100的累加求和流程圖923.C語言代碼#include"stdio.h"voidmain(){inti=1,sum=0;/*初始化循環控制變量i和累加器sum*/while(i<=100) /*循環條件*/{sum+=i; /*實現累加*/i++; /*循環控制變量i增1*/}printf("sum=%d\n",sum);
}4.程序運行結果sum=5050思考1:如果要計算1~100之間的所有奇數之和,應該怎樣修改程序?分析:奇數之和,每次循環變量加2,所以只需要將上面程序中的i++修改為:i=i+2。思考2:如果要計算1~100之間的所有偶數之和,應該怎樣修改程序?分析:從2開始累加,將上面的程序中的循環變量i的初值i=1改為i=2,將i++改為i=i+2。思考3:如何求n!?933.5循環結構的程序設計在現實問題求解中我們往往會按照已定的條件反復執行一定的操作,這種操作我們稱為循環。例如,要輸入全校學生的成績;求前100名學生的數學平均成績;迭代求根等。幾乎所有實用的程序都包含循環。循環結構是結構化程序三種基本結構之一,它和順序結構、選擇結構共同作為各種復雜程序的基本構造單元。循環程序結構就是重復執行某一段程序,直到某個條件出現為止。循環程序結構同選擇程序結構有相似之處,都是根據條件來實現的。94在循環結構中應明確三個問題:(1)循環體:需要重復執行的語句,也包括為控制循環的語句,即使循環條件向不成立的方向轉化。(2)循環條件:是一個表達式,其值為真時執行循環體、為假時退出循環結構,執行循環結構的下一條語句。(3)循環控制:涉及循環條件中的一個或多個變量(循環變量),以及循環體中對循環變量的改變。同時也涉及對循環初值的設定。C語言提供了多種循環語句,可以組成各種不同形式的循環結構。(1)用while語句;(2)用do-while語句;(3)用for語句;(4)用goto語句和if語句構成循環。953.5.1while語句
while語句用于實現“當型”循環結構,一般形式為圖3.15while循環執行流程圖while(表達式)循環體語句其中,表達式就是循環條件,當它的值為真(非0)時,執行while語句中的循環體語句。之后繼續判斷表達式的值是否為真(非0),如果為真(非0),繼續執行循環體語句,再進行判斷,如此重復,直到表達式的值為假,則離開循環結構,轉去執行while語句后的下一條語句。while循環的執行過程如圖3.15所示。特點:先判斷表達式,后執行語句。圖3.15while循環執行流程圖
96說明:(1)?while是關鍵字,“while(表達式)”的意思為“當條件成立時執行”;(2)“表達式”為任意合法的表達式,其兩端的圓括號不能少;(3)循環之前循環變量應有值,以便能計算條件(表達式);(4)循環體中應有改變循環變量的語句,以便最后能結束循環,否則會產生死循環;(5)注意循環的次數以及循環變量的終止值(該值可能后面的語句會用到);(6)該種循環先判斷循環條件,再執行循環體;循環體可能執行多次,也可能一次也不執行;(7)循環體語句如果包括有一個以上的語句,則必須用{}括起來,組成復合語句。如果不加{},則while語句的范圍只到while后面第一個語句結束。973.5.2do-while語句
do-while語句用于實現“直到型”循環結構,一般形式為
do{
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經權益所有人同意不得將文件中的內容挪作商業或盈利用途。
- 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
- 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 長沙醫學院《高等數學Ⅰ(下)》2023-2024學年第一學期期末試卷
- 2025年陜西省商洛市洛南縣重點名校初三下學期第一次月考試題化學試題試卷含解析
- 遵義師范學院《經典譯著賞析》2023-2024學年第二學期期末試卷
- 德陽農業科技職業學院《國際新聞作品案例解析》2023-2024學年第二學期期末試卷
- 二甲護理條款解讀
- 廣西貴港市覃塘區重點名校2025年高中畢業班第二次模擬(英語試題文)試卷含答案
- 2025屆山東省泰安一中、寧陽一中高三第四次月考(物理試題理)試題含解析
- 海南省瓊海市嘉積中心校2024-2025學年三年級數學第二學期期末聯考試題含解析
- 2025年青海省玉樹州高三4月“圓夢之旅”(九)生物試題含解析
- 2025年廈門市重點中學高三第二次教學質量檢查考試物理試題試卷含解析
- 鐵路職工政治理論應知應會題庫
- 青少年模擬法庭劇本(敲詐勒索)
- 中考復習確定二次函數的解析式課件
- 音樂歌曲網上搜課件
- 萬用表校準報告
- 地鐵盾構法施工技術試題
- 直線導軌裝配文檔課件
- DBJ04∕T 253-2021 建筑工程施工安全管理標準
- 二元一次方程組(課堂PPT)
- Q∕GDW 12082-2021 輸變電設備物聯網無線傳感器通用技術規范
- 醫院藥房考試試題及答案
評論
0/150
提交評論