從問題到程序:CC++程序設(shè)計(jì)基礎(chǔ) 課件 PtoP-6-數(shù)組_第1頁
從問題到程序:CC++程序設(shè)計(jì)基礎(chǔ) 課件 PtoP-6-數(shù)組_第2頁
從問題到程序:CC++程序設(shè)計(jì)基礎(chǔ) 課件 PtoP-6-數(shù)組_第3頁
從問題到程序:CC++程序設(shè)計(jì)基礎(chǔ) 課件 PtoP-6-數(shù)組_第4頁
從問題到程序:CC++程序設(shè)計(jì)基礎(chǔ) 課件 PtoP-6-數(shù)組_第5頁
已閱讀5頁,還剩124頁未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡介

第6章數(shù)組高級語言程序設(shè)計(jì)2程序的活動(dòng)都與數(shù)據(jù)有關(guān):輸入/輸出、存儲、計(jì)算等。需要處理的信息多種多樣。數(shù)據(jù)可能簡單或復(fù)雜,數(shù)據(jù)間可有豐富多采、密切或松弛的關(guān)系。語言需要提供一套數(shù)據(jù)機(jī)制,描述與數(shù)據(jù)有關(guān)的問題:必須足夠豐富,以滿足需要;不能過龐雜,臃腫難用;也不能太低級,使描述過于煩瑣。高級語言的通行方式:把數(shù)據(jù)分為類型,每個(gè)類型是一個(gè)數(shù)據(jù)集。一組基本數(shù)據(jù)類型;書寫方式;基本操作。一組構(gòu)造復(fù)合數(shù)據(jù)類型或?qū)ο蟮臋C(jī)制。3組合的數(shù)據(jù)對象稱為復(fù)合數(shù)據(jù)對象。復(fù)合對象形成的類型稱為復(fù)合數(shù)據(jù)類型,組成部分稱為成分/成員/元素??蓜?chuàng)建能存放復(fù)合類型數(shù)據(jù)的變量。它們可作為整體使用,通過名字可以訪問整個(gè)復(fù)合對象。提供訪問復(fù)合數(shù)據(jù)對象成分的操作,以存取復(fù)合變量的成分:使用成分的值或給成分賦值。常見組合機(jī)制是數(shù)組和結(jié)構(gòu)體,另一重要機(jī)制是指針,用于構(gòu)造更復(fù)雜的數(shù)據(jù)結(jié)構(gòu)。4第6章數(shù)組6.1數(shù)組的概念、定義和使用

6.1.1數(shù)組變量定義

6.1.2數(shù)組的使用

6.1.3數(shù)組的初始化6.2數(shù)組程序?qū)嵗?.3數(shù)組作為函數(shù)參數(shù)6.4兩維和多維數(shù)組6.5字符數(shù)組與字符串6.6編程實(shí)例56.1數(shù)組的概念、定義和使用數(shù)組(array)是多個(gè)同類型數(shù)據(jù)對象的組合。一個(gè)數(shù)組匯集了多個(gè)數(shù)據(jù)項(xiàng),數(shù)組元素??蓮臄?shù)組出發(fā)處理各元素,以統(tǒng)一方式處理一批/所有元素,是數(shù)組和一組獨(dú)立變量的主要區(qū)別。為此需要:數(shù)組描述,數(shù)組變量定義數(shù)組使用,包括通過數(shù)組變量使用其元素?cái)?shù)組實(shí)現(xiàn),數(shù)組的存儲方式66.1.1數(shù)組變量的定義定義數(shù)組變量(簡稱“數(shù)組”)時(shí)需要說明:數(shù)組元素類型,變量名數(shù)組(變量)的元素個(gè)數(shù)(數(shù)組大小或長度) 用方括號內(nèi)的整型表達(dá)式說明元素個(gè)數(shù)。按照ANSIC的要求,表達(dá)式應(yīng)該能夠在編譯時(shí)靜態(tài)地確定其值。例:定義兩個(gè)數(shù)組:intarray[8];doubledb[20];元素類型變量名元素個(gè)數(shù)7可用const關(guān)鍵詞先定義整型常變量或用enum定義枚舉常量,然后用這些常量來指定數(shù)組大小;或者用#define

做簡單宏定義,然后用宏名來指定數(shù)組大小??梢栽谝粭l語句中定義多個(gè)數(shù)組變量。constintNUM=10;inta1[NUM],a2[NUM+1];doubledb1[NUM],db2[NUM+2];enum{LEN=20};inta3[LEN],a4[LEN*2];doubledb3[LEN],db4[LEN*3];#defineSIZE100inta5[SIZE],a6[SIZE*4+1];doubledb5[SIZE],db6[SIZE*5-2];語言標(biāo)準(zhǔn)(ANSIC、C99、C++)對數(shù)組定義的差別按照ANSIC標(biāo)準(zhǔn),在定義數(shù)組時(shí)不能用無法在編譯時(shí)靜態(tài)求值的整型變量或表達(dá)式來指定數(shù)組大小。不合法的數(shù)組定義:intn;cin>>n;intarr[n];//數(shù)組大小由運(yùn)行時(shí)用戶輸入的數(shù)值確定函數(shù)中的不合法的數(shù)組定義:voidf(intm,intn){intb[n];//數(shù)組大小來自于調(diào)用時(shí)的參數(shù)值 ....}C99和C++支持定義變長數(shù)組(見后文),編程時(shí)更自由,但是在程序安全方面有更多的要求。建議初學(xué)者遵循ANSIC標(biāo)準(zhǔn)。9數(shù)組定義可以與其它變量的定義混和寫在一起:intm,n,a2[16],a3[25];doubledb2[20],db3[50],x,y;數(shù)組變量定義可以出現(xiàn)在任何能定義簡單變量的地方,而且在作用域和存在期方面與簡單變量沒有差別。根據(jù)定義位置不同,數(shù)組分為外部數(shù)組和函數(shù)內(nèi)的局部數(shù)組,包括函數(shù)內(nèi)的靜態(tài)局部數(shù)組和普通的自動(dòng)數(shù)組。定義方式(及位置)決定了它們的作用域與存在期。在大型程序中有時(shí)還需要寫出數(shù)組的外部聲明。

此時(shí)不必寫數(shù)組大小,只要在數(shù)組變量名后寫一對方括號:externinta1[];externdoubledb1[];局部變量(自動(dòng)變量):定義在函數(shù)內(nèi)部,前面不加static。由于它們的作用域是限制在所屬的復(fù)合結(jié)構(gòu)內(nèi)部,所以也叫局部變量。因?yàn)樗鼈兊拇鎯臻g的創(chuàng)建和銷毀都是由系統(tǒng)自動(dòng)處理的,所以叫自動(dòng)變量。(自動(dòng)局部變量)外部變量(全局變量):定義在函數(shù)外部的變量。由于作用域是全局性的,所以也叫全局變量。全程存在期,一次初始化。靜態(tài)局部變量:定義在函數(shù)內(nèi)部,前面加static。局部作用域,全程存在期,一次初始化。復(fù)習(xí):116.1.2數(shù)組使用元素順序編號,首元素序號0,其余順序編號。

