2019-02-28 計算機二級C語言程序設(shè)計之數(shù)組(上)

參考資料:
高教版《全國計算機等級考試二級教程——C語言程序設(shè)計》
《21天學通C語言》

數(shù)組的基本概念

數(shù)組是一組帶索引的數(shù)據(jù)存儲位置碧绞,各位置的名稱相同冷冗,以不同的下標索引來區(qū)分催跪。下標(也叫作索引)指的是數(shù)組變量名后面方括號中的數(shù)字。數(shù)組中的每個存儲位置被稱為數(shù)組元素夷野。

與其他C語言的變量類似懊蒸,在使用數(shù)組前必須聲明它。

一維數(shù)組的定義和一維數(shù)組元素的引用

一維數(shù)組的定義

當數(shù)組中的每個元素只帶有一個下標時悯搔,稱這樣的數(shù)組為一維數(shù)組骑丸。

在C語言中,定義一維數(shù)組的語句一般形式如下:

類型名 數(shù)組名[整型常量表達式],……妒貌;

例如:

int a[8];

在這里通危,int是類型名,a[8]就是一維數(shù)組說明符灌曙。

以上語句說明了以下幾點:

  1. 定義了一個名為a的一維數(shù)組菊碟。
  2. 方括號中的8規(guī)定了a數(shù)組含有8個元素,它們是a[0],a[1],a[2]……
  3. 類型名int規(guī)定了a數(shù)組中每個元素都是整型在刺,在每個元素中只能存放整型數(shù)逆害。
  4. 每個元素只有一個下標。每個數(shù)組中第一個元素的下標總為0(稱為數(shù)組下標的下界)蚣驼,因此魄幕,以上a數(shù)組中的最后一個元素的下標是7(稱為數(shù)組下標的上界)。
  5. C編譯程序?qū)閍數(shù)組在內(nèi)存中開辟名為a[0]-a[7]的8個連續(xù)的存儲單元颖杏,可以用這些名字來直接引用各存儲單元纯陨。

在一個定義數(shù)組的語句中,可以有多個數(shù)組說明符留储,它們之間用逗號隔開翼抠,如:

double w[22], v[100], u[5];

數(shù)組說明符和普通變量名可同時出現(xiàn)在一個類型定義語句中,如:

char c1, c2, carr[81];

注意:數(shù)組說明符的一對方括號中只能是整型常量或整型常量表達式获讳。

聲明數(shù)組時机久,可以用字面常量或通過#define創(chuàng)建的符號常量來指定元素的個數(shù),因此以下兩種聲明方式等價:

#define MONTHS 12
int array[MONTHS];

int array[12];

注意:大部分編輯器都不允許用const關(guān)鍵字創(chuàng)建的符號常量來聲明數(shù)組的元素赔嚎。

以下語句在編譯時會報錯:

const int MONTHS = 12;
int array[MONTHS];

一維數(shù)組元素的引用

一維數(shù)組的引用形式如下:

數(shù)組名 [下標表達式]

例如膘盖,若有以下定義語句:

double x[8];

則x[0],x[j]尤误,x[i + k]都是對x數(shù)組中元素的合法引用形式侠畔。

  • 一個數(shù)組元素實質(zhì)上就是一個變量名,代表內(nèi)存中的一個存儲單元损晤。
  • 一個數(shù)組占有一串連續(xù)的存儲單元软棺。
  • 在C語言中,一個數(shù)組不能整體引用尤勋。數(shù)組名中存放的是一個地址常量喘落,它代表整個數(shù)組的首地址茵宪。

一維數(shù)組的初始化

一維數(shù)組初始化的形式為:

int a[8] = {0,1,2,3,4,5,6,7};

以上語句給a[0]賦初值0,給a[1]賦初值1……給a[7]賦初值7瘦棋。

當所賦初值少于所定義數(shù)組元素的個數(shù)時稀火,將自動給后面的元素補以初值0。

對于字符型數(shù)組也同樣補以初值0赌朋。例如凰狞,以下兩個定義相等:

char c[5] = {'@'};
char c[5] = {'@', '\0', '\0', '\0', '\0'};

當所賦初值多與所定義數(shù)組元素的個數(shù)時,在編譯時會報錯沛慢。

通過賦初值定義數(shù)組的大小

C語言規(guī)定可以通過賦初值來定義數(shù)組的大小赡若,這時數(shù)組說明符的一對方括號中可以不指定數(shù)組的大小祟敛。例如该窗,以下兩條語句等價:

int a[] = {0, 0, 0, 0, 0};
int a[5] = {0};

一維數(shù)組的使用

數(shù)組元素可用于程序中任何相同類型的非數(shù)組變量的地方秕重,通過使用數(shù)組名和帶方括號的數(shù)組下標來訪問數(shù)組中的各元素诸典。

例如望侈,以下語句將89.95存儲在第2個數(shù)組元素中:

expenses[1] = 89.95;

下面的語句將數(shù)組元素expenses[11]中存儲的值的副本賦給expenses[10]數(shù)組元素:

expenses[10] = expenses[11];

程序中經(jīng)常會將整型變量或表達式作為下標搂蜓,或者甚至是另一個數(shù)組元素漏策,例如:

float expenses[100];
int a[10];
//其他語句已省略
expenses[i] = 100;      //i是一個整型變量
expenses[2 + 3] = 100;  //expenses[2 + 3]相當于expenses[5]
expenses[a[2]] = 100;   //a[]是一個數(shù)組

如果有一個整型數(shù)組a[]胁镐,其中元素a[2]中存儲8圾另,則以下兩種寫法的效果相同:

expenses[a[2]] = 100;

expenses[8] = 100;

一維數(shù)組和指針

一維數(shù)組和數(shù)組元素的地址

在C語言中霸株,在函數(shù)體中或在函數(shù)外部定義的數(shù)組名可以認為是一個存放地址值的指針變量名,其中的地址值是數(shù)組第一個元素的地址集乔,定義數(shù)組時的類型即是此指針變量的基類型去件,數(shù)組名是指向數(shù)組第一個元素的指針。

注意:這個指針變量中的地址值不可改變扰路,也就是說不可以給數(shù)組名重新賦值尤溜,可以認為數(shù)組名是一個地址常量。

比如汗唱,定義:

float a[10], *p, x;

語句a = &x;或a++都是非法的宫莱,因為不能給a重新賦地址值。a將永遠指向數(shù)組的首地址哩罪。

但是授霸,可以聲明一個指針變量并將其初始化以指向該數(shù)組。例如际插,下面的代碼聲明并初始化指針變量p_array碘耳,把array數(shù)組首元素的地址存儲在p_array中:

int array[100];
int *p_array = array;
//其他代碼已省略

因為p_array是一個指針變量,所以可以修改它的值讓它指向別處框弛,或指向array[]的其他元素辛辨。

可以用對數(shù)組名加一個整數(shù)的辦法,來依次表達該數(shù)組中不同元素的地址。例如:

int k;
for(k = 0; k < 10; k++)
    p = a + k;

在循環(huán)中并沒有改變a的值斗搞,但通過表達式a+k指攒,逐一給出了a數(shù)組中每個元素的地址,使p依次指向a數(shù)組中的每一個元素僻焚。

可以通過以下循環(huán)從終端讀入數(shù)據(jù)依次放入a數(shù)組中:

for(k = 0; k <10; k++)
    scanf("%d", a + k);

語句p = &a[0]和p = a都是合法的允悦。這兩條語句都使指針變量p指向數(shù)組a的首地址。

以下循環(huán)語句中溅呢,由于在進入循環(huán)時使指針變量p指向了a數(shù)組的首地址,p++將使指針變量p依次指向a數(shù)組中的每一個元素:

for(p = a, k = 0; k < 10; k++)
    p++;

下面的兩條循環(huán)語句也可以從終端讀入數(shù)據(jù)依次放入a數(shù)組中猿挚,這種操作在一些簡單的OJ題目中比較常見:

for(p = a, k = 0; k < 10; k++)
    scanf("%d", p++);

