版權說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權,請進行舉報或認領
文檔簡介
第7章數(shù)組7.1一維數(shù)組
7.2函數(shù)間一維數(shù)組的傳遞
7.3二維數(shù)組
7.4函數(shù)間二維數(shù)組的傳遞
習題
7.1一維數(shù)組
7.1.1數(shù)組概述
通過前面的學習,我們知道,如果在程序中需要暫時存放幾個數(shù)據(jù),就需要定義幾個變量。但是,這種方法在處理大批量的同類型的數(shù)據(jù)的時候,就顯得不是很方便了。例如,某個班級有45名同學,在“程序設計基礎”這門課程考試結束后,要編寫一個程序,統(tǒng)計一下成績高于平均分的人數(shù)。針對這個問題,可以設計出如下算法:
①依次接受并暫存45個成績;
②計算總分和平均分;③置計數(shù)器為0;
④對每一個成績,若它大于平均分,則計數(shù)器累加1;
⑤輸出計數(shù)器的值。
按照以上算法的要求,如果在程序中定義45個變量去暫存這45個成績,顯然是一種比較笨拙的辦法。
那么,有沒有更好的辦法呢?其實,針對這種大批量數(shù)據(jù)的存儲問題,C語言中提供了數(shù)組這種數(shù)據(jù)類型來解決。數(shù)組的實質是內(nèi)存中一段連續(xù)的存儲空間,例如內(nèi)存中連續(xù)的20個字節(jié)的存儲空間就可以稱為一個數(shù)組。這個數(shù)組如果用來存放int型的數(shù)據(jù),則可以存放10個(若每個int型的數(shù)據(jù)需要兩個字節(jié)的存儲空間)。此時每兩個字節(jié)構成數(shù)組中一個存儲單元,稱為數(shù)組元素或數(shù)組分量;當然,這個數(shù)組也可以用于存放5個float型的數(shù)據(jù)(若每個float型的數(shù)據(jù)需要4個字節(jié)的存儲空間),此時,每4個字節(jié)構成一個數(shù)組分量。在程序中,數(shù)組用一個名字來表示,數(shù)組中分量用編號來區(qū)分。采用這種方式,不但解決了大批量同類型數(shù)據(jù)的存儲問題,而且方便用循環(huán)的方式來對這些數(shù)據(jù)進行運算和處理。存放在數(shù)組中的多個數(shù)據(jù),從邏輯上可以看做是按一個方向排列的,也可以看做是按兩個方向排列的。例如20個整數(shù)可以看做是按一個方向排列的,在C語言中稱為一維數(shù)組;這20個整數(shù)也可以分為4組,每組5個,在C語言中就稱為二維數(shù)組。這種情況下,通常仿照數(shù)學中行列式的形式,稱這20個數(shù)構成4行5列的二維數(shù)組。當然,一組數(shù)也可以看做是按多個方向排列的,這在C語言中就稱為多維數(shù)組了。7.1.2一維數(shù)組的定義和初始化
一維數(shù)組的定義形式如下:
數(shù)據(jù)類型數(shù)組名[分量個數(shù)];
數(shù)組名和變量名一樣,是C語言中的標識符,必須符合標示符的命名規(guī)則。分量個數(shù)必須是一個整型數(shù),通常是常量或常量表達式。分量個數(shù)表示的數(shù)組中存儲單元的個數(shù),也就是這個數(shù)組中可以最多存放的數(shù)據(jù)的個數(shù)。數(shù)據(jù)類型用來指定數(shù)組中可以存放的數(shù)據(jù)的類型。例如:
intarray[10];以上語句,定義array是一個數(shù)組,這個數(shù)組是用來存放int型數(shù)據(jù)的,最多可以存放10個int型的數(shù)據(jù)。
定義了數(shù)組之后,如果這個數(shù)組是外部數(shù)組,則數(shù)組中每個分量中存放的都是0,也就是說,每個數(shù)組元素的值都是0;如果這個數(shù)組是內(nèi)部數(shù)組,則數(shù)組中元素的值是隨機值。定義數(shù)組時,可以把特定的值存放在數(shù)組中,這種情況稱為數(shù)組的初始化,例如:
intarray[10]={1,2,3,4,5,6,7,8,9,10};以上語句,定義array是一個有10個元素的int型數(shù)組,同時把1,2,3,…,10這10個數(shù)依次存放在數(shù)組的10個元素中。當然,也可以對數(shù)組進行部分初始化,例如:
intarray[10]={1,2,3};
以上語句,在定義數(shù)組的同時,把1、2、3依次存放在數(shù)組的第1、第2和第3個元素中,此時,數(shù)組中其余元素自動被初始化為0。7.1.3一維數(shù)組元素的引用
數(shù)組在使用中,通常不會做整體的引用,更多的是引用數(shù)組中某一個分量中存放的數(shù)據(jù)。一維數(shù)組中的每一個分量都對應一個編號。需要特別注意的是分量的編號是從0開始的,即數(shù)組中第一個分量的編號為0,第二個分量的編號為1,依此類推。在程序中,引用數(shù)組分量的形式為“數(shù)組名[編號]”,這里的編號為一個取值為int型的表達式。例如,對如下定義的數(shù)組:
intarray[10];如果要將其中的第1個分量賦值為5,則表達為如下語句:
array[0]=5;
再例如要將數(shù)組array中第3個分量和第4個分量中存放的值求和后,存放在數(shù)組的第5個分量中,可使用如下語句:
array[4]=array[2]+array[3];
在對數(shù)組中存放的數(shù)據(jù)進行運算和處理時,通常采用循環(huán)的方式,例如對于前面提到的成績統(tǒng)計的問題,可以編寫出如下的源程序:/*源程序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]);
}
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);
}7.1.4簡單排序算法
排序問題是計算機編程中的一個常見問題。在日常的數(shù)據(jù)處理中,面對大量的數(shù)據(jù),也許有成百上千種的處理要求,而這些處理往往是以排序作為前提的。例如查找,在有序的數(shù)據(jù)中進行查找,當然比在無序的數(shù)據(jù)中進行查找要容易得多。在計算機發(fā)展的歷史中,前人為我們留下了很多經(jīng)典的排序算法,它們都是智慧的結晶。下面就討論其中比較簡單的兩種排序算法。首先把排序的問題具體化:假如有10個整數(shù),按照任意次序存放在計算機的一段連續(xù)內(nèi)存(為了描述方便,把這一段連續(xù)內(nèi)存看做是有10個分量的一維數(shù)組array)中,我們要做的就是將array數(shù)組中的這10個數(shù)的存放位置調(diào)整為由大到小。下面先看第一種簡單排序方法,選擇排序法。
針對前面所描述的問題,可以采用如下算法來解決:
(1)從array[0]至array[9]中找出一個最大的數(shù),假如這個數(shù)在array[max_index]中,把它交換到數(shù)組的第一個位置,即array[max_index]與array[0]交換;
(2)從array[1]至array[9]中找出一個最大的數(shù),假如這個數(shù)在array[max_index]中,把它交換到數(shù)組的第一個位置,即array[max_index]與array[1]交換;
(3)從array[2]至array[9]中找出一個最大的數(shù),假如這個數(shù)在array[max_index]中,把它交換到數(shù)組的第一個位置,即array[max_index]與array[2]交換;
……
(9)從array[8]至array[9]中找出一個最大的數(shù),假如這個數(shù)在array[max_index]中,把它交換到數(shù)組的第一個位置,即array[max_index]與array[8]交換。
以上的算法,用偽代碼的形式描述如下:
for(i=0;i<=9;i++){
從array[i]至array[9]中找出一個最大的數(shù),假如這個數(shù)在array[max_index]中,
把它交換到數(shù)組的第一個位置,即array[max_index]與array[i]交換;
}
我們再把從array[i]至array[9]中找最大數(shù)的算法和交換的算法細化,得到如下算法描述: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;
}下面給出一個完整的源程序,程序中的10個數(shù)是調(diào)用隨機函數(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;
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){ 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]);
}程序運行結果如下:
上面的程序中,每一次都是通過比較先找到最大數(shù)所在位置的編號max_index,然后再進行交換。還可以把比較的過程和最后的交換結合起來,也就是在比較的過程中完成交換,這樣,源程序可以修改成如下形式:/*源程序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]);
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]);
}選擇排序法之所以叫做選擇排序法,就是因為這種方法每次選出一個合適的數(shù),放到合適的位置上。很容易就可以推知,對n個數(shù)進行排序,共需要n-1次這樣的選擇。
下面再來看另一種簡單排序算法,這種排序算法有一個非常有趣的名字,叫做冒泡排序。為什么叫做冒泡排序呢?還是以前面給出的問題為例來說明。
要對數(shù)組array中存放的10個整數(shù)排序,首先對array數(shù)組做一遍這樣的處理:
從array[0]至array[9],相鄰的兩個數(shù)依次比較,即array[0]與array[1]比較,array[1]與array[2]比較,…,array[8]與array[9]比較,在比較的過程中,如果前面的數(shù)小于后面的數(shù),則交換兩個數(shù)的位置。通過這樣一遍處理,雖然整個數(shù)組還是沒有順序的,但是最小的一個數(shù)在比較的過程中被逐漸的后移,最終被交換到最后一個位置了。這個過程有點像水里的氣泡從水底逐漸地浮到水面的過程,所以這種排序算法叫做冒泡排序法。然后,使用同樣的方法,依次對array[0]至array[8]、array[0]至array[7]、…、array[0]至array[1]做同樣的處理。前后共做9次這樣的處理,就可以得到由大到小的次序。這個過程用偽代碼描述為:
for(i=9;i>=1;i--){
從array[0]至array[i],相鄰的兩個數(shù)依次比較,如果前面的數(shù)小于后面的數(shù),則交換兩個數(shù)的位置。
}對相鄰兩個數(shù)比較并交換的算法進行細化,得到如下算法描述:
for(i=9;i>=1;i--){
for(j=0;j<=i-1;j++){
若array[j]<array[j+1],則交換array[j]與array[j+1];
}
}
下面,給出完整的源程序:/*源程序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]);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]);
}程序運行結果如下:
7.2函數(shù)間一維數(shù)組的傳遞
7.2.1一維數(shù)組元素地址的表示
在前面一章中介紹了指針的概念,我們知道指針就是地址,數(shù)據(jù)的指針就是數(shù)據(jù)的地址。在C語言中,地址可以和整型數(shù)進行加、減法運算。首先需要明確的是地址和整型數(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");
}程序運行結果如下:
以上程序的運行結果說明,&array[0]+1的結果還是一個地址,這個地址就是&array[1]的地址。當然,&array[1]-1的結果就是&array[0]。也就是說,一個數(shù)據(jù)的地址加1或減1,得到的是后一個或前一個數(shù)據(jù)的地址。由此可以推知在數(shù)組array中,&array[0]+i(0≤i≤9)等價于&array[i],進一步講,*(&array[0]+i)等價于array[i]。7.2.2利用指針變量訪問一維數(shù)組
C語言程序中的一維數(shù)組對應的是計算機內(nèi)存中一段連續(xù)的內(nèi)存。而數(shù)組的名字,實質是一個地址常量,這個地址常量和數(shù)組首元素的地址是相同的。下面看一個程序的例子:/*源程序7-6*/
#include"stdio.h"
main()
{
intarray[10];
if(array==&array[0])
printf("arrayequal&array[0]\n");
else
printf("arraydon'tequal&array[0]\n");
}程序運行結果如下:
以上程序的運行結果證明了在C語言中數(shù)組的名字確實等價于數(shù)組首元素的地址,即在以上程序中,array等價于&array[0]。結合前面的結論可以得出,在以上程序中,有如下等價關系:
array+i?等價于&array[i]
*(array+i)等價于array[i]其實,“array[i]”這種形式,可以看做是“*(array+i)”的簡略形式。從而可以得到一個結論:“*(地址+i)”這種形式的表達式可以等價地寫成“地址[i]”這種簡略形式。而這個地址,既可以是地址常量,如數(shù)組名,也可以是地址變量,也就是指針變量。比如下面的程序:/*源程序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");
}程序運行結果如下:
以上程序中,語句“p=array;”把數(shù)組首元素的地址賦給了指針變量p,從而使在程序中p與&array[0]等價。由此得到以下等價關系:
p+i?等價與&array[0]+i
*(p+i)等價于*(&array[0]+i)
p[i]等價于array[i]
把上面的結論簡單地歸納一下:在程序中,當把一個一維數(shù)組首元素的地址賦給一個指針變量時,這個指針變量就可以當做這個一維數(shù)組的名字來使用。7.2.3在函數(shù)間傳遞一維數(shù)組
函數(shù)是一段相對獨立的程序代碼,其功能是進行數(shù)據(jù)的處理和加工。它所處理和加工的數(shù)據(jù)的來源通常就是函數(shù)的形式參數(shù),其處理結果就是函數(shù)的返回值。也就是說,函數(shù)調(diào)用時,被調(diào)函數(shù)通過形式參數(shù)從主調(diào)函數(shù)中獲取需要處理和加工的數(shù)據(jù),經(jīng)過加工和處理后,再以返回值的形式傳遞給主調(diào)函數(shù),做進一步的處理。那么,當主調(diào)函數(shù)需要把一個一維數(shù)組交給被調(diào)函數(shù)時,應該如何解決呢?一種辦法就是主調(diào)函數(shù)把一維數(shù)組中每一個元素的值傳遞給被調(diào)函數(shù),這就意味著數(shù)組中有多少個元素,被調(diào)函數(shù)就要定義多少個形式參數(shù),顯然這不是一個好辦法。其實,因為一維數(shù)組在內(nèi)存中是連續(xù)的,主調(diào)函數(shù)只需要把數(shù)組首元素的地址傳遞給被調(diào)函數(shù),通過這個地址,被調(diào)函數(shù)就可以訪問到這個一維數(shù)組中的所有元素了。當然這里還有一個問題,就是被調(diào)函數(shù)只獲得一維數(shù)組首元素的地址是不夠的,它還必須獲得一維數(shù)組元素的個數(shù)。否則,它知道這個一維數(shù)組從哪里開始,而不知道在哪里結束,也是不能正確地訪問這個一維數(shù)組的。通過上面的分析可知,當主調(diào)函數(shù)要把一個一維數(shù)組傳遞給被調(diào)函數(shù)的時候,要向被調(diào)函數(shù)傳遞兩個值:數(shù)組首元素的地址和數(shù)組元素的個數(shù)。那么,被調(diào)函數(shù)的形式參數(shù)對應的就應該是一個指針變量和一個普通變量,而在被調(diào)函數(shù)中,這個指針變量是被當做一維數(shù)組來使用的。下面看一個程序的例子,這個程序的功能是將一個一維數(shù)組中存放的數(shù)據(jù)逆置,即數(shù)組中第一個元素和最后一個元素交換位置,第二個元素與倒數(shù)第二個元素交換位置,依次類推。/*源程序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;
}}
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");
reversal(array,10);
printf("Afterreversal:\n");
for(i=0;i<10;i++)
printf("%d\t",array[i]);
printf("\n");
}
程序運行結果如下:說明:
函數(shù)reversal的形式參數(shù)p是一個指針變量,用來接收一維數(shù)組首元素的地址,在函數(shù)中是被當做一維數(shù)組使用的。為了提高程序的可讀性,可以把它的定義寫成一維數(shù)組的形式,即該函數(shù)的首部可以寫成:
voidreversal(intp[],intn)
需要注意的是,p的定義雖然寫成了一維數(shù)組的形式,但它實際是一個指針變量,所以沒有必要定義元素的個數(shù);即使定義了元素的個數(shù),也是沒有意義的。主調(diào)函數(shù)中的調(diào)用語句“reversal(array,10)”也可以寫成“reversal(&array[0],10)”。
函數(shù)調(diào)用發(fā)生后,被調(diào)函數(shù)中p所代表的數(shù)組和主調(diào)函數(shù)中array所代表的數(shù)組實際上是同一個數(shù)組,這就是為什么被調(diào)函數(shù)中逆置了p數(shù)組,而主調(diào)函數(shù)中的array數(shù)組也被逆置了的原因。
讀者可以思考一下,把上面程序中main函數(shù)中的調(diào)用語句改成“reversal(array+3,5)”,可不可以?如果可以,則程序的運行結果是什么?
7.3二維數(shù)組
7.3.1二維數(shù)組的定義和初始化
數(shù)組是用來解決大批量同類型數(shù)據(jù)的存儲和處理問題的。有時候要處理的一批數(shù)據(jù)在邏輯上是分組的,例如在前面提到的成績統(tǒng)計問題中,假如要處理的不是一門課的成績,而是五門課程的成績,也就是說共有225個成績需要處理。這些成績數(shù)據(jù),可以按照課程來分組,共5組,每組45個;也可以按照學生來分組,共45組,每組5個。當然,也可以把這225個成績看做是5行45列或45行5列的矩陣。對于邏輯上有這種結構的數(shù)據(jù),直接使用一維數(shù)組存儲處理起來不是非常方便。C語言中提供了二維數(shù)組,可以很方便的存儲和處理類似這種結構的數(shù)據(jù)。二維數(shù)組的定義形式如下:
數(shù)據(jù)類型數(shù)組名[行數(shù)][列數(shù)];
例如如下語句:
inta[3][4];
該語句定義了一個二維數(shù)組a,共有12個存儲單元(元素),被邏輯地分成3行4列,每個存儲單元(元素)可以存放一個int型的數(shù)據(jù)。二維數(shù)組中的每個存儲單元(元素)是用兩個編號來確定的,借用行列式的術語,把這兩個編號分別稱為行編號和列編號。與一維數(shù)組相同,編號都是從0開始的。
上面定義的二位數(shù)組的邏輯結構和物理結構如圖7-1所示。圖7-1二維數(shù)組的邏輯結構和物理結構定義二維數(shù)組的同時,可以對其進行初始化,也就是給二維數(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};
以上程序中,對二維數(shù)組a的初始化是分行的,而對二維數(shù)組b的初始化是不分行的。不分行初始化是按照二維數(shù)組元素在內(nèi)存中的排列次序,依次把給定初值賦給數(shù)組元素。初始化的效果如圖7-2所示。圖7-2二維數(shù)組的初始化對二維數(shù)組初始化時,可以進行部分初始化,也就是給出二維數(shù)組中的部分元素的初始值,在這種情況下,沒有給定初始值的數(shù)組元素被編譯系統(tǒng)自動初始化為0,例如以下的程序片段:
inta[3][4]={{1,2},{5}};
floatb[2][5]={0.1,1.2,2.3};
按照以上初始化形式,對于數(shù)組a,元素a[0][0]、a[0][1]和a[1][0]被分別初始化為1、2和5,其他的元素被初始化為0;對于數(shù)組b,元素b[0][0]、b[0][1]和b[0][2]被分別初始化為0.1、1.2和2.3,其他元素被初始化為0。在對二維數(shù)組初始化時,可以省略行數(shù)的定義,這時候由編譯系統(tǒng)根據(jù)初始化的形式自動確定二維數(shù)組的行數(shù),例如以下的程序片段:
inta[][4]={{1,2},{5},{9}};
floatb[][5]={0.1,1.2,2.3,3.4,4.5,5.6,6.7};
對以上的初始化,編譯系統(tǒng)會自動確定數(shù)組a的行數(shù)為3,數(shù)組b的行數(shù)為2。需要注意的是,定義二維數(shù)組時,列數(shù)的定義在任何情況下都是不能省略的。7.3.2二維數(shù)組元素的引用
二維數(shù)組元素的引用類似于一維數(shù)組元素的引用,不同的是引用二維數(shù)組元素時,需要指定行編號和列編號(行下標和列下標),引用的形式為:
數(shù)組名[行編號][列編號]
下面通過一個例子來說明二維數(shù)組在程序中的應用。
例7-1
編寫一個程序,功能是輸入5個學生的成績,每個學生有3門功課的成績,計算每個學生的平均成績。
對于這個問題,首先考慮的是如何在程序中存儲這些成績。顯然,可以利用一個5行3列的二維數(shù)組來存放成績,在這個二維數(shù)組中,每行對應一個學生,每列對應一門課程。計算每個學生的平均成績,就是計算這個二維數(shù)組中每一行的平均值。根據(jù)這個思路編寫出如下源程序:/*源程序7-9*/
#include<stdio.h>
main()
{
floatscore[5][3],sum,avg;
inti,j;
for(i=0;i<5;i++){
printf("請輸入第%d個學生的成績:",i+1);
for(j=0;j<3;j++)
scanf("%f",&score[i][j]);}
for(i=0;i<5;i++){
sum=0;
for(j=0;j<3;j++)
sum=sum+score[i][j];
avg=sum/3;
printf("第%d個學生的平均成績?yōu)?%f\n",i+1,avg);
}
}程序運行結果如下:
二維數(shù)組特別適合處理數(shù)學中有關行列式的問題。
例7-2
編寫程序計算如下兩個行列式的乘積:
??
把第一個行列式命名為a,把第二個行列式命名為b,把乘積行列式命名為c。根據(jù)行列式乘法運算的定義,c是一個3行5列的行列式,其中:
在程序中定義了三個二維數(shù)組,分別存放行列式a、b和c。使用循環(huán),逐一計算乘積行列式每一個分量的值,編寫源程序如下:×1≤i≤3,1≤j≤5/*源程序7-10*/
#include<stdio.h>
main()
{
inta[3][4]={
{1,2,3,4},
{5,6,7,8},
{9,10,11,12},};
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++) 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");
}
}程序運行結果如下:
7.4函數(shù)間二維數(shù)組的傳遞
7.4.1二維數(shù)組元素的地址表示法
C語言中的二維數(shù)組,可以看做是由一維數(shù)組作為元素構成的一維數(shù)組,例如有如下定義:
inta[3][5];
以上語句,定義a是一個3行5列的二維數(shù)組。把這個二維數(shù)組的每一行看做是一個整體,也就是看做是一個元素,那么它就是一個有3個元素的一維數(shù)組。這個一維數(shù)組的每一個元素,都是一個有5個元素的一維數(shù)組。如果把數(shù)組a看做一維數(shù)組,它就是由a[0]、a[1]和a[2]三個元素組成的,那么自然就有表達式“a”等價于表達式“&a[0]”(因為一維數(shù)組名的值是一維數(shù)組首元素的地址)。表達式“&a[0]”代表的是數(shù)組中第一行的地址,這個地址加1還是一個地址,自然就是數(shù)組中第二行的地址了,即表達式“&a[0]+1”等價于表達式“&a[1]”。推廣一下,就有表達式“&a[0]+i”等價于表達式“&a[i]”(0≤i≤2),表達式“a+i”等價于表達式“&a[i]”。表達式“a[i]”代表的是什么呢?就是數(shù)組中行號為i的這一行,也就是一個一維數(shù)組,它的5個元素是a[i][0]、a[i][1]、…、a[i][4]。因此,就有表達式“a[i]”等價于“&a[i][0]”,表達式“a[i]+j”等價于表達式“&a[i][j]”(0≤i≤2,0≤j≤4)。綜合以上結論,可以有如下推導過程:
∵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]
這樣,在程序中訪問二維數(shù)組a的元素,就有如下三種形式:a[i][j]、*(a[i]+j)、*(*(a+i)+j)。在這三種形式中,表達式“*(*(a+i)+j)”是本質形式,表達式“a[i][j]”是簡略形式,表達式“*(a[i]+j)”是兩者之間的一種過渡形式。7.4.2利用行指針變量訪問二維數(shù)組元素
繼續(xù)前面的例子,對于如下定義的二維數(shù)組:
inta[3][5];
表達式“a”代表的是首行的地址,即“&a[0]”,那么可不可以把這個地址存放在一個指針變量當中呢?如果可以,這個指針變量該如何定義呢?來看下面的定義語句:
int(*pa)[5];在這個語句中定義了一個變量pa,“*”指定了它是一個指針變量,這個指針變量是用來存放連續(xù)的5個int型數(shù)據(jù)的地址的。可以把連續(xù)的5個整數(shù)看做是一個一維數(shù)組,也可以看做是某個二維數(shù)組中的一行,所以這個指針變量是一個指向一維數(shù)組的指針變量,或者說是一個行指針變量。表達式“a”的值恰好是連續(xù)的5個整數(shù)的地址,所以可以有如下賦值:
pa=a;
經(jīng)過以上賦值,就有:
*(*(pa+i)+j)
*(*(a+i)+j)
a[i][j]結合前面討論過的“*(地址+i)”可以簡寫成“地址[i]”的形式,表達式“*(*(pa+i)+j)”可以簡寫成“*(pa[i]+j)”,進一步簡寫成“pa[i][j]”。也就是說,行指針變量pa可以當作二維數(shù)組名使用。
行指針變量在聲明時要注意括號的應用,例如把變量pa的定義寫成如下形式:
int*pa[5];
因為“[]”的優(yōu)先級高于“*”,所以pa就被定義為一個有5個元素的數(shù)組了,這個數(shù)組中存放的是int型數(shù)組的地址。這時候,pa就不是一個行指針變量,而是一個指針數(shù)組。另外,對行指針變量賦值時必須賦予合適的地址,例如有如下語句:
pa=&a[0][0];
這個語句就是錯誤的,因為表達式“&a[0][0]”的值是“1個int數(shù)據(jù)的地址”,和變量pa的類型(5個int型數(shù)據(jù)的地址)是不同的,所以這個賦值從邏輯和語法上來說都是錯誤的。7.4.3函數(shù)之間二維數(shù)組的傳遞
在函數(shù)之間傳遞二維數(shù)組,只需要傳遞二維數(shù)組首行的地址。此時,主調(diào)函數(shù)的實參是二維數(shù)組名,而與之對應的被調(diào)函數(shù)的形參應該是行指針變量。同時,主調(diào)函數(shù)還需要向被調(diào)函數(shù)傳遞二維數(shù)組的行數(shù)。下面看一個程序的例子。
例7-3
把方陣的行和列交換。例如一個5階方陣行和列交換前后如圖7-3所示。圖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;
}}
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()
{
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}
};
printf("Beforeinversing:\n");
outputMatrix(a,5);
inverseMatrix(a,5);
printf("Afterinversing:\n");
outputMatrix(a,5);
}程序運行結果如下:
習題
1.編寫函數(shù)fun,函數(shù)原型為:intfun(intscore[],intm,intbelow[])。它的功能是:m個人的成績存放在score數(shù)組中,將低于平均分的人數(shù)作為函數(shù)值返回,將低于平均分的分數(shù)放在below所指的數(shù)組中。例如,當score數(shù)組中的數(shù)據(jù)為10、20、30、40、50、60、
溫馨提示
- 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. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025年浙科版選擇性必修3化學下冊月考試卷
- 2025年浙科版選修6地理下冊階段測試試卷含答案
- 2025年人教A版九年級歷史下冊階段測試試卷含答案
- 2025年岳麓版八年級地理下冊階段測試試卷含答案
- 2025年滬科版拓展型課程化學上冊月考試卷
- 二零二五年度出口合同履約環(huán)節(jié)的知識產(chǎn)權侵權監(jiān)測與應對合同3篇
- 2025年度生態(tài)環(huán)保型幕墻材料采購與施工合同4篇
- 2025年度車輛抵押貸款合同示范文本4篇
- 2025年度個人小額貸款合同簽訂流程詳解4篇
- 二零二五版智能安防系統(tǒng)采購與安裝合同4篇
- 中國末端執(zhí)行器(靈巧手)行業(yè)市場發(fā)展態(tài)勢及前景戰(zhàn)略研判報告
- 北京離婚協(xié)議書(2篇)(2篇)
- 2025中國聯(lián)通北京市分公司春季校園招聘高頻重點提升(共500題)附帶答案詳解
- Samsung三星SMARTCAMERANX2000(20-50mm)中文說明書200
- 2024年藥品質量信息管理制度(2篇)
- 2024年安徽省高考地理試卷真題(含答案逐題解析)
- 廣東省廣州市2024年中考數(shù)學真題試卷(含答案)
- 高中學校開學典禮方案
- 內(nèi)審檢查表完整版本
- 3級人工智能訓練師(高級)國家職業(yè)技能鑒定考試題及答案
- 孤殘兒童護理員技能鑒定考試題庫(含答案)
評論
0/150
提交評論