長度為LEN的數(shù)組的元素編號是0到LEN-1。定義:inta[8];元素編號為0、1、2、…、7。稱為下標(biāo)或指標(biāo)。元素訪問通過[]運(yùn)算符,優(yōu)先級最高,運(yùn)算對象是數(shù)組名和括號里表示下標(biāo)的表達(dá)式。表達(dá)式或語句里的“a[0]”、“a[3]”、“a[6]”這種寫法

稱為下標(biāo)表達(dá)式。例:有上面定義后,可寫:

a[0]=1;a[1]=1; a[2]=a[0]+a[1];12數(shù)組的存儲實(shí)現(xiàn)程序運(yùn)行時(shí),數(shù)組占據(jù)一片連續(xù)存儲區(qū),元素順序排列,0號元素在最前面,各元素占相同空間。例如:

inta[8];則

數(shù)組a的存儲空間恰好能存放8個(gè)整型數(shù)據(jù):a至少相當(dāng)于8個(gè)int變量,a[0]~a[7]可以看作變量名。保證元素排在一起,能以統(tǒng)一方式使用?!璦[0]a[1]a[2]a[3]a[4]a[5]a[6]a[7]數(shù)組a的起始存儲位置

13

a[0]=1;a[1]=1;a[2]=a[0]+a[1];簡單情況可用簡單變量代替數(shù)組,如定義:intb0,b1,b2,b3;可以寫類似語句。這沒有表現(xiàn)出數(shù)組的價(jià)值。數(shù)組意義是能以統(tǒng)一方式描述對一組數(shù)據(jù)的處理。下標(biāo)表達(dá)式可用一般的整型表達(dá)式。如: a[i]=a[i-1]+a[i-2];訪問哪個(gè)元素由i值確定。同一語句可以訪問不同元素,可用在循環(huán)里訪問一批元素。for(i=0;i<100;++i){b[i]+=a1[i]*a2[i];}//假設(shè)已定義數(shù)組b[100]、a1[100]和a2[100]循環(huán)中涉及到300個(gè)基本數(shù)據(jù)對象。14【例6-1】寫程序創(chuàng)建包含前30個(gè)Fibonacci數(shù)的數(shù)組,然后從小到大打印數(shù)組中所有的數(shù)。intmain(){constintNUM=30;intfib[NUM]

;intn;fib[0]=1;fib[1]=1;for(n=2;n<NUM;++n)//計(jì)算

fib[n]=fib[n-1]+fib[n-2];cout<<"Fibonaccisequence:"<<endl;for(n=0;n<=NUM-1;++n)//打印輸出cout<<fib[n]<<(n%5==4?'\n':'\t');return0;}15對數(shù)組的多個(gè)或全部元素操作,常用for語句。令變量遍歷數(shù)組下標(biāo):

for(n=0;n<

數(shù)組長度;++n)...for(n=0;n<=

數(shù)組長度-1;++n)...n取值與數(shù)組下標(biāo)相同。用超范圍的下標(biāo)訪問稱為越界訪問,是數(shù)組使用中最常見的錯(cuò)誤。下標(biāo)值超范圍是運(yùn)行中的問題。問題:fib是NUM個(gè)元素的數(shù)組,假設(shè)程序里寫:

for(n=2;n<=NUM;++n) fib[n]=fib[n-1]+fib[n-2];循環(huán)中試圖訪問fib[NUM],實(shí)際無此元素。16C/C++不檢查數(shù)組元素訪問的合法性,運(yùn)行中出現(xiàn)越界不會報(bào)錯(cuò)。超范圍訪問是嚴(yán)重錯(cuò)誤,后果無法預(yù)料。可能的后果:某些系統(tǒng)(如Windows)中,越界訪問可能導(dǎo)致動(dòng)態(tài)錯(cuò)誤,系統(tǒng)會強(qiáng)行終止出錯(cuò)的程序。某些系統(tǒng)(如DOS)不檢查非法訪問,越界可能破壞本程序的數(shù)據(jù)/程序本身/其他軟件,甚至操作系統(tǒng)。編程者要保證數(shù)組下標(biāo)值的合法性,保證不越界。通俗的比喻:行人應(yīng)該在人行道上行走才能保證自身安全,如果走到機(jī)動(dòng)車道上,有時(shí)會毫發(fā)無損,有時(shí)會遇上車禍。176.1.3數(shù)組初始化定義數(shù)組時(shí)可直接初始化。外部數(shù)組、自動(dòng)數(shù)組和靜態(tài)局部數(shù)組都可在定義時(shí)進(jìn)行初始化。寫法:={初值表達(dá)式,

初值表達(dá)式,...}定義時(shí)初始化的例子:intb[4]={1,1,2,3};doubleax[6]={1.3,2.24,5.11,8.37,6.5};初值表達(dá)式必須是常量表達(dá)式。這種寫法只能用于數(shù)組初始化,不能用在語句里。18初始化語句的特殊用法:1、只為部分元素提供初值,其余元素將自動(dòng)賦初值

0。初始化的元素個(gè)數(shù)不得超過數(shù)組元素個(gè)數(shù)。例:longfib[NUM]={1,1};數(shù)組中其它元素將自動(dòng)賦初值0。常用技巧:僅把首元素賦初值0(其它元素自動(dòng)賦初值0):inta[NUM]={0};2、若給了所有元素的初值,可以不寫數(shù)組大小而只寫方括號,元素個(gè)數(shù)由初值個(gè)數(shù)確定。例: inta[]={1,1,2,3,5,8,13,21,34,55};這種寫法能減少維護(hù)負(fù)擔(dān),有利于程序修改。求數(shù)組長度:sizeof(a)/sizeof(a[0])19【例6-1】寫程序創(chuàng)建包含前30個(gè)Fibonacci數(shù)的數(shù)組,然后從小到大打印數(shù)組中所有的數(shù)。intmain(){constintNUM=30;intfib[NUM]={1,1};intn;fib[0]=1;fib[1]=1;for(n=2;n<NUM;++n)//計(jì)算

fib[n]=fib[n-1]+fib[n-2];cout<<"Fibonaccisequence:"<<endl;for(n=0;n<=NUM-1;++n)//打印輸出cout<<fib[n]<<(n%5==4?'\n':'\t');return0;}20若定義時(shí)未初始化,外部數(shù)組和靜態(tài)局部數(shù)組的元素自動(dòng)初始化為0;自動(dòng)數(shù)組不自動(dòng)初始化。【例6-2】寫一個(gè)程序,里面包含有未初始化的外部數(shù)組和函數(shù)內(nèi)的自動(dòng)數(shù)組,對比它們的初值。#include<iostream>usingnamespacestd;constintNUM=8;//定義全局整型常變量NUMintga[NUM]; //定義外部數(shù)組ga,未初始化intmain(){

intarray[NUM]; //局部數(shù)組array,未初始化

for(inti=0;i<NUM;i++) cout<<ga[i]<<(i==NUM-1?"\n":"\t"); for(inti=0;i<NUM;i++) cout<<array[i]<<(i==NUM-1?"\n":"\t"); return0;}00000000????????????????216.1.4C99和C++中的變長數(shù)組C99和C++中允許定義變長數(shù)組:長度不是在編譯時(shí)確定,而是在運(yùn)行時(shí)確定,在不同運(yùn)行時(shí)的長度可能不同。(1)使用已有合法值的整型變量作為數(shù)組長度intn=10;intarray1[n];cin>>n;intarray2[n];(2)使用參數(shù)值作為數(shù)組長度voidfunc(intm){ intb1[m],b2[m+10]; …}存在安全隱患,需要謹(jǐn)慎處理!建議初學(xué)者不用。(如果要用,就必須學(xué)習(xí)完整用法)22第6章數(shù)組6.1數(shù)組的概念、定義和使用6.2數(shù)組程序?qū)嵗?.2.1計(jì)算日期的天數(shù)序號6.2.2從字符到下標(biāo)(整數(shù))6.2.3篩法求質(zhì)數(shù)6.2.4約瑟夫問題6.2.5多項(xiàng)式求值6.2.6定義數(shù)組的考慮6.3數(shù)組作為函數(shù)參數(shù)6.4兩維和多維數(shù)組6.5字符數(shù)組與字符串6.6編程實(shí)例示例程序表現(xiàn)了數(shù)組編程的一些常用方法和技巧,其中一些方法有廣泛意義。6.2.1計(jì)算日期的天數(shù)序號【例6-3】輸入一個(gè)日期(包含年月日),判斷該年是否為閏年,并計(jì)算該日期為該年的第幾天。如果不用數(shù)組,則需要分別處理各月的天數(shù),程序較為復(fù)雜??梢杂靡粋€(gè)長度為12的整型數(shù)組保存各月的天數(shù)(1~12月的天數(shù)分別保存在下標(biāo)為0~11的數(shù)組元素中),并注意根據(jù)平年和閏年的情況設(shè)置2月份的天數(shù)。在使用數(shù)組時(shí)需要特別注意避免下標(biāo)越界,即需要檢查用戶輸入的月份值是否介于

