當需要處理的資料比較多時,僅依靠前面的知識是不夠的,即使簡單的問題也可能需要比較複雜的程式來處理生的某門課程的成績,打印出低於平均分的學生序號與成績
我們需要把一大批具有相同性質的資料組合成一個新型別的變數,可以用簡單的程式(比如迴圈50次)對這個新變數的各個分量進行相同的處理,每個分量仍然保留單個變數的所有性質。
工具/原料
Dev-c++
方法/步驟
一、為什麼要使用陣列
例題:輸入50個學生的某門課程的成績,打印出低於平均分的學生序號與成績。
【分析】在解決這個問題時,雖然可以通過一個變數來累加讀入的50個成績求出學生的總分,進而求出平均分。但因為只有讀入最後一個學生的分數後才能求得平均分,並且要求打印出低於平均分的學生序號和成績,故必須把50個學生的成績都保留起來,然後逐個和平均分比較,把低於平均分的成績打印出來。如果,用簡單變數a1,a2,…,a50儲存這些資料,要用50個變數儲存輸入的資料,程式片斷如下:
cin>>a1>>a2>>…>>a10;
…
cin>>a41>>a42>>…>>a50;
注意,如果真正要像上面這樣編寫程式,則上面的所有省略號必須用完整的語句寫出來。可以看出,這樣的程式是多麼繁瑣。如果說處理的資料規模達到成千上萬,上面的例子單單讀入就會異常複雜,電腦的優勢沒有得到體現。
從以上的討論可以看出,如果只使用簡單變數處理大量資料,就必須使用大量只能單獨處理的變數,即使是簡單問題也需要編寫冗長的程式。
如果能像數學中使用下標變數ai形式表示這50個數,則問題就容易實現。在C++語言中,具有下標性質的資料型別是陣列。如果使用陣列,上面的問題就變得十分簡單、清晰。例如,讀入50個學生的成績,只需寫如下語句即可:
for (int i=1;i<=50;++i)
cin>>a[i];
在這裡引用了帶下標的變數(分量變數稱為陣列元素)a[i]來代替a1,a2…,a50,方括號中的i稱為下標,當迴圈變數i=1時a[i]就是a[1];當i=2時a[i]就是a[2]……;當i=50時a[i]就是a[50]。輸入的時候,讓i從1變化到50,迴圈體內輸入語句中的a[i]也就分別代表了a1,a2…,a50這50個帶下標的變數。這樣上述問題的程式可寫為:
tot = 0; // tot儲存50個學生的總分
for (int i=1;i<=50;++i) // 迴圈讀入每一個學生的成績,並把它累加到總分中
{
cin>>a[i];
tot+=a[i];
}
ave= tot/50; //計算平均分
for (int i=1;i<=50;++i)
if (a[i]
//如果第i個同學成績小於平均分,則將輸出這個學生的序號和成績。
要在程式中使用下標變數,必須先說明這些下標變數的整體為陣列,即陣列是若干個同名(如上面的下標變數的名字都為a)下標變數的集合,這些變數的型別全部一致。
二、一維陣列的定義
當陣列中每個元素只帶有一個下標時,我們稱這樣的陣列為一維陣列。
陣列的定義格式如下:
型別識別符號 陣列名[常量表達式]
說明:
①陣列名的命名規則與變數名的命名規則一致。
②常量表達式表示陣列元素的個數。可以是常量和符號常量,但不能是變數。
例如:
int a[10]; //陣列a定義是合法的
int b[n]; //陣列b定義是非法的
三、一組陣列的引用
通過給出的陣列名稱和這個元素在陣列中的位置編號(即下標),程式可以引用這個陣列中的任何一個元素。
一維陣列元素的引用格式:
陣列名[下標]
例如:
int a[10];
其中,a是一維陣列的陣列名,該陣列有10個元素,依次表示為:
a[0],a[1],a[2],a[3],a[4],a[5],a[6],a[7],a[8],a[9]。
需要注意的是:a[10]不屬於該陣列的空間範圍。
當在說明部分定義了一個數組變數之後,C++編譯程式為所定義的陣列在記憶體空間開闢一串連續的儲存單元。例如:
上例中的a陣列在記憶體的儲存如表所示:
a陣列共有10個元素組成,在記憶體中10個數組元素共佔10個連續的儲存單元。a陣列最小下標為0,最大下標9。按定義a陣列所有元素都是整型變數。
再次提醒注意:型別和變數是兩個不同概念,不能混淆。就陣列而言,程式的執行部分使用的不是陣列型別而是陣列變數。
說明:
(1)下標可以是整型常量或整型表示式。如果使用表示式作為下標,就要計算表示式的值以確定下標。
(2)C++語言中,每個陣列第一個元素的下標都是0,因此第一個元素為第0個數組元素。
(3)C++語言只能逐個引用陣列元素,而不能一次引用整個陣列。
例如:int a[100],b[100]; a=b;這樣的寫法是非法的。
(4)陣列元素可以像同類型的普通變數那樣使用,對其進行賦值和運算的操作,和普通變數完全相同。
例如: c[10]=34;實現了給c[10]賦值為34。
四、一維陣列的初始化
陣列的初始化可以在定義時一併完成。格式:
型別識別符號 陣列名[常量表達式]={值1,值2,…}
例如:
int a[5]={1,2,3,4,5}
說明:
(1)在初值列表中可以寫出全部陣列元素的值,也可以寫出部分。例如,以下方式可以對陣列進行初始化:
int x[10]={0,1,2,3,4};
該方法一次僅對陣列的前5個元素依次進行初始化。
(2)對陣列元素全部初始化為0,可以簡寫為:{0}。
例如:
int a[5]={0}; 將陣列a的5個元素都初始化為0。
五、一維陣列的應用
例5.1 輸入n個數,要求程式按輸入時的逆序把這n個數打印出來,已知整數不超過100個。也就是說,按輸入相反順序列印這n個數。
【分析】我們可定義一個數組a用以存放輸入的n個數, 然後將陣列a中的內容逆序輸出。
#include
int a[100];
int main()
{
int x,n=0;
while(scanf("%d",&x)==1) a[n++]=x; //相當{a[n]=x;n++;}
for (int i=n-1;i>=1;--i)
printf("%d ",a[i]); //注意%d後面有一個空格,保證行首行尾均無空格
printf("%d\n",a[0]);
return 0;
}
【說明】:
語句int a[100]聲明瞭一個包含100個整型變數的陣列,它們是:a[0],a[1],a[2],…,a[99]。注意,沒有a[100]。在上述程式中,陣列a被宣告在main函式的外面。只有放在外面時,陣列a才可以開得很大;放在main函式內時,陣列稍大就會異常退出。。
陣列不能夠進行賦值操作:如果宣告的是int a[MAXN],b[MAXN],是不能賦值b=a的(Pascal語言可以的)。如果要從陣列a複製k個元素到陣列b,可以這樣做:memcpy(b,a,sizeof(int)*k)。如果陣列a和b都是浮點型的,複製時要寫成memcpy(b,a,sizeof(double)*k)。如果需要把陣列a全部複製到陣列b中,可以寫得簡單一些:memcpy(b,a,sizeof(a))。使用memcpy函式要包含標頭檔案cstring。
注意事項
注意一維陣列的第一個元素位數是0!