![程序設(shè)計(jì)基礎(chǔ)(C語(yǔ)言)章-課件7_第1頁(yè)](http://file4.renrendoc.com/view/ebca527d0a4c9bda44f5263d25f7f721/ebca527d0a4c9bda44f5263d25f7f7211.gif)
![程序設(shè)計(jì)基礎(chǔ)(C語(yǔ)言)章-課件7_第2頁(yè)](http://file4.renrendoc.com/view/ebca527d0a4c9bda44f5263d25f7f721/ebca527d0a4c9bda44f5263d25f7f7212.gif)
![程序設(shè)計(jì)基礎(chǔ)(C語(yǔ)言)章-課件7_第3頁(yè)](http://file4.renrendoc.com/view/ebca527d0a4c9bda44f5263d25f7f721/ebca527d0a4c9bda44f5263d25f7f7213.gif)
![程序設(shè)計(jì)基礎(chǔ)(C語(yǔ)言)章-課件7_第4頁(yè)](http://file4.renrendoc.com/view/ebca527d0a4c9bda44f5263d25f7f721/ebca527d0a4c9bda44f5263d25f7f7214.gif)
![程序設(shè)計(jì)基礎(chǔ)(C語(yǔ)言)章-課件7_第5頁(yè)](http://file4.renrendoc.com/view/ebca527d0a4c9bda44f5263d25f7f721/ebca527d0a4c9bda44f5263d25f7f7215.gif)
版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
第7章數(shù)組7.1一維數(shù)組
7.2函數(shù)間一維數(shù)組的傳遞
7.3二維數(shù)組
7.4函數(shù)間二維數(shù)組的傳遞
習(xí)題
第7章數(shù)組7.1一維數(shù)組
7.1一維數(shù)組
7.1.1數(shù)組概述
通過(guò)前面的學(xué)習(xí),我們知道,如果在程序中需要暫時(shí)存放幾個(gè)數(shù)據(jù),就需要定義幾個(gè)變量。但是,這種方法在處理大批量的同類型的數(shù)據(jù)的時(shí)候,就顯得不是很方便了。例如,某個(gè)班級(jí)有45名同學(xué),在“程序設(shè)計(jì)基礎(chǔ)”這門課程考試結(jié)束后,要編寫一個(gè)程序,統(tǒng)計(jì)一下成績(jī)高于平均分的人數(shù)。針對(duì)這個(gè)問(wèn)題,可以設(shè)計(jì)出如下算法:
①依次接受并暫存45個(gè)成績(jī);
②計(jì)算總分和平均分; 7.1一維數(shù)組
7.1.1數(shù)組概述
③置計(jì)數(shù)器為0;
④對(duì)每一個(gè)成績(jī),若它大于平均分,則計(jì)數(shù)器累加1;
⑤輸出計(jì)數(shù)器的值。
按照以上算法的要求,如果在程序中定義45個(gè)變量去暫存這45個(gè)成績(jī),顯然是一種比較笨拙的辦法。
那么,有沒(méi)有更好的辦法呢?其實(shí),針對(duì)這種大批量數(shù)據(jù)的存儲(chǔ)問(wèn)題,C語(yǔ)言中提供了數(shù)組這種數(shù)據(jù)類型來(lái)解決。③置計(jì)數(shù)器為0;
④對(duì)每一個(gè)成績(jī),若它大于平均分?jǐn)?shù)組的實(shí)質(zhì)是內(nèi)存中一段連續(xù)的存儲(chǔ)空間,例如內(nèi)存中連續(xù)的20個(gè)字節(jié)的存儲(chǔ)空間就可以稱為一個(gè)數(shù)組。這個(gè)數(shù)組如果用來(lái)存放int型的數(shù)據(jù),則可以存放10個(gè)(若每個(gè)int型的數(shù)據(jù)需要兩個(gè)字節(jié)的存儲(chǔ)空間)。此時(shí)每?jī)蓚€(gè)字節(jié)構(gòu)成數(shù)組中一個(gè)存儲(chǔ)單元,稱為數(shù)組元素或數(shù)組分量;當(dāng)然,這個(gè)數(shù)組也可以用于存放5個(gè)float型的數(shù)據(jù)(若每個(gè)float型的數(shù)據(jù)需要4個(gè)字節(jié)的存儲(chǔ)空間),此時(shí),每4個(gè)字節(jié)構(gòu)成一個(gè)數(shù)組分量。在程序中,數(shù)組用一個(gè)名字來(lái)表示,數(shù)組中分量用編號(hào)來(lái)區(qū)分。采用這種方式,不但解決了大批量同類型數(shù)據(jù)的存儲(chǔ)問(wèn)題,而且方便用循環(huán)的方式來(lái)對(duì)這些數(shù)據(jù)進(jìn)行運(yùn)算和處理。數(shù)組的實(shí)質(zhì)是內(nèi)存中一段連續(xù)的存儲(chǔ)空間,例如內(nèi)存中連續(xù)的2存放在數(shù)組中的多個(gè)數(shù)據(jù),從邏輯上可以看做是按一個(gè)方向排列的,也可以看做是按兩個(gè)方向排列的。例如20個(gè)整數(shù)可以看做是按一個(gè)方向排列的,在C語(yǔ)言中稱為一維數(shù)組;這20個(gè)整數(shù)也可以分為4組,每組5個(gè),在C語(yǔ)言中就稱為二維數(shù)組。這種情況下,通常仿照數(shù)學(xué)中行列式的形式,稱這20個(gè)數(shù)構(gòu)成4行5列的二維數(shù)組。當(dāng)然,一組數(shù)也可以看做是按多個(gè)方向排列的,這在C語(yǔ)言中就稱為多維數(shù)組了。存放在數(shù)組中的多個(gè)數(shù)據(jù),從邏輯上可以看做是按一個(gè)方向排列7.1.2一維數(shù)組的定義和初始化
一維數(shù)組的定義形式如下:
數(shù)據(jù)類型數(shù)組名[分量個(gè)數(shù)];
數(shù)組名和變量名一樣,是C語(yǔ)言中的標(biāo)識(shí)符,必須符合標(biāo)示符的命名規(guī)則。分量個(gè)數(shù)必須是一個(gè)整型數(shù),通常是常量或常量表達(dá)式。分量個(gè)數(shù)表示的數(shù)組中存儲(chǔ)單元的個(gè)數(shù),也就是這個(gè)數(shù)組中可以最多存放的數(shù)據(jù)的個(gè)數(shù)。數(shù)據(jù)類型用來(lái)指定數(shù)組中可以存放的數(shù)據(jù)的類型。例如:
intarray[10];7.1.2一維數(shù)組的定義和初始化
一維數(shù)組的定義形式以上語(yǔ)句,定義array是一個(gè)數(shù)組,這個(gè)數(shù)組是用來(lái)存放int型數(shù)據(jù)的,最多可以存放10個(gè)int型的數(shù)據(jù)。
定義了數(shù)組之后,如果這個(gè)數(shù)組是外部數(shù)組,則數(shù)組中每個(gè)分量中存放的都是0,也就是說(shuō),每個(gè)數(shù)組元素的值都是0;如果這個(gè)數(shù)組是內(nèi)部數(shù)組,則數(shù)組中元素的值是隨機(jī)值。定義數(shù)組時(shí),可以把特定的值存放在數(shù)組中,這種情況稱為數(shù)組的初始化,例如:
intarray[10]={1,2,3,4,5,6,7,8,9,10};以上語(yǔ)句,定義array是一個(gè)數(shù)組,這個(gè)數(shù)組是用來(lái)存放i以上語(yǔ)句,定義array是一個(gè)有10個(gè)元素的int型數(shù)組,同時(shí)把1,2,3,…,10這10個(gè)數(shù)依次存放在數(shù)組的10個(gè)元素中。當(dāng)然,也可以對(duì)數(shù)組進(jìn)行部分初始化,例如:
intarray[10]={1,2,3};
以上語(yǔ)句,在定義數(shù)組的同時(shí),把1、2、3依次存放在數(shù)組的第1、第2和第3個(gè)元素中,此時(shí),數(shù)組中其余元素自動(dòng)被初始化為0。以上語(yǔ)句,定義array是一個(gè)有10個(gè)元素的int型數(shù)組7.1.3一維數(shù)組元素的引用
數(shù)組在使用中,通常不會(huì)做整體的引用,更多的是引用數(shù)組中某一個(gè)分量中存放的數(shù)據(jù)。一維數(shù)組中的每一個(gè)分量都對(duì)應(yīng)一個(gè)編號(hào)。需要特別注意的是分量的編號(hào)是從0開(kāi)始的,即數(shù)組中第一個(gè)分量的編號(hào)為0,第二個(gè)分量的編號(hào)為1,依此類推。在程序中,引用數(shù)組分量的形式為“數(shù)組名[編號(hào)]”,這里的編號(hào)為一個(gè)取值為int型的表達(dá)式。例如,對(duì)如下定義的數(shù)組:
intarray[10];7.1.3一維數(shù)組元素的引用
數(shù)組在使用中,通常不會(huì)如果要將其中的第1個(gè)分量賦值為5,則表達(dá)為如下語(yǔ)句:
array[0]=5;
再例如要將數(shù)組array中第3個(gè)分量和第4個(gè)分量中存放的值求和后,存放在數(shù)組的第5個(gè)分量中,可使用如下語(yǔ)句:
array[4]=array[2]+array[3];
在對(duì)數(shù)組中存放的數(shù)據(jù)進(jìn)行運(yùn)算和處理時(shí),通常采用循環(huán)的方式,例如對(duì)于前面提到的成績(jī)統(tǒng)計(jì)的問(wèn)題,可以編寫出如下的源程序:如果要將其中的第1個(gè)分量賦值為5,則表達(dá)為如下語(yǔ)句:
/*源程序7-1*/
#include"stdio.h"
main()
{
floatscore[45],sum,avg;
inti,counter;
for(i=0;i<45;i++){
printf("Paleaseinputscore[%d]:",i);
scanf("%d",&score[i]);/*源程序7-1*/
#include"stdio.h"
m
}
sum=0;
for(i=0;i<45;i++)
sum+=score[i];
avg=sum/45;
counter=0;
for(i=0;i<45;i++)
if(score[i]>avg)
counter++;
printf("counter=%d\n",counter);
}}
sum=0;
for(i=0;i<7.1.4簡(jiǎn)單排序算法
排序問(wèn)題是計(jì)算機(jī)編程中的一個(gè)常見(jiàn)問(wèn)題。在日常的數(shù)據(jù)處理中,面對(duì)大量的數(shù)據(jù),也許有成百上千種的處理要求,而這些處理往往是以排序作為前提的。例如查找,在有序的數(shù)據(jù)中進(jìn)行查找,當(dāng)然比在無(wú)序的數(shù)據(jù)中進(jìn)行查找要容易得多。在計(jì)算機(jī)發(fā)展的歷史中,前人為我們留下了很多經(jīng)典的排序算法,它們都是智慧的結(jié)晶。下面就討論其中比較簡(jiǎn)單的兩種排序算法。首先把排序的問(wèn)題具體化:假如有10個(gè)整數(shù),按照任意次序存放在計(jì)算機(jī)的一段連續(xù)內(nèi)存(為了描述方便,把這一段連續(xù)內(nèi)存看做是有10個(gè)分量的一維數(shù)組array)中,我們要做的就是將array數(shù)組中的這10個(gè)數(shù)的存放位置調(diào)整為由大到小。7.1.4簡(jiǎn)單排序算法
排序問(wèn)題是計(jì)算機(jī)編程中的一個(gè)下面先看第一種簡(jiǎn)單排序方法,選擇排序法。
針對(duì)前面所描述的問(wèn)題,可以采用如下算法來(lái)解決:
(1)從array[0]至array[9]中找出一個(gè)最大的數(shù),假如這個(gè)數(shù)在array[max_index]中,把它交換到數(shù)組的第一個(gè)位置,即array[max_index]與array[0]交換;
(2)從array[1]至array[9]中找出一個(gè)最大的數(shù),假如這個(gè)數(shù)在array[max_index]中,把它交換到數(shù)組的第一個(gè)位置,即array[max_index]與array[1]交換;
(3)從array[2]至array[9]中找出一個(gè)最大的數(shù),假如這個(gè)數(shù)在array[max_index]中,把它交換到數(shù)組的第一個(gè)位置,即array[max_index]與array[2]交換;
……下面先看第一種簡(jiǎn)單排序方法,選擇排序法。
針對(duì)前面所
(9)從array[8]至array[9]中找出一個(gè)最大的數(shù),假如這個(gè)數(shù)在array[max_index]中,把它交換到數(shù)組的第一個(gè)位置,即array[max_index]與array[8]交換。
以上的算法,用偽代碼的形式描述如下:
for(i=0;i<=9;i++){
從array[i]至array[9]中找出一個(gè)最大的數(shù),假如這個(gè)數(shù)在array[max_index]中,
把它交換到數(shù)組的第一個(gè)位置,即array[max_index]與array[i]交換;
}
我們?cè)侔褟腶rray[i]至array[9]中找最大數(shù)的算法和交換的算法細(xì)化,得到如下算法描述:(9)從array[8]至array[9]中找出一個(gè)最for(i=0;i<=8;i++){
max_index=i;
for(j=max_index+1;j<=9;j++)
if(array[j]>array[max_index])
max_index=j;
if(max_index!=i){
t=array[i];
array[i]=array[max_index];
array[max_index]=t;
}for(i=0;i<=8;i++){
max_i下面給出一個(gè)完整的源程序,程序中的10個(gè)數(shù)是調(diào)用隨機(jī)函數(shù)生成的100以內(nèi)的數(shù)。
/*源程序7-2*/
#include"stdio.h"
#include"stdlib.h"
main()
{
intarray[10],i,j,t,max_index;
for(i=0;i<=9;i++)
array[i]=rand()%100;下面給出一個(gè)完整的源程序,程序中的10個(gè)數(shù)是調(diào)用隨機(jī)函數(shù)
printf("Beforesorting:\n");
for(i=0;i<=9;i++)
printf("%d\t",array[i]);
for(i=0;i<=8;i++){
max_index=i;
for(j=max_index+1;j<=9;j++)
if(array[j]>array[max_index])
max_index=j;
if(max_index!=i){printf("Beforesorting:\n");
t=array[i];
array[i]=array[max_index];
array[max_index]=t;
}
}
printf("\nAftersorting:\n");
for(i=0;i<=9;i++)
printf("%d\t",array[i]);
} t=array[i];
array[i]=a程序運(yùn)行結(jié)果如下:
上面的程序中,每一次都是通過(guò)比較先找到最大數(shù)所在位置的編號(hào)max_index,然后再進(jìn)行交換。還可以把比較的過(guò)程和最后的交換結(jié)合起來(lái),也就是在比較的過(guò)程中完成交換,這樣,源程序可以修改成如下形式:程序運(yùn)行結(jié)果如下:
上面的程序中,每一次都是通/*源程序7-3*/
#include"stdio.h"
#include"stdlib.h"
main()
{
intarray[10],i,j,t;
for(i=0;i<=9;i++)
array[i]=rand()%100;
printf("Beforesorting:\n");
for(i=0;i<=9;i++)
printf("%d\t",array[i]);/*源程序7-3*/
#include"stdio.h"
#
for(i=0;i<=8;i++){
for(j=i+1;j<=9;j++)
if(array[j]>array[i]){
t=array[i];
array[i]=array[j];
array[j]=t;
}
}
printf("\nAftersorting:\n");
for(i=0;i<=9;i++)
printf("%d\t",array[i]);
}for(i=0;i<=8;i++){
for選擇排序法之所以叫做選擇排序法,就是因?yàn)檫@種方法每次選出一個(gè)合適的數(shù),放到合適的位置上。很容易就可以推知,對(duì)n個(gè)數(shù)進(jìn)行排序,共需要n-1次這樣的選擇。
下面再來(lái)看另一種簡(jiǎn)單排序算法,這種排序算法有一個(gè)非常有趣的名字,叫做冒泡排序。為什么叫做冒泡排序呢?還是以前面給出的問(wèn)題為例來(lái)說(shuō)明。
要對(duì)數(shù)組array中存放的10個(gè)整數(shù)排序,首先對(duì)array數(shù)組做一遍這樣的處理:
從array[0]至array[9],相鄰的兩個(gè)數(shù)依次比較,即array[0]與array[1]比較,array[1]與array[2]比較,…,array[8]與array[9]比較,在比較的過(guò)程中,如果前面的數(shù)小于后面的數(shù),則交換兩個(gè)數(shù)的位置。選擇排序法之所以叫做選擇排序法,就是因?yàn)檫@種方法每次選出通過(guò)這樣一遍處理,雖然整個(gè)數(shù)組還是沒(méi)有順序的,但是最小的一個(gè)數(shù)在比較的過(guò)程中被逐漸的后移,最終被交換到最后一個(gè)位置了。這個(gè)過(guò)程有點(diǎn)像水里的氣泡從水底逐漸地浮到水面的過(guò)程,所以這種排序算法叫做冒泡排序法。然后,使用同樣的方法,依次對(duì)array[0]至array[8]、array[0]至array[7]、…、array[0]至array[1]做同樣的處理。前后共做9次這樣的處理,就可以得到由大到小的次序。這個(gè)過(guò)程用偽代碼描述為:
for(i=9;i>=1;i--){
從array[0]至array[i],相鄰的兩個(gè)數(shù)依次比較,如果前面的數(shù)小于后面的數(shù),則交換兩個(gè)數(shù)的位置。
}通過(guò)這樣一遍處理,雖然整個(gè)數(shù)組還是沒(méi)有順序的,但是最小的對(duì)相鄰兩個(gè)數(shù)比較并交換的算法進(jìn)行細(xì)化,得到如下算法描述:
for(i=9;i>=1;i--){
for(j=0;j<=i-1;j++){
若array[j]<array[j+1],則交換array[j]與array[j+1];
}
}
下面,給出完整的源程序:對(duì)相鄰兩個(gè)數(shù)比較并交換的算法進(jìn)行細(xì)化,得到如下算法描述:/*源程序7-4*/
#include"stdio.h"
#include"stdlib.h"
main()
{
intarray[10],i,j,t;
for(i=0;i<=9;i++)
array[i]=rand()%100;
printf("Beforesorting:\n");
for(i=0;i<=9;i++)
printf("%d\t",array[i]);/*源程序7-4*/
#include"stdio.h"
#for(i=9;i>=1;i--)
for(j=0;j<=i-1;j++)
if(array[j]<array[j+1]){
t=array[j];
array[j]=array[j+1];
array[j+1]=t;
}
printf("\nAftersorting:\n");
for(i=0;i<=9;i++)
printf("%d\t",array[i]);
}for(i=9;i>=1;i--)
for(j=0;程序運(yùn)行結(jié)果如下:程序運(yùn)行結(jié)果如下:
7.2函數(shù)間一維數(shù)組的傳遞
7.2.1一維數(shù)組元素地址的表示
在前面一章中介紹了指針的概念,我們知道指針就是地址,數(shù)據(jù)的指針就是數(shù)據(jù)的地址。在C語(yǔ)言中,地址可以和整型數(shù)進(jìn)行加、減法運(yùn)算。首先需要明確的是地址和整型數(shù)進(jìn)行加、減運(yùn)算的結(jié)果還是地址。下面,先看一個(gè)程序?qū)嵗?7.2函數(shù)間一維數(shù)組的傳遞
7.2.1一維數(shù)/*源程序7-5*/
#include"stdio.h"
main()
{
intarray[10];
if(&array[0]+1==&array[1])
printf("&array[0]+1==&array[1]\n");
else
printf("&array[0]+1!=&array[1]\n");
}/*源程序7-5*/
#include"stdio.h"
m程序運(yùn)行結(jié)果如下:
以上程序的運(yùn)行結(jié)果說(shuō)明,&array[0]+1的結(jié)果還是一個(gè)地址,這個(gè)地址就是&array[1]的地址。當(dāng)然,&array[1]-1的結(jié)果就是&array[0]。也就是說(shuō),一個(gè)數(shù)據(jù)的地址加1或減1,得到的是后一個(gè)或前一個(gè)數(shù)據(jù)的地址。由此可以推知在數(shù)組array中,&array[0]+i(0≤i≤9)等價(jià)于&array[i],進(jìn)一步講,*(&array[0]+i)等價(jià)于array[i]。程序運(yùn)行結(jié)果如下:
以上程序的運(yùn)行結(jié)果說(shuō)明,&a7.2.2利用指針變量訪問(wèn)一維數(shù)組
C語(yǔ)言程序中的一維數(shù)組對(duì)應(yīng)的是計(jì)算機(jī)內(nèi)存中一段連續(xù)的內(nèi)存。而數(shù)組的名字,實(shí)質(zhì)是一個(gè)地址常量,這個(gè)地址常量和數(shù)組首元素的地址是相同的。下面看一個(gè)程序的例子:7.2.2利用指針變量訪問(wèn)一維數(shù)組
C語(yǔ)言程序中的一/*源程序7-6*/
#include"stdio.h"
main()
{
intarray[10];
if(array==&array[0])
printf("arrayequal&array[0]\n");
else
printf("arraydon'tequal&array[0]\n");
}/*源程序7-6*/
#include"stdio.h"
m程序運(yùn)行結(jié)果如下:
以上程序的運(yùn)行結(jié)果證明了在C語(yǔ)言中數(shù)組的名字確實(shí)等價(jià)于數(shù)組首元素的地址,即在以上程序中,array等價(jià)于&array[0]。結(jié)合前面的結(jié)論可以得出,在以上程序中,有如下等價(jià)關(guān)系:
array+i?等價(jià)于&array[i]
*(array+i)等價(jià)于array[i]程序運(yùn)行結(jié)果如下:
以上程序的運(yùn)行結(jié)果證明了在C其實(shí),“array[i]”這種形式,可以看做是“*(array+i)”的簡(jiǎn)略形式。從而可以得到一個(gè)結(jié)論:“*(地址+i)”這種形式的表達(dá)式可以等價(jià)地寫成“地址[i]”這種簡(jiǎn)略形式。而這個(gè)地址,既可以是地址常量,如數(shù)組名,也可以是地址變量,也就是指針變量。比如下面的程序:其實(shí),“array[i]”這種形式,可以看做是“*(ar/*源程序7-7*/
#include"stdio.h"
main()
{
intarray[10]={1,2,3,4,5,6,7,8,9,10},i;
int*p;
p=array;
for(i=0;i<10;i++)
printf("%d\t",p[i]);
printf("\n");
}/*源程序7-7*/
#include"stdio.h"
m程序運(yùn)行結(jié)果如下:
以上程序中,語(yǔ)句“p=array;”把數(shù)組首元素的地址賦給了指針變量p,從而使在程序中p與&array[0]等價(jià)。由此得到以下等價(jià)關(guān)系:
p+i?等價(jià)與&array[0]+i
*(p+i)等價(jià)于*(&array[0]+i)
p[i]等價(jià)于array[i]
把上面的結(jié)論簡(jiǎn)單地歸納一下:在程序中,當(dāng)把一個(gè)一維數(shù)組首元素的地址賦給一個(gè)指針變量時(shí),這個(gè)指針變量就可以當(dāng)做這個(gè)一維數(shù)組的名字來(lái)使用。程序運(yùn)行結(jié)果如下:
以上程序中,語(yǔ)句“p=a7.2.3在函數(shù)間傳遞一維數(shù)組
函數(shù)是一段相對(duì)獨(dú)立的程序代碼,其功能是進(jìn)行數(shù)據(jù)的處理和加工。它所處理和加工的數(shù)據(jù)的來(lái)源通常就是函數(shù)的形式參數(shù),其處理結(jié)果就是函數(shù)的返回值。也就是說(shuō),函數(shù)調(diào)用時(shí),被調(diào)函數(shù)通過(guò)形式參數(shù)從主調(diào)函數(shù)中獲取需要處理和加工的數(shù)據(jù),經(jīng)過(guò)加工和處理后,再以返回值的形式傳遞給主調(diào)函數(shù),做進(jìn)一步的處理。那么,當(dāng)主調(diào)函數(shù)需要把一個(gè)一維數(shù)組交給被調(diào)函數(shù)時(shí),應(yīng)該如何解決呢?一種辦法就是主調(diào)函數(shù)把一維數(shù)組中每一個(gè)元素的值傳遞給被調(diào)函數(shù),這就意味著數(shù)組中有多少個(gè)元素,被調(diào)函數(shù)就要定義多少個(gè)形式參數(shù),顯然這不是一個(gè)好辦法。7.2.3在函數(shù)間傳遞一維數(shù)組
函數(shù)是一段相對(duì)獨(dú)立的其實(shí),因?yàn)橐痪S數(shù)組在內(nèi)存中是連續(xù)的,主調(diào)函數(shù)只需要把數(shù)組首元素的地址傳遞給被調(diào)函數(shù),通過(guò)這個(gè)地址,被調(diào)函數(shù)就可以訪問(wèn)到這個(gè)一維數(shù)組中的所有元素了。當(dāng)然這里還有一個(gè)問(wèn)題,就是被調(diào)函數(shù)只獲得一維數(shù)組首元素的地址是不夠的,它還必須獲得一維數(shù)組元素的個(gè)數(shù)。否則,它知道這個(gè)一維數(shù)組從哪里開(kāi)始,而不知道在哪里結(jié)束,也是不能正確地訪問(wèn)這個(gè)一維數(shù)組的。其實(shí),因?yàn)橐痪S數(shù)組在內(nèi)存中是連續(xù)的,主調(diào)函數(shù)只需要把數(shù)組首元通過(guò)上面的分析可知,當(dāng)主調(diào)函數(shù)要把一個(gè)一維數(shù)組傳遞給被調(diào)函數(shù)的時(shí)候,要向被調(diào)函數(shù)傳遞兩個(gè)值:數(shù)組首元素的地址和數(shù)組元素的個(gè)數(shù)。那么,被調(diào)函數(shù)的形式參數(shù)對(duì)應(yīng)的就應(yīng)該是一個(gè)指針變量和一個(gè)普通變量,而在被調(diào)函數(shù)中,這個(gè)指針變量是被當(dāng)做一維數(shù)組來(lái)使用的。下面看一個(gè)程序的例子,這個(gè)程序的功能是將一個(gè)一維數(shù)組中存放的數(shù)據(jù)逆置,即數(shù)組中第一個(gè)元素和最后一個(gè)元素交換位置,第二個(gè)元素與倒數(shù)第二個(gè)元素交換位置,依次類推。通過(guò)上面的分析可知,當(dāng)主調(diào)函數(shù)要把一個(gè)一維數(shù)組傳遞給被調(diào)/*源程序7-8*/
#include"stdio.h"
voidreversal(int*p,intn)
{
inti,j,t;
for(i=0,j=n-1;i<j;i++,j--){
t=p[i];
p[i]=p[j];
p[j]=t;
}/*源程序7-8*/
#include"stdio.h"
v}
main()
{
intarray[10]={1,2,3,4,5,6,7,8,9,10},i;
printf("Beforereversal:\n");
for(i=0;i<10;i++)
printf("%d\t",array[i]);
printf("\n");}
main()
{
intarray[10]=
reversal(array,10);
printf("Afterreversal:\n");
for(i=0;i<10;i++)
printf("%d\t",array[i]);
printf("\n");
}
程序運(yùn)行結(jié)果如下:reversal(array,10);
說(shuō)明:
函數(shù)reversal的形式參數(shù)p是一個(gè)指針變量,用來(lái)接收一維數(shù)組首元素的地址,在函數(shù)中是被當(dāng)做一維數(shù)組使用的。為了提高程序的可讀性,可以把它的定義寫成一維數(shù)組的形式,即該函數(shù)的首部可以寫成:
voidreversal(intp[],intn)
需要注意的是,p的定義雖然寫成了一維數(shù)組的形式,但它實(shí)際是一個(gè)指針變量,所以沒(méi)有必要定義元素的個(gè)數(shù);即使定義了元素的個(gè)數(shù),也是沒(méi)有意義的。說(shuō)明:
函數(shù)reversal的形式參數(shù)p是一個(gè)指針變主調(diào)函數(shù)中的調(diào)用語(yǔ)句“reversal(array,10)”也可以寫成“reversal(&array[0],10)”。
函數(shù)調(diào)用發(fā)生后,被調(diào)函數(shù)中p所代表的數(shù)組和主調(diào)函數(shù)中array所代表的數(shù)組實(shí)際上是同一個(gè)數(shù)組,這就是為什么被調(diào)函數(shù)中逆置了p數(shù)組,而主調(diào)函數(shù)中的array數(shù)組也被逆置了的原因。
讀者可以思考一下,把上面程序中main函數(shù)中的調(diào)用語(yǔ)句改成“reversal(array+3,5)”,可不可以?如果可以,則程序的運(yùn)行結(jié)果是什么?主調(diào)函數(shù)中的調(diào)用語(yǔ)句“reversal(array,1
7.3二維數(shù)組
7.3.1二維數(shù)組的定義和初始化
數(shù)組是用來(lái)解決大批量同類型數(shù)據(jù)的存儲(chǔ)和處理問(wèn)題的。有時(shí)候要處理的一批數(shù)據(jù)在邏輯上是分組的,例如在前面提到的成績(jī)統(tǒng)計(jì)問(wèn)題中,假如要處理的不是一門課的成績(jī),而是五門課程的成績(jī),也就是說(shuō)共有225個(gè)成績(jī)需要處理。這些成績(jī)數(shù)據(jù),可以按照課程來(lái)分組,共5組,每組45個(gè);也可以按照學(xué)生來(lái)分組,共45組,每組5個(gè)。當(dāng)然,也可以把這225個(gè)成績(jī)看做是5行45列或45行5列的矩陣。對(duì)于邏輯上有這種結(jié)構(gòu)的數(shù)據(jù),直接使用一維數(shù)組存儲(chǔ)處理起來(lái)不是非常方便。C語(yǔ)言中提供了二維數(shù)組,可以很方便的存儲(chǔ)和處理類似這種結(jié)構(gòu)的數(shù)據(jù)。 7.3二維數(shù)組
7.3.1二維數(shù)組的定二維數(shù)組的定義形式如下:
數(shù)據(jù)類型數(shù)組名[行數(shù)][列數(shù)];
例如如下語(yǔ)句:
inta[3][4];
該語(yǔ)句定義了一個(gè)二維數(shù)組a,共有12個(gè)存儲(chǔ)單元(元素),被邏輯地分成3行4列,每個(gè)存儲(chǔ)單元(元素)可以存放一個(gè)int型的數(shù)據(jù)。二維數(shù)組中的每個(gè)存儲(chǔ)單元(元素)是用兩個(gè)編號(hào)來(lái)確定的,借用行列式的術(shù)語(yǔ),把這兩個(gè)編號(hào)分別稱為行編號(hào)和列編號(hào)。與一維數(shù)組相同,編號(hào)都是從0開(kāi)始的。
上面定義的二位數(shù)組的邏輯結(jié)構(gòu)和物理結(jié)構(gòu)如圖7-1所示。二維數(shù)組的定義形式如下:
數(shù)據(jù)類型數(shù)組名[行數(shù)圖7-1二維數(shù)組的邏輯結(jié)構(gòu)和物理結(jié)構(gòu)圖7-1二維數(shù)組的邏輯結(jié)構(gòu)和物理結(jié)構(gòu)定義二維數(shù)組的同時(shí),可以對(duì)其進(jìn)行初始化,也就是給二維數(shù)組的元素賦值。初始化的形式既可以是分行的,也可以是不分行的,例如下面的程序片段:
inta[3][4]={{1,2,3,4},{5,6,7,8},{9,10,11,12}};
floatb[2][5]={0.1,1.2,2.3,3.4,4.5,5.6,6.7,7.8,8.9,9.0};
以上程序中,對(duì)二維數(shù)組a的初始化是分行的,而對(duì)二維數(shù)組b的初始化是不分行的。不分行初始化是按照二維數(shù)組元素在內(nèi)存中的排列次序,依次把給定初值賦給數(shù)組元素。初始化的效果如圖7-2所示。定義二維數(shù)組的同時(shí),可以對(duì)其進(jìn)行初始化,也就是給二維數(shù)組圖7-2二維數(shù)組的初始化圖7-2二維數(shù)組的初始化對(duì)二維數(shù)組初始化時(shí),可以進(jìn)行部分初始化,也就是給出二維數(shù)組中的部分元素的初始值,在這種情況下,沒(méi)有給定初始值的數(shù)組元素被編譯系統(tǒng)自動(dòng)初始化為0,例如以下的程序片段:
inta[3][4]={{1,2},{5}};
floatb[2][5]={0.1,1.2,2.3};
按照以上初始化形式,對(duì)于數(shù)組a,元素a[0][0]、a[0][1]和a[1][0]被分別初始化為1、2和5,其他的元素被初始化為0;對(duì)于數(shù)組b,元素b[0][0]、b[0][1]和b[0][2]被分別初始化為0.1、1.2和2.3,其他元素被初始化為0。對(duì)二維數(shù)組初始化時(shí),可以進(jìn)行部分初始化,也就是給出二維數(shù)在對(duì)二維數(shù)組初始化時(shí),可以省略行數(shù)的定義,這時(shí)候由編譯系統(tǒng)根據(jù)初始化的形式自動(dòng)確定二維數(shù)組的行數(shù),例如以下的程序片段:
inta[][4]={{1,2},{5},{9}};
floatb[][5]={0.1,1.2,2.3,3.4,4.5,5.6,6.7};
對(duì)以上的初始化,編譯系統(tǒng)會(huì)自動(dòng)確定數(shù)組a的行數(shù)為3,數(shù)組b的行數(shù)為2。需要注意的是,定義二維數(shù)組時(shí),列數(shù)的定義在任何情況下都是不能省略的。在對(duì)二維數(shù)組初始化時(shí),可以省略行數(shù)的定義,這時(shí)候由編譯系7.3.2二維數(shù)組元素的引用
二維數(shù)組元素的引用類似于一維數(shù)組元素的引用,不同的是引用二維數(shù)組元素時(shí),需要指定行編號(hào)和列編號(hào)(行下標(biāo)和列下標(biāo)),引用的形式為:
數(shù)組名[行編號(hào)][列編號(hào)]
下面通過(guò)一個(gè)例子來(lái)說(shuō)明二維數(shù)組在程序中的應(yīng)用。7.3.2二維數(shù)組元素的引用
二維數(shù)組元素的引用類似
例7-1
編寫一個(gè)程序,功能是輸入5個(gè)學(xué)生的成績(jī),每個(gè)學(xué)生有3門功課的成績(jī),計(jì)算每個(gè)學(xué)生的平均成績(jī)。
對(duì)于這個(gè)問(wèn)題,首先考慮的是如何在程序中存儲(chǔ)這些成績(jī)。顯然,可以利用一個(gè)5行3列的二維數(shù)組來(lái)存放成績(jī),在這個(gè)二維數(shù)組中,每行對(duì)應(yīng)一個(gè)學(xué)生,每列對(duì)應(yīng)一門課程。計(jì)算每個(gè)學(xué)生的平均成績(jī),就是計(jì)算這個(gè)二維數(shù)組中每一行的平均值。根據(jù)這個(gè)思路編寫出如下源程序:例7-1編寫一個(gè)程序,功能是輸入5個(gè)學(xué)生的成績(jī),每個(gè)/*源程序7-9*/
#include<stdio.h>
main()
{
floatscore[5][3],sum,avg;
inti,j;
for(i=0;i<5;i++){
printf("請(qǐng)輸入第%d個(gè)學(xué)生的成績(jī):",i+1);
for(j=0;j<3;j++)
scanf("%f",&score[i][j]);/*源程序7-9*/
#include<stdio.h>
m}
for(i=0;i<5;i++){
sum=0;
for(j=0;j<3;j++)
sum=sum+score[i][j];
avg=sum/3;
printf("第%d個(gè)學(xué)生的平均成績(jī)?yōu)?%f\n",i+1,avg);
}
}}
for(i=0;i<5;i++){
sum=程序運(yùn)行結(jié)果如下:
二維數(shù)組特別適合處理數(shù)學(xué)中有關(guān)行列式的問(wèn)題。程序運(yùn)行結(jié)果如下:
二維數(shù)組特別適合處理數(shù)學(xué)中有
例7-2
編寫程序計(jì)算如下兩個(gè)行列式的乘積:
??
把第一個(gè)行列式命名為a,把第二個(gè)行列式命名為b,把乘積行列式命名為c。根據(jù)行列式乘法運(yùn)算的定義,c是一個(gè)3行5列的行列式,其中:
在程序中定義了三個(gè)二維數(shù)組,分別存放行列式a、b和c。使用循環(huán),逐一計(jì)算乘積行列式每一個(gè)分量的值,編寫源程序如下:×1≤i≤3,1≤j≤5例7-2編寫程序計(jì)算如下兩個(gè)行列式的乘積:
??/*源程序7-10*/
#include<stdio.h>
main()
{
inta[3][4]={
{1,2,3,4},
{5,6,7,8},
{9,10,11,12},/*源程序7-10*/
#include<stdio.h};
intb[4][5]={
{20,19,18,17,16},
{15,14,13,12,11},
{10,9,8,7,6},
{5,4,3,2,1}
};
intc[3][5];
inti,j,k;
for(i=0;i<3;i++)};
intb[4][5]={
{20,19,18 for(j=0;j<5;j++){
c[i][j]=0;
for(k=0;k<4;k++)
c[i][j]=c[i][j]+a[i][k]*b[k][j];
}
printf("Matrixc:\n");
for(i=0;i<3;i++){
for(j=0;j<5;j++)
printf("%d\t",c[i][j]);
printf("\n");
}
} for(j=0;j<5;j++){
c[i][j]程序運(yùn)行結(jié)果如下:程序運(yùn)行結(jié)果如下:
7.4函數(shù)間二維數(shù)組的傳遞
7.4.1二維數(shù)組元素的地址表示法
C語(yǔ)言中的二維數(shù)組,可以看做是由一維數(shù)組作為元素構(gòu)成的一維數(shù)組,例如有如下定義:
inta[3][5];
以上語(yǔ)句,定義a是一個(gè)3行5列的二維數(shù)組。把這個(gè)二維數(shù)組的每一行看做是一個(gè)整體,也就是看做是一個(gè)元素,那么它就是一個(gè)有3個(gè)元素的一維數(shù)組。這個(gè)一維數(shù)組的每一個(gè)元素,都是一個(gè)有5個(gè)元素的一維數(shù)組。 7.4函數(shù)間二維數(shù)組的傳遞
7.4.1二維數(shù)組如果把數(shù)組a看做一維數(shù)組,它就是由a[0]、a[1]和a[2]三個(gè)元素組成的,那么自然就有表達(dá)式“a”等價(jià)于表達(dá)式“&a[0]”(因?yàn)橐痪S數(shù)組名的值是一維數(shù)組首元素的地址)。表達(dá)式“&a[0]”代表的是數(shù)組中第一行的地址,這個(gè)地址加1還是一個(gè)地址,自然就是數(shù)組中第二行的地址了,即表達(dá)式“&a[0]+1”等價(jià)于表達(dá)式“&a[1]”。推廣一下,就有表達(dá)式“&a[0]+i”等價(jià)于表達(dá)式“&a[i]”(0≤i≤2),表達(dá)式“a+i”等價(jià)于表達(dá)式“&a[i]”。如果把數(shù)組a看做一維數(shù)組,它就是由a[0]、a[1]和a表達(dá)式“a[i]”代表的是什么呢?就是數(shù)組中行號(hào)為i的這一行,也就是一個(gè)一維數(shù)組,它的5個(gè)元素是a[i][0]、a[i][1]、…、a[i][4]。因此,就有表達(dá)式“a[i]”等價(jià)于“&a[i][0]”,表達(dá)式“a[i]+j”等價(jià)于表達(dá)式“&a[i][j]”(0≤i≤2,0≤j≤4)。表達(dá)式“a[i]”代表的是什么呢?就是數(shù)組中行號(hào)為i的這綜合以上結(jié)論,可以有如下推導(dǎo)過(guò)程:
∵a+i&a[i]
∴*(a+i)*&a[i]a[i]&a[i][0](0≤i≤2)
∴*(a+i)+j&a[i][0]+j&a[i][j](0≤j≤4)
∴*(*(a+i)+j)a[i][j]
這樣,在程序中訪問(wèn)二維數(shù)組a的元素,就有如下三種形式:a[i][j]、*(a[i]+j)、*(*(a+i)+j)。在這三種形式中,表達(dá)式“*(*(a+i)+j)”是本質(zhì)形式,表達(dá)式“a[i][j]”是簡(jiǎn)略形式,表達(dá)式“*(a[i]+j)”是兩者之間的一種過(guò)渡形式。綜合以上結(jié)論,可以有如下推導(dǎo)過(guò)程:
∵a+i&7.4.2利用行指針變量訪問(wèn)二維數(shù)組元素
繼續(xù)前面的例子,對(duì)于如下定義的二維數(shù)組:
inta[3][5];
表達(dá)式“a”代表的是首行的地址,即“&a[0]”,那么可不可以把這個(gè)地址存放在一個(gè)指針變量當(dāng)中呢?如果可以,這個(gè)指針變量該如何定義呢?來(lái)看下面的定義語(yǔ)句:
int(*pa)[5];7.4.2利用行指針變量訪問(wèn)二維數(shù)組元素
繼續(xù)前面的在這個(gè)語(yǔ)句中定義了一個(gè)變量pa,“*”指定了它是一個(gè)指針變量,這個(gè)指針變量是用來(lái)存放連續(xù)的5個(gè)int型數(shù)據(jù)的地址的??梢园堰B續(xù)的5個(gè)整數(shù)看做是一個(gè)一維數(shù)組,也可以看做是某個(gè)二維數(shù)組中的一行,所以這個(gè)指針變量是一個(gè)指向一維數(shù)組的指針變量,或者說(shuō)是一個(gè)行指針變量。表達(dá)式“a”的值恰好是連續(xù)的5個(gè)整數(shù)的地址,所以可以有如下賦值:
pa=a;
經(jīng)過(guò)以上賦值,就有:
*(*(pa+i)+j)
*(*(a+i)+j)
a[i][j]在這個(gè)語(yǔ)句中定義了一個(gè)變量pa,“*”指定了它是一個(gè)指針結(jié)合前面討論過(guò)的“*(地址+i)”可以簡(jiǎn)寫成“地址[i]”的形式,表達(dá)式“*(*(pa+i)+j)”可以簡(jiǎn)寫成“*(pa[i]+j)”,進(jìn)一步簡(jiǎn)寫成“pa[i][j]”。也就是說(shuō),行指針變量pa可以當(dāng)作二維數(shù)組名使用。
行指針變量在聲明時(shí)要注意括號(hào)的應(yīng)用,例如把變量pa的定義寫成如下形式:
int*pa[5];
因?yàn)椤癧]”的優(yōu)先級(jí)高于“*”,所以pa就被定義為一個(gè)有5個(gè)元素的數(shù)組了,這個(gè)數(shù)組中存放的是int型數(shù)組的地址。這時(shí)候,pa就不是一個(gè)行指針變量,而是一個(gè)指針數(shù)組。結(jié)合前面討論過(guò)的“*(地址+i)”可以簡(jiǎn)寫成“地址[i]另外,對(duì)行指針變量賦值時(shí)必須賦予合適的地址,例如有如下語(yǔ)句:
pa=&a[0][0];
這個(gè)語(yǔ)句就是錯(cuò)誤的,因?yàn)楸磉_(dá)式“&a[0][0]”的值是“1個(gè)int數(shù)據(jù)的地址”,和變量pa的類型(5個(gè)int型數(shù)據(jù)的地址)是不同的,所以這個(gè)賦值從邏輯和語(yǔ)法上來(lái)說(shuō)都是錯(cuò)誤的。另外,對(duì)行指針變量賦值時(shí)必須賦予合適的地址,例如有如下語(yǔ)7.4.3函數(shù)之間二維數(shù)組的傳遞
在函數(shù)之間傳遞二維數(shù)組,只需要傳遞二維數(shù)組首行的地址。此時(shí),主調(diào)函數(shù)的實(shí)參是二維數(shù)組名,而與之對(duì)應(yīng)的被調(diào)函數(shù)的形參應(yīng)該是行指針變量。同時(shí),主調(diào)函數(shù)還需要向被調(diào)函數(shù)傳遞二維數(shù)組的行數(shù)。下面看一個(gè)程序的例子。
例7-3
把方陣的行和列交換。例如一個(gè)5階方陣行和列交換前后如圖7-3所示。7.4.3函數(shù)之間二維數(shù)組的傳遞
在函數(shù)之間傳遞二維圖7-35階方陣的行列互換圖7-35階方陣的行列互換源程序如下:
/*源程序7-11*/
#include<stdio.h>
voidinverseMatrix(int(*pa)[10],intn)
{
inti,j,temp;
for(i=1;i<n;i++)
for(j=0;j<i;j++){
temp=pa[i][j];
pa[i][j]=pa[j][i];
pa[j][i]=temp;
}源程序如下:
/*源程序7-11*/
#includ}
voidoutputMatrix(int(*pa)[10],intn)
{
inti,j;
for(i=0;i<n;i++){
for(j=0;j<n;j++)
printf("%d\t",pa[i][j]);
printf("\n");
}
}
main()
{}
voidoutputMatrix(int(*pa)[
inta[10][10]={
{1,2,3,4,5},
{6,7,8,9,10},
{11,12,13,14,15},
{16,17,18,19,20},
{21,22,23,24,25}
};inta[10][10]={
{1,2,3,4,5}
printf("Beforeinversing:\n");
outputMatrix(a,5);
inverseMatrix(a,5);
printf("Afterinversing:\n");
outputMatrix(a,5);
}printf("Beforeinversing:\n"程序運(yùn)行結(jié)果如下:程序運(yùn)行結(jié)果如下:
習(xí)題
1.編寫函數(shù)fun,函數(shù)原型為:intfun(intscore[],intm,intbelow[])。它的功能是:m個(gè)人的成績(jī)存放在score數(shù)組中,將低于平均分的人數(shù)作為函數(shù)值返回,將低于平均分的分?jǐn)?shù)放在below所指的數(shù)組中。例如,當(dāng)score數(shù)組中的數(shù)據(jù)為10、20、30、40、50、60、70、80、90時(shí),函數(shù)返回的人數(shù)應(yīng)該是4,below中的數(shù)據(jù)應(yīng)為10、20、30、40。 習(xí)題
1.編寫函數(shù)fun,函數(shù)原型為:i
2.編寫函數(shù)fun,函數(shù)原型為:voidfun(intx,intpp[],int*n)。它的功能是:求出能整除形參x且不是偶數(shù)的各整數(shù),并按從小到大的順序放在pp所指的數(shù)組中,這些除數(shù)的個(gè)數(shù)通過(guò)形參n返回。例如,若x中的值為35,則有4個(gè)數(shù)符合要求,它們是1、5、7、35。2.編寫函數(shù)fun,函數(shù)原型為:voidfun(
3.編寫函數(shù)fun,函數(shù)原型為:voidfun(int(*s)[10],int*b,int*n,intmm,intnn)。它的功能是:將10行10列的二維數(shù)組s中的前mm行nn列的數(shù)據(jù),按行的順序依次放到一維數(shù)組b中,一維數(shù)組中數(shù)據(jù)的個(gè)數(shù)存放在形參n所指的存儲(chǔ)單元中。例如,二維數(shù)組中的數(shù)據(jù)為
33333333
44444444
55555555
則一維數(shù)組中的內(nèi)容應(yīng)是
3333333344444444555555553.編寫函數(shù)fun,函數(shù)原型為:voidfun(i
4.編寫函數(shù)fun,函數(shù)原型為:intfun(int*s,intt,int*k)。它的功能是:求出數(shù)組的最大元素,并將最大元素在數(shù)組中的下標(biāo)存放在k所指的存儲(chǔ)單元中。例如,輸入如下整數(shù):
876675896101301401980431451777,則結(jié)果為980,6。
5.編寫函數(shù)fun,函數(shù)原型為:voidfun(intm,intk,intxx[])。它的功能是:將大于形參m且緊靠m的k個(gè)素?cái)?shù)存入xx所指的數(shù)組中。例如,若輸入17,5,則應(yīng)輸出19,23,29,31,37。4.編寫函數(shù)fun,函數(shù)原型為:intfun(int
6.編寫函數(shù)fun,函數(shù)原型為:intfun(inta[M][N])。它的功能是:求出二維數(shù)組M行N列周邊元素之和,作為函數(shù)值返回。二維數(shù)組中的值在主函數(shù)中賦予。例如:二維數(shù)組中的值為
13579
29994
69998
13570
則函數(shù)值為61。6.編寫函數(shù)fun,函數(shù)原型為:intfun(int
7.編寫函數(shù)fun,函數(shù)原型為:intfun(inta[],intn)。它的功能是:刪去一維數(shù)組中所有相同的數(shù),使之只剩一個(gè)。數(shù)組中的數(shù)已按由小到大的順序排列,函數(shù)返回刪除后數(shù)組中數(shù)據(jù)的個(gè)數(shù)。例如,一維數(shù)組中的數(shù)據(jù)是
2223445666677899101010
刪除后,數(shù)組中的內(nèi)容應(yīng)該是
23456789107.編寫函數(shù)fun,函數(shù)原型為:intfun(int
8.編寫函數(shù)fun,函數(shù)原型為:voidfun(int*w,intp,intn)。它的功能是:移動(dòng)一維數(shù)組中的內(nèi)容;若數(shù)組中有n個(gè)整數(shù),要求把下標(biāo)從0到p(含p,p≤n-1)的數(shù)組元素平移到數(shù)組的最后。例如,一維數(shù)組中的原始內(nèi)容為
1,2,3,4,5,6,7,8,9,10
p的值為3。移動(dòng)后,一維數(shù)組中的內(nèi)容應(yīng)為
5,6,7,8,9,10,1,2,3,48.編寫函數(shù)fun,函數(shù)原型為:voidfun(in
9.編寫函數(shù)fun,函數(shù)原型為:voidfun(int*a)。它的功能是:調(diào)用隨機(jī)函數(shù)產(chǎn)生20個(gè)互不相同的整數(shù),存放在形參a所指數(shù)組中。
10.編寫函數(shù)fun,函數(shù)原型為:intfun(int*b)。它的功能是:從整數(shù)1到55之間,選出能被3整除,且有一位上的數(shù)是5的那些數(shù),把這些數(shù)放在b所指的數(shù)組中,并將這些數(shù)的個(gè)數(shù)作為函數(shù)值返回。9.編寫函數(shù)fun,函數(shù)原型為:voidfun(in感謝感謝謝謝,精品課件資料搜集謝謝,精品課件資料搜集第7章數(shù)組7.1一維數(shù)組
7.2函數(shù)間一維數(shù)組的傳遞
7.3二維數(shù)組
7.4函數(shù)間二維數(shù)組的傳遞
習(xí)題
第7章數(shù)組7.1一維數(shù)組
7.1一維數(shù)組
7.1.1數(shù)組概述
通過(guò)前面的學(xué)習(xí),我們知道,如果在程序中需要暫時(shí)存放幾個(gè)數(shù)據(jù),就需要定義幾個(gè)變量。但是,這種方法在處理大批量的同類型的數(shù)據(jù)的時(shí)候,就顯得不是很方便了。例如,某個(gè)班級(jí)有45名同學(xué),在“程序設(shè)計(jì)基礎(chǔ)”這門課程考試結(jié)束后,要編寫一個(gè)程序,統(tǒng)計(jì)一下成績(jī)高于平均分的人數(shù)。針對(duì)這個(gè)問(wèn)題,可以設(shè)計(jì)出如下算法:
①依次接受并暫存45個(gè)成績(jī);
②計(jì)算總分和平均分; 7.1一維數(shù)組
7.1.1數(shù)組概述
③置計(jì)數(shù)器為0;
④對(duì)每一個(gè)成績(jī),若它大于平均分,則計(jì)數(shù)器累加1;
⑤輸出計(jì)數(shù)器的值。
按照以上算法的要求,如果在程序中定義45個(gè)變量去暫存這45個(gè)成績(jī),顯然是一種比較笨拙的辦法。
那么,有沒(méi)有更好的辦法呢?其實(shí),針對(duì)這種大批量數(shù)據(jù)的存儲(chǔ)問(wèn)題,C語(yǔ)言中提供了數(shù)組這種數(shù)據(jù)類型來(lái)解決。③置計(jì)數(shù)器為0;
④對(duì)每一個(gè)成績(jī),若它大于平均分?jǐn)?shù)組的實(shí)質(zhì)是內(nèi)存中一段連續(xù)的存儲(chǔ)空間,例如內(nèi)存中連續(xù)的20個(gè)字節(jié)的存儲(chǔ)空間就可以稱為一個(gè)數(shù)組。這個(gè)數(shù)組如果用來(lái)存放int型的數(shù)據(jù),則可以存放10個(gè)(若每個(gè)int型的數(shù)據(jù)需要兩個(gè)字節(jié)的存儲(chǔ)空間)。此時(shí)每?jī)蓚€(gè)字節(jié)構(gòu)成數(shù)組中一個(gè)存儲(chǔ)單元,稱為數(shù)組元素或數(shù)組分量;當(dāng)然,這個(gè)數(shù)組也可以用于存放5個(gè)float型的數(shù)據(jù)(若每個(gè)float型的數(shù)據(jù)需要4個(gè)字節(jié)的存儲(chǔ)空間),此時(shí),每4個(gè)字節(jié)構(gòu)成一個(gè)數(shù)組分量。在程序中,數(shù)組用一個(gè)名字來(lái)表示,數(shù)組中分量用編號(hào)來(lái)區(qū)分。采用這種方式,不但解決了大批量同類型數(shù)據(jù)的存儲(chǔ)問(wèn)題,而且方便用循環(huán)的方式來(lái)對(duì)這些數(shù)據(jù)進(jìn)行運(yùn)算和處理。數(shù)組的實(shí)質(zhì)是內(nèi)存中一段連續(xù)的存儲(chǔ)空間,例如內(nèi)存中連續(xù)的2存放在數(shù)組中的多個(gè)數(shù)據(jù),從邏輯上可以看做是按一個(gè)方向排列的,也可以看做是按兩個(gè)方向排列的。例如20個(gè)整數(shù)可以看做是按一個(gè)方向排列的,在C語(yǔ)言中稱為一維數(shù)組;這20個(gè)整數(shù)也可以分為4組,每組5個(gè),在C語(yǔ)言中就稱為二維數(shù)組。這種情況下,通常仿照數(shù)學(xué)中行列式的形式,稱這20個(gè)數(shù)構(gòu)成4行5列的二維數(shù)組。當(dāng)然,一組數(shù)也可以看做是按多個(gè)方向排列的,這在C語(yǔ)言中就稱為多維數(shù)組了。存放在數(shù)組中的多個(gè)數(shù)據(jù),從邏輯上可以看做是按一個(gè)方向排列7.1.2一維數(shù)組的定義和初始化
一維數(shù)組的定義形式如下:
數(shù)據(jù)類型數(shù)組名[分量個(gè)數(shù)];
數(shù)組名和變量名一樣,是C語(yǔ)言中的標(biāo)識(shí)符,必須符合標(biāo)示符的命名規(guī)則。分量個(gè)數(shù)必須是一個(gè)整型數(shù),通常是常量或常量表達(dá)式。分量個(gè)數(shù)表示的數(shù)組中存儲(chǔ)單元的個(gè)數(shù),也就是這個(gè)數(shù)組中可以最多存放的數(shù)據(jù)的個(gè)數(shù)。數(shù)據(jù)類型用來(lái)指定數(shù)組中可以存放的數(shù)據(jù)的類型。例如:
intarray[10];7.1.2一維數(shù)組的定義和初始化
一維數(shù)組的定義形式以上語(yǔ)句,定義array是一個(gè)數(shù)組,這個(gè)數(shù)組是用來(lái)存放int型數(shù)據(jù)的,最多可以存放10個(gè)int型的數(shù)據(jù)。
定義了數(shù)組之后,如果這個(gè)數(shù)組是外部數(shù)組,則數(shù)組中每個(gè)分量中存放的都是0,也就是說(shuō),每個(gè)數(shù)組元素的值都是0;如果這個(gè)數(shù)組是內(nèi)部數(shù)組,則數(shù)組中元素的值是隨機(jī)值。定義數(shù)組時(shí),可以把特定的值存放在數(shù)組中,這種情況稱為數(shù)組的初始化,例如:
intarray[10]={1,2,3,4,5,6,7,8,9,10};以上語(yǔ)句,定義array是一個(gè)數(shù)組,這個(gè)數(shù)組是用來(lái)存放i以上語(yǔ)句,定義array是一個(gè)有10個(gè)元素的int型數(shù)組,同時(shí)把1,2,3,…,10這10個(gè)數(shù)依次存放在數(shù)組的10個(gè)元素中。當(dāng)然,也可以對(duì)數(shù)組進(jìn)行部分初始化,例如:
intarray[10]={1,2,3};
以上語(yǔ)句,在定義數(shù)組的同時(shí),把1、2、3依次存放在數(shù)組的第1、第2和第3個(gè)元素中,此時(shí),數(shù)組中其余元素自動(dòng)被初始化為0。以上語(yǔ)句,定義array是一個(gè)有10個(gè)元素的int型數(shù)組7.1.3一維數(shù)組元素的引用
數(shù)組在使用中,通常不會(huì)做整體的引用,更多的是引用數(shù)組中某一個(gè)分量中存放的數(shù)據(jù)。一維數(shù)組中的每一個(gè)分量都對(duì)應(yīng)一個(gè)編號(hào)。需要特別注意的是分量的編號(hào)是從0開(kāi)始的,即數(shù)組中第一個(gè)分量的編號(hào)為0,第二個(gè)分量的編號(hào)為1,依此類推。在程序中,引用數(shù)組分量的形式為“數(shù)組名[編號(hào)]”,這里的編號(hào)為一個(gè)取值為int型的表達(dá)式。例如,對(duì)如下定義的數(shù)組:
intarray[10];7.1.3一維數(shù)組元素的引用
數(shù)組在使用中,通常不會(huì)如果要將其中的第1個(gè)分量賦值為5,則表達(dá)為如下語(yǔ)句:
array[0]=5;
再例如要將數(shù)組array中第3個(gè)分量和第4個(gè)分量中存放的值求和后,存放在數(shù)組的第5個(gè)分量中,可使用如下語(yǔ)句:
array[4]=array[2]+array[3];
在對(duì)數(shù)組中存放的數(shù)據(jù)進(jìn)行運(yùn)算和處理時(shí),通常采用循環(huán)的方式,例如對(duì)于前面提到的成績(jī)統(tǒng)計(jì)的問(wèn)題,可以編寫出如下的源程序:如果要將其中的第1個(gè)分量賦值為5,則表達(dá)為如下語(yǔ)句:
/*源程序7-1*/
#include"stdio.h"
main()
{
floatscore[45],sum,avg;
inti,counter;
for(i=0;i<45;i++){
printf("Paleaseinputscore[%d]:",i);
scanf("%d",&score[i]);/*源程序7-1*/
#include"stdio.h"
m
}
sum=0;
for(i=0;i<45;i++)
sum+=score[i];
avg=sum/45;
counter=0;
for(i=0;i<45;i++)
if(score[i]>avg)
counter++;
printf("counter=%d\n",counter);
}}
sum=0;
for(i=0;i<7.1.4簡(jiǎn)單排序算法
排序問(wèn)題是計(jì)算機(jī)編程中的一個(gè)常見(jiàn)問(wèn)題。在日常的數(shù)據(jù)處理中,面對(duì)大量的數(shù)據(jù),也許有成百上千種的處理要求,而這些處理往往是以排序作為前提的。例如查找,在有序的數(shù)據(jù)中進(jìn)行查找,當(dāng)然比在無(wú)序的數(shù)據(jù)中進(jìn)行查找要容易得多。在計(jì)算機(jī)發(fā)展的歷史中,前人為我們留下了很多經(jīng)典的排序算法,它們都是智慧的結(jié)晶。下面就討論其中比較簡(jiǎn)單的兩種排序算法。首先把排序的問(wèn)題具體化:假如有10個(gè)整數(shù),按照任意次序存放在計(jì)算機(jī)的一段連續(xù)內(nèi)存(為了描述方便,把這一段連續(xù)內(nèi)存看做是有10個(gè)分量的一維數(shù)組array)中,我們要做的就是將array數(shù)組中的這10個(gè)數(shù)的存放位置調(diào)整為由大到小。7.1.4簡(jiǎn)單排序算法
排序問(wèn)題是計(jì)算機(jī)編程中的一個(gè)下面先看第一種簡(jiǎn)單排序方法,選擇排序法。
針對(duì)前面所描述的問(wèn)題,可以采用如下算法來(lái)解決:
(1)從array[0]至array[9]中找出一個(gè)最大的數(shù),假如這個(gè)數(shù)在array[max_index]中,把它交換到數(shù)組的第一個(gè)位置,即array[max_index]與array[0]交換;
(2)從array[1]至array[9]中找出一個(gè)最大的數(shù),假如這個(gè)數(shù)在array[max_index]中,把它交換到數(shù)組的第一個(gè)位置,即array[max_index]與array[1]交換;
(3)從array[2]至array[9]中找出一個(gè)最大的數(shù),假如這個(gè)數(shù)在array[max_index]中,把它交換到數(shù)組的第一個(gè)位置,即array[max_index]與array[2]交換;
……下面先看第一種簡(jiǎn)單排序方法,選擇排序法。
針對(duì)前面所
(9)從array[8]至array[9]中找出一個(gè)最大的數(shù),假如這個(gè)數(shù)在array[max_index]中,把它交換到數(shù)組的第一個(gè)位置,即array[max_index]與array[8]交換。
以上的算法,用偽代碼的形式描述如下:
for(i=0;i<=9;i++){
從array[i]至array[9]中找出一個(gè)最大的數(shù),假如這個(gè)數(shù)在array[max_index]中,
把它交換到數(shù)組的第一個(gè)位置,即array[max_index]與array[i]交換;
}
我們?cè)侔褟腶rray[i]至array[9]中找最大數(shù)的算法和交換的算法細(xì)化,得到如下算法描述:(9)從array[8]至array[9]中找出一個(gè)最for(i=0;i<=8;i++){
max_index=i;
for(j=max_index+1;j<=9;j++)
if(array[j]>array[max_index])
max_index=j;
if(max_index!=i){
t=array[i];
array[i]=array[max_index];
array[max_index]=t;
}for(i=0;i<=8;i++){
max_i下面給出一個(gè)完整的源程序,程序中的10個(gè)數(shù)是調(diào)用隨機(jī)函數(shù)生成的100以內(nèi)的數(shù)。
/*源程序7-2*/
#include"stdio.h"
#include"stdlib.h"
main()
{
intarray[10],i,j,t,max_index;
for(i=0;i<=9;i++)
array[i]=rand()%100;下面給出一個(gè)完整的源程序,程序中的10個(gè)數(shù)是調(diào)用隨機(jī)函數(shù)
printf("Beforesorting:\n");
for(i=0;i<=9;i++)
printf("%d\t",array[i]);
for(i=0;i<=8;i++){
max_index=i;
for(j=max_index+1;j<=9;j++)
if(array[j]>array[max_index])
max_index=j;
if(max_index!=i){printf("Beforesorting:\n");
t=array[i];
array[i]=array[max_index];
array[max_index]=t;
}
}
printf("\nAftersorting:\n");
for(i=0;i<=9;i++)
printf("%d\t",array[i]);
} t=array[i];
array[i]=a程序運(yùn)行結(jié)果如下:
上面的程序中,每一次都是通過(guò)比較先找到最大數(shù)所在位置的編號(hào)max_index,然后再進(jìn)行交換。還可以把比較的過(guò)程和最后的交換結(jié)合起來(lái),也就是在比較的過(guò)程中完成交換,這樣,源程序可以修改成如下形式:程序運(yùn)行結(jié)果如下:
上面的程序中,每一次都是通/*源程序7-3*/
#include"stdio.h"
#include"stdlib.h"
main()
{
intarray[10],i,j,t;
for(i=0;i<=9;i++)
array[i]=rand()%100;
printf("Beforesorting:\n");
for(i=0;i<=9;i++)
printf("%d\t",array[i]);/*源程序7-3*/
#include"stdio.h"
#
for(i=0;i<=8;i++){
for(j=i+1;j<=9;j++)
if(array[j]>array[i]){
t=array[i];
array[i]=array[j];
array[j]=t;
}
}
printf("\nAftersorting:\n");
for(i=0;i<=9;i++)
printf("%d\t",array[i]);
}for(i=0;i<=8;i++){
for選擇排序法之所以叫做選擇排序法,就是因?yàn)檫@種方法每次選出一個(gè)合適的數(shù),放到合適的位置上。很容易就可以推知,對(duì)n個(gè)數(shù)進(jìn)行排序,共需要n-1次這樣的選擇。
下面再來(lái)看另一種簡(jiǎn)單排序算法,這種排序算法有一個(gè)非常有趣的名字,叫做冒泡排序。為什么叫做冒泡排序呢?還是以前面給出的問(wèn)題為例來(lái)說(shuō)明。
要對(duì)數(shù)組array中存放的10個(gè)整數(shù)排序,首先對(duì)array數(shù)組做一遍這樣的處理:
從array[0]至array[9],相鄰的兩個(gè)數(shù)依次比較,即array[0]與array[1]比較,array[1]與array[2]比較,…,array[8]與array[9]比較,在比較的過(guò)程中,如果前面的數(shù)小于后面的數(shù),則交換兩個(gè)數(shù)的位置。選擇排序法之所以叫做選擇排序法,就是因?yàn)檫@種方法每次選出通過(guò)這樣一遍處理,雖然整個(gè)數(shù)組還是沒(méi)有順序的,但是最小的一個(gè)數(shù)在比較的過(guò)程中被逐漸的后移,最終被交換到最后一個(gè)位置了。這個(gè)過(guò)程有點(diǎn)像水里的氣泡從水底逐漸地浮到水面的過(guò)程,所以這種排序算法叫做冒泡排序法。然后,使用同樣的方法,依次對(duì)array[0]至array[8]、array[0]至array[7]、…、array[0]至array[1]做同樣的處理。前后共做9次這樣的處理,就可以得到由大到小的次序。這個(gè)過(guò)程用偽代碼描述為:
for(i=9;i>=1;i--){
從array[0]至array[i],相鄰的兩個(gè)數(shù)依次比較,如果前面的數(shù)小于后面的數(shù),則交換兩個(gè)數(shù)的位置。
}通過(guò)這樣一遍處理,雖然整個(gè)數(shù)組還是沒(méi)有順序的,但是最小的對(duì)相鄰兩個(gè)數(shù)比較并交換的算法進(jìn)行細(xì)化,得到如下算法描述:
for(i=9;i>=1;i--){
for(j=0;j<=i-1;j++){
若array[j]<array[j+1],則交換array[j]與array[j+1];
}
}
下面,給出完整的源程序:對(duì)相鄰兩個(gè)數(shù)比較并交換的算法進(jìn)行細(xì)化,得到如下算法描述:/*源程序7-4*/
#include"stdio.h"
#include"stdlib.h"
main()
{
intarray[10],i,j,t;
for(i=0;i<=9;i++)
array[i]=rand()%100;
printf("Beforesorting:\n");
for(i=0;i<=9;i++)
printf("%d\t",array[i]);/*源程序7-4*/
#include"stdio.h"
#for(i=9;i>=1;i--)
for(j=0;j<=i-1;j++)
if(array[j]<array[j+1]){
t=array[j];
array[j]=array[j+1];
array[j+1]=t;
}
printf("\nAftersorting:\n");
for(i=0;i<=9;i++)
printf("%d\t",array[i]);
}for(i=9;i>=1;i--)
for(j=0;程序運(yùn)行結(jié)果如下:程序運(yùn)行結(jié)果如下:
7.2函數(shù)間一維數(shù)組的傳遞
7.2.1一維數(shù)組元素地址的表示
在前面一章中介紹了指針的概念,我們知道指針就是地址,數(shù)據(jù)的指針就是數(shù)據(jù)的地址。在C語(yǔ)言中,地址可以和整型數(shù)進(jìn)行加、減法運(yùn)算。首先需要明確的是地址和整型數(shù)進(jìn)行加、減運(yùn)算的結(jié)果還是地址。下面,先看一個(gè)程序?qū)嵗?7.2函數(shù)間一維數(shù)組的傳遞
7.2.1一維數(shù)/*源程序7-5*/
#include"stdio.h"
main()
{
intarray[10];
if(&array[0]+1==&array[1])
printf("&array[0]+1==&array[1]\n");
else
printf("&array[0]+1!=&array
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025年計(jì)算器及貨幣專用設(shè)備合作協(xié)議書
- 2025年棕、藤、草制品合作協(xié)議書
- 2025年壓力校驗(yàn)器合作協(xié)議書
- 2025年高壓化成箔合作協(xié)議書
- 2022-2023學(xué)年山東省德州市夏津縣四年級(jí)(上)期末數(shù)學(xué)試卷
- 惠州惠東縣幼兒教師招聘幼兒考試試題及答案
- 滬教版四年級(jí)下冊(cè)數(shù)學(xué)小數(shù)的加減法測(cè)試題
- 歷年高級(jí)財(cái)務(wù)會(huì)計(jì)試題及部分答案
- 四年級(jí)下冊(cè)人教版數(shù)學(xué)教學(xué)計(jì)劃
- 2025年交通事故一次性終結(jié)賠償協(xié)議范文(2篇)
- 2025年魯泰集團(tuán)招聘170人高頻重點(diǎn)提升(共500題)附帶答案詳解
- 2024-2025學(xué)年成都高新區(qū)七上數(shù)學(xué)期末考試試卷【含答案】
- 企業(yè)員工食堂管理制度框架
- 電力溝施工組織設(shè)計(jì)-電纜溝
- 2024年煤礦安全生產(chǎn)知識(shí)培訓(xùn)考試必答題庫(kù)及答案(共190題)
- 2024年山東鐵投集團(tuán)招聘筆試參考題庫(kù)含答案解析
- (完整word版)中國(guó)銀行交易流水明細(xì)清單模版
- 膠合板公司人員招聘與配置(模板)
- 軟件功能點(diǎn)估算.xls
- 燃?xì)廨啓C(jī)LM2500介紹
- (精選)淺談在小學(xué)數(shù)學(xué)教學(xué)中如何進(jìn)行有效提問(wèn)
評(píng)論
0/150
提交評(píng)論