1~12。除此之外還要檢查用戶輸入的年份的合法性(應(yīng)該大于

0

)和日數(shù)的合法性(應(yīng)該介于

1

至當(dāng)月天數(shù))。intmain(){ //計(jì)算給定的某個(gè)日期是該年的第幾天intyear=2020,month=2,day=28;//定義變量并初始化為示例數(shù)據(jù)cout<<"請輸入表示年月日的三個(gè)整數(shù):";cin>>year>>month>>day;if(year<0||month<1||month>12){//檢查年份和月份的合法性cout<<"錯(cuò)誤:年份或月份不合法!"<<endl;exit(1); //終止程序}intmdays[12]={31,28,31,30,31,30,31,31,30,31,30,31};//各月天數(shù)if((year%100!=0&&year%4==0)||year%400==0)mdays[1]=29; //閏年的二月份有29天if(day>mdays[month-1]){//檢查日數(shù)的合法性cout<<"錯(cuò)誤:日數(shù)不合法!"<<endl;exit(1); //終止程序}//年月日都合法,下面進(jìn)行計(jì)算intdaynum=day; //天數(shù)序號,初始化為當(dāng)前日for(inti=0;i<month-1;++i) //累加前幾個(gè)月的天數(shù)daynum+=mdays[i];cout<<year<<"年"<<month<<"月"<<day<<"日是當(dāng)年的第"<<daynum<<"天。\n";return0;}6.2.2從字符到下標(biāo)(整數(shù))【例6-4】寫程序統(tǒng)計(jì)由標(biāo)準(zhǔn)輸入得到的數(shù)字字符的個(gè)數(shù)。用字符分類函數(shù)isdigit判斷是否數(shù)字字符,然后計(jì)數(shù)。不用數(shù)組:定義10個(gè)計(jì)數(shù)變量,都賦初值0,用if或switch區(qū)分情況,遇數(shù)字字符(isdigit)時(shí)對應(yīng)計(jì)數(shù)器加1。intch,a0=0,a1=0,a2=0,a3=0,a4=0,a5=0,a6=0,a7=0,a8=0,a9=0;while((ch=getchar())!=EOF)if(isdigit(ch)){//是數(shù)字字符 if(ch=='0')a0++; elseif(ch=='1')a1++; elseif(ch=='2')a2++; elseif(ch=='3')a3++; ...... }}27用數(shù)組的辦法:定義數(shù)組cs[10],用于計(jì)數(shù)。intch,cs[10]={0};

//定義數(shù)組,用于計(jì)數(shù)while((ch=getchar())!=EOF){if(isdigit(ch))//是數(shù)字字符if(ch=='0')cs[0]++; elseif(ch=='1')cs[1]++; elseif(ch=='2')cs[2]++; elseif(ch=='3')cs[3]++; elseif(ch=='4')cs[4]++; elseif(ch=='5')cs[5]++; elseif(ch=='6')cs[6]++; elseif(ch=='7')cs[7]++; elseif(ch=='8')cs[8]++; elseif(ch=='9')cs[9]++;}數(shù)字字符順序排列intk=ch-'0';cs[k]++;cs[ch-'0']++;從字符到下標(biāo)28控制符控制符西文字符

ASCII碼(美國信息交換標(biāo)準(zhǔn)代碼)編碼為33–126的字符為可打印的人讀字符29完整程序:intmain(){intch,cs[10]={0};cout<<"inputsomechars(Ctrl+Ztoend):";while((ch=getchar())!=EOF)if(isdigit(ch))cs[ch-'0']++;for(inti=0;i<10;++i)cout<<"Numberof"<<i<<":"<<cs[i]<<endl;return0;}習(xí)題6-2

寫程序統(tǒng)計(jì)由標(biāo)準(zhǔn)輸入得到的一批字符中各個(gè)英文字母(不區(qū)分大小寫)出現(xiàn)的次數(shù)。(使用標(biāo)準(zhǔn)庫中的字符函數(shù)判斷所輸入的字符是否英文字母,并把英文字母統(tǒng)一轉(zhuǎn)換為大寫或小寫,然后參考例6-3

中的技術(shù)進(jìn)行統(tǒng)計(jì)。)intmain(){ intch,i; //用一個(gè)含有26個(gè)元素的數(shù)組分別存儲各個(gè)字符的出現(xiàn)次數(shù) intcs[26]={0};//0號元素初始化為0,其它元素自動(dòng)初始化為0 cout<<"inputsomechars(Ctrl-Ztoend):"; while((ch=cin.get())!=EOF){ //從標(biāo)準(zhǔn)輸入中讀取字符 if(isalpha(ch)) //!!判斷是英文字符

cs[tolower(ch)-'a']++;

//字符轉(zhuǎn)換為小寫,相應(yīng)的計(jì)數(shù)器加1 } for(i=0;i<26;++i) cout<<"Numberof"<<(char)(i+'a')<<":"<<cs[i]<<endl; return0;}習(xí)題6-3

把0到RAMD_MAX分成間隔相同的32個(gè)區(qū)間,然后使用標(biāo)準(zhǔn)庫中的隨機(jī)數(shù)生成函數(shù)生成10萬個(gè)介于[0,RAND_MAX]之間的整數(shù),統(tǒng)計(jì)落在各個(gè)區(qū)間中的數(shù)字的個(gè)數(shù)并打印輸出。

【分析】區(qū)間寬度為(RAND_MAX+1)/32。所產(chǎn)生的隨機(jī)數(shù)對區(qū)間寬度作整除,就得到數(shù)組下標(biāo),相應(yīng)計(jì)數(shù)器增1。intmain(){//10萬個(gè)隨機(jī)數(shù)分區(qū)間統(tǒng)計(jì)constintN=32;inta[N]={0};//第0號元素初始化為0,其它元素自動(dòng)初始化為0intwid=(RAND_MAX+1)/32;//分組的區(qū)間寬度srand(time(0));//cout<<"產(chǎn)生大量隨機(jī)整數(shù)并分為"<<N<<"組統(tǒng)計(jì)個(gè)數(shù):"<<endl;for(inti=0;i<1000000;i++)

a[rand()/wid]++;

//產(chǎn)生隨機(jī)整數(shù),并對區(qū)間寬度整除,得到下標(biāo),使相應(yīng)計(jì)數(shù)器增1//上面語句非常緊湊。也可以定義變量k并拆開寫:

//k=rand();

k=k/wid;a[k]++;for(inti=0;i<N;i++)

cout<<a[i]<<(i%10==9?'\n':'\t');return0;}32

6.2.3篩法求質(zhì)數(shù)【例6-5】篩法是求質(zhì)數(shù)的著名方法。具體算法:取2開始的整數(shù)序列:令n等于2,它是質(zhì)數(shù);劃掉序列中所有n的倍數(shù);令n等于下一未劃元素(是質(zhì)數(shù)),回到步驟2。用數(shù)組表示整數(shù)序列:定義數(shù)組an以元素下標(biāo)表示對應(yīng)整數(shù):an[i]的下標(biāo)i代表相應(yīng)整數(shù)i。用元素的值表示未劃掉(1)或劃掉(0)。

開始時(shí)元素置1,而后不斷將元素置0,直到確定了給定范圍里的所有質(zhì)數(shù)。33假設(shè)NUM是給定范圍://定義數(shù)組an,元素初始化1,//將an[0]和an[1]置0(它們不是質(zhì)數(shù))for(inti=2;i值不大于某個(gè)數(shù);

++i)if(an[i]==1)//i留存,是質(zhì)數(shù)

for(intj=i*2;j<NUM;j+=i)//i的倍數(shù)an[j]=0;//劃掉外層循環(huán)何時(shí)結(jié)束?可用NUM作為界限:i<=NUM仔細(xì)分析不難發(fā)現(xiàn),只要i超過NUM的平方根,就可以劃掉到既定范圍內(nèi)的所有合數(shù):i*i<=NUM34intmain(){//篩法求質(zhì)數(shù)

constintNUM=200;intan[NUM+1];inti,j;//數(shù)組初始化:用1表示未劃掉,用0表示已被劃掉

//an[0]=an[1]=0;//0和1不是質(zhì)數(shù)

for(i=2;i<=NUM;++i)//開始時(shí)數(shù)組元素設(shè)置為1an[i]=1;//篩法

for(i=2;i*i<=NUM;++i) //不用sqrt函數(shù)

if(an[i]==1)for(j=i*2;j<=NUM;j+=i)an[j]=0;//輸出

for(i=2,j=0;i<=NUM;++i)if(an[i]!=0)cout<<i<<((++j)%10!=0?'\t':'\n');cout<<endl;return0;}35小結(jié):由上面兩個(gè)程序可知,在程序中使用數(shù)組時(shí),需要事先規(guī)劃好元素的下標(biāo)和元素的值各代表什么含義。例6-3中,數(shù)組cs[10]各個(gè)元素的下標(biāo)0,1,2,3,4,5,6,7,8,9表示相應(yīng)的數(shù)字字符

