算法與程序設計基礎_第1頁
算法與程序設計基礎_第2頁
算法與程序設計基礎_第3頁
算法與程序設計基礎_第4頁
算法與程序設計基礎_第5頁
已閱讀5頁,還剩133頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

C語言程序設計(第3版)中國鐵道出版社ChinaRailwayPublishingHouse普通高等教育“十一五”國家級規(guī)劃教材主教材:C語言程序設計(第三版)

書號:ISBN978-7-113-09512-3

中國鐵道出版社2009年2月第3版

配套教材:C語言程序設計實驗教程

書號:ISBN978-7-113-09513-0

中國鐵道出版社2009年2月第1版

作者電子郵箱:

Luojian116@126.com

wsjwhz@126.com3.1算法概述3.3結構化程序設計方法3.2算法的常用表示方法3.4C語句概述3.6循環(huán)結構程序設計

3.7綜合程序應用舉例3.5選擇結構程序設計第3章算法與程序設計基礎結束放映3.1算法概述程序(program)是計算機可以執(zhí)行的指令或語句序列。它是用計算機解決現(xiàn)實生活中的一個實際問題而編制的。設計、編制、調試程序的過程稱為程序設計。編寫程序所用的語言即為程序設計語言,它為程序設計提供了一定的語法和語義,所編寫出的程序必須嚴格遵守它的語法規(guī)則,這樣編寫出來的程序才能被計算機所接受、運行,并產生預期的結果。3.1.1算法的概念解決一個實際問題而采取的方法和步驟,稱之為“算法”。對于同一個問題,可能有不同的方法和步驟,即有不同的算法。

【例3.1】求1+2+3+4+…+100=?算法1步驟1:1+2=3步驟2:3+3=6步驟3:6+4=10…步驟99:4950+100=5050算法2步驟1:0+100=100步驟2:1+99=100步驟3:2+98=100…步驟50:49+51=100步驟51:100*50=5000步驟52:5000+50=5050算法3步驟1:k=1,s=0步驟2:如果k>100,則算法結束,s即為所求的和,輸出s;否則轉向步驟3步驟3:s=s+k,k=k+1步驟4:轉向步驟2當然,算法也有優(yōu)劣之分,有的算法較簡練,而有的算法較煩瑣。上面三個算法中,算法2比算法1步驟少,算法3比算法2步驟少,算法3的質量最優(yōu)。一般地說,希望采用方法簡單、運算步驟少的方法。3.1.2算法的特性一個算法應具有如下五個特點:1.有窮性2.確定性3.可行性4.有零個或多個輸入5.有一個或多個輸出3.2算法的常用表示方法3.2.1自然語言表示法

所謂自然語言,就是人們日常使用的語言,可以是漢語、英語或其他語言。3.2.2流程圖流程圖是用圖形的方式來表示算法,用一些幾何圖形來代表各種不同性質的操作。ANSI(美國國家標準化協(xié)會)規(guī)定的一些常用流程圖符號(見圖3-1)已被大多數(shù)國家接受。

1.順序結構順序結構的程序是按語句的書寫順序執(zhí)行的,用圖3-2表示2.選擇結構選擇結構或稱分支結構、條件結構,用圖3-3表示

3.循環(huán)結構循環(huán)結構又稱重復結構,有兩種方式:一種是先判斷條件,若條件成立再進入循環(huán)體,可用圖3-4表示;另一種是先進入循環(huán)體執(zhí)行,再判斷條件是否成立??捎脠D3-5表示。3.2.3N-S結構流程圖1973年美國的計算機科學家I.Nassi和B.Shneiderman提出了一種新的流程圖形式。在這種流程圖中把流程線完全去掉了,全部算法寫在一個矩形框內,在框內還可以包含其他框,即由一些基本的框組成一個較大的框。這種流程圖稱為N-S結構流程圖(以兩人名字的頭一個字母組成)。3.2.4偽代碼表示法偽代碼(pseudocode)是用介于自然語言和計算機語言之間的文字和符號來表示算法,即計算機程序設計語言中具有的語句關鍵字用英文表示,其他的可用漢字,也可用英文,只要便于書寫和閱讀就可。3.2.5用計算機語言表示算法用計算機語言描述算法必須嚴格遵循所用語言的語法規(guī)則#include<stdio.h>voidmain(){

int

sign,i,n;floatsum;

printf("\nPleaseinputanintegerton:");

scanf("%d",&n);sign=1;sum=1;i=1;

while(i<=n){sign=(-1)*sign;sum=sum+sign/(3.0*i);i=i+1;}

printf("\nsum=%f",sum);}程序運行結果如下:

Pleaseinputanintegerton:5sum=0.7388893.3結構化程序設計方法在拿到一個需要求解的實際問題之后,怎樣才能編寫出程序呢?以數(shù)值計算問題為例,一般應按圖3-12所示的步驟進行。要設計出結構化的程序,可采取以下的方法: ◆自頂向下 ◆逐步細化 ◆模塊化 ◆結構化編碼【例3.5】輸入10個整數(shù)(每個數(shù)都≥3),打印出其中的素數(shù)。分析:素數(shù)又稱質數(shù),是指只能被1和它本身整除的整數(shù)。本題采用自頂向下、逐步細化方法來處理這個問題。先把這個問題分為三部分(如圖3-14所示):①輸入10個數(shù)給x1~x10;②把其中的素數(shù)找出來(或者把非素數(shù)除去)③打印出全部素數(shù)。對【例3.5】求解步驟進行細化后得到的分步驟流程圖。【例3.5】的完整流程圖3.4C語句概述1.說明語句說明語句用來定義變量的數(shù)據(jù)類型。例如:

