




版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領
文檔簡介
第六章數組6.1數組的概念6.2一維數組6.3二維數組6.4字符數組與字符串6.5程序設計舉例習題6.1數組的概念
例6.1
輸入5個學生某門課的成績,要求按與輸入次序相反的順序輸出。
#include<stdio.h>
voidmain()
{
floats1,s2,s3,s4,s5;
printf("Enterfivescores:");
scanf("%f,%f,%f,%f,%f",&s1,&s2,&s3,&s4,&s5);
printf("\nThescoreinreverseorderare:");
printf("%f\n",s5);
printf("%f\n",s4);
printf("%f\n",s3);
printf("%f\n",s2);
printf("%f\n",s1);
}從上例不難看出,程序比較繁瑣。若輸入的不是5個學生的成績,而是20個,甚至3000個學生的成績,這樣來編寫程序就顯得太笨了。本章我們將介紹一種新的數據類型——數組,它在處理大量的、同類型的數據時,非常方便。數組是由相同類型的數據組成的有序集合,集合中的每一個數據稱為數組的元素,每個數組元素用數組名和下標唯一標識訪問,在程序中可方便地按下標組織循環(huán)來訪問數組元素。下面用數組來改寫例6.1,請讀者體會數組的作用。#include<stdio.h> voidmain() { floats[5];
inti;
printf("Enterfivescores:");
for(i=1;i<=5;i++) scanf("%f",&s[i]);
printf("\nThescoreinreverseorderare:");
for(i=5;i>=1;i--) printf("%f",s[i]);
}6.2一維數組6.2.1一維數組的定義和引用一維數組的定義方式為:
類型標識符數組名[常量表達式];其中,類型標識符表明數組中的每個數據(稱為數組元素)所具有的共同的數據類型;數組名起名的規(guī)則和變量名相同,遵循標識符定名規(guī)則;常量表達式的值是數組的額定長度,即數組中所包含的元素個數。例如,例6.1中的學生成績可存放于如下的一維數組中:
floatscore[5];其中,score是數組名,常量5表明這個數組有5個元素,每個元素都是float型。在定義數組時,需要注意的是:
(1)表示數組長度的常量表達式,必須是正的整型常量表達式。
(2)相同類型的數組、變量可以在一個類型說明符下一起說明,互相之間用逗號隔開。例如,“inta[5],b[10],i;”。
(3)C語言不允許定義動態(tài)數組,即數組的長度不能依賴于程序運行過程中變化著的量,下面這種數組定義方式是不允許的。
inti;
scanf("%d",&i);
inta[i];因為C語言是在編譯階段為數組開辟單元的,而運行時才能得到的變量值遠晚于編譯階段,是無法實現的。數組必須先定義,后使用。C語言規(guī)定只能逐個引用數組元素,而不能一次引用整個數組。數組元素的引用方式如下:數組名[下標表達式]其中,下標表達式可以是整型常量或整型表達式。當數組的長度為n時,下標表達式的取值范圍為0,1,…,n-1,即C語言中的各數組元素總是從0開始編號的。如inta[5]之后,數組a共有5個元素,分別用a[0],a[1],a[2],a[3],a[4]來表示。需要強調指出的是,在程序設計中,C語言的編譯系統(tǒng)對數組下標越界(即引用a[5],a[6],…),并不給出錯誤提示,因此用戶在編程時應格外注意,以免影響系統(tǒng)的正常運行。例6.2用數組來處理Fibonacci數列問題。分析:求Fibonacci數列的問題已在第五章中接觸過,現在用數組來處理。我們可用數組中的20個數來代表數列中的20個數,從第3個數開始,可用表達式f[i]=f[i-2]+f[i-1]求出各數。請讀者比較用數組和不用數組時的兩個程序。程序如下:#include<stdio.h>voidmain(){inti,n;/*n用來統(tǒng)計輸出元素的個數*/longinta[20];a[0]=1;a[1]=1;printf("%12ld%12ld",a[0],a[1]);n=2;for(i=2;i<20;i++){a[i]=a[i-1]+a[i-2];printf("%12ld",a[i]);n++;if(n%4==0)/*每行輸出4個元素*/printf("\n");}}運行結果:11235813213455891442333776109871597258441816765
顯然,使用數組后,再配合循環(huán)語句,給處理大量數據的程序設計帶來了極大的方便。6.2.2一維數組的初始化可以在程序運行后用賦值語句或輸入語句使數組中的元素得到值,也可以使數組在程序運行之前(即編譯階段)就得到初值,后者稱為數組的初始化。對數組元素的初始化可以用以下方法實現。在定義數組時對數組元素賦以初值,如:
ints[5]={78,87,77,91,60};也可以只給一部分元素賦值。例如:
ints[5]={78,87,77};其結果是:s[0]=78,s[1]=87,s[2]=77,s[3]=0,s[4]=0,即花括號內的值只賦給了數組的前幾個元素,后幾個元素的值為0。若對全部數組元素賦初值時,可以不指定數組長度。例如:
ints[5]={1,2,3,4,5};可以寫成:
ints[]={1,2,3,4,5};一維數組元素是按下標遞增的順序連續(xù)存放的,即數組占有連續(xù)的存儲空間。如s數組在內存中的存儲示意如圖6.1所示。圖6.1s數組存儲示意圖
例6.3用冒泡排序法對給定的15個整數按遞增的順序排序。分析:冒泡排序也稱起泡排序,其基本思路是將待排序的相鄰數據元素兩兩比較,若逆序(與最終排序要求次序相反)則交換。當從前向后依此掃描比較之后,最大的數會被放在最后一個位置,這個過程稱為一趟排序。第二趟掃描只需從第二個數據元素開始,到倒數第二個數結束。掃描結束時,次大數被放在倒數第二個位置。這個過程重復進行,直到所有待排數據按大小次序排列。由于在排序過程中,小的數像氣泡一樣逐趟“上浮”,而大的數則逐趟“下沉”,所以形象地將這種排序稱為冒泡排序。
排序過程可以從前向后掃描,也可以從后向前掃描。若從前向后掃描,則每趟排序將大數后移,而從后向前掃描,則每趟排序將小數前移,但最終排序結果都是一樣的。若待排序的數據元素為n個,則整個排序最多需n-1趟。若從前向后掃描,則排序過程如圖6.2所示。圖6.2冒泡法排序過程具體程序如下:
#defineN15
#include<stdio.h>
voidmain()
{
inti,j,t;
inta[N]={10,1,23,-5,0,78,11,104,65,-1,12,23,36,3,53};
printf("待排數據:");
for(i=0;i<N;i++)
printf("%d",a[i]);
for(j=1;j<=N-1;j++)/*外循環(huán)控制排序趟數*/
for(i=0;i<=N-j;i++)/*每趟排序時對相鄰的兩個數進行比較*/
if(a[i]>a[i+1]) /*逆序就交換*/
{
t=a[i];
a[i]=a[i+1];
a[i+1]=t;
}
printf("\n排序后:");
for(i=0;i<N;i++)printf("%d",a[i]);}運行結果:待排數據:10123-50781110465-1122336353排序后:-5-1013101112232336536578104
說明:若待排元素為n個,則冒泡排序至多需進行n-1趟排序。但上面的程序還可改進,若在某趟排序過程中沒有元素交換,則說明待排的數據已經達到有序狀態(tài),則后面的若干趟排序可不必進行。請讀者思考,如何修改完善以上程序?6.3二維數組6.3.1二維數組的定義和引用二維數組的定義形式為:
類型標識符數組名[常量表達式][常量表達式];例如,“inta[3][2];”表示數組a是一個3×2(3行2列)的數組,共有6個元素,每個元素都是int型。二維數組的應用之一是矩陣和行列式。其中,左起第一個下標表示行數,第二個下標表示列數。我們也可以把二維數組看成是一種特殊的一維數組:它的元素又是一個一維數組。例如,可將以上的a數組看成是一個一維數組,它有3個元素,分別是a[0],a[1],a[2],每個元素又是一個包含2個元素的一維數組,如圖6.2所示,因此可以把a[0],a[1],a[2]看做是三個一維數組的名字。上面定義的二維數組就可理解為定義了三個一維數組,即相當于
inta[0][2],a[1][2],a[2][2];圖6.3二維數組a[3][2]a[0]——a[0][0]a[0][1]aa[1]——a[1][0]a[1][1]
a[2]——a[2][0]a[2][1]
C語言的這種處理方法在數組初始化和用指針表示時顯得很方便,這一點我們在以后的學習過程中可進一步體會。二維數組的引用與一維數組類似,其表現形式為:
數組名[下標表達式][下標表達式]其中,下標表達式可以是整型常量或整型表達式。如:
inta[3][2];它共有6個元素,分別用a[0][0],a[0][1],a[1][0],a[1][1],a[2][0],a[2][1]來表示(注意a[3][0],a[0][2],a[3][2]等均越界,不能引用)。數組中的每個元素都具有相同的數據類型,且占有連續(xù)的存儲空間。一維數組的元素是按下標遞增的順序連續(xù)存放的,二維數組元素的排列順序是按行存放的,即在內存中,先順序存放第一行元素,再存放第二行元素。如此類推,我們不難掌握多維數組的定義及存放順序。簡單地講,多維數組存放時,各元素仍然是連續(xù)存放,且其最右邊的下標變化最快。圖6.3給出了一維數組及二維數組的排列方式。圖6.34數組元素的排列方式
6.3.2二維數組的初始化對二維數組元素賦初值,可以用分行賦值的方法,例如:
inta[3][2]={{1,2},{3,4},{5,6}};其中內{}代表一行元素的初值。經過如此的初始化后,每個數組元素分別被賦以如下各值:
a[0][0]=1,a[0][1]=2,a[1][0]=3,
a[1][1]=4,a[2][0]=5,a[2][1]=6寫成行列式形如:
這種初始化的方式也可以只為數組的部分元素賦值,例如:
inta[3][2]={{1},{2,3},{4}};這樣,數組的前幾個元素的值為:
a[0][0]=1,a[1][0]=2,a[1][1]=3,
a[2][0]=4而其余元素的初值將自動設為0。在初始化時,也可將所有數據寫在一個花括號內,按數組的排列順序對各元素賦初值。如:
inta[3][2]={1,2,3,4};其結果是:a[0][0]=1,a[0][1]=2,a[1][0]=3,a[1][1]=4,其余元素的值自動設為0。若對全部元素都賦初值,則定義數組時對第一維的長度可以不指定,但對第二維的長度不能省。如:
inta[][2]={1,2,3,4,5,6};系統(tǒng)會根據數據總個數分配存儲空間,一共6個元素,每行2列,當然可確定為3行。需要強調的是,如果沒有進行初始化,則在定義二維數組時,所有維的長度都必須給出。例6.4從鍵盤為一個N×N的整型數組輸入數據,并將每一行的最小值顯示出來。
#defineN6
#include<stdio.h>
voidmain()
{
inta[N][N],m[N],i,j;
printf("Inputnumbers:\n");
for(i=0;i<N;i++)
for(j=0;j<N;j++)
scanf("%d",&a[i][j]);
for(i=0;i<N;i++)
{
m[i]=a[i][0];
for(j=1;j<N;j++)
if(m[i]>a[i][j])m[i]=a[i][j];/*找出每行的最小值*/
}
printf("Minis:");
for(i=0;i<N;i++)
printf("%d",m[i]);
}運行結果:
Inputnumbers:
12
3
4
67
22
9↙
8
23
61
19
20
8↙
3
78
5
7
12
15↙
19
89
1
6
8
2↙
11
22
81
36
2
4↙
53
32
17
19
11
5↙
Minis:3
8
3
1
2
56.4字符數組與字符串6.4.1字符數組的定義和初始化字符數組的定義方式與前面介紹的類似,形式如下:
char數組名[常量表達式];如:“charc[6];”,則定義c為字符數組,包含6個元素。賦值方法與一般的一維數組是一樣的,例如:
c[0]=′s′;c[1]=′t′;c[2]=′r′;c[3]=′i′;c[4]=′n′;c[5]=′g′;需要說明的是,由于字符型與整型是互相通用的,故字符數組的處理基本上與整型數組相同,只不過每個元素的值都是小于255的整數而已。字符數組的初始化即是在定義時將字符逐個賦給數組中各元素。例如:
charc[6]={′s′,′t′,′r′,′i′,′n′,′g′};其存儲情況如圖6.5所示。但應注意的是,初值個數應小于等于數組長度,否則作語法錯誤處理。圖6.5字符數組的初始化如果提供的初值個數與預定的數組長度相同,在定義時可省略數組長度,系統(tǒng)就會自動根據初值個數確定數組長度。如:
charc[]={′s′,′t′,′r′,′i′,′n′,′g′};對于二維字符數組的定義與初始化,我們不難以此為基礎類推。例如:
charch[3][2]={{′1′,′2′},{′2′,′2′},{′3′,′2′}};內存中如圖6.6所示。
圖6.6二維字符數組的內存存儲6.4.2字符串字符串常量是用雙引號括起來的字符序列。一個字符串在數組中是按串中字符的排列順序依次存放的,每個字符占一個字節(jié),但須在末尾存放一個字符′\0′(其ASCII碼值為0),以它作為字符串結束的標記。例如字符串“string”共有6個字符,但在內存中占7個字節(jié),最后一個字節(jié)存放′\0′。 一個字符數組中存儲的串的長度是指從第一個字符元素到串結束標記′\0′之間的字符個數,注意′\0′不算在內。在程序設計中通常通過檢測′\0′來判定字符串是否結束,而不是根據字符數組長度。在定義字符數組存放字符串時,應保證字符數組的長度大于將存放的字符串的長度。為了方便處理字符數組,C語言還允許用一個簡單的字符串常量來初始化一個字符數組,而不必使用一串單個字符。如:
charc[]={"string"};或charc[]="string";經過上述初始化后,c數組中每個元素的初值如下:
c[0]=′s′,c[1]=′t′,c[2]=′r′,c[3]=′i′,c[4]=′n′,c[5]=′g′,c[6]=′\0′應注意的是,字符串常量的最后由系統(tǒng)自動在末尾加上結束字符′\0′,所以c數組有7個元素。但若如上節(jié)逐個元素初始化,則要顯式加′\0′,即charc[]={′s′,′t′,′r′,′i′,′n′,′g′,′\0′}。需要說明的是,C語言并不要求所有的字符數組的最后一個字符一定是′\0′,但為了處理上的方便,往往需要以′\0′作為字符串的結尾(這也是字符數組編程上不同于其它類型數組之處)。同時,C語言庫函數中有關字符處理的函數,一般都要求所處理的字符串必須以′\0′結尾,否則將會出現錯誤。
例6.5統(tǒng)計某一給定字符串中的字符數,不包括結束符′\0′。
#include<stdio.h>
voidmain()
{
charstr[]={"string"};
inti=0;
while(str[i]!=′\0′)i++;
printf("Thelengthofstringis:%d\n",i);
}運行結果:
Thelengthofstringis:66.4.3字符數組的輸入和輸出字符數組的輸入和輸出有兩種形式:
(1)采用“%c”格式符,逐個輸入、輸出。例6.6中的str[]數組,若執(zhí)行
printf(“%c”,str[5]);則輸出結果為g。
(2)采用“%s”格式符,整個字符串一次輸入、輸出。例6.6中的str[]數組,若執(zhí)行
printf("%s",str);則輸出結果為string。使用"%s"格式來輸入、輸出字符串時,應注意以下幾個問題:①用格式符"%s"輸出字符串時,printf函數中的輸出項是字符串常量或字符數組名,且字符數組中存放的必須是字符串,即必須包含串結束標志′\0′。這是因為格式符"%s"對字符串的輸出過程是:從字符串的內存起始地址(數組名即代表字符串的內存起始地址)開始逐個字符進行輸出,直到遇到′\0′結束,但輸出字符不包括結束符′\0′。②使用scanf()函數來輸入字符串時,應直接寫字符數組的名字,而不應寫取地址運算符,如scanf("%s",str),而不是scanf("%s",&str),因為數組名就代表數組的首地址。③輸入字符串時,串長度應小于已定義的字符數組長度,因為系統(tǒng)在有效字符后會自動添加字符串結束標志′\0′。④字符串的輸入是以“空格”、“Tab”或“回車”來結束輸入的。通常,在利用一個scanf()函數來同時輸入多個字符串時,字符串之間以“空格”為間隔,最后按“回車”結束輸入。如執(zhí)行scanf("%s%s%s",c1,c2,c3)時,鍵入:cisfun↙,其結果如圖6.7所示。按%s格式輸出字符串時,printf()函數中的輸出項也要求是字符數組名,而不是數組元素名。圖6.4字符串存儲示例6.4.4常用字符串處理函數
1.gets字符串輸入函數調用形式:gets(字符數組)功能:從標準輸入文件(詳見第10章)中讀取一個字符串到字符數組中。它讀取字符直到遇到換行符′\n′,并將換行符轉換為字符結束標志符′\0′存放到字符數組中。函數調用成功則返回字符數組的起始地址,否則返回空地址NULL(NULL在頭文件stdio.h中已被定義為0)。
2.puts字符串輸出函數調用形式:puts(字符串常量或字符數組名)功能:將字符串(以′\0′為字符串結束標志)輸出到標準輸出設備。在輸出時將字符串結束標志′\0′轉換成換行符′\n′,即輸出字符串后換行。
3.strcmp字符串比較函數調用形式:strcmp(字符串常量或字符數組1,字符串常量或字符數組2)功能:將兩個字符串從左至右逐個進行比較(按ASCII碼值大小比較),直到出現不同的字符或遇到′\0′為止。比較的結果由函數值帶回。函數值=0——字符串1=字符串2函數值>0——字符串1>字符串2函數值<0——字符串1<字符串2
4.strcpy字符串拷貝函數調用形式:
strcpy(字符數組1,字符串常量或字符數組2)或
strcpy(字符數組1,字符串常量或字符數組2,n)功能:將字符串2拷貝到字符數組1中去。第二種形式是將字符串常量或字符數組2的前n個字符拷貝到字符數組1中。如果函數調用成功,則函數返回字符數組1的起始地址。說明:字符數組1必須定義得足夠大,以便容納被拷貝的字符串。
5.strcat字符串連接函數調用形式:strcat(字符數組1,字符串常量或字符數組2)功能:將字符串常量或字符數組2接到字符數組1中字符串的后面,結果放在字符數組1中。如果函數調用成功,函數返回字符數組1的起始地址。說明:字符數組1必須足夠大,以便容納連接后的新字符串。
6.strlen字符串長度測試函數調用形式:strlen(字符串常量或字符數組)功能:測試字符串常量或字符數組的長度,函數的返回值為字符串常量或字符數組的實際長度(不包括′\0′)。
7.strlwr字符串轉換函數調用形式:strlwr(字符串常量或字符數組)功能:將字符串常量或字符數組中大寫字母轉換成小寫字母。
8)strupr字符串轉換函數調用形式:strupr(字符串常量或字符數組)功能:將字符串常量或字符數組中的小寫字母轉換成大寫字母。需要說明的是,庫函數并非C語言本身的組成部分,而是人們?yōu)槭褂梅奖憔帉懙墓埠瘮担總€系統(tǒng)提供的函數數量、函數功能都不盡相同,使用時要小心,必要時查一下庫函數手冊。當然,有一些基本的函數(包括函數名和函數功能),不同的系統(tǒng)所提供的是相同的,這就為程序的通用性提供了基礎。ANSIC標準要求在使用字符串函數時要包含頭文件<string.h>。
例6.6有三個字符串,要求找出其中最大者。
分析:設一個二維的字符數組str(3×20),每一行可容納20個字符,可以把它們如同一維數組那樣處理。我們用gets函數分別讀入三個字符串,經過二次比較,就可得到最大值,把它放在一維字符數組string中。具體程序如下:
#include<stdio.h>
#include<string.h>
voidmain()
{
charstring[20];
charstr[3][20];
inti;
for(i=0;i<3;i++)
gets(str[i]);
if(strcmp(str[0],str[1])>0)strcpy(string,str[0]);
elsestrcpy(string,str[1]);
if(strcmp(str[2],string)>0)strcpy(string,str[2]);
printf("\nthelargeststringis:%s\n",string);
}運行結果:
CHINA↙
HOME↙
ACHINESE↙
thelargeststringis:HOME注意:用gets讀入字符串與用scanf("%s",str)是不同的,它以回車作為字符串的結束符,一行中的空格也作為字符串的一個元素讀入。6.5程序設計舉例
例6.7
用選擇排序法對數組中的N個整數排序,按由小到大順序輸出。
分析:選擇排序法的思路是:先在a[0]~a[N-1]中選出最小的數,將它與數組中的第一個元素對換;然后拋開a[0],再將a[1]~a[N-1]中的最小的數與a[1]對換;……每比較一輪,找出一個未經排序的數中最小的一個,逐步縮小排序范圍直至完成排序。若數組中的元素個數為N,則共需進行N-1輪比較。具體程序如下:
#defineN10
#include<stdio.h>
voidmain()
{
intarray[N],i,j,k,t;
printf("Input%dnumber:\n",N);
for(i=0;i<N;i++)
scanf("%d",&array[i]);
printf("\n");
for(i=0;i<N-1;i++)
/*外循環(huán),控制N-1輪比較,即找N-1遍*/
{
k=i;
for(j=i+1;j<N;j++)
/*內循環(huán),用k記住所找數中最小數的下標*/
if(array[j]<array[k])k=j;
if(i!=k)/*將最小數換至最前面*/
{
t=array[k];
array[k]=array[i];
array[i]=t;
}
}
printf("Thesortednumbers:\n");
for(i=0;i<N;i++)
printf("%d",array[i]);
}運行結果:
Input10numbers:
4671013219203↙
Thesortednumbers:
1234679101320例6.8將數組a的內容逆置重放。要求不得另外開辟數組,只能借助于一個臨時存儲單元。
分析:假定a數組有8個元素,它們原始存放的內容如下:現要求改變成如下的存放形式:完成以上操作,只需按以下箭頭所指的形式,將兩個元素中的內容對調就行了。若用i,j分別代表進行對調的兩個元素的下標,則首先需要確定i和j的關系,其次需要確定i變化的范圍。假定有n個元素,當i=0時,j應該指向第n-1個元素;當i=1時,j應指向第n-2個元素;所以i和j的關系為j=n-i-1。
i移動的起始位置為0,終止位置為p,p=n/2-1。若n是偶數,假定為8,則p等于3,如上例所示,最后使a[3]和a[4]對調。如果n是奇數,假定為9,則p等于3,最后使a[3]和a[5]對調,即a[4]在中間沒有移動。根據以上分析,具體程序如下:
#defineN8
#include<stdio.h>
voidmain()
{
inta[N],i,j,p,t;
printf("Input%dnumbertothearray:",N);
for(i=0;i<N;i++)
scanf("%d",&a[i]);
p=N/2-1;
for(i=0;i<=p;i++)
{
j=N-i-1;
t=a[i];a[i]=a[j];a[j]=t;
}
printf("\nThearrayhasbeeninverted:");
for(i=0;i<N;i++)
printf("%d",a[i]);
}運行結果:
Input8numbertothearray:4728125103↙
Thearrayhasbeeninverted:3105128274
例6.9
將字符串s轉換成相應的雙精度浮點數。分析:這種轉換在詞法分析程序及其它場合經常是有用的。其實,系統(tǒng)的庫函數中已提供了這種功能的函數?,F在我們自己來設計程序完成這一功能。首先應對字符串中出現的′+′和′-′進行處理,其次處理′.′前的部分,即將每一個數字字符轉換成相應的數值,并加權累加成相應的整數部分。最后處理′.′后的部分(如果有的話),結果存放在變量number中。程序如下:
#include<stdio.h>
voidmain()
{
chars[8];
doubleval,power,number;
inti,sign;
printf("Inputstringofanumber:");
gets(s);
i=0;
sign=1;
if(s[i]==′+′||s[i]==′-′)
/*sign處理符號*/
sign=(s[i++]==′+′)?1:-1;
for(val=0;s[i]>=′0′&&s[i]<=′9′;i++)
/*處理整數數字部分*/
val=10*val+s[i]-′0′;
if(s[i]==′.′)
i++;
for(power=1;s[i]>=′0′&&s[i]<=′9′;i++)
/*處理小數數字部分*/{
val=10*val+s[i]-′0′;
power*=10;
}number=sign*val/power;
printf("\nnumber=%f\n",number);
}運行結果:
Inputstringofanumber:-234.55↙
number=-234.550000
例6.10輸入一個由若干單詞組成的文本行(最多80個字符),每個單詞之間用若干個空格隔開,統(tǒng)計此文本行中單詞的個數。
分析:要統(tǒng)計單詞的個數首先要解決如何去判斷一個單詞。假定把一個文本行放在str數組中,那么這一辨別工作即從str[0]開始去逐個檢查數組元素,跳過所有的空格后,找到的第一個字母就是一個單詞的開頭,這時計數器就可加1,在此之后如果連續(xù)讀到的是非空格字符,則這些字符是屬于剛統(tǒng)計過的那個單詞,因此不應計數。下一次計數應在讀到一個或幾個空格后再遇到非空格字符時進行。根據以上的分析,對單詞個數加1必須同時滿足兩個條件:第一,當前所檢查的這個字符是非空格;第二,所檢查字符的前一個字符是空格。假設num用來統(tǒng)計單詞的個數,prec存放所檢查的前一個字符,nowc存放當前所檢查的字符。程序如下:
#include<stdio.h>
voidmain()
{
charstr[80],prec,nowc;
inti,num;
printf("Inputatextline:");
gets(str);
prec=′′;num=0;i=0;
while(str[i]!=′\0′)
{
nowc=str[i];
if(nowc!=′′&&prec==′′)num++;
/*是新單詞,個數加1*/
prec=nowc;/*將已檢查的字符保存至prec,繼續(xù)查*/
i++;
}
printf("\nThenumberofwordsis:%d",num);
}運行結果:
Inputatextline:thebigcar↙
Thenumberofwordsis:3
例6.11
輸入3行4列的矩陣,找出在行上最大,在列上最小的那個元素。如果沒有這樣的元素,則打印出相應的信息。
分析:在一個矩陣中符合上述條件的元素稱為鞍點。為簡單起見,假定每行和每列中的元素值各不相同。算法可描述如下:
(1)找出第i行上最大的元素。記下所在的列號c,最大元素的值rmax。
(2)在第c列上,把rmax和該列上的其它元素比較,判斷在該列上rmax是否是最小的元素。只要發(fā)現有一個元素小于或等于它,則說明rmax在該列上不是最小的元素。
(3)若rmax是第c列上的最小元素,則找到鞍點,打印此鞍點的值。
(4)重復以上步驟,使i從第1行到第3行重復以上步驟,并且一旦找到一個鞍點就退出循環(huán)。程序如下:
#include<stdio.h>
voidmain()
{
inta[3][4],i,j,r,c,k,rmax,find;
printf("Thematrixis:\n");
for(i=0;i<3;i++)
for(j=0;j<4;j++)
scanf("%d",&a[i][j]);
find=0;i=0;/*find為0,標志還未打回鞍點*/
while(i<3&&(find==0))/*若未找到鞍點,則重復查找矩陣每一行*/
{
rmax=a[i][0];c=0;
for(j=1;j<4;j++)
if(rmax<a[i][j])
{rmax=a[i][j];c=j;}
/*某行最大值→ramx,所在列號→c*/
find=1;k=0;
/*先假設行上的最大值即為列上的最小值*/
while(k<3&&find==1)
/*內循環(huán)查rmax是否為c列上的最小數*/
{
if(k!=i)
if(a[k][c]<=rmax)find=0;/*若列上有一數小于rmax,則置find=0,結束循環(huán)*/
k++;
}
if(find==1)
printf("Thesaddlepointeris:a[%d][%d]
=%d\n",i,c,a[i][c]);
i++;
}
if(find==0)printf("notbeenfound");
}運行結果:
Thematrixis:
18121913
79655238
63887149
Thesaddlepointeris:a[0][2]=19例6.12用計算機洗撲克牌。
分析:將54張撲克牌統(tǒng)一編號為0,1,2,…,52,53,然后隨機地從中一一抽取一張牌,并依此放起,形成新的序列。具體要解決兩個問題:
(1)如何存儲54張撲克牌。我們可用數組pk來存儲54張撲克牌。每個數組元素是一位3位整數,表示每張撲克牌,其中第一位表示牌種類,后兩位表示牌號,例如:
101,113:分別表示紅桃A,紅桃K;
201,213:分別表示方塊A,方塊K;
301,313:分別表示梅花A,梅花K;
401,413:分別表示黑桃A,黑桃K;
501,502:分別表示大、小王。
(2)在此基礎上如何一一抽取。我們先介紹將用到的庫函數,rand()用于產生隨機數,srand函數是隨機數發(fā)生器的初始化函數,它需要提供一個種子,如srand(1),不過通常使用系統(tǒng)時間來初始化
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
- 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
- 6. 下載文件中如有侵權或不適當內容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 北京市2025年度預售商品房備案手續(xù)合同范本
- 2025年度智能穿戴設備設計團隊雇傭合同
- 二零二五年度商鋪分租租賃合同租賃物損壞賠償協(xié)議
- 2025年度電子商務平臺銷售人員勞動合同實施細則
- 2025年度非全日制勞動合同標準范本
- 家電代理居間合同解除
- 個人供應合同范例
- 公司車輛租借合同范例
- 倉庫搬運合同范例
- 公里樁合同范例
- 食品倉儲的庫房的安全巡檢考核試卷
- 人教版六年級數學下冊《全冊完整》教案
- 《《中央企業(yè)合規(guī)管理辦法》解讀》課件
- 橋式起重機作業(yè)安全培訓
- 2021醫(yī)師定期考核題庫(人文2000題)
- 2025年中考語文專題復習:寫作技巧 課件
- (2024)云南省公務員考試《行測》真題及答案解析
- 60歲以上務工免責協(xié)議書
- 靶向治療患者的護理常規(guī)
- 二年級心理健康教育課:你的感受我知道
- 2024年社區(qū)工作者考試必考1000題【歷年真題】
評論
0/150
提交評論