for(p = a; p - a < 10; p++)
    scanf("%d", p);

例:

以下程序通過聲明short咐旧、float、double類型的數(shù)組并且依次顯示數(shù)組元素的地址绩蜻,演示了不同類型數(shù)組的元素和地址之間的關(guān)系铣墨。

#include <stdio.h>

//聲明一個計數(shù)器變量和三個數(shù)組
int chr;
short array_s[10];
float array_f[10];
double array_d[10];

int main(void)
{
    //打印表頭
    printf("\t\tShort\t\tFloat\t\tDouble");
    printf("\n============================================================");
    //打印各數(shù)組元素的地址
    for(ctr = 0; ctf < 10; ctr++)
        printf("\nElement %d:\t%ld\t%ld\t%ld", ctr, &array_s[ctr], &array_f[ctr], &array_d[ctr]);
    printf("\n============================================================");
    
    return 0;
}

輸出:

                Short           Float           Double
============================================================
Element 0:      13084064        13084000        13083904
Element 1:      13084066        13084004        13083912
Element 2:      13084068        13084008        13083920
Element 3:      13084070        13084012        13083928
Element 4:      13084072        13084016        13083936
Element 5:      13084074        13084020        13083944
Element 6:      13084076        13084024        13083952
Element 7:      13084078        13084028        13083960
Element 8:      13084080        13084032        13083968
Element 9:      13084082        13084036        13083976
============================================================

可以看出,相鄰兩個short類型的元素的間隔是2字節(jié)办绝,相鄰兩個float類型的元素的間隔是4字節(jié)伊约,相鄰兩個double類型的元素的間隔是8字節(jié)。

通過數(shù)組的首地址引用數(shù)組元素

a是a數(shù)組元素的首地址孕蝉,a的值等于&a[0]屡律,則a + 1的值等于&a[1]……a+9的值等于&a[9]。

可以通過間接訪問運算符“*”來引用地址所在的存儲單元降淮,因此對于數(shù)組元素a[0]超埋,可以用表達式*&a[0]來引用,也可以用*(a + 0)或*a來引用佳鳖。

因此霍殴,可以通過以下語句逐個輸出a中數(shù)組元素的值:

for(k = 0; k < 10; k++)
    printf("%4d", *(a + k));

此語句與以下語句等效:

for(k = 0; k < 10; k++)
    printf("%4d", a[k]);

通過指針引用一維數(shù)組元素

若有:

float a[10], *p, k;
p = a;      //或p = &a[0];

可以使用間接訪問運算符,通過指針p來引用a數(shù)組中的元素系吩。

對于數(shù)組元素a[0]来庭,可以用表達式*(p + 0),即*p來引用穿挨;同理月弛,對于數(shù)組元素a[1],可以用表達式*(p + 1)來引用科盛。

因此尊搬,可以通過以下語句逐個輸出a數(shù)組元素的值:

for(p = a, k = 0; k < 10; k++)
    printf("%4d", *(p + k));

以上語句與以下語句等效:

for(k = 0; k < 0; k++)
    printf("%4d", a[k]);

以上兩種寫法都沒有移動指針p⊥晾裕可以用以下兩種方式逐步移動指針p來引用a數(shù)組中的每一個元素佛寿,逐個輸出a數(shù)組元素的值:

for(p = a, k = 0; k < 10; k++)
    printf("%4d", *p++);

for(p = a; p - a < 10; p ++)
    printf("%4d", *p);

用帶下標的指針變量來引用一維數(shù)組元素

若有:

int *p, s[10], i;       //0≤i<10
p = s;

已經(jīng)知道:

  • 可以用&s[i]、s + i和p + i來表示s[i]的地址
  • 可以用s[i]、*(s + i)冀泻、*(p + i)來表示數(shù)組元素s[i]

所以常侣,*(p + i)也可以用p[i]來表示。

事實上弹渔,在C語言中胳施,方括號是一種運算符。