int

sign,i,n;/*說明sign,i,n是整型變量*/2.函數(shù)調用語句 由一個函數(shù)調用加一個分號構成函數(shù)調用語句。如上例中的:printf("\nPleaseinputanintegerton:");scanf("%d",&n);3.表達式語句 在C語言中,由一個表達式加上一個分號就構成了一條表達式語句。最典型的是,由賦值表達式加上分號構成賦值語句。例如:sign=1;sum=1;i=1;sign=(-1)*sign;sum=sum+sign/(3.0*i);i=i+1;表達式能構成語句是C語言的一重要特色。其實函數(shù)調用語句也是表達式語句,因為函數(shù)調用也屬于表達式的一種。4.空語句僅由一個分號構成的語句就是空語句。例如:

;5.復合語句

復合語句是由大括號括起來的,在邏輯上相關的一組語句。如上例中的:{sign=(-1)*sign;sum=sum+sign/(3.0*i);i=i+1;}6.控制語句 控制語句用來規(guī)定語句執(zhí)行的順序,C語言共有9種控制語句。(1)if(條件){…}else{…}(條件語句)(2)for(條件){…}(循環(huán)語句)(3)while(條件){…}(循環(huán)語句)(4)do{…}while(條件);(循環(huán)語句)(5)continue;(結束本次循環(huán)語句)(6)break;(結束循環(huán)語句或結束switch語句)(7)switch(表達式){…}(多分支選擇語句)(8)goto

標號;(轉向語句)(9)return(表達式);(從函數(shù)返回語句)3.5選擇結構程序設計3.5.1關系運算符和關系表達式關系表達式用關系運算符連接起來的表達式稱為關系表達式,關系表達式的結果為邏輯值真(用“1”表示)或假(用“0”表示)。例如:

c>a+b

若a=3,b=4,c=9則結果為1a==b<c 若a=3,b=4,c=9則結果為0a=b>c 若b=4,c=9 則a的值為0

兩個數(shù)值進行比較,是比較其數(shù)值的大小,兩個字符進行比較,是比較其ASCII碼值的大小。3.5.2邏輯運算符和邏輯表達式

1.邏輯運算符及優(yōu)先次序邏輯運算符與其他運算符的運算優(yōu)先順序如下圖所示:例如:原式可寫為(a>b)&&(x>y) a>b&&x>y(a==b)||(x==y) a==b||x==y(!a)||(a>b) !a||a>b2.邏輯表達式用邏輯運算符將關系表達式或邏輯表達式連接起來的式子稱邏輯表達式。例如,若a=4,b=2,x=6,y=7,則:a>b&&x>y表達式的結果為0a==b||x==y表達式的結果為0!a||a>b 表達式的結果為1注意:(1)在C語言中規(guī)定:非零為“真”,“真”用1表示;零為“假”,“假”用0表示。例如:

'a'&&'b' 其結果為1!5.34 其結果為0(2)對邏輯表達式的求解,并不是所有的邏輯運算符都被執(zhí)行,只是在必須執(zhí)行下一個邏輯運算符才能求出表達式的解時,才執(zhí)行該運算符?!纠?.6】運行下面的程序四次,若分別輸入000,101,123,100,分別寫出其對應的輸出結果。#include<stdio.h>voidmain(){

int

a,b,c;

scanf("%d%d%d",&a,&b,&c);

printf("e=%d,a=%d,b=%d,c=%d\n", ++a&&b--&&++c,a,b,c);

printf("a=%d,b=%d,c=%d,e=%d,\n",

a,b,c,++a&&b--&&++c);c=a||((a=c)>b);

printf("a=%d,b=%d,c=%d\n",a,b,c);

printf("e=%d,a=%d,b=%d,c=%d\n", --c||b--||++a,a,b,c);

printf("a=%d,b=%d,c=%d,e=%d\n",

a,b,c,--c||b--||++a);}在VisualC++6.0環(huán)境下運行,若輸入000↙其輸出為:e=0,a=1,b=-1,c=0a=2,b=-2,c=1,e=1,a=2,b=-2,c=1e=1,a=2,b=-3,c=0a=2,b=-3,c=-1,e=1在TurboC2.0環(huán)境下運行,若輸入000↙其輸出為:e=0,a=0,b=0,c=0a=2,b=-2,c=1,e=1,a=2,b=-2,c=1e=1,a=2,b=-2,c=1a=2,b=-3,c=-1,e=13.5.3if語句C語言提供了兩種格式:格式1:if(表達式)語句;該語句的功能是:首先計算表達式的值,然后判斷表達式的值是否為非零(真),若為非零(真),則執(zhí)行語句。其執(zhí)行過程見圖3-22所示【例3.7】輸入一個字符c,若c是字母,則輸出“Yes!”。#include<stdio.h>voidmain(){charc;c=getchar();

if(c>='a'&&c<='z'||c>='A'&&c<='Z')printf("Yes!");}運行情況如下:x↙Yes!程序如下:#include<math.h>#include<stdio.h>voidmain(){floatx;doublez;

printf("\nx=");

scanf("%f",&x);

if(x<0)z=-1;

if(x==0)z=0;

if(x>0)z=log(x);

printf("z=%f\n",z);}格式2:

if(表達式)語句1;else語句2;該語句的功能是:首先計算表達式的值,然后判斷表達式的值是否為非零(真),若非零(真),則執(zhí)行語句1,否則執(zhí)行語句2。其執(zhí)行過程下圖【例3.9】輸入兩個數(shù)并判斷兩數(shù)是否相等。程序清單如下:#include<stdio.h>voidmain(){