0,1,2,3,4,5,6,7,8,9;元素cs[0],cs[1],...cs[9]的值表示數(shù)字字符0,1,2,3,4,5,6,7,8,9的出現(xiàn)次數(shù)。例6-4中,元素的下標(biāo)表示相應(yīng)的數(shù)字;元素的值表示它是否留存(1為留存,0為劃掉)。當(dāng)然,具體含義可以根據(jù)自己的想法來進(jìn)行設(shè)置。36intmain(){//篩法求質(zhì)數(shù)(改為用0表示未劃掉,用1表示已被劃掉)

constintNUM=200;intan[NUM+1]={0};//全部初始化為0inti,j;//數(shù)組已初始化,不需要給元素賦初值//篩法

for(i=2;i*i<=NUM;++i) //不用sqrt函數(shù)

if(an[i]==0)for(j=i*2;j<=NUM;j+=i)an[j]=1;//劃掉//輸出

for(i=2,j=0;i<=NUM;++i)if(an[i]==0)//未劃掉cout<<i<<((++j)%10!=0?'\t':'\n');cout<<endl;return0;}37

6.2.4約瑟夫問題【例6-6】“約瑟夫環(huán)”是一個(gè)數(shù)學(xué)上和計(jì)算機(jī)編程上的經(jīng)典問題:設(shè)有n個(gè)人(以編號1,2,3,...,n分別表示)圍成一個(gè)圓圈,從編號m的人開始由1開始報(bào)數(shù),每個(gè)正好報(bào)到數(shù)k的人退出游戲,后面的一個(gè)人重新由1開始報(bào)數(shù),數(shù)到k的那個(gè)人又出列;依此規(guī)律重復(fù)下去,直到只剩下最后一人。求最后剩下那個(gè)人的編號。首先要考慮數(shù)據(jù)的表示。很顯然需要使用一個(gè)數(shù)組。如何表示人員的編號和人員的去留?——只能使用數(shù)組元素的下標(biāo)和數(shù)組元素的值來分別表示??梢杂卸喾N方法。按照不同的表示方法,可以設(shè)計(jì)出不同的編程算法。38下面選擇用數(shù)組元素下標(biāo)表示所有人員的編號、用元素的值表示人員的去留。題目要求把n個(gè)人編號為1~n來表示。(假如只定義一個(gè)長度為n的數(shù)組,則需要用下標(biāo)0~n-1來表示1~n這些數(shù)字,程序中容易出錯(cuò)。)定義一個(gè)長度為n+1

的數(shù)組,并把下標(biāo)為0的元素閑置不用。使元素下標(biāo)與所表示的值直接對應(yīng)。線性排列可以視為環(huán)形排列:12345678可以用1表示留存、用0表示退出。有必要把所有人的出列順序都記錄下來。因此,決定用0表示留存,用大于0的正數(shù)表示依次退出的序號(程序中需要用一個(gè)變量來記錄)。40循環(huán)過程:需要一個(gè)變量記錄報(bào)數(shù)的數(shù)值。在按照圓圈循環(huán)報(bào)數(shù)時(shí),需要檢查數(shù)組的元素值:值為0則報(bào)數(shù)加1,值大于0則報(bào)數(shù)不變。最終結(jié)果:求“最后剩下那個(gè)人的編號”,可以調(diào)整為求出“最后退出的那個(gè)人”的編號即可。方便觀察:每退出一人就全部輸出數(shù)組所有元素的值。41intmain(){enum{n=8};//總?cè)藬?shù)

inth[n+1]={0};//定義數(shù)組并賦初值

//(以元素下標(biāo)表示人員編號,0號閑置)//初值為0表示留在圓圈內(nèi)

intm=4,k=3;//直接給出m和k的初值(從m開始,輪數(shù)k)intcnt=0;//報(bào)數(shù)時(shí)進(jìn)行計(jì)數(shù)counter

intnum=0;//退出序號

inti;cout<<"Josephusproblemsolution"<<endl;cout<<"n="<<n<<"m="<<m<<"k="<<k<<endl;while(num<n){//所有人依次退出。最末退出為勝利者

cnt=(h[m]==0?1:0);//根據(jù)h[m]的值報(bào)數(shù)1或0while(cnt<k){//進(jìn)行報(bào)數(shù),報(bào)數(shù)到km++;//m往后移

if(m==n+1)m=1;//到數(shù)組末尾時(shí),重新從編號為1的元素開始

if(h[m]==0)cnt++;//此人仍留在圈內(nèi),報(bào)數(shù)增1//如果h[m]!=0,則此人已退出,報(bào)數(shù)不增加。

}42num++;//上面循環(huán)結(jié)束時(shí),已報(bào)數(shù)到k,可退出一人

h[m]=num;//此人標(biāo)記為非0值。寫成退出編號以方便觀察

for(i=1;i<=n;i++)//輸出數(shù)組(不含0號元素),以便觀察

cout<<h[i]<<(i!=n?'\t':'\n');}cout<<"lastone:"<<m<<endl;//最末退出者(第n個(gè))即為勝利者

return0;}43按照題目中給出的n、m和k值(n=8,m=4,k=3),運(yùn)行此程序時(shí),屏幕輸出結(jié)果為:Josephusproblemsolutionn=8m=4k=30000010020000100200301002003010420035104206351042063517428635174lastone:2程序中每退出一人時(shí)就把整個(gè)數(shù)組的值全部輸出一次,