因此肢专,當p指向s數(shù)組的首地址時舞肆,表示數(shù)組元素s[i]的表達方式有:

  1. s[ i ]
  2. *(s + i)
  3. *(p + i)
  4. p[ i ]

注意:s是不可變的,p中的地址是可變的博杖。

函數(shù)之間對一維數(shù)組和數(shù)組元素的引用

數(shù)組元素作為實參

調(diào)用函數(shù)時椿胯,數(shù)組元素可以作為實參傳遞給形參,每個數(shù)組元素實際上代表內(nèi)存中的一個存儲單元剃根,所以對于的形參必須是類型相同的變量哩盲。

數(shù)組名作為實參

數(shù)組名也可以作為實參傳遞,但數(shù)組名本身是一個地址值狈醉,所以對應(yīng)的形參就應(yīng)當是一個指針變量廉油,其基類型必須與數(shù)組的類型一致。

在函數(shù)中苗傅,可以通過此指針變量來引用調(diào)用函數(shù)中對應(yīng)的數(shù)組元素抒线,從而對調(diào)用函數(shù)中對應(yīng)的數(shù)組元素進行操作二改變其中的值。

例1(高教版《全國計算機等級考試二級教程——C語言程序設(shè)計》P117 例9.2):

編寫程序渣慕,通過一個函數(shù)給主函數(shù)中定義的數(shù)組輸入若干大于或等于0的整數(shù)十兢,用負數(shù)作為輸入結(jié)束的標志;調(diào)用另一個函數(shù)輸出該數(shù)組中的數(shù)據(jù)摇庙。

#include <stdio.h>
#define M 100

void arrout(int *, int);    //函數(shù)說明語句旱物,此函數(shù)用以輸出數(shù)組中的值
int arrin(int *);           //函數(shù)說明語句,此函數(shù)用以給數(shù)組輸入數(shù)據(jù)

int main(void)
{
    int s[M], k;
    k = arrin(s);
    arrout(s, k);
    return 0;
}

int arrin(int *a)
{
    int i = 0, x;
    scanf("%d", &x);
    while(x >= 0)
    {
        *(a + 1) = x;
        i++;
        scanf("%d", &x);
    }
    return i;
}

void arrout(int *a, int n)
{
    int i;
    for(i = 0; i < n; i++)
        printf(((i + 1) % 5 == 0) ? "%4d\n" : *(a + 1));    //根據(jù)i的值來確定不同的格式串
    printf("\n");
}

當數(shù)組名作為實參時卫袒,對應(yīng)的形參除了是指針外宵呛,還可以有其他形式。上例中arrin函數(shù)的首部還可以寫成以下形式:

int arrin(int a[])
int arrin(int a[M])

此外夕凝,通過指針引用數(shù)組元素時宝穗,除了可以用上例的*(a + i)外,也可以寫出a[ i ]的形式码秉。

數(shù)組元素地址作為實參

當用數(shù)組元素地址作為實參時逮矛,對應(yīng)的形參也應(yīng)當是基類型相同的指針變量。

例2(高教版《全國計算機等級考試二級教程——C語言程序設(shè)計》P119 例9.3):

編寫函數(shù)转砖,對具有10個元素的char類型數(shù)組须鼎,從下標為4的元素開始鲸伴,全部設(shè)置星號“*”,保持前四個元素的內(nèi)容不變晋控。

#include <stdio.h>
#define M 10
#define B 4

void setstar(char *, int);
void arrout(char *, int);

int main(void)
{
    char c[M] = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J'};
    setstar(&c[4], M - B);
    arrout(c, M);
    return 0;
}

void setstar(char *a, int n)
{
    int i;
    for(i = 0; i < n; i++)
        *(a + i) = '*';
}

void arrout(char *a, int n)
{
    int i;
    for(i = 0; i < n; i++)
        printf("%c", a[i]);
        printf("\n");
}

輸出:

ABCD******

setstar函數(shù)的首部還可以寫成以下形式:

void setstar(int a[], int n)
void setstar(int a[M - B], int n)
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末汞窗,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子赡译,更是在濱河造成了極大的恐慌仲吏,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,542評論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件蝌焚,死亡現(xiàn)場離奇詭異裹唆,居然都是意外死亡,警方通過查閱死者的電腦和手機只洒,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,822評論 3 394
  • 文/潘曉璐 我一進店門许帐,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人红碑,你說我怎么就攤上這事舞吭∨堇” “怎么了析珊?”我有些...
    開封第一講書人閱讀 163,912評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長蔑穴。 經(jīng)常有香客問我忠寻,道長,這世上最難降的妖魔是什么存和? 我笑而不...
    開封第一講書人閱讀 58,449評論 1 293
  • 正文 為了忘掉前任奕剃,我火速辦了婚禮,結(jié)果婚禮上捐腿,老公的妹妹穿的比我還像新娘纵朋。我一直安慰自己,他們只是感情好茄袖,可當我...
    茶點故事閱讀 67,500評論 6 392
  • 文/花漫 我一把揭開白布操软。 她就那樣靜靜地躺著,像睡著了一般宪祥。 火紅的嫁衣襯著肌膚如雪聂薪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,370評論 1 302
  • 那天蝗羊,我揣著相機與錄音藏澳,去河邊找鬼。 笑死耀找,一個胖子當著我的面吹牛翔悠,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 40,193評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼凉驻,長吁一口氣:“原來是場噩夢啊……” “哼腻要!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起涝登,我...
    開封第一講書人閱讀 39,074評論 0 276
  • 序言:老撾萬榮一對情侶失蹤雄家,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后胀滚,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體趟济,經(jīng)...
    沈念sama閱讀 45,505評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,722評論 3 335
  • 正文 我和宋清朗相戀三年咽笼,在試婚紗的時候發(fā)現(xiàn)自己被綠了顷编。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,841評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡剑刑,死狀恐怖媳纬,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情施掏,我是刑警寧澤钮惠,帶...
    沈念sama閱讀 35,569評論 5 345
  • 正文 年R本政府宣布,位于F島的核電站七芭,受9級特大地震影響素挽,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜狸驳,卻給世界環(huán)境...
    茶點故事閱讀 41,168評論 3 328
  • 文/蒙蒙 一预明、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧耙箍,春花似錦撰糠、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,783評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至卤材,卻和暖如春遮斥,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背扇丛。 一陣腳步聲響...
    開封第一講書人閱讀 32,918評論 1 269
  • 我被黑心中介騙來泰國打工术吗, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人帆精。 一個月前我還...
    沈念sama閱讀 47,962評論 2 370
  • 正文 我出身青樓较屿,卻偏偏與公主長得像隧魄,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子隘蝎,可洞房花燭夜當晚...
    茶點故事閱讀 44,781評論 2 354

推薦閱讀更多精彩內(nèi)容

  • 指針是C語言中廣泛使用的一種數(shù)據(jù)類型购啄。 運用指針編程是C語言最主要的風格之一。利用指針變量可以表示各種數(shù)據(jù)結(jié)構(gòu)嘱么; ...
    朱森閱讀 3,444評論 3 44
  • 參考資料:《全國計算機等級考試二級教程——C語言程序設(shè)計》《21天學通C語言》 變量的地址和指針 在程序中狮含,一個變...
    NoelleMu閱讀 1,480評論 0 1
  • 第十章 指針 1. 地址指針的基本概念: 在計算機中,所有的數(shù)據(jù)都是存放在存儲器中的曼振。一般把存儲器中的一個字節(jié)稱為...
    堅持到底v2閱讀 1,069評論 2 3
  • 數(shù)組在程序設(shè)計中几迄,為了處理方便, 把具有相同類型的若干變量按有序的形式組織起來冰评。這些按序排列的同類數(shù)據(jù)元素的集合稱...
    朱森閱讀 3,926評論 2 13
  • 一年四季都燥熱的卡斯小鎮(zhèn)映胁,今天格外熱,熱的人心惶惶…… 九月開學季甲雅,今天是珊珊初一開學的日子解孙。一大早,媽媽剛做7好...
    徐小八閱讀 194評論 0 0