int

a,b;

printf("Enterintegera:");

scanf("%d",&a);

printf("Enterintegerb:");

scanf("%d",&b);

if(a==b)printf("a==b\n");elseprintf("a!=b\n");}【例3.10】輸入一個整數(shù),若該數(shù)不為零,則輸出。#include<stdio.h>voidmain(){intx;

scanf("%d",&x);

if(x)printf("\nx=%d",x);}程序運行結果如下:-5↙

{輸入}x=-5 {輸出}說明:if后面的表達式可以為任何類型的表達式,只要表達式的結果為非零,則表示條件成立,否則表示條件不成立。總結:1.if后面的表達式可以為任何類型的表達式,只要表達式的結果為非零,則表示條件成立,否則表示條件不成立。2.if語句中的語句1,語句2可以是一條語句,也可以是由{}構成的一個復合語句,如果在該語句處需要寫多條語句才能完成所必要的功能時,就使用復合語句的形式。3.在格式2中的else前面的語句必須要有一個分號,整個語句結束處有一個分號。如例3.9中的if語句。3.5.4if語句的嵌套在一個if語句中,如果又完全包含了另一個(或者多個)if語句,則稱為if語句的嵌套。

if嵌套的一般形式如下:

if(表達式1)if(表達式2)語句1;

else語句2;elseif(表達式3)語句3;else語句4;if語句的嵌套既可以嵌套在if后面,也可以嵌套在else后面,具體嵌套的位置要根據(jù)實際需要而定?!纠?.11】編寫程序,求下列分段函數(shù)的值?!纠?.11】的程序清單如下:#include<math.h>#include<stdio.h>voidmain(){floatx;doublez;

printf("\nx=");

scanf("%f",&x);

if(x<0)z=-1;elseif(x>0)z=log(x);elsez=0;

printf("z=%f\n",z);}對【例3.11】程序的另一種修改:#include<math.h>#include<stdio.h>voidmain(){floatx;doublez;

printf("\nx=");

scanf("%f",&x);

if(x<=0)

if(x<0)z=-1;elsez=0;elsez=log(x);

printf("z=%f\n",z);}else的最近配對原則:C語言規(guī)定:else總是與它上面最近的且又沒有配對的if語句進行配對。在下面這條嵌套的if語句中

if(表達式1)if(表達式2)語句1;

else語句2;elseif(表達式3)語句3;else語句4;若把else語句2去掉,變成:

if(表達式1)if(表達式2)語句1;

elseif(表達式3)語句3;else語句4;

第一個else將和哪個if配對?根據(jù)else的最近配對原則,第一個else將與第2個if(表達式2)語句1;配對,如圖3-27所示。在下面的if嵌套語句中if(表達式1)if(表達式2)語句1;elseif(表達式3)語句3;else語句4;

如果用戶希望else只能和if(表達式1)配對,而不是與現(xiàn)在的if(表達式2)語句1;配對,則應該在if(表達式2)語句1;的兩端加上花括號,從而確定了新的配對關系,修改后的結果:if(表達式1){if(表達式2)語句1;}elseif(表達式3)語句3;else語句4;【例3.12】寫出下面程序的運行結果。#include<stdio.h>voidmain(){int

a,b,c;a=5;b=3;c=0;

if(c)

if(a>b)

printf("\nmax=%d",a);else

printf("\nmax=%d",b);else

printf("\nc=%d",c);}運行結果如下:c=03.5.5條件運算符和條件表達式

條件運算符(?:)是C語言中唯一的一個三目運算符,其格式如下:

表達式1?表達式2:表達式3功能:如果表達式1的值為真,則該條件表達式的結果取表達式2的值,否則取表達式3的值。例如:下述的if語句

if(a>b)max=a;elsemax=b;可以用條件表達式來改寫:

max=a>b?a:b;條件表達式說明:1.條件表達式的執(zhí)行順序:先計算表達式1的值,若表達式1的值為真,則計算表達式2的值,并把該值作為整個條件表達式的結果,表達式3不會計算;否則計算表達式3的值,并把表達式3的值作為整個條件表達式的結果,此時表達式2不會計算。2.運算優(yōu)先級:高于賦值運算符,低于算術運算符和關系運算符。例:max=(a>b)?a:b相當于max=((a>b)?a:b)a>b?a:b+1相當于a>b?a:(b+1)3.條件運算符的結合方向為“自右至左”。如:a>b?a:c>d?c:d相當于a>b?a:(c>d?c:d)【例3.13】閱讀下面的程序,若輸入為59,則輸出結果是什么?#include<stdio.h>voidmain(){

intscore;chargrade;

printf("pleaseinputascore:\n");

scanf("%d",&score);grade=score>=90?'A':(score>=60?'B':'C');

printf("%dbelongsto%c",score,grade);}運行結果如下:pleaseinputascore:59↙59belongstoC3.5.6switch語句

switch語句屬于多分支結構語句,通常用于描述有多種情況的選擇,其格式如下:

switch(表達式) { case常量表達式1: 語句1; case常量表達式2: 語句2; … case常量表達式n:

語句n; default:

語句(n+1); }上式中的default:和語句(n+1);可以省略不寫。

switch語句的執(zhí)行過程如下:首先計算表達式的值,然后用此值來查找各個case后面的常量表達式,直到找到一個等于表達式值的常量表達式,則轉向該case后面的語句去執(zhí)行;若表達式的值與下面任何一個case常量表達式的值都不相等,則自動轉去執(zhí)行default部分的語句;如果沒有default部分,退出該switch語句,執(zhí)行switch語句后面的那條語句。