由此可以清晰地看到每個(gè)人的退出順序。44【例6-7】設(shè)數(shù)組p中存放多項(xiàng)式,po[i]存放系數(shù)ai:a0+a1x+a2x2+…+anxn寫程序求po表示的多項(xiàng)式在指定點(diǎn)的值。6.2.5多項(xiàng)式(polynomial)求值方法1:求出各項(xiàng)值累加。假設(shè)指定點(diǎn)值存于x:for(sum=0.0,i=0;i<n;++i){for(t=po[n],j=1;j<=i;++j)t*=x;//計(jì)算po[i]*x^isum+=t;}循環(huán)體內(nèi)可以改寫為(先算x的冪):

for(t=1.0,i=1;j<=i;++j)

t*=x;//只計(jì)算x^isum+=

t*po[i]; //累加時(shí)才乘以乘數(shù)可發(fā)現(xiàn)有大量重復(fù)計(jì)算。有必要改進(jìn)。a0a1a2a3ak45通過保存前次的t值(x的冪次),減少重復(fù)計(jì)算:for(sum=0.0,t=1.0,i=0;i<n;++i){sum+=t*po[i];

t*=x;}方法2:多項(xiàng)式可以變形為Horner范型:按照這個(gè)公式,求值循環(huán)可寫為:for(sum=0.0,i=n-1;i>=0;--i)sum=sum*x+po[i];主函數(shù)采用方法2,采用其它方式的程序請讀者作為練習(xí)自行寫出。intmain(){doublepo[]={2.1,3.,5.6,8.2,6.4};

//數(shù)組儲存系數(shù)并以示例數(shù)據(jù)初始化intn=sizeof(po)/sizeof(po[0]);//數(shù)組長度doublesum,x;inti;cout<<"CalculatePolynomialvalue"<<endl;while(1){//無限循環(huán),內(nèi)部用break退出cout<<"Pleaseenternextvalueforx:";if(!(cin>>x))//用戶輸入x值(輸入非數(shù)值時(shí)為輸入錯(cuò)誤)break;for(sum=0.0,i=n-1;i>=0;--i)sum=sum*x+po[i];//按Horner形式對sum累加cout<<"Polynomialvalue:"<<sum<<endl<<endl;}return0;}47第6章數(shù)組6.1數(shù)組的定義和使用6.2數(shù)組程序?qū)嵗?.3以數(shù)組為參數(shù)的函數(shù)

6.3.1僅調(diào)用數(shù)組元素值的函數(shù)

6.2.2修改實(shí)參數(shù)組的元素6.4二維和多維數(shù)組6.5字符數(shù)組與字符串6.6編程實(shí)例486.3以數(shù)組為參數(shù)的函數(shù)各種數(shù)據(jù)對象,都需要考慮與函數(shù)的關(guān)系。用函數(shù)處理數(shù)組,有兩種已知的方法:①元素是基本類型時(shí),將數(shù)組元素作為函數(shù)實(shí)參,與將基本類型的變量作為實(shí)參一樣。局限性:只能處理個(gè)別元素,不能批量修改數(shù)組元素的值。②函數(shù)可直接訪問外部數(shù)組。局限性:只能處理確定的外部數(shù)組,而且無法讓同一函數(shù)在不同時(shí)刻處理不同的數(shù)組。例例49#include<iostream>usingnamespacestd;voidprtout(intk){ k++; cout<<k<<endl;}intmain(){ inti=0,n[5]={0,2,4,6,8}; for(i=0;i<5;++i)cout<<n[i]<<endl;//事先打印一次

for(inti=0;i<5;++i)

prtout(n[i]);//以形參方式訪問局部數(shù)組的元素

for(i=0;i<5;++i)cout<<n[i]<<endl;//事后打印一次

return0;}方法①:將數(shù)組元素作為函數(shù)實(shí)參。局限性:只能處理個(gè)別元素;不能批量修改多個(gè)數(shù)組元素值。50#include<iostream>usingnamespacestd;intgn[5]={0,2,4,6,8}; //外部數(shù)組voidprtout2(){ for(inti=0;i<5;++i) cout<<++gn[i];}intmain(){ inti=0; for(i=0;i<5;++i)cout<<gn[i]<<endl;//事先打印一次

prtout2();//調(diào)用prtout2函數(shù)。注意需要寫括號。

for(i=0;i<5;++i)cout<<gn[i]<<endl;//事后打印一次

