版權說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權,請進行舉報或認領
文檔簡介
第三章基本控制結構程序設計結構化程序設計的特點是任何程序都可由三種基本結構及其組合來描述。本章將介紹C++分支結構和循環(huán)結構的設計方法。還將介紹一些常用算法。第三章基本控制結構程序設計
3.1分支結構程序設計
3.5枚舉類型
3.4常用算法的應用實例
3.3轉向語句
3.2循環(huán)結構程序設計
3.6輸入輸出文件簡介3.1分支結構程序設計對程序的運行流程進行控制,主要通過執(zhí)行專門用來控制流程的語句來實現(xiàn)。流程控制語句也稱為過程化語句。分支語句是三種基本流程控制語句之一。C++提供以下三種分支語句:
if語句
條件運算符“?:”
swith
語句
3.1分支結構程序設計3.1.1if語句
3.1.2條件運算符“?:”
3.2.1swich語句
3.1.1if
語句if語句有兩種基本格式為:1、if(<表達式>)<語句1>;2、if(<表達式>)<語句1>else <語句2>;
if語句【例3.1】輸入一個年份,判斷是否閏年。算法分析:假定年份為year,閏年的條件是:year%4==0&&year%100!=0||year%400==0。#include<iostream.h>voidmain(){ intyear; cout<<"輸入年份:"<<endl; cin>>year; if(year%4==0&&year%100!=0 ||year%400==0)
cout<<year<<"是閏年"<<endl; elsecout<<year<<"不是閏年"<<endl;}ok分析:讀入三個數(shù),先求出兩個數(shù)中較大者,再將該大數(shù)與第三個數(shù)比較,求出最大數(shù)。#include<iostream.h>voidmain(){inta,b,c,max;cout<<"輸入三個正數(shù):";cin>>a>>b>>c;
cout<<"a="<<a<<'\t'<<"b="<<b<<'\t‘ <<"c="<<c<<endl;if(a>b)max=a;elsemax=b;if(c>max)cout<<“最大數(shù)為:”<<c<<endl;elsecout<<“最大數(shù)為:”<<max<<endl;}
if
語句【例3.2】從鍵盤上輸入三個整數(shù),輸出其中的最大數(shù)。ok
if語句中,如果內(nèi)嵌語句又是if語句,就構成了嵌套if語句。if語句可實現(xiàn)二選一分支,而嵌套if語句則可以實現(xiàn)多選一的多路分支情況。嵌套有兩種形式,第一種是嵌套在else分支中:if(<表達式1>)<語句1>;elseif(<表達式2>)語句2;elseif…else<語句n>;
第二種是嵌套在if分支中為:if(<表達式1>)if(<表達式2>)<語句1>;
else<語句2>;
if語句//方法1:采用if中嵌套形式#include<iostream.h>voidmain(){ inta,b,c,max; cout<<"輸入三個正數(shù):"; cin>>a>>b>>c; cout<<"a="<<a<<'\t'<<"b="<<b<<'\t'<<"c="<<c<<endl; if(a>b)if(a>c)max=a;//a>b且a>c elsemax=c;//a>b且a<c else if(b>c)max=b;//a<=b且b>c elsemax=c;//a<=b且b<c cout<<"最大數(shù)max="<<max;}
if
語句【例3.3】用嵌套if語句完成【例3.2】的任務。ok//方法2:采用else中嵌套形式#include<iostream.h>voidmain(){ inta,b,c,max; cout<<"輸入三個正數(shù):"; cin>>a>>b>>c; cout<<"a="<<a<<'\t'<<"b="<<b<<'\t'<<"c="<<c<<endl; if(a>b&&a>c)max=a; elseif(b>a&&b>c)max=b; elsemax=c; cout<<"最大數(shù)為:max="<<max;}
if
語句ok
要特別注意else和if的配對關系。C++規(guī)定了if和else的“就近配對”原則,即相距最近且還沒有配對的一對if和else首先配對。按上述規(guī)定,第二種嵌套形式中的else應與第二個if配對。如果根據(jù)程序的邏輯需要改變配對關系,則要將屬于同一層的語句放在一對“{}”中。如第二種嵌套形式中,要讓else和第一個if配對,語句必須寫成:if(表達式1){if(表達式2)語句1;}else語句2;
第二種嵌套形式較容易產(chǎn)生邏輯錯誤,而第一種形式配對關系則非常明確,因此從程序可讀性角度出發(fā),建議盡量使用第一種嵌套形式。請看以下兩個語句://語句1:if(n%3==0)if(n%5==0)cout<<n<<″是15的倍數(shù)″<<endl;elsecout<<n<<″是3的倍數(shù)但不是5的倍數(shù)″<<endl;//語句2:if(n%3==0){if(n%5==0)cout<<n<<″是15的倍數(shù)″<<endl;}elsecout<<n<<″不是3的倍數(shù)″兩個語句的差別只在于一個“{}”,但表達的邏輯關系卻完全不同?!纠?.4】某商場優(yōu)惠活動規(guī)定,某種商品單價為80元,一次購買5件以上(包含
5件)10件以下(不包含10件)打9
折,一次購買10件以上(包含10件)打8折。設計程序根據(jù)客戶的購買量計算總價。
if
語句算法1、輸入購買件數(shù)count,設置單價price=80(元)2、根據(jù)count值確定折扣discount;3、實際售價amount=price*count*discount;4、輸出amount的值。算法細化:2.1、if(count<5)discount=1;2.2、if(count>=5&&count<10)discount=0.9;2.3、if(count>=10)discount=0.8;ok#include<iostream.h>voidmain(){floatprice=80,discount,amount;//單價,折扣,總價
intcount; //購買件數(shù)
cout<<"輸入購買件數(shù):"<<endl;
cin>>count;
if(count<5)discount=1;elseif(count<10)discount=0.9;elsediscount=0.8;amount=price*count*discount;
cout<<"購買件數(shù):"<<count<<endl;
cout<<"單價:"<<price<<'\t'<<"折扣:“
<<discount<<endl;
cout<<"總價:"<<amount<<endl;}請在VC++平臺上運行,輸入不同的件數(shù),使程序所有分支都可以被執(zhí)行一次。ok【例3.5】求一元二次方程
ax2+bx+c=0的根。其中系數(shù)a(a≠0)、b、c的值由鍵盤輸入。分析:輸入系數(shù)a(a≠0)、b、c后,令delta=b2–4ac,結果有三種情況:若delta=0,方程有兩個相同實根;若delta>0,方程有兩個不同實根;若delta<0,方程無實根。
if
語句算法1、輸入系數(shù)a(a≠0)、b、c;2、令delta=b2–4ac;3、根據(jù)delta的值求方程的根;4、輸出方程的根;算法細化:3.1、if(delta==0)方程有兩個相同實根;計算…3.2、if(delta>0)方程有兩個不同實根;計算…3.3、if(delta<0)方程無實根;計算…ok#include<iostream.h>#include<math.h>voidmain(){ floata,b,c; floatdelta,x1,x2; constfloatzero=0.0001;//定義一個很小的常數(shù)
cout<<"輸入三個系數(shù)a(a!=0),b,c:"<<endl;
cin>>a>>b>>c;
cout<<"a="<<a<<'\t'<<"b="<<b<<'\t‘ <<"c="<<c<<endl; delta=b*b-4*a*c;求一元二次方程的根源程序if(fabs(delta)<zero){//絕對值很小的數(shù)即被認為是0
cout<<"方程有兩個相同實根:";
cout<<"x1=x2="<<-b/(2*a)<<endl;}elseif(delta>0){ delta=sqrt(delta); x1=(-b+delta)/(2*a); x2=(-b-delta)/(2*a);
cout<<"方程有兩個不同實根:";
cout<<"x1="<<x1<<'\t'<<"x2=“ <<x2<<endl;} else //delta<0
cout<<"方程無實根!"<<endl;}請在VC++平臺上運行,輸入不同的系數(shù),使程序所有分支都可以被執(zhí)行一次。3.1.2條件運算符“?:”
if語句在某些情況下可以用條件運算符“?:”來簡化表達?!?:”是一個三元運算符,其構成的表達式格式為:<表達式1>?<表達式2>:<表達式3>執(zhí)行邏輯:先計算表達式1,若其值為真(或非0),則計算表達式2(不計算表達式3),并將該值作為整個表達式的值;反之,即表達式1的值為假或為0,則計算表達式3(不計算表達式2),并將該值作為整個表達式的值。例如:inta=6,b=7,min=a<b?a:b;//min=6 min=a<b?++a:++b;//min=7a=7b=7min=a<b?a++:b++;//min=6a=7b=7ok3.1.3switch語句用嵌套if語句可以實現(xiàn)多選一的情況。另外C++中還提供了一個switch語句,稱為開關語句,也可以用來實現(xiàn)多選一:switch(表達式){case常量表達式1:《語句序列1》《break;》……case常量表達式n:《語句序列n》《break;》《default:語句序列》}
switch語句格式(1)各個case(包括default)分支出現(xiàn)的次序可以任意,通常將default放在最后。(2)break語句可選,如果沒有break語句,每一個case分支都只作為開關語句的執(zhí)行入口,執(zhí)行完該分支后,還將接著執(zhí)行其后的所有分支。因此,為保證邏輯的正確實現(xiàn),通常每個case分支都與break語句聯(lián)用。(3)每個常量表達式的取值必須各不相同,否則將引起歧義。(4)允許多個常量表達式對應同一個語句序列。例如:charscore;cin>>score;switch(score){case′A′:case′a′:cout<<″excellent″; break;case′B′:case′b′:cout<<″good″;break;default:cout<<″fair″;}(5)從形式上看,switch語句的可讀性比嵌套if語句好,但不是所有多選一的問題都可由開關語句完成,這是因為開關語句中限定了條件表達式的取值類型。
ok
switch語句例子【例3.6】
運輸公司對所運貨物實行分段計費。設運輸里程為s,則運費打折情況如下:
s<250 不打折扣
250<=s<500 2%折扣
500<=s<1000 5%折扣
1000<=s<2000 8%折扣
2000<=s<3000 10%折扣
3000<=s 15%折扣設每公里每噸的基本運費為p,貨物重量為w,折扣為d,則總運費f為:f=p*w*s*(1-d)設計程序,當輸入p、w和s后,計算運費f。算法1、輸入每噸運費p、貨物重量w、運輸里程s;2、根據(jù)運輸里程s計算折扣d;3、計算總運費f=p*w*s*(1-d);4、輸出計算結果;算法細化:2、根據(jù)運輸里程s計算折扣d分析:如果用switch語句,必須使表達式符合語法要求,分析發(fā)現(xiàn),里程s的分段點均是250的倍數(shù),因此,將里程s除以250,取整數(shù)商,便得到若干整數(shù)值。okswitch(c=s/250){case0:d=0;break;case1:d=0.02;break;case2:case3:d=0.05;break;case4:case5:case6:case7:d=0.08;break;case8:case9:case10:case11:d=0.1;break;default:d=0.15;}s<250 不打折扣250<=s<500 2%折扣500<=s<1000 5%折扣1000<=s<2000 8%折扣2000<=s<3000 10%折扣3000<=s15%折扣#include<iostream.h>#include<iomanip.h>voidmain(){intc,s;floatp,w,d,f; cout<<"輸入運輸單價p,重量w和里程s:"<<endl; cin>>p>>w>>s;c=s/250;
switch(c){ case0:d=0;break; case1:d=0.02;break; case2:case3:d=0.05;break; case4:case5:case6:case7:d=0.08;break; case8:case9:case10:case11:d=0.1;break; default:d=0.15;} f=p*w*s*(1-d); cout<<"運輸單價為"<<p<<'\t'<<"重量為"<<w<<'\t‘ <<"里程為"<<s<<endl; cout<<"折扣為"<<d<<endl; cout<<"運費為"<<f<<endl;}請在VC++平臺上運行,輸入不同的里程,使程序所有分支都可以被執(zhí)行一次。ok【例3.7】
設計一個計算器程序,實現(xiàn)加、減、乘、除運算。分析:讀入兩個操作數(shù)和運算符,根據(jù)運算符完成相應運算。#include<iostream.h>voidmain(){floatnum1,num2;charop;cout<<"輸入操作數(shù)1,運算符,操作數(shù)2:"<<endl;cin>>num1>>op>>num2;
switch(op){case'+':cout<<num1<<op<<num2<<"="<<num1+num2<<endl;break;case'-':cout<<num1<<op<<num2<<"="<<num1-num2<<endl;break;case'*':cout<<num1<<op<<num2<<"="<<num1*num2<<endl;break;case'/':cout<<num1<<op<<num2<<"="<<num1/num2<<endl;break;default:cout<<op<<"是無效運算符!";}}常量表達式采用字符型,上機運行一下。循環(huán)控制語句是三種基本流程控制語句之一。C++提供以下三種循環(huán)語句:
while語句
do-while語句
for語句3.2循環(huán)結構程序設計
循環(huán)結構程序設計3.2.1while語句
3.2.4循環(huán)的嵌套
3.2.3for語句
3.2.2do-while語句
3.2.1while語句while語句也稱為當循環(huán)。語句格式為:while(表達式)
循環(huán)體語句;
圖3.1while語句的執(zhí)行流程圖求表達式的值表達式值為真?是否執(zhí)行循環(huán)體語句
while語句【例3.8】求1+2+3+4的值。okN個連續(xù)整數(shù)相加算法1、設置變量i用來放被加數(shù),變量sum用來放和值,并初始化;2、從第一個數(shù)開始,依次將被加數(shù)賦給i,并進行操作sumsum+i;3、輸出sum;細化算法2:
while(還有被加數(shù)) { i=當前被加數(shù);
sum+=i;i準備接受下一個被加數(shù);
}源程序如下:#include<iostream.h>voidmain(){
inti=1,sum=0;//循環(huán)初始條件
while(i<=4){ sum+=i; i++; //修改循環(huán)條件
}
cout<<"sum="<<sum<<endl;
}在VC++平臺上運行,試一試是否正確okwhile語句注意:在有循環(huán)語句的程序中,通常循環(huán)開始前對循環(huán)條件進行初始化;而在循環(huán)體語句中要包含修改循環(huán)條件的語句,否則循環(huán)將不能終止而陷入死循環(huán)。C++表達方式靈活,上例中的循環(huán)語句還可以寫成:while(i<=n)sum+=i++;或者while(sum+=i++,i<=n);//循環(huán)體為空語句修改程序后在VC++平臺上運行,看是否正確3.2.2do-while語句
do-while語句稱為直到循環(huán),格式為:
do循環(huán)體語句
while(表達式)
否是表達式的值為真?執(zhí)行循環(huán)體語句求表達式的值圖3.2do-while語句的執(zhí)行流程圖do-while語句do/while語句和while語句的區(qū)別:多數(shù)情況下可以互相替代。區(qū)別是do/while語句至少執(zhí)行一次循環(huán)體后再判斷循環(huán)條件是否滿足;while語句先判斷條件是否滿足,然后才執(zhí)行循環(huán)體。【例3.9】
用迭代法求a的平方根近似值。求平方根的迭代公式為:
要求前后兩個迭代根之差小于10-5。
do-while語句迭代法求解:a是已知正數(shù),x0是迭代初值,給x0一個值,假定x0=a/2;則用迭代公式依次計算:x1=(x0+a/x0)/2;x2=(x1+a/x1)/2;……xk+1=(xk+a/xk)/2;當|xk+1–xk|<ε(ε是一個較小的正數(shù))時,迭代終止,取xk+1的值為a的平方根近似值。ok1、輸入a(a>0)及較小正數(shù)delta(也可用常變量);2、x0=a/2;用迭代公式算
x1=(x0+a/x0)/2;3、while(|x1–x0|>=delta)
{ x0=x1
;//把最近的值給x0
;
x1=(x0+a/x0)/2;
}//求xk+1時只需要知道xk的值,所以只需2個變量;4、取x1的值為a的平方根近似值,輸出。2、3步驟很適合用do/while語句實現(xiàn):
x1=a/2;
do{ x0=x1; x1=(x0+a/x0)/2;
}while(|x1–x0|>=delta);和迭代法對應的程序算法是
遞推算法:回到題目#include<iostream.h>#include<math.h>voidmain(){floatx0,x1,a;
cout<<"輸入一個正數(shù):"; cin>>a;
if(a<0)cout<<a<<"不能開平方!"<<endl;else{ //有實數(shù)解的情況
x1=a/2; //x1用于保存結果
do{ x0=x1; x1=(x0+a/x0)/2; }while(fabs(x1-x0)>=1e-5);
cout<<a<<"的平方根為:"<<x1<<endl;}}在VC++平臺上運行,輸入2,3,4,5試一試是否正確回到題目【例3.10】
輸入一段文本,統(tǒng)計文本的行數(shù)、單詞數(shù)及字符數(shù)。假定單詞之間以空格或跳格或換行符間隔,且文本開始沒有空行。算法分析:1、逐個讀入文本中的字符,直到讀到一個輸入結束符EOF為止。2、如何算行數(shù)?行結束標志為讀到字符′\n′;3、如何算單詞數(shù)?設一個變量isword,讀到字符時isword=1,讀到間隔符時isword=0;如果讀到一個間隔符而此時isword值為1,則說明剛讀完一個單詞;(如果讀到一個字符而此時isword值為0,則說明剛開始讀一個單詞;)4、如何算字符數(shù)?
do-while語句ok算法1、設置變量line、word、ch分別代表行數(shù)、單詞數(shù)、非分隔字符數(shù),并初始化;設置變量isword來輔助統(tǒng)計單詞數(shù);2、do{ 從鍵盤讀入一個字符c;
if(c==’\n’)line++; if(是單詞開頭)word++; if(c不是分隔符)ch++; }while(c!=EOF);3、輸出統(tǒng)計結果。將下面的程序在VC++平臺上運行,試一試是否正確#include<iostream.h>voidmain(){charc;intline=0,word=0,ch=0;intisword=0;do{c=cin.get();if(ch==′\n′)line++;//遇換行符行數(shù)+1if(c!=′′&&c!=′\t′&&c!=′\n′){//讀到非間隔符
if(isword==0)word++;//在單詞的起始處給單詞數(shù)+1
ch++; //字符數(shù)加+1
isword=1;}elseisword=0; //讀到間隔符}while(c!=EOF);cout<<”行數(shù):”<<line<<endl;cout<<”單詞數(shù):”<<word<<endl;cout<<”字符數(shù):”<<char<<endl;}3.2.3for語句for循環(huán)語句的格式為:for(<表達式1>;<表達式2>;<表達式3>)<循環(huán)體語句>圖3.3for語句的執(zhí)行流程圖否是求表達式1的值求表達式2的值表達式2值為真?執(zhí)行循環(huán)體語句求表達式3的值okfor語句、while語句、do/while語句實現(xiàn)相同的功能:1+2+3+4inti=1,sum=0;
//循環(huán)初始條件while(i<=4)
{sum+=i;i++;
//修改循環(huán)條件
}inti=1,sum=0;//循環(huán)初始條件do{ sum+=i; i++;//修改循環(huán)條件
}while(i<=4);for(inti=1,sum=0;i<=4;i++){ sum+=i;}/*習慣上:表達式1:循環(huán)初始條件;表達式2:循環(huán)終止條件;表達式3:修改循環(huán)條件*/okfor語句的應用for語句的幾點說明:1、是先判斷型的,同while語句;2、使用更為靈活:三個表達式可以是任意表達式,因此他們就可以實現(xiàn)循環(huán)初始化、計算、修改循環(huán)條件等任務,而不一定非在循環(huán)體中進行;
for語句的應用【例3.11】設計程序輸出Fibonacii數(shù)列的前20項,要求每行輸出5個數(shù)據(jù)。Fibonacii數(shù)列定義如下:算法分析:除了第0項和第1項外,每一項都是由類似方法產(chǎn)生,即前兩項之和;所以求當前項時,只需要記住前兩項;程序不需要為每一項設置專用變量;屬遞推算法。算法:1、設置變量n表示第幾項,變量f1和f2用來記住當前項f3之前的兩項;變量初始化n=0;2、while(當前項不到第20項)
{ if(當前項是第0項)f1=0; if(當前項是第1項)f2=1;if(當前項是第2項或更高項)f3=f1+f2;
按要求輸出f3;f1=f2;f2=f3;//記住最近兩項 當前項后移一位;
}【例3.11】設計程序輸出Fibonacii數(shù)列的前20項,要求每行輸出2個數(shù)據(jù)。Fibonacii數(shù)列定義如下:程序如下://文件名:Ex3_11.cpp#include<iostream.h>#include<iomanip.h>voidmain(){intfib0=0,fib1=1,fib2; cout<<setw(5)<<fib0<<setw(5)<<fib1<<endl; for(intn=3;n<=20;n++){ fib2=fib0+fib1; cout<<setw(5)<<fib2; if(n%5==0)cout<<endl;
//控制每行2個數(shù)據(jù)
fib0=fib1;fib1=fib2;}}for語句的應用在VC++平臺上運行運行結果:0 1 1 2 3 5 8 13 21 3455 89 144 233377610 987 159725844181【例3.12】輸入一個不超過5位的整數(shù),將其反向后輸出。例如輸入247,變成742輸出。算法分析:1、將整數(shù)的各個數(shù)位逐個位分開,用一個數(shù)組保存各個位的值,然后反向組成新的整數(shù)。2、將整數(shù)各位數(shù)字分開的方法是,通過求余得到個位數(shù),然后將整數(shù)縮小十倍,再求余,并重復上述過程,分別得到十位、百位……,直到整數(shù)的值變成0為止。
for語句的應用ok數(shù)據(jù):1、設置變量num表示輸入的整數(shù),整型數(shù)組digit[5]用來存放num的各個位;變量i用來表示數(shù)組的當前下標;算法:1、輸入num;變量初始化:i=0;2、while(num!=0)
{ num對10取余,得num的當前個位數(shù)digit[i];
num整除10,即去掉個位數(shù),十位變個位,百位變十位,……;
i++;數(shù)組digit準備記錄下一位;}3、將數(shù)組元素按下標從高到低的順序輸出;程序如下:#include<iostream.h>voidmain(){
intnum,subscript;
intdigit[5];
cout<<"輸入一個整數(shù):"<<endl;
cin>>num;
cout<<"原來整數(shù)為:"<<num<<endl; subscript=0; //數(shù)組下標初值
do{digit[subscript]=num%10; num=num/10; subscript++; //修改下標
}while(num>0);
for(inti=0;i<subscript;i++)//整數(shù)的反向組合
num=num*10+digit[i];
cout<<"反向后整數(shù)為:"<<num<<endl;}在VC++平臺上運行,試一試是否正確3.2.4
循環(huán)的嵌套【例3.13】打印九九表。打印格式為:*123456789
112243369…991827364554637281當循環(huán)語句中的循環(huán)體中又有循環(huán)語句時,就構成了嵌套循環(huán)。嵌套層次一般不超過3層,已保證可讀性。
循環(huán)的嵌套分析:1、計算機的輸出是按行進行的,因此可以先用一個循環(huán)語句輸出第一行表頭。2、表中各行數(shù)據(jù)的輸出可以用下面的算法描述:for(i=1;i<10;i++){cout<<i; //輸出行號輸出第i行數(shù)據(jù); //A
cout<<endl;//準備輸出下一行
}3、第A行需要進一步細化。由于第i行數(shù)據(jù)是一組有規(guī)律的數(shù)列,每個數(shù)的值是其所在行與列的乘積,因此輸出第i行可以:
for(j=1;j<10;j++)cout<<setw(4)<<i*j;4、按上述算法輸出的每一行都將有九列,即打印出的是矩形表而不是下三角形表。進一步分析發(fā)現(xiàn)每一行的列數(shù)與所在行數(shù)相關,因此要輸出三角形表,上面的循環(huán)語句需稍作修改:
for(j=1;j<=i;j++)cout<<setw(4)<<i*j;將此語句放到頂層算法的A行即可。
循環(huán)的嵌套算法:1、輸出表頭,用一個循環(huán)語句即可;2、輸出表體:for(i=1;i<10;i++){cout<<i; //輸出行號輸出第i行數(shù)據(jù); //A
cout<<endl;//準備輸出下一行
}3、A行細化:
for(j=1;j<=i;j++)cout<<setw(4)<<i*j;
循環(huán)的嵌套在VC++平臺上運行下面的程序:#include<iostream.h>#include<iomanip.h>voidmain()cout<<setw(3)<<'*'<<setw(4)<<''; for(inti=1;i<10;i++) cout<<setw(4)<<i;//輸出表頭(乘數(shù)) cout<<endl<<endl; for(i=1;i<10;i++){ cout<<setw(3)<<i<<setw(4)<<'';
//輸出行號(被乘數(shù)) for(intj=1;j<=i;j++) cout<<setw(4)<<i*j; //輸出表中數(shù)據(jù)(乘積) cout<<endl;//準備輸出下一行}}3.2.4
循環(huán)嵌套__打印九九表3.3
轉向語句3.3.1break語句
3.3.4return語句
3.3.3goto語句
3.3.2continue語句
3.3.1break語句
break語句只能用在switch語句和循環(huán)語句中,用來跳出switch語句或提前終止循環(huán),轉去執(zhí)行switch語句或循環(huán)語句之后的語句。在for循環(huán)中可以用break結束循環(huán):
for(;;){ … if(<表達式>)break; … }
break語句應用【例3.14】給定正整數(shù)m,判定其是否為素數(shù)。分析:如果m>2,m是素數(shù)的條件是不能被2,3,…,(取整)整除。因此可以用2,3,…,(取整)逐個去除m,如果被其中某個數(shù)整除了,則m不是素數(shù),否則是素數(shù)?!惴▽儆诟F舉法。1、輸入被測數(shù)m(m>2);令整型變量k=sqrt(m)2、判斷m是否素數(shù):設置輔助整型變量i,使i從2開始直到k依次測試m能否整除i,若能,則不是素數(shù);for(i=2;i<=k;i++)if(m%i==0)break;
/*條件滿足,m不是素數(shù),停止測試,結束for語句。*/3、根據(jù)i是否已達到k,輸出結果是否為素數(shù)。#include<iostream.h>#include<math.h> voidmain(){
int
m,i,k;
cout<<"輸入整數(shù)m:"<<endl;
cin>>m;
if(m==2)cout<<m<<"是素數(shù)"<<endl; else{ k=sqrt(m);
for(i=2;i<=k;i++)if(m%i==0)break; //只要有一個整除,就可停止
if(i>k)cout<<m<<"是素數(shù)"<<endl; //循環(huán)提前終止表示是非素數(shù)
elsecout<<m<<"不是素數(shù)"<<endl; }}在VC++平臺上運行,改一下,使程序自動算出100以內(nèi)的素數(shù)3.3.2continue語句
continue語句只能用在循環(huán)語句中,用來終止本次循環(huán)。當程序執(zhí)行到continue語句時,將跳過其后尚未執(zhí)行的循環(huán)體語句,開始下一次循環(huán)。下一次循環(huán)是否執(zhí)行仍然取決于循環(huán)條件的判斷。
continue語句與break語句的區(qū)別在于,continue語句結束的只是本次循環(huán),而break結束的是整個循環(huán)。
例:輸出1~100內(nèi)3的倍數(shù)。分析:設置整型變量I從1變化到100,依次測試I是否3的倍數(shù),算法屬于窮舉法。
for(I=1;I<=100;I++){if(I%3!=0)continue;
//I不是3的倍數(shù),不輸出,繼續(xù)下一個I;
輸出I的值;//I是3的倍數(shù)才輸出
}3.3.3goto語句
goto語句和標號語句一起使用,所謂標號語句是用標識符標識的語句,它控制程序從goto語句所在的地方轉移到標號語句處。goto語句會導致程序結構混亂,可讀性降低,而且它所完成的功能完全可以用算法的三種基本結構實現(xiàn),因此一般不提倡使用goto語句。但在某些特定場合下goto語句可能會顯出價值,比如在多層循環(huán)嵌套中,要從深層地方跳出所有循環(huán),如果用break語句,不僅要使用多次,而且可讀性較差,這時goto語句可以發(fā)揮作用。3.3.4return語句
return語句用于結束函數(shù)的執(zhí)行,返回調用者,如果是主函數(shù),則返回至操作系統(tǒng)。利用一個return語句可以將一個數(shù)據(jù)返回給調用者。通常,當函數(shù)的返回類型為void時,return語句可以省略,如果使用也僅作為函數(shù)或程序結束的標志。3.4
常用算法的應用實例【例3.15】用歐基里德算法(也稱輾轉法)求兩個整數(shù)的最大公約數(shù)。分析:假定兩個整數(shù)分別為num1和num2,最大公約數(shù)應當是不超過其中較小數(shù)的一個整數(shù)。輾轉法的思想是:用num1除以num2,求出余數(shù)resd,如果resd==0,則當前num2就是最大公約數(shù),否則如果resd!=0,num1=num2,num2=resd,重復以上過程,直到resd==0為止?!纠?.15】【例3.16】【例3.17】【例3.18】1、設置兩個整型變量num1和num2代表兩個數(shù);輸入num1、num2;2、輾轉法:
2.1、使num1>num2;2.2.1、設置變量resd=num1%num2;
2.2.2、if(resd==0)當前num2就是最大公 約數(shù);
Else{num1=num2,num2=resd;}
重復2.2.1和2.2.2,直到resd==0為止。
2.2、do{
resd=num1%num2;
if(resd==0)當前num2就是最大公約數(shù);
else{num1=num2,num2=resd;} }while(resd!=0);3、輸出當前的num2。程序如下:#include<iostream.h>voidmain(){
intnum1,num2;
cout<<"輸入兩個整數(shù):"<<endl; cin>>num1>>num2; cout<<num1<<"和"<<num2<<"的最大公約數(shù)為:"; for(;;){ intresd; resd=num1%num2; if(resd==0)break; num1=num2;num2=resd; } cout<<num2<<endl;}【例3.16】用篩選法求100之內(nèi)的所有素數(shù),并將這些素數(shù)輸出,每行輸出2個數(shù)據(jù)。分析算法一窮舉法:1、判斷一個數(shù)是否素數(shù)?方法窮舉法;2、100之內(nèi)的所有素數(shù)?方法:一個個試;綜上所述,得到一個循環(huán)嵌套的算法:
for(intm=2;m<=100;k++)//窮舉法
if(m是素數(shù))按要求的格式輸出k;k=sqrt(m);for(i=2;i<=k;i++)//窮舉法
if(k%i==0)break;//k不是素數(shù)if(i<=k)k不是素數(shù);
//剛才的for是由break結束的分析算法二篩選法:1、一個數(shù)如果是其他數(shù)的倍數(shù),則這個數(shù)肯定不是素數(shù);2、在由多個大于1的數(shù)組成的集合中,剔除所有的非素數(shù),剩下的就都是素數(shù)了;綜上所述,得到算法二(及所需的相應數(shù)據(jù)):1、將100之內(nèi)的整數(shù)映射到一個集合。可以采用一個數(shù)組a來表示,數(shù)組元素值為各個整數(shù);2、在數(shù)組a中,從素數(shù)2開始剔除掉新找到的素數(shù)的整數(shù)倍的元素值(置0,非素數(shù));3、輸出數(shù)組a中數(shù)組元素值非0的元素,他們都是素數(shù)。算法二第2步的細化(篩選法):for(i=0;i<=9;i++)//數(shù)組下標0~9,元素值1~10{ 2.1、if(a[i]==0)continue;
//i已被定為非素數(shù),已被篩掉
2.2、將數(shù)組中所有是a[i]倍數(shù)的元素置0;
for(intj=i+1;j<=99;j++)
if(a[j]%a[i]==0)a[j]=0; 2.3、判定a[i]是否素數(shù);
if(a[i]不是素數(shù))a[i]=0;//a[i]肯定是素數(shù)
}
3.4常用算法的應用實例#include<iostream.h>#include<iomanip.h>#include<math.h>constintn=100;voidmain(){int
a[n];int
i,j;for(i=0;i<n;i++)a[i]=1+i;//用數(shù)組保存整數(shù)1-100a[0]=0; //1不是素數(shù),置0for(i=0;i<n;i++){
if(a[i]==0)continue;//該數(shù)已經(jīng)置0,判斷下一個
for(j=i+1;j<n;j++) if(a[j]%a[i]==0)a[j]=0;
//是a[i]倍數(shù)的元素置0;
}3.4
常用算法的應用實例intcount=0;cout<<"1—"<<n<<"之間的素數(shù):"<<endl;for(i=0;i<n;i++)//輸出所有素數(shù)
if(a[i]!=0){
cout<<setw(6)<<a[i]; count++; if(count%10==0)cout<<endl;//每行10個
}
cout<<endl;}運行結果:1—100之間的素數(shù):23571113171923293137414347535961677173798389973.4
常用算法的應用實例3.4
常用算法的應用實例【例3.17】世界數(shù)學史上著名的“百雞問題”:雞翁一,值錢五,雞母一,值錢三,雞雛三,值錢一。百錢買百雞,問雞翁、母、雛各幾何?分析:設雞翁、母、雛分別為i,j,k,根據(jù)題意可得:i*5+j*3+k/3*1=100;i+j+k=100;兩個方程無法解出三個變量,只能將各種可能的取值代入,其中能滿足兩個方程的就是所需的解,因此這是枚舉算法(也叫窮舉法)的應用。
i、j、k可能的取值有哪些?分析可知,百錢最多可買雞翁20,雞母33,雞雛300。
算法:for(i=0;i<=20;i++) for(j=0;j<=33;j++) for(k=0;k<=300;k++) if((i+j+k==100)&&(5*i+3*j+k/3==100))
cout<<i<<j<<k;
這個算法使用三重循環(huán),執(zhí)行時間函數(shù)是立方階,循環(huán)體將執(zhí)行20*33*300=198000次。我們希望在算法上改進一下,如能減少一重循環(huán),將大大縮短運行時間。3.4常用算法的應用實例實際上,當i、j確定時,k就可由題目要求確定為100-i-j,因此實際上只要用i、j去測試,用錢數(shù)檢測就可以了。循環(huán)體將執(zhí)行:20*33=660次。算法改進為:for(i=0;i++<=20;)for(j=0;j++<=33;)if(5*i+3*j+(100-i-j)/3==100)
cout<<i<<j<<k;3.4
常用算法的應用實例程序如下:#include<iostream.h>#include<iomanip.h>voidmain(){int
i,j,k;cout<<"公雞母雞小雞"<<endl;for(i=0;i<=20;i++)
for(j=0;j<=33;j++){
k=100-i-j; if((5*i+3*j+k/3==100)&&(k%3==0))
//注意(k%3==0)非常重要 ,想一想為什么
cout<<setw(6)<<i<<setw(10)<<j<<setw(10)<<k<<endl;
}}3.4常用算法的應用實例程序運行后將輸出:公雞 母雞 小雞
0 25 754 18 788 11 81124843.4常用算法的應用實例3.4
常用算法的應用實例【例3.18】輸入一個8位二進制數(shù),將其轉換為十進制數(shù)輸出。分析:二進制轉換為十進制只要將每位二進制數(shù)乘以該位的權然后相加。實際上屬于多項式求和問題:
對于本例,x=2。多項式的系數(shù)ai即為二進制數(shù)的各個位,可以用數(shù)組保存。如果直接求冪再求和,需要做(n*(n+1)/2)次乘法。現(xiàn)將多項式作如下變形:就變成一個十分簡單的計算,僅做了n次乘法。算法:1、數(shù)組bin[8]用來放各個二進制位;2、整型變量dec=0
;x=2;//初始化2、for(i=7;i>=0;i--)//系數(shù)從an到a0依次投入運算
dec=dec*x+(bin[i]-'0');
//(bin[i]-'0'):數(shù)字字符轉換為數(shù)字3.4常用算法的應用實例程序如下:#include<iostream.h>constintn=8;voidmain(){charbin[n];
intx=2,a,dec,i;
cout<<"輸入二進制序列:"<<endl;
for(i=n-1;i>=0;i--)cin>>bin[i];//先輸入的是高位
dec=0;
for(i=n-1;i>=0;i--){ a=bin[i]-'0'; //數(shù)字字符轉換為數(shù)字
dec=dec*x+a;}
cout<<"二進制序列(";
for(i=n-1;i>=0;i--)cout<<bin[i];
cout<<")的值為:"<<dec<<endl;}3.5枚舉類型
3.5.1枚舉類型的定義
3.5.2枚舉變量的使用
枚舉類型(enumerate)是c++中的一種派生數(shù)據(jù)類型,它是用戶定義的若干枚舉常量的集合。枚舉類型的變量,只能取枚舉常量表中所列的值。定義枚舉類型的主要目的是增加程序的可讀性。3.5.1枚舉類型的定義
枚舉類型的定義格式為:enum<類型名>{<枚舉常量表>};關鍵字enum指明其后的標識符是一個類型的名字,枚舉常量表中列出該類型的所有取值,各枚舉常量之間以“,”間隔。例:enmucolor_set1{RED,BLUE,WHITE,BLACK};enumweek{Sun,Mon,Tue,Wed,Thu,Fri,Sat};枚舉常量(或稱枚舉成員)是以標識符形式表示的整型量,例如下面的定義是非法的:enum
letter_set{‘a(chǎn)’,‘d’,‘F’,’s’,‘T’}; //枚舉常量只能是標識符enumyear_set{2000,2001,2002,2003,2004,2005};//改為y2000等則正確3.5.1枚舉類型的定義
各個枚舉常量代表該枚舉類型的變量可能取的值,編譯系統(tǒng)為每個枚舉常量指定一個整數(shù)值,缺省狀態(tài)下,這個整數(shù)就是所列舉元素的序號,序號從0開始。如上例中RED、BLUE、WHITE、BLACK的值分別為0、1、2、3。用戶也可以在類型定義時為部分或全部枚舉常量指定整數(shù)值,在第一個指定值之前的枚舉常量仍按缺省方式取值,而指定值之后的枚舉常量按依次加1的原則取值。各枚舉常量的值可以重復,但各枚舉常量標識符必須不同。例如,enum
fruit_set{apple,orange,banana=1,peach,grape}enumweek{Sun=7,Mon=1,Tue,Wed,Thu,Fri,Sat};枚舉常量apple、orange、banana、peach、grape的值分別為0、1、1、2、3。枚舉常量Sun,Mon,Tue,Wed,Thu,Fri,Sat的值分別為7、1、2、3、4、5、6。3.5.2枚舉類型的變量的使用
1、定義枚舉類型之后,就可以定義枚舉類型的變量;亦可類型與變量同時定義(甚至類型名可?。篶olor_set1color1,color2;enum{Sun,Mon,Tue,Wed,Thu,Fri,Sat}weekday1,weekday2;2、枚舉變量的取值范圍就是整型數(shù)的一個子集。枚舉變量占用內(nèi)存的大小與整型數(shù)相同。3、枚舉變量允許的操作只有賦值和關系運算;例如:
if(color3==color4)cout<<”相等”;
cout<<color3<WHITE; 4、枚舉變量不能直接輸入,可以直接輸出,但輸出的是變量的整數(shù)值。例如:
cin>>color1 //非法
cout<<color3 //合法,輸出的是2
從程序的合法性和可讀性出發(fā),枚舉變量的輸入輸出一般都采用switch語句將其轉換為字符或字符串。同時,枚舉類型數(shù)據(jù)的其他處理也往往應用switch語句。3.5.2枚舉類型的變量的使用
【例3.19】口袋中有紅、黃、藍、白、黑五種顏色的球若干個,每次從口袋中取三個不同顏色的球,統(tǒng)計并輸出所有的取法。分析:每個球的顏色都是這五種顏色之一,因此可以使用枚舉類型來定義球的顏色。假設所取三個球的顏色分別為i,j,k,每個量都有5種取值,其中i≠j≠k就是滿足要求的取法,因此用枚舉算法(窮舉法)可以解決。3.5.2枚舉類型的變量的使用
算法:1、定義枚舉類型及相應變量;
enumcolor{red,yellow,blue,white,black};colori,j,k,col;2、for(i=red;i<=black;i++)
for(j=red;j<=black;j++)
if(i!=j)//前兩個球顏色不同
for(k=red;k<=black;k++)
if(k!=i&&k!=j)//第三個球不同于前兩個,滿足要求;找到一種取法3、輸出該取法:注意枚舉量的輸出方法。3.5.2枚舉類型的變量的使用
程序如下:#include<iostream.h>#include<iomanip.h>void
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經(jīng)權益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
- 6. 下載文件中如有侵權或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 辦公大樓幕墻施工安裝合同
- 電子元器件瑕疵管理方案
- 物業(yè)管理集團福利費管理手冊
- 家具行業(yè)項目招投標信息表
- 高空農(nóng)業(yè)噴灑合同
- 2025個人信用貸款借款合同
- 臨沂生態(tài)農(nóng)場租賃合同
- 門店市場調研渠道分析
- 醫(yī)用高值耗材管理指南
- 智能家居大清包施工合同
- 新《安全生產(chǎn)法》解讀PPT課件
- E車E拍行車記錄儀說明書 - 圖文-
- 人才梯隊-繼任計劃-建設方案(珍貴)
- WLANAP日常操作維護規(guī)范
- 《健身氣功》(選修)教學大綱
- 王家?guī)r隧道工程地質勘察報告(總結)
- GE公司燃氣輪機組支持軸承結構及性能分析
- 《昆明的雨》優(yōu)質課一等獎(課堂PPT)
- 油氣田地面建設工程ppt課件
- 電動蝶閥安裝步驟說明
- 全自動電鍍流水線操作說明書(共12頁)
評論
0/150
提交評論