【例3.14】

編寫一個程序,要求輸入學生的分數(shù),輸出其成績的分數(shù)段,用A、B、C、D、E分別表示90分以上、80~89分、70~79分、60~69分和不及格(0~59分)5個分數(shù)段?!纠?.14】的程序清單。#include<stdio.h>voidmain(){int

score,grade;

printf("\nInputascore(0~100):");

scanf("%d",&score);grade=score/10;

switch(grade){case0:case1:case2:case3:case4:case5:printf("grade=E!\n");break;case6:printf("grade=D!\n");break;case7:printf("grade=C!\n");break;case8:printf("grade=B!\n");break;case9:case10:printf("grade=A!\n");break;default:printf("Thescoreisoutofrange!\n");}}【例3.14】程序的運行結果:Inputascore(0~100):50↙{輸入分數(shù)}grade=E! {輸出結果}再運行一次:Inputascore(0~100):90↙grade=A! {輸出結果}switch語句的補充說明:(1)switch后的表達式,可以是整型或字符型,也可以是枚舉類型,不能是除這三種類型以外的其它類型;(2)每個case后的常量表達式只能是常量組成的表達式,當switch后的表達式的值與某一個常量表達式的值一致時,程序就轉到此case后的語句開始執(zhí)行;如果沒有一個常量表達式的值與switch后的值一致,就執(zhí)行default部分的語句;(3)每個case后的常量表達式的值必須互不相同,否則程序就無法判斷應該執(zhí)行哪個語句;(4)case的擺放順序并不影響執(zhí)行結果,但通常情況下是將出現(xiàn)頻率較高(即較常使用的case部分,盡量往前擺放;另外,default部分也不一定非要放在最后;(5)在執(zhí)行完一個case后面的語句后,程序流程轉到下一個case后的語句開始執(zhí)行,直至整個switch語句結束,別誤解為執(zhí)行完一個case語句之后,程序就會轉到switch后的語句去執(zhí)行。(6)如果希望在執(zhí)行完某個case語句之后,轉到執(zhí)行switch下面的那條語句,則應該在該case語句的最后補上break語句(即跳轉語句)。在執(zhí)行完break語句之后,會跳出switch語句,轉去執(zhí)行switch后面的語句?!纠?.21】從鍵盤輸入一個日期,判斷這一天是這一年的第幾天?#include<stdio.h>voidmain(){intday,month,year,sum,leap;

printf("\nPleaseinputyear,month,day\n");

scanf("%d,%d,%d",&year,&month,&day);

switch(month)/*先計算某個月之前總天數(shù)*/{

case1:sum=0;break;

case2:sum=31;break;

case3:sum=59;break;

case4:sum=90;break;

case5:sum=120;break;

case6:sum=151;break;

case7:sum=181;break;

case8:sum=212;break;

case9:sum=243;break;

case10:sum=273;break;

case11:sum=304;break;

case12:sum=334;break;

default:printf("dataerror");}sum+=day;/*總天數(shù)再加上輸入的幾號*/

if(year%400==0||(year%4==0&&year%100!=0))

leap=1; /*判斷出是閏年*/

elseleap=0;

if(leap==1&&month>2)sum++;

/*如果是閏年且月份大于2,則總天數(shù)應再加1天*/

printf("Itisthe%dth

day.",sum);}【例3.15】程序分析:以2008年7月19日為例,首先應該把7月份之前共六個月的總天數(shù)加起來,然后再加上本月的19天就得到本年度的第幾天。特殊情況下,若該年是閏年且輸入月份值大于二月份時,需要考慮多加一天。程序運行結果如下:Pleaseinputyear,month,day

2008,7,19↙{輸入年月日}Itisthe201thday.{輸出}3.5.7選擇結構程序設計舉例【例3.16】求一元二次方程ax2+bx+c=0的實數(shù)解,并顯示結果,這里假設a≠0。圖3-29用嵌套的if語句求一元二次方程的解#include<stdio.h>#include<math.h>voidmain(){floata,b,c,d;

printf("\na=");

scanf("%f",&a);

printf("b=");

scanf("%f",&b);

printf("c=");

scanf("%f",&c);d=b*b-4*a*c;

if(d>0){printf("\nx1=%f",(-b+sqrt(d))/(a*2));printf("\nx2=%f",(-b-sqrt(d))/(a*2));}else

if(d==0)printf("\nx1=x2=%f",(-b)/(a*2));elseprintf("\nTheequationhasnorealroot!");}【例3.16】的程序清單【例3.16】程序的運行結果:第一次運行:572↙ {輸入a,b,c}x1=-0.400000{輸出}x2=-1.000000第二次運行:441↙

x1=x2=-0.500000第三次運行:414↙Theequationhasnorealroot!【例3.17】輸入兩個正整數(shù)a和b,其中a不大于31,b最大不超過三位數(shù)。使a在左,b在右,拼成一個新的數(shù)c。例如a=23,b=30,則c為2330。若a=1,b=15,則c為115。分析:根據(jù)以上問題,可以從中抽象分析出以下數(shù)學模型,決定c的值的計算公式如下:當b為一位數(shù)時,c=a*10+b;

當b為二位數(shù)時,c=a*100+b;當b為三位數(shù)時,c=a*1000+b;因此,求c的公式為c=a*k+b(k的取值可以為10、100或1000)?!纠?.17】的流程圖。#include<stdio.h>voidmain(){int

a,b,c,k;

printf("\nInputtwopositiveintegernumber:");

scanf("%d,%d",&a,&b);

if(a<0||b<0||a>31||b>999){c=-1; /*出錯標志,代表輸入數(shù)據(jù)有誤*/

printf("Inputdataerror!");}else{if(b<10)k=10;elseif(b<100)k=100; elseif(b<1000)k=1000;c=a*k+b;}

printf("\na=%2d,b=%3d,c=%5d",a,b,c);}【例3.17】的程序清單【例3.17】程序運行結果:第一次運行:Inputtwopositiveintegernumber:23,30↙a=23,b=30,c=2330 {有效的結果}第二次運行:(2)Inputtwopositiveintegernumber:44,19↙Inputdataerror!a=44,b=19,c=-1{無效的結果,因為a>31}例3.18:假設個人所得稅的計征辦法是月收入低于1000元者,不計稅,高于1000元低于2000元者,高出部分征收5%;高于2000元低于5000元者,高出部分征收10%;高于5000元低于是10000元,高出部分征收15%,高于10000元的征收35%。輸入一個人的月收入,求出其應交的個人所得稅。#include<stdio.h>voidmain(){longintr;floatf;