return0;}方法②:函數(shù)直接訪問外部數(shù)組局限性:只能處理特定的外部數(shù)組。51假設(shè)有多個(gè)數(shù)組都需要求平均值。上面方法都不合適。需要定義以數(shù)組為參數(shù)的函數(shù)。以數(shù)組為參數(shù),處理整個(gè)數(shù)組不再是問題。不同調(diào)用可以完成對不同數(shù)組的計(jì)算。定義以double數(shù)組為參數(shù),求元素平均值的函數(shù)就可解決所有double數(shù)組的平均值問題526.3.1僅調(diào)用數(shù)組元素值的函數(shù)【例6-8】編寫一個(gè)求元素平均值的函數(shù),該函數(shù)需要從參數(shù)中獲得數(shù)組名稱和數(shù)組長度。doubleavrg(int

len,

double

a[]){doublesum=0.0;for(inti=0;i<len;++i)sum+=a[i];returnsum/len;}C和C++允許函數(shù)有數(shù)組形參,描述方式是在參數(shù)名后面寫一對方括號,其中不必寫數(shù)組的大小。實(shí)際編寫函數(shù)時(shí),還需要把數(shù)組的大小也傳遞給函數(shù)。通常是用另一個(gè)參數(shù)傳遞數(shù)組的大小。53調(diào)用上述函數(shù):intmain(){doubleb1[3]={1.2,2.43,1.074};

//定義數(shù)組并以示例數(shù)據(jù)初始化

doubleb2[5]={6.54,9.23,8.463,4.25,0.386};cout<<"averages:"<<avrg(3,b1)<<"\t"<<avrg(5,b2)<<endl;return0;}使用時(shí)必須關(guān)注越界問題。

例:avrg(5,b1)引起數(shù)組越界(b1只有3個(gè)元素)。長度實(shí)參可小于數(shù)組大小,avrg(3,b2)求b2前3個(gè)元素的平均值。可將數(shù)組前段當(dāng)作數(shù)組使用。問:上面說要在函數(shù)的參數(shù)表中用一個(gè)參數(shù)傳遞數(shù)組參數(shù)的大小,能否不用這樣的參數(shù),而是在函數(shù)中用“sizeof(a)/sizeof(a[0])”的方法求出數(shù)組大???例如,上面例題的函數(shù)改為:doubleavrg(int

len,

double

a[]){...}

intlen=sizeof(a)/sizeof(a[0]);doublesum=0.0;for(inti=0;i<len;++i)sum+=a[i];returnsum/len;}答:不能用“sizeof(a)/sizeof(a[0])”的方法求出數(shù)組大小!因?yàn)閿?shù)組參數(shù)實(shí)際上并不是傳遞整個(gè)數(shù)組,而僅是傳遞一個(gè)指針(見下一章)。所以用sizeof(a)求出的不是整個(gè)數(shù)組的大小,而只是一個(gè)指針的大小。556.3.2修改實(shí)參數(shù)組的元素復(fù)習(xí):C/C++中基本的參數(shù)機(jī)制是值參數(shù),形參作為函數(shù)體中的局部變量使用。調(diào)用時(shí),實(shí)參的值單向復(fù)制給形參。以數(shù)組為參數(shù)的函數(shù)不是普通的值參數(shù)機(jī)制。以數(shù)組為參數(shù)的函數(shù)在執(zhí)行時(shí),對形參數(shù)組元素的操作,就是直接對函數(shù)調(diào)用時(shí)的實(shí)參數(shù)組元素的操作。這樣定義函數(shù),就可以改變實(shí)參數(shù)組元素的值。這是數(shù)組參數(shù)的特殊情況,詳情在第7章解釋。56【例6-9】定義函數(shù),翻轉(zhuǎn)參數(shù)數(shù)組里元素的位置:voidreverse(intn,inta[]){intt,i,j;for(i=0,j=n-1;i<j;++i,--j){t=a[i];a[i]=a[j];a[j]=t;}}寫程序檢查reverse的效果?!璱ntmain(){ inti,b[]={1,2,3,4,5,6,7}; intn=sizeof(b)/sizeof(b[0]); for(i=0;i<n;i++)cout<<b[i]<<(i==n-1?"\n":"\t");

reverse(n,b);//!!! cout<<endl<<"Afterreverseersion:"<<endl; for(i=0;i<n;i++)cout<<b[i]<<(i==n-1?"\n":"\t"); return0;}ij57【例6-10】數(shù)組元素排序(修改實(shí)參數(shù)組的元素)。對一組數(shù)據(jù)經(jīng)常要做的一個(gè)操作是把它們按照某種標(biāo)準(zhǔn)重新排列,這種操作被稱為排序(sorting)。假定有n個(gè)數(shù)值存放在數(shù)組a中,寫一個(gè)函數(shù),把它們從小到大重新排列。排序的方法很多,這里介紹直接插入排序。假設(shè)左邊那部分?jǐn)?shù)據(jù)已經(jīng)排好序(最開始時(shí),第一個(gè)元素已排好序),右邊是尚未排序的元素。i下標(biāo)0到i-1的部分已排序。反復(fù)把i處的數(shù)據(jù)插入已排序部分。隨著i增大右段越來越短,最終所有數(shù)據(jù)都排好。58?>t?jit考慮元素a[i]如何插入到a[i-1]到a[0]之間:先把a(bǔ)[i]存入臨時(shí)變量t里,于是a[i]閑置。用t逐個(gè)與a[i-1]到a[0]比較:變量j從i-1遞減到0。如果元素a[j]比t要大,就后移一位(于是a[j]閑置)。當(dāng)a[j]不大于t時(shí),正好把t放入空位,a里的前i個(gè)值就排好序了。59voidinsertsort(intn,inta[]){//整型數(shù)組按照遞增序直接插入排序

inti,j;intt;for(i=1;i<n;++i){for(t=a[i],j=i-1;j>=0&&t<a[j];--j)a[j+1]=a[j];//大元素依次后移

if(j!=i-1)a[j+1]=t;}}開始令左段只有一個(gè)元素(已排序),排序過程可如下描述:for(i=1;i<n;++i){

把a(bǔ)[i]的值插入a[0]到a[i-1]一段里的 正確位置,保持其他元素順序不變}60用于測試此排序函數(shù)的輔助打印函數(shù)和主函數(shù)如下:voidprintall(intn,inta[]){for(inti=0;i<n;++i)cout<<a[i]<<'\t';cout<<endl;}intmain(){intarr[]={3,2,5,1,7,8,10,6,5};//定義數(shù)組并初始化

intn=sizeof(arr)/sizeof(arr[0]);cout<<"beforesorting:"<<endl;printall(n,arr);

insertsort(n,arr);//!!!cout<<"aftersorting:"<<endl;printall(n,arr);return0;}教學(xué)說明可以在IDE中對此程序進(jìn)行調(diào)試,在調(diào)試過程中觀察變量的值,以便深刻地理解直接插入排序算法。本頁隱藏,不播放6162第6章數(shù)組6.1數(shù)組的概念、定義和使用6.2數(shù)組程序?qū)嵗?.3數(shù)組作為函數(shù)參數(shù)6.4兩維和多維數(shù)組

6.4.1多維數(shù)組的初始化

6.4.2多維數(shù)組的使用

6.4.3多維數(shù)組作為函數(shù)的參數(shù)6.4字符數(shù)組與字符串6.5編程實(shí)例636.4兩維和多維數(shù)組一維數(shù)組有一個(gè)下標(biāo),元素線性排列。需要處理更復(fù)雜的結(jié)構(gòu),如線性代數(shù)中的二維矩陣??梢远x兩維/多維數(shù)組:

inta[3][2]; //3×2的int數(shù)組

doubleb[4][4];//4×4的double數(shù)組

inta1[3][2][4];//三維數(shù)組兩維數(shù)組看作一維數(shù)組的數(shù)組,元素的成員類型和成員個(gè)數(shù)都相同。例如a是長度為3、成員為長度為2的一維數(shù)組。646.4.1多維數(shù)組的初始化定義時(shí)直接初始化:

inta[3][2]={{1,2},{3,4},{5,6}};

內(nèi)嵌括號初始化成員數(shù)組。不足時(shí)自動(dòng)置0。也可不寫內(nèi)嵌括號:

inta[3][2]={1,2,3,4,5,6};

初始值按順序賦給基本成分,不夠時(shí)置0。若初始化給出了全部元素值,第一下標(biāo)的元素個(gè)數(shù)可以不寫(可根據(jù)初始化表示算出)。

inta[][2]={{1,2},{3,4},{5,6}}; intb[][2]={1,2,3,4,5,6};656.4.2多維數(shù)組的表示和使用設(shè)有數(shù)組定義:inta[3][2];doubleb[4][4]; a表示整個(gè)數(shù)組,a[0]、a[1]和a[2]表示成員數(shù)組。a[0][1]表示a的0成員數(shù)組中下標(biāo)1的元素。例:a[2][1]=a[0][1]+a[1][1];for(i=0;i<4;++i)for(j=0;j<4;++j)b[i][j]=i+j;66aa[0]a[1]a[2]a[0][0]a[0][1]a[1][0]a[1][1]a[2][0]a[2][1](語言細(xì)節(jié))數(shù)組元素連續(xù)存儲,多維數(shù)組一樣,依次存儲成員數(shù)組,成員數(shù)組按同樣方式表示。二維數(shù)組a[3][2]

的內(nèi)部表示:注意:a的開始位置也是其首成員a[0]的開始位置,也是a[0]首成員a[0][0]的位置。C/C++的數(shù)組存放方式,一行(成員數(shù)組)元素連續(xù)存儲,這種形式又稱按行方式或行優(yōu)先方式。67【例6-11】寫程序段求出由兩維數(shù)組A、B表示的4×4矩陣的乘積,存入兩維數(shù)組C(設(shè)A,B已經(jīng)有值)并輸出。for(i=0;i<N;++i)for(j=0;j<N;++j)for(C[i][j]=0.0,k=0;k<N;++k)C[i][j]+=A[i][k]*B[k][j];for(i=0;i<N;++i)for(j=0;j<N;++j)cout<<C[i][j]<<(j==N-1?'\n':'\t');686.4.3多維數(shù)組作為函數(shù)參數(shù)多維數(shù)組作為函數(shù)參數(shù)時(shí)不必給出最左一維長度,但要求給出除最左一維外其他各維的長度?!纠?-12】求出n×5數(shù)組中數(shù)據(jù)均值(n是參數(shù)):doubleaaverage(intn,doublea[][5]){inti,j;doublesum=0.0;for(i=0;i<n;++i)for(j=0;j<5;++j)sum+=a[i][j];returnsum/(5*n);}可用于任何n×5的數(shù)組,但不能用于例如4×7的數(shù)組下章將介紹一種定義通用函數(shù)的方法(利用指針)。69第6章數(shù)組6.1數(shù)組的概念、定義和使用6.2數(shù)組程序?qū)嵗?.3數(shù)組作為函數(shù)參數(shù)6.4兩維和多維數(shù)組6.5字符數(shù)組與字符串

