文章目錄
先來看一個需求,超女選秀一共有5人蔘加,輸入每位超女的體重並保存在變量中,最後計算出超女的的平均體重。
示例(book40.c)
/*
* 程序名:book40.c,此程序用於演示沒有數組的情況下的多個變量求和
* 作者:C語言技術網(www.freecplus.net) 日期:20190525
*/
#include <stdio.h>
int main()
{
double aa,bb,cc,dd,ee; // 定義5個變量存放5名超女的體重
aa=bb=cc=dd=ee=0;
printf("請輸入第1名超女的體重(公斤):");
scanf("%lf",&aa);
printf("請輸入第2名超女的體重(公斤):");
scanf("%lf",&bb);
printf("請輸入第3名超女的體重(公斤):");
scanf("%lf",&cc);
printf("請輸入第4名超女的體重(公斤):");
scanf("%lf",&dd);
printf("請輸入第5名超女的體重(公斤):");
scanf("%lf",&ee);
printf("超女的平均體重是:%lf\n",(aa+bb+cc+dd+ee)/5);
}
如果有100名超女,這個程序將會很長很煩鎖。
一、數組
數組(array)是一組數據類型相同的變量,可以存放一組數據,它定義的語法是:
數據類型 數組名[數組長度];
例如:
double money[20];
money是一個數組,包含了20個元素,每個元素都一個double類型的變量,可以通過下標訪問數組中元素(element),數組下標的編號從0開始,數組的第1個元素是money[0],第2個元素是money[1],以此類推,直到第20個元素money[19]。
給每個元素賦double類型的值,可以這樣寫:
money[0] = 10.55;
money[1] = 32.54;
money[2] = 2055.65;
……
money[19] = 2055.65;
定義數組的時候,數組的長度必須是整數,可以是常量,也可以是變量。
數據的下標也必須是整數,可以是常量,也可以是變量。
使用數組元素和使用同類型的變量一樣。
scanf("%lf", &money[4]); // 把一個值讀入數組的第5個元素
數組的類型可以是任意數據類型。
int no[22]; // 可儲存22個int類型整數的數組
char actors[26]; // 可儲存26個字符的數組
double big[500]; // 可儲存500個double類型整數的數組
二、佔用內存的大小
我們已經知道如何獲取單個變量佔用內存大小的方法。
int ii; // 定義一個整型變量
printf("sizeof(ii)=%d\n",sizeof(ii)); // 輸出結果:sizeof(ii)=4
printf("sizeof(ii)=%d\n",sizeof(int)); // 輸出結果:sizeof(ii)=4
數組是有多個變量組成,佔用內存總空間的大小爲多個變量佔用的內存空間之和,用sizeof(數組名)就可以得到整個數組佔用內存的大小,如下:
int ii[10]; // 定義一個整型數組變量
printf("sizeof(ii)=%d\n",sizeof(ii)); // 輸出結果:sizeof(ii)=40
三、數組的初始化
採用memset函數對數組進行初始化,如下:
int no[10];
memset(no,0,sizeof(no));
第一個參數是數組名,第二個參數填0,第三個參數是數組佔用的內存總空間,用sizeof(變量名)獲取。
四、注意事項
1)定義數組的時候,數組的長度必須是整數,可以用常量和變量。
int size=100;
int numbers[size];
2)使用數組的時候,數組的下標也必須是整數,可以用常量和變量。
3)使用數組的時候,編譯器不會檢查數組的下標是否正確,但是在程序中下標一定不能越界,如果程序運行時數組下標越界,就相當於訪問了其它程序的內存,可能會導致程序異常中斷(Core dump),後果非常嚴重。
示例(book41.c)
/*
* 程序名:book41.c,此程序演示數組下標越界的後果
* 作者:C語言技術網(www.freecplus.net) 日期:20190525
*/
#include <stdio.h>
#include <string.h>
int main()
{
int ii=0;
int sum[5]; // 定義一維數組
for (ii=0;ii<100;ii++)
{
printf("ii=%d\n",ii);
sum[ii]=ii;
}
return 0;
}
運行效果
段錯誤,就是程序非法操作內存,引起程序的崩潰。
如果數組的下標越界了,是不是一定會引起程序的崩潰呢?不一定,如果把book41.c的循環改爲6,可能就不會出現段錯誤。
五、在for循環中數組
在學習了數組的知識以後,本章節開始時的那個需求有了更好的解決方法,程序book40.c必須修改。
示例(book42.c)
/*
* 程序名:book42.c,此程序演示採用for循環語句和數組結合使用
* 作者:C語言技術網(www.freecplus.net) 日期:20190525
*/
#include <stdio.h>
#include <string.h>
int main()
{
int ii=0; // 用於循環的計數器
int total=5; // 超女的總人數,初始化爲5
double weight[total]; // 定義數組,用於存放超女的體重
double sum=0; // 存放超女體重的和
memset(weight,0,sizeof(weight)); // 初始化數組爲0
// 循環輸入超女的體重,並計算體重的總和
for (ii=0;ii<total;ii++)
{
printf("請輸入第%d名超女的體重:",ii+1); // 輸入提示信息
scanf("%lf",&weight[ii]); // 接受從鍵盤輸入的體重
sum=sum+weight[ii]; // 計算超女體重的和
}
printf("超女的平均體重是:%lf\n",sum/total); // 輸出平均體重
}
運行效果
for循環提供了一個簡單直接的方法來使用數組下標,使用數組和for循環處理數據,這比使用5個單獨的scanf語句方便得多。不管是5個還是100個超女,程序也不會再增加代碼。
六、二維數組
二維數組定義的語法是:
數據類型 數組名[第一維的長度][第二維的長度];
在我們現實生活中,二維數組到處都是,例如超女選秀,一共有5個小組,每組4人,如果要指明某位超女,必須同時指明該超女的小組編號和她在組內序號。
int girl[5][4];
girl[0][0] girl[0][1] girl[0][2] girl[0][3]
girl[1][0] girl[1][1] girl[1][2] girl[1][3]
girl[2][0] girl[2][1] girl[2][2] girl[2][3]
girl[3][0] girl[3][1] girl[3][2] girl[3][3]
girl[4][0] girl[4][1] girl[4][2] girl[4][3]
也可以將二維數組看成一個座標系,有 x 軸和 y 軸,要想在一個平面中確定一個點,必須同時指定 x 和 y 值。
二維數組的初始化也是用memset,例如:
memset(girl,0,sizeof(girl));
把本章節剛開始的那個需求增加一點難度:超女選秀有3個組,每組有5名選手,請提供一個界面,輸入每個超女的體重,最後計算每組的超女的平均體重。
示例(book43.c)
/*
* 程序名:book43.c,此程序演示採用for循環語句和二維數組結合使用
* 作者:C語言技術網(www.freecplus.net) 日期:20190525
*/
#include <stdio.h>
#include <string.h>
int main()
{
int ii=0; // 用於組別循環的計數器
int jj=0; // 用於超女人數循環的計數器
int class=3; // 小組總數,初始化爲3
int total=5; // 每個組超女的總人數,初始化爲5
double weight[class][total]; // 定義二維數組,存放超女的體重
double sum[class]; // 定義一維數組存放超女體重的和
memset(weight,0,sizeof(weight)); // 初始化數組爲0
memset(sum,0,sizeof(sum)); // 初始化數組爲0
// 採用兩個循環,第一級循環爲小組數,第二級循環爲超女人數
for (ii=0;ii<class;ii++)
{
for (jj=0;jj<total;jj++)
{
printf("請輸入第%d組第%d名超女的體重:",ii+1,jj+1);
scanf("%lf",&weight[ii][jj]); // 接受從鍵盤輸入的體重
sum[ii]=sum[ii]+weight[ii][jj]; // 計算小組超女體重的和
}
}
}
運行效果
七、多維數組
從二維數組可以類推出多維數組的用法,在實際開發中,二維以上的數組應用場景很少。
對初學者來說,建議先不要把這個問題複雜化,能掌握一維和二維數組就可以了,等功力提升之後,會發現多維數組其實也很容易。
八、字符串
1、字符串的概念
字符串就是一個以空字符’\0’結束的字符數組,是一個特別的字符數組,這是約定,是規則。
空字符’\0’也可以直接寫成0。
因爲字符串需要用0結束,所以在定義字符串的時候,要預留多一個字節來存放0。
char name[21]; // 定義一個最多存放20個字符或10個漢字的字符串
2、字符串的初始化
字符串是數組,當然可以用初始化數組的方法來初始化字符串。
char strname[21];
memset(strname,0,sizeof(strname));
3、字符串的賦值
如果想在strword中存入字符串“hello”,可以用strcpy函數,也可以採用以下代碼:
strcpy(strword,"hello");
// 或者用以下代碼
char strword[21];
memset(strword,0,sizeof(strword));
strword[0]='h';
strword[1]='e';
strword[2]='l';
strword[3]='l';
strword[4]='o';
strword[5]='\0'; // 或者 name[5]=0;
4、關於字符串結束符0的討論
您可能會問,如果字符串不用0結束,會有什麼樣的結果,我們用代碼來演示一下。
示例(book44.c)
/*
* 程序名:book44.c,此程序用於演示字符串沒有用0結束的後果
* 作者:C語言技術網(www.freecplus.net) 日期:20190525
*/
#include <stdio.h>
#include <string.h>
int main()
{
char name[3];
memset(name,0,sizeof(name));
name[0]='a';
name[1]='b';
name[2]='c';
printf("name=%s=\n",name);
}
運行效果
可以看到,輸出abc之後,有亂碼,並且每次執行程序輸出的結果不可預知。
您可能還會問,如果字符串以0結束了,但是後面的內容並不是0,怎麼辦?後面的內容將被丟棄。
5、字符串數組
以0結束的一維字符數組是一個字符串。
char strname[21]; // 可以存放20個字符的字符串
memset(strname,0,sizeof(strname));
strcpy(strname,"我真的可以存十個漢字");
給一維字符數組加上一維,就是字符串數組了。
char strname[10][21]; // 10個字符串,每個字符串可以存放20個字符
memset(strname,0,sizeof(strname));
strcpy(strname[0],"坦已");
strcpy(strname[1],"褒似");
strcpy(strname[2],"西施");
strcpy(strname[3],"王昭君");
strcpy(strname[4],"貂嬋");
……
strcpy(strname[9],"陳圓圓");
十、課後作業
1)編寫示例程序,從界面上輸入一個字符串,計算字符串的長度。如果輸入的是"abcdaaf",顯示的結果是7。
2)編寫示例程序,從界面上輸入一個字符串,把字符串的每個字符從左到右一個一個的顯示出來,如果輸入的是"abcdaaf",顯示的結果是:a b c d a a f。
3)編寫示例程序,從界面上輸入一個字符串,把字符串的每個字符從右到左一個一個的顯示出來,如果輸入的是"abcdaaf",顯示的結果是:f a a d c b a。
4)編寫示例程序,某班有10個學生,定義一個一維數組,從界面上輸入每個學生的成績,最後顯示這個班的平均成績。
5)編寫示例程序,某年級有兩個班,每班有8名學生,定義一個二維數組,從界面上輸入每個學生的成績,最後顯示每個班的平均成績和年級的平均成績。
6)編寫示例程序,定義一個可以存放10個字符串的數組,字符串的有效長度是30個字符,從界面上輸入10個字符串並存放在數組中,然後把這10個字符串顯示出來。
以下題難難度較大,可以等到以後功力提升的時候再做。
7)如果還覺得不過隱,可以挑戰一下三維數組,某學校有兩個年級,每個年級有三個班,每個班有四名學生,從界面上輸入每個學生的成績,最後顯示每個班的平均成績、年級的平均成績和全校的平均成績。
別玩三維以上的數組,沒什麼意義。
十一、版權聲明
C語言技術網原創文章,轉載請說明文章的來源、作者和原文的鏈接。
來源:C語言技術網(www.freecplus.net)
作者:碼農有道
如果文章有錯別字,或者內容有錯誤,或其他的建議和意見,請您留言指正,非常感謝!!!