printf("Inputanintegertor:");

scanf(“%ld”,&r); {輸入月收入}if(r>0){switch(r/1000){case0:f=0;break;case1:f=(r-1000)*0.05;break;case2:case3:

case4:f=1000*0.05+(r-2000)*0.1;break;【例3.18】的程序清單

case5:case6:case7:case8:case9:f=1000*0.05+3000*0.1+(r-5000)*0.15;break;default:f=1000*0.05+3000*0.1+5000*0.15+(r-10000)*0.35;}

printf(“f=%f”,f); {輸出所得稅}}else

printf(“Inputadataerror!”); {輸入數(shù)據(jù)有誤}}【例3.19】輸入兩個實數(shù)a,b,再輸入一個運算符(可以是+,-,*或/),根據(jù)運算符計算并輸出a,b兩個數(shù)的和、差、積和商。#include<stdio.h>voidmain(){floata,b;charc;

scanf("%f%f",&a,&b);c=getchar();

switch(c){case'+':printf("%f+%f=%f\n",a,b,a+b);break;case'-':printf("%f-%f=%f\n",a,b,a-b);break;case'*':printf("%f*%f=%f\n",a,b,a*b);break;case'/':if(b)printf("%f/%f=%f\n",a,b,a/b);break;default:printf("Can'tcompute!");}}【例3.19】運行結果如下:第一次運行:58+↙ {輸入}5.000000+8.000000=13.000000 {輸出}第二次運行:56/↙{輸入}5.000000/6.000000=0.833333 {輸出}【例3.20】給一個不多于5位的正整數(shù),編程求:①它是幾位數(shù),②逆序打印出各位數(shù)字,③若為兩位以上的數(shù),則判斷該數(shù)是否為回文數(shù)。分析:分解出該數(shù)每一個數(shù)位上的數(shù)字。若萬位數(shù)大于零,則為5位數(shù);否則,若千位數(shù)大于零,則為4位數(shù);否則,若百位數(shù)大于零,則為3位數(shù);否則,若十位數(shù)大于零,則為兩位數(shù);否則,若個位數(shù)大于零,則為1位數(shù),否則提示輸入錯誤。所謂回文數(shù),是指左右對稱的數(shù),即從左往右讀與從右往左讀得到的結果一樣,譬如161就是回文數(shù)。若為5位數(shù),只需判斷該數(shù)的個位數(shù)與萬位數(shù)是否相同,十位數(shù)與千位數(shù)是否相同,若兩者均相同,則為回文數(shù)。對于其他位數(shù)的判斷,請讀者自已歸納?!纠?.20】程序清單如下:#include<stdio.h>voidmain(){

int

a,b,c,d,e;longx;do{printf("\nPleaseinputapositiveintegernumbertox:");

scanf("%ld",&x);}while(x<=0||x>=100000);/*上述循環(huán)能夠確保輸入的x值一定是一個不超過5位的正整數(shù)*/a=x/10000; /*分解出萬位數(shù)字*/b=x%10000/1000; /*千位數(shù)字*/c=x%1000/100; /*百位數(shù)字*/d=x%100/10; /*十位數(shù)字*/e=x%10; /*個位數(shù)字*/if(a>0)/*萬位數(shù)字*/{printf("thereare5,%d%d

%d

%d%d\n",e,d,c,b,a);

if(e==a&&d==b)printf("thisnumberisahuiwen\n");elseprintf("thisnumberisnotahuiwen\n");}else

if(b>0)/*千位數(shù)字*/{printf("thereare4,%d%d%d%d\n",e,d,c,b);

if(e==b&&d==c)printf("thisnumberisahuiwen\n");elseprintf("thisnumberisnotahuiwen\n");}else

if(c>0)/*百位數(shù)字*/{printf("thereare3,%d%d%d\n",e,d,c);

if(e==c)printf("thisnumberisahuiwen\n");elseprintf("thisnumberisnotahuiwen\n");}

else

if(d>0)/*十位數(shù)字*/{printf("thereare2,%d%d\n",e,d);

if(e==d)printf("thisnumberisahuiwen\n");elseprintf("thisnumberisnotahuiwen\n");}else/*個位數(shù)字*/

if(e>0)printf("thereare1,%d\n",e);}【例3.20】程序運行結果:Pleaseinputapositiveintegernumbertox:543↙thereare3,345thisnumberisnotahuiwen再運行一次:Pleaseinputapositiveintegernumbertox:121↙thereare3,121thisnumberisahuiwen3.6循環(huán)結構程序設計在C語言中提供了四種實現(xiàn)循環(huán)結構的方法:(1)goto語句以及用goto語句構成的循環(huán)(2)用while語句(3)用do-while語句(4)用for語句3.6.1goto語句以及用goto語句