6.5.1字符數(shù)組

6.5.2字符串

6.5.3程序?qū)嵗?/p>

6.5.4標(biāo)準(zhǔn)庫字符串處理函數(shù)

6.5.5輸出文本里的最長行6.6編程實(shí)例706.5字符數(shù)組與字符串6.5.1字符數(shù)組C和C++常用于寫文字處理程序,文字信息以字符形式存在字符數(shù)組里。對字符數(shù)組有一些特殊機(jī)制。字符數(shù)組定義方式(與其他數(shù)組一樣):

charline[1000];字符數(shù)組可在定義時(shí)初始化:

charcity[15]={'B','e','i','j','i','n','g'};未指定初值的元素自動(dòng)設(shè)為編碼為0的字符。

0字符/空字符,用

'\0'表示,有特殊用途。716.5.2字符串字符串寫法:

"字符串文字量"。字符串不能跨行。如果多個(gè)字符串之間僅由空白分隔,系統(tǒng)會將它們連成一個(gè)長字符串。不能直接寫出的字符采用換意序列:\n\t\"字符串是由系統(tǒng)自動(dòng)地以字符數(shù)組形式保存,存儲形式是在所有字符后存放'\0'作為串結(jié)束標(biāo)志。例:cout<<"Beijing";Beijing\0'\0'不是串內(nèi)容,卻是字符串表示不可缺的部分。標(biāo)準(zhǔn)庫的字符串處理函數(shù)都按這種表示設(shè)計(jì),寫字符串處理程序時(shí)也應(yīng)該遵守這一規(guī)則。72問:能在定義的字符數(shù)組變量里存放字符串嗎?字符數(shù)組里至少存放一個(gè)空字符,就符合字符串形式,可當(dāng)作字符串使用。

數(shù)組里存放著字符串。有多個(gè)空字符時(shí),以從左向右第一個(gè)認(rèn)為是字符串結(jié)束符。chara[5]={'i','s','n','o','t'},//不是字符串

b[5]={'g','o','o','d','\0'},//是字符串

c[5]={'f','i','n','e'}, //是字符串

d[5]={'o','k','\0'}, //是字符串

e[5]={'o','k','\0','x'}; //是可用字符串指定字符數(shù)組的初值(是簡寫):

chara1[20]="PekingUniversity";未標(biāo)元素個(gè)數(shù)時(shí),數(shù)組大小確定為串長加1。

chara3[]="PekingUniversity";//18個(gè)字符元素736.5.3字符串的輸出與輸入字符串(以雙引號括起來的字符串常量,或者存放了字符串的字符數(shù)組)的輸出可用兩種方法:逐字符輸出:cout<<,putchar,cout.put整個(gè)字符串一次性輸出:cout<<,puts【例6-13】測試用多種方法輸出字符數(shù)組或字符串。每次輸出之后故意添加輸出字符'#',以便觀察各種輸出方法的差異。intmain(){constintLEN=20;charstr[LEN]="Hello,world!";//定義字符數(shù)組str并初始化。

//注意,這樣初始化的字符數(shù)組在字符后面部分自動(dòng)填充為多個(gè)空字符

for(inti=0;i<LEN;i++)//輸出方法1:逐字符輸出

putchar(str[i]);//或cout.put(str[i]);或cout<<str[i];cout<<'#'<<endl;Hello,world!#74

cout<<str<<'#'<<endl;//輸出方法2:字符串整體輸出

str[4]='\0';//把第5個(gè)字符'o'改為空字符

for(inti=0;i<LEN;i++)//輸出方法1:逐字符輸出

putchar(str[i]);//或cout.put(str[i]);或cout<<str[i];cout<<'#'<<endl;

cout<<str<<'#'<<endl;//輸出方法2:字符串整體輸出(cout<<)

puts(str);//輸出方法2:字符串整體輸出(puts)并換行