構成的循環(huán)goto語句為無條件轉向語句,其格式為

goto

語句標號;通常在兩種情況下使用goto語句:(1)與if語句一起構成循環(huán)結構;(2)從循環(huán)體中跳轉到循環(huán)體外,但在C語言中可以用break語句和continue語句跳出本層循環(huán)和結束本次循環(huán)。【例3.21】用if語句和goto語句構成循環(huán),求

#include<stdio.h>voidmain(){

inti=1;

intsum=0;loop:if(i<=100){sum+=i; i++;

gotoloop;}printf("\n1+2+3+…+100=%d",sum);}運行結果如下:1+2+3+…+100=5050說明:處于loop語句標識符和gotoloop之間的語句序列構成該程序的循環(huán)體,語句標識符loop后面要加冒號(:)。3.6.2while語句while語句又稱當循環(huán)語句,其一般的形式如下:

while(表達式)循環(huán)體語句;while語句的執(zhí)行過程:第1步:計算表達式的值,若表達式的值為真(非0),則執(zhí)行第二步,若表達式的值為假(值為0),則轉到第四步執(zhí)行。第2步:執(zhí)行循環(huán)體語句,循環(huán)體語句可以是簡單的一條語句,也可以是由多條語句構成的復合語句。第3步:轉到第一步執(zhí)行。第4步:結束循環(huán),執(zhí)行while語句后的第一條語句。

【例3.22】用while語句來求100以內偶數(shù)的和。#include<stdio.h>voidmain(){

intsum=0,i=2;

while(i<=100){sum=sum+i;i=i+2;}printf("2+4+…+100=%d",sum);}有關while循環(huán)的說明:(1)while循環(huán)的次數(shù)可以事先不清楚,因為在循環(huán)執(zhí)行時,能夠根據(jù)條件來判定循環(huán)是否終止;(2)循環(huán)體語句可以是簡單的語句,也可以是復合語句;若為復合語句,則需要用花括號括起來;(3)在循環(huán)體語句中,一定要有改變循環(huán)條件的語句,使循環(huán)最終能夠終止。例如:【例3.22】中的i=i+2;就是控制循環(huán)變量i不斷地加2,朝著循環(huán)的終止條件(i<=100)逼近;此處若刪除循環(huán)控制語句i=i+2;,即i值永遠不變,則循環(huán)條件(i<=100)即2<=100永真,此時的無限循環(huán)稱為死循環(huán),編程時應杜絕死循環(huán)的出現(xiàn)?!纠?.23】閱讀下面的程序,寫出運行結果。#include<stdio.h>voidmain(){

inti=1,s=1;

while(i<7)s*=i;

printf("\ns=%d\n",s);}

顯然,本例在循環(huán)體中缺少用來控制循環(huán)變量的值變化的語句,因此導致程序中出現(xiàn)死循環(huán)。若上述程序在VisualC++6.0環(huán)境下運行,由于死循環(huán),因此不會出現(xiàn)運行結果,此時應該按下組合鍵【Ctrl+Break】,或者單擊運行窗口上的“關閉”按鈕來終止程序的運行,返回到編輯狀態(tài)對程序進行修改。3.6.3do-while語句do-while循環(huán)語句又稱直到型循環(huán)語句,但是與Pascal語言中的repeat-until語句又有所不同。C語言中do-while語句的格式:do

循環(huán)體語句;while(表達式);

do-while語句的執(zhí)行過程如下:(1)執(zhí)行循環(huán)體語句,循環(huán)體語句可以是簡單的一條語句,也可以是由多條語句構成的復合語句;(2)計算表達式的值,如果表達式的值為真(非0),則執(zhí)行第(1)步,若表達式的值為假(值為0),則轉到第(3)步執(zhí)行;(3)循環(huán)結束之后,將執(zhí)行do-while語句下面的那條語句?!纠?.24】用do-while語句來實現(xiàn)求100以內的奇數(shù)和。

N-S流程圖如下圖所示?!纠?.24】的程序清單如下:#include<stdio.h>voidmain(){

intsum=0,i=1;do{sum+=i;i=i+2;}while(i<=100);

printf("\n1+3+…+99=%d\n",sum);}運行結果如下:1+3+…+99=2500說明:(1)do…while語句一般也是用于事先不知道循環(huán)次數(shù)的情況下,在循環(huán)執(zhí)行的過程中,根據(jù)條件來決定循環(huán)是否結束。(2)在循環(huán)體語句中可以是一條簡單的語句,也可以是復合語句,若為復合語句則要用花括號括起來。(3)在循環(huán)體語句中,一定要有改變循環(huán)條件的語句,使循環(huán)能終止。如上例中的i=i+2;語句就是使循環(huán)變量i增加2,改變循環(huán)條件的語句,若沒有該語句,則i的值永遠不會改變,循環(huán)就是一個死循環(huán)。(4)在while(表達式)的后面一定要有一個分號,它用來表示do-while語句的結束。(5)do…while語句和while語句最大的差別就是do-while語句至少要執(zhí)行一次循環(huán)體語句,而while語句可以一次都不執(zhí)行。請看例3.25?!纠?.25】while循環(huán)和do…while循環(huán)的比較。程序如下:

voidmain() voidmain(){{

int

m,n=1; int

m,n=1;

scanf("%d",&m);scanf("%d",&m);dowhile(m<=10){{n+=m;n+=m;m++;m++;}while(m<=10);}

printf(“n=%d,m=%d”,n,m);printf("n=%d,m=%d",n,m);}}程序運行結果如下:程序運行結果如下:5↙ 5↙n=46,m=11n=46,m=11再運行一次:再運行一次:11↙ 11↙n=12,m=12n=1,m=113.6.4for語句for語句的一般形式為:

for(表達式1;表達式2;表達式3)循環(huán)體語句其執(zhí)行過程如下:(1)先求解表達式1;(2)求解表達式2,若為真(表達式2的值為非0),則執(zhí)行for語句中指定的內嵌循環(huán)體語句,然后執(zhí)行第(3)步,若為假(表達式2的值為0),則結束循環(huán),轉到第(5)步;(3)求解表達式3;(4)返回第(2)步繼續(xù)執(zhí)行;(5)循環(huán)結束,執(zhí)行for語句后面的第一條語句。圖3-35for語句的執(zhí)行圖解for語句執(zhí)行過程的圖解形式如圖3-35所示。說明:

(1)可以把for循環(huán)的格式

for(表達式1;表達式2;表達式3)循環(huán)體語句改寫為以下容易理解的形式

for(循環(huán)變量賦初值;循環(huán)條件;循環(huán)變量增值)循環(huán)體語句

(2)for語句中的表達式1可以省略,但其后面的分號不能省略,此時應在執(zhí)行for語句之前,給循環(huán)變量賦初值,即

表達式1;

for(;表達式2;表達式3)循環(huán)體語句(3)表達式2也可省略,但其后的分號不能省略,即

for(表達式1;;表達式3)循環(huán)體語句此時等于沒有循環(huán)條件,執(zhí)行for語句時,就不要判斷循環(huán)條件,也就認為

表達式2始終為真。此時循環(huán)體中一定要有一條語句能夠跳出循環(huán),否則將是一個死循環(huán)。(4)表達式3也可以省略,但它前面的分號不能省略,即

for(表達式1;表達式2;)循環(huán)體語句此時應在循環(huán)體中要有用于改變循環(huán)變量值的語句,否則循環(huán)也會變成死循環(huán);(5)表達式1、表達式2、表達式3可以省略一個或者兩個,也可同時全部省略,但對應的分號不能省略,譬如:

for(表達式1;;)循環(huán)體語句

for(;表達式2;)循環(huán)體語句

for(;;表達式3)循環(huán)體語句

for(;;)循環(huán)體語句(6)表達式1、表達式2、表達式3可以是任何類型的表達式,包括逗號表達式。既可以是與循環(huán)變量有關的表達式,也可以是與循環(huán)變量無關的表達式?!纠?.26】求1000以內的奇數(shù)和。程序清單如下#include<stdio.h>voidmain(){

inti;longintsum=0;

for(i=1;i<1000;i+=2)sum+=i;

printf("\nsum=%ld\n",sum);}運行結果如下:sum=250000【例3.27】從鍵盤接收字符并顯示字符的個數(shù)。#include<stdio.h>voidmain(){

inti;charc;

for(i=0;(c=getchar())!='\n';i++);

printf("Thesumis%d\n",i);}運行結果如下:Iamachinese!{輸入的字符序列,最后以敲回車結束}Thesumis15

請注意:該例中循環(huán)體語句為空語句,即什么都不做,其實程序把循環(huán)體要執(zhí)行的工作,全部移到for后面的表達式了?!纠?.28】中國剩余定理:“有物不知幾何,三三數(shù)余一,五五數(shù)余二,七七數(shù)余三,問物有幾何?”。編程求1000以內的所有解。#include<stdio.h>voidmain(){int

m,count=0;

for(m=1;m<=1000;m++)if(m%3==1&&m%5==2&&m%7==3){printf(“%5d”,m);count++;if(count%5==0)printf(“\n”);}}程序運行結果如下:

521572623674725776827878929973.6.5多重循環(huán)如果在循環(huán)結構中又包含另外一個循環(huán)結構,稱為多重循環(huán),也叫循環(huán)的嵌套?!纠?.29】打印如圖3-36所示的“九-九”乘法表。

【例3.29】的程序清單。#include<stdio.h>voidmain(){

int

i,j;

for(i=1;i<=9;i++) /*外循環(huán),控制行*/{

for(j=1;j<=9;j++) /*內循環(huán),控制列*/

printf("%d*%d=%d\t",i,j,i*j);

printf("\n");}}本例的N-S流程圖如圖3-37所示。

如果想打印出以下4種形狀的“九九”乘法表,請問該如何編程?第1種圖形:

如果想打印出以下4種形狀的“九九”乘法表,請問該如何編程?第2種圖形:

如果想打印出以下4種形狀的“九九”乘法表,請問該如何編程?第3種圖形:

如果想打印出以下4種形狀的“九九”乘法表,請問該如何編程?第4種圖形:【例3.30】

問用1、2、3、4個這四個數(shù)字,能夠組成多少個互不相同且無重復數(shù)字的三位數(shù)?它們分別是多少?#include<stdio.h>voidmain(){

int

i,j,k,count=0;

for(i=1;i<5;i++)/*判斷百位數(shù)字i*/

for(j=1;j<5;j++)/*判斷十位數(shù)字j*/for(k=1;k<5;k++)/*判斷個位數(shù)字k*/{if(i!=k&&i!=j&&j!=k)/*確保i、j、k互不相同*/{count++;

printf("%d%d%d",i,j,k);if(count%5==0)printf("\n");}}

printf(“\ncount=%d\n”,count);}【例3.30】程序的運行結果如下:123124132134142143213214231234241243312314321324341342412413421423431432count=24{輸出符合條件的總數(shù)}3.6.6循環(huán)結構中的break語句break語句格式:

break;

break語句的作用是從最內層的switch、for、while或do…while語句中跳出,終止這些語句的執(zhí)行,把控制流程轉移到被中斷的循環(huán)語句(或者switch語句)后去執(zhí)行。通過使用break語句,可以不必等到循環(huán)或switch語句執(zhí)行結束,而是根據(jù)情況,提前結束這些語句的執(zhí)行?!纠?.31】求當半徑r為何值時,圓的面積第一次開始大于100?#include<stdio.h>voidmain(){

intr;floatarea,pi=3.1415927;

for(r=1;;r++){area=pi*r*r;

if(area>100)break;{面積開始大于100了}

printf("%f\n",area);}

printf("r=%d\n",r);}【例3.31】程序運行結果如下:3.14159312.56637128.27433450.26548478.539818r=6

本程序運行后,for循環(huán)運行了5次,當運行第6次(r=6)時,area=113.097336>100,這時程序不輸出area的值,同時中斷了for循環(huán)語句的繼續(xù)運行,轉到for循環(huán)的下一條語句輸出r的值。3.6.7continue語句continue語句的形式:continue;其作用是提前結束本次循環(huán),即跳過循環(huán)體中那些尚未執(zhí)行的語句,緊接著進行下一次是否執(zhí)行循環(huán)的判斷。【例3.32】從鍵盤輸入整數(shù),顯示出其中的正整數(shù),若輸入的是0,則退出。#include<stdio.h>voidmain(){

intx;do{scanf("%d",&x);

if(x<0)continue;

printf("%d\n",x);}

while(x!=0);}【例3.33】下面程序的作用是求連續(xù)的奇數(shù)和,當奇數(shù)和剛好超過1000時停止計算,并按運行結果輸出。程序中有兩空,請補充完整,使之能實現(xiàn)上述功能。#include<stdio.h>voidmain(){

int

i,sum=0;

for(i=1;;i++){if(i%2==0)continue;sum+=i;

if(sum>1000)break;}printf("1+3+5+…+%d=%d\n",i,sum);}【例3.33】程序分析:在程序中,第一空前面的條件表示i為偶數(shù)時要執(zhí)行的情況,由于本題偶數(shù)不符合題目累加的條件,故不應執(zhí)行累加語句。因此,第一空應填continue。第二個空前面的條件表示累加和大于1000,按題目要求應退出循環(huán),因此,第二空應填break。答案:(1)continue

(2)break

程序運行結果:

1+3+5+…+63=10243.6.8循環(huán)程序設計舉例【例3.34】從鍵盤輸入一個整數(shù)n,判斷n是否為素數(shù)。

素數(shù)又叫質數(shù),是指只能被1和它本身整除的自然數(shù)。在編程時,可以根據(jù)素數(shù)的定義來進行判斷,不過循環(huán)次數(shù)太多,效率較低。這里介紹一種效率更高的求素數(shù)的方法:引入一個整型變量k=。讓變量j位于區(qū)間[2,k]內,從j=2開始循環(huán),直至j=k結束,判斷變量n能否被變量j整除。如果在區(qū)間[2,k]內有變量n能被變量j整除,則j值必然小于或等于k值,表明n不是素數(shù),應該提前結束循環(huán)。如果變量n不能被[2,k]之間的任何一個整數(shù)整除,則表明n是素數(shù)?!纠?.34】的流程圖#include<stdio.h>#include<math.h>voidmain(){intn,j,k;

printf("\nInputanintegerton:");

scanf("%d",&n);k=sqrt(n);j=2;

while(j<=k){

if(n%j==0)break;j++;}

if(j>=k+1)printf(“\n%disaprimenumber!\n”,n);{是素數(shù)}elseprintf(“\n%disnotaprimenumber!\n”,n);{不是素數(shù)}

}【例3.34】的程序清單【例3.34】程序運行結果如下:Inputanintegerton:235↙235isnotaprime!再運行一次:Inputaintegerton:29↙29isaprime!【例3.35】某人想將手中一張100元的人民幣兌換成5元、1元和5角這三種面值的零鈔,同時要求所兌換的零鈔總數(shù)為100張,而且每種零鈔的數(shù)目不少于1張。問有哪幾種兌換方法?假設兌換后5元面值的鈔票有i張,1元的鈔票有j張,5角的鈔票有k張,則有以下方程組成立:不過三個變量只能列出兩個方程式,這是一個不定方程組的求解。其實題目中還隱含了如下的條件:1<=i<20且1<=j<95且1<=k<=98

在i、j、k的取值范圍內嘗試各種可能的情況,從中判斷哪種可能是符合要求的解,這就是窮舉法的思想。【例3.35】的程序清單。#include<stdio.h>voidmain(){

int

i,j,k;

printf("\nijk\n");

for(i=1;i<20;i++){5元面值}

for(j=1;j<95;j++){1元面值}

for(k=1;k<=98;k++){5角面值} if((i+j+k==100)&&(10*i+2*j+k==200)) printf("%7d%7d%7d\n",i,j,k);}【例3.35】運行結果如下(有11組解)

ijk191828216373

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
  • 6. 下載文件中如有侵權或不適當內容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論