cout<<'#'<<endl;

return0;}Hell,world!#Hell#Hello,world!#小結(jié):逐字符輸出時(shí),空字符被輸出為空格(或怪字符)。整體輸出時(shí),遇到第一個(gè)空字符就結(jié)束輸出。Hell#75輸入字符串時(shí),也有多種方法可以逐字符輸入或整體輸入。但是需要注意的是,有些方法不能接收空格,有些方法則可以接收空格。如果在程序中所需要輸入的字符串中含有空格(例如英文姓名全稱或者英文書名),那就必須選用可以接收空格的輸入方法。逐字符輸入時(shí),可以用三種方法:(1)getchar()函數(shù);(2)cin.get()函數(shù);(3)cin>>流式輸入(不能接收空格)。最容易想到的逐字符輸入一個(gè)字符串的方法:

for(inti=0;i<LEN-1;i++)//i最大值為LEN-2str[i]=getchar();//str[i]=cin.get();//cin>>str[i];str[i]='\0';//添加空字符作為字符串結(jié)束符缺點(diǎn)是必須輸入LEN-1

個(gè)字符。76改進(jìn),讀取字符同時(shí)判斷是否為指定結(jié)束字符:

inti;for(i=0;i<LEN-1&&(str[i]=getchar())!='\n';i++) //cin.get()亦可

;//空循環(huán)體

str[i]='\0';//添加空字符作為字符串結(jié)束符這個(gè)循環(huán)將一行字符讀入到數(shù)組str,以接受到回車鍵作為輸入結(jié)束(用戶可以改為EOF甚至其它字符)。注意,用條件i<LEN-1保證對數(shù)組str的訪問不越界。讀入完畢后,i記錄著讀入字符的個(gè)數(shù),而且我們需要在字符串末尾添加空字符作為字符串結(jié)束符。77對字符串整體輸入時(shí),簡單的方法是這樣:

cin>>str;缺點(diǎn):不能接收空格,遇到空格就會認(rèn)為是字符串結(jié)束。要想讓字符串整體輸入時(shí)接受空格字符,就需要使用C++提供的cin流中的

getline()函數(shù):cin.getline(字符數(shù)組名str,字符個(gè)數(shù)n,結(jié)束符'\n')功能:一次連續(xù)讀入多個(gè)字符(包括空格)直到讀滿

n-1

個(gè)或遇到指定的結(jié)束符(默認(rèn)為回車符)為止。讀入的字符串存放于字符數(shù)組str中,但不存儲結(jié)束符。自動(dòng)在字符串末尾添加空字符。例:cin.getline(str,LEN);字符串整體輸入時(shí)還可以用

gets

函數(shù),但是它不能控制所輸入字符的個(gè)數(shù),存在安全隱患。因此不推薦初學(xué)者使用,本書不作介紹。78還需要注意:由于系統(tǒng)是緩沖式輸入,因此上一次輸入時(shí)最末鍵入的多余字符或回車符可能被意外地被下一次輸入讀到。因此在連續(xù)多次輸入時(shí),需要注意把上一次輸入的多余字符清除掉。需要用到cin.clear()和cin.sync()這兩個(gè)函數(shù),清除輸入緩沖區(qū)中殘留的輸入數(shù)據(jù)。當(dāng)然,也可以使用字符串類或文件作為輸入源(參見“4.3.4字符串流與文件流輸入輸出”),這時(shí)可以類似地使用相應(yīng)的get()函數(shù)和getline()函數(shù)。79【例6-14】分別用getchar()和cin.getline()方法輸入字符串,并注意在前后兩次輸入時(shí)清除輸入緩沖區(qū)。intmain(){constintLEN=20;charstr[LEN];cout<<"Inputstringwithgetchar:";inti;for(i=0;

i<LEN-1&&(str[i]=getchar())!='\n';i++);//空循環(huán)體

str[i]='\0';cout<<"str:"<<str<<endl<<endl;

cin.clear();//清除狀態(tài)標(biāo)記

cin.sync();//清空緩沖區(qū)

cout<<"Inputstringwithcin.getline:";

cin.getline(str,LEN);//輸入時(shí)默認(rèn)以回車符為結(jié)束符

cout<<"str:"<<str<<endl;return0;}當(dāng)?shù)谝淮屋斎氲淖址麛?shù)超過字符數(shù)組str的長度LEN時(shí),多余的字符可能會自動(dòng)地成為第二次的輸入。只有使用這兩個(gè)函數(shù),第二次輸入才不會受到前一次輸入的影響。806.5.4字符串處理程序?qū)嵗纠?-15】編寫函數(shù)將一個(gè)字符串復(fù)制到一個(gè)字符數(shù)組。假定數(shù)組足以存放被復(fù)制串及空字符。定義:voidstringcopy(chars[],constchart[]){//string,templateinti=0;while(t[i]!='\0'){s[i]=t[i];++i;}s[i]='\0';}循環(huán)結(jié)束時(shí)t[i]的空字符正好賦給s[i]。賦值有值:voidstringcopy(chars[],constchart[]){inti=0;while((s[i]=t[i])!='\0')++i;}LOVE\0iLOVE\0i81進(jìn)一步簡化:voidstringcopy(chars[],constchart[]){inti=0;while(s[i]=t[i])++i; //最后一個(gè)值就是\0}

教師演示編寫用于調(diào)用的主程序,并作調(diào)試字符串處理函數(shù)的典型循環(huán):for(i=0;s[i]!='\0';++i){……}for(i=0;s[i];++i){……}用是否空字符確定對字符串的處理是否已完成。LOVE\0i82【例6-16】(二進(jìn)制轉(zhuǎn)換)寫函數(shù),給它一個(gè)表示二進(jìn)制數(shù)的0/1字符串,它算出這個(gè)串表示的整數(shù)值。二進(jìn)制數(shù)bnbn-1...b2b1b0的值可以用下面公式計(jì)算:(((...((bn×2)+bn-1)×2+...)×2+b2)×2+b1)×2+b0據(jù)此可寫出循環(huán),循環(huán)條件判斷二進(jìn)制數(shù)是否結(jié)束。二進(jìn)制數(shù)位只能是0/1,只需要在遇到1時(shí)加一。83intbin2int(constchars[]){inti=0,n=0;for(i=0;s[i]!='\0'&&(s[i]=='0'||s[i]=='1');++i){n=n*2;

if(s[i]=='1')++n;

}returnn;}由于數(shù)字字符的編碼連續(xù)排列,人們常用:intbin2int(constchars[]){inti,n=0;for(i=0;s[i]!='\0'&&(s[i]=='0'||s[i]=='1')++i)n=n*2+(s[i]-'0');

returnn;}//這種寫法可以推廣到十進(jìn)制和其他進(jìn)制84【例6-17】考慮一個(gè)在保存字符串的數(shù)組里操作的例子。假定需要一個(gè)函數(shù),它處理保存著字符串的數(shù)組,它刪除字符串的前n個(gè)字符,留下刪除后的字符串。先找到要保留的第一個(gè)字符位置,然后把從那里開始的有效字

溫馨提示

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

評論

0/150

提交評論