謝邀。

C語言已經是非常簡潔的編程語言了,數組肯定不是多餘的語法了。可以說,數組基本上是所有現代高級編程語言不可或缺的語法了。但是C語言中的數組並不難,題主也不用太擔心自己學不會。

我的上一個回答,討論了C語言中的結構體,它是一種複合數據類型,有了結構體,C語言可以應對各種複雜的數據模型,比如上一節的平行四邊形問題。

但是有些問題,就算是結構體,也很難解決。請看下面這個問題:

小明班級有 60 個人,期末考試出成績後,編寫C語言程序找出這 60 個人的最高得分。

這當然不是什麼難題,會判斷兩個數的大小就能解決這個問題。只不過,這 60 個人的成績怎麼用 C 語言描述呢?定義 60 個變數?這樣是不是太麻煩了?就算不嫌麻煩,比較兩個數大小的邏輯怎麼寫呢,每兩個變數就得寫一個 if ?

這時C語言的數組就很好用了

和結構體類似,數組也是一種複合數據類型,只不過,數組是由一系列相同類型的元素組成的。比如上面 60 人的成績得分,每一個人的得分在C語言中都可以用 float 來定義,屬於同一數據類型,所以這 60 個人的成績得分,在C語言中可以定義為:

float score[60];

score 後面的 [60] 表示一共有 60 個 score 這樣的(即 float 類型的)數據,所以 60 個同學的成績得分,C語言程序定義這麼一個數組就可以了,並不需要定義多個變數。如果人數更多,把 60 改大些就可以解決。

請看上圖,我們用方框表示數組的存儲單元(元素),一系列方框在一起組成了數組。方框裡面的數字是成績得分,方框外面的數字是數組的下標,每個存儲單元可以用數組名+下標訪問:score[0],score[1],score[28] 等等。

注意,在定義數組時,float score[60]; 這裡的 60 表示數組長度,而在訪問時, score[60] 這裡的 60 是指 score 數組的第 60 個元素。

和我們平常數數不同,數組元素是從「第0個」開始數的,大多數編程語言都是這麼規定的。這樣規定使得訪問數組元素非常方便,比如 score 數組中的每個元素佔 4 個位元組,則 score[i] 位於從數組開頭跳過 4 * i 個位元組的存儲位置。score[i] 也可以做左值,i 也可以是表達式:

只要確保下標都是整數,這些都是合法的。

數組的初始化結構體相似,例如:

float score[60] = {68.0, 84.2, };

如果定義數組同時初始化它,可以不指定數組長度,例如:

float score[] = {68.0, 84.2, 77.7};

這時,編譯器會根據初始化信息確定 score 數組的長度為 3。不過,結構體可以互相賦值,數組卻不能互相賦值:

既然數組不能互相賦值,也就不能用數組類型作為函數的返回值。這部分內容,可能需要討論到指針,鑒於題主才學到數組,就不展開討論了。

使用C語言數組解決上述問題

好了,說了這麼多,來看一個實例吧,我們使用C語言數組來記錄小明班同學成績,然後找到最高的成績得分:

例子只使用了 6 個成績做演示,原理是通的,編譯並執行上面這段C語言程序,發現找到最高成績了。

使用C語言數組注意事項

使用數組下標不能超出數組的長度範圍,這一點在使用變數做數組下標時尤其要注意。C語言編譯器並不檢查 score[-1] 或是 score[100] 這樣的訪問越界錯誤,編譯時能順利通過,運行時卻會出錯。

有時候這種錯誤很隱蔽,發生訪問越界時程序可能並不會立即崩潰,而執行到後面某個正確的語句時卻有可能突然崩潰。所以,從一開始寫代碼時就要小心避免出問題,事後依靠調試來解決問題的成本是很高的。

為什麼C語言編譯器對這麼明顯的錯誤都不做處理?

理由一,這種錯誤並不總是顯而易見的,如果題主學了指針,就會發現指針指向數組的什麼位置只有運行時才知道,編譯時無法檢查是否越界,而運行時檢查數組訪問越界會影響性能,C語言是極其重視效率的編程語言,所以乾脆不檢查了;

理由二, C99 Rationale 指出,C語言的設計精神是:相信每個C程序員都是高手,不要阻止程序員去幹他們需要乾的事,高手們使用count[-1]這種技巧其實並不少見,不能當作錯誤

歡迎在評論區一起討論,質疑。文章都是手打原創,每天最淺顯的介紹C語言、linux等嵌入式開發,喜歡我的文章就關注一波吧,可以看到最新更新和之前的文章哦。


數組是最基本的數據結構,應該學好。其實關鍵是模型,腦中自始至終明白數組是怎樣的一個結構即可。

數組的基本模型,就是一排編了號的房屋,每間房屋的結構都是一樣的,尺寸也一樣,還是順序排列的。也就是說,你只要知道每間房屋的尺寸,根據房屋的編號,就可以用最簡單的乘除法得到它的位置,從而把裡面的內容提取出來。

整排房屋的基準是第一間的地址。對數組x來說,x[0]就是第一間房屋,它的地址是&x[0],如果你要用一個指針p指向它,就可以用p=&x[0]。當用指針的時候,要把指針指向的內容提取出來,就用*p,這個*p其實就是x[0]。

知道第一間房屋的地址後,用x[n]就可以提取第n間房屋的內容,若用指針,就是*(p+n)。

在你使用指針操作數組的時候,千萬不要丟失指向首地址的指針!用過p++之類的操作,要記得p移動了多少步,即把n記住,否則你不知道回退多少纔是頭,退多了就是越界溢出錯誤。同樣,數組的容量是有幾間房屋,也是必須記住的,不管怎麼操作,千萬不要越過容量,只有10間屋,你叫指針去取第11間的內容,那叫越界訪問,後果是未知的,但C語言麻煩在它允許你這樣做而不報告有問題。有些程序員,偏愛指針運算,一來二去,最後指針指向哪裡自己都不清楚(把程序寫複雜點你就知道永遠是這個問題在困擾你,不管是怎樣的高手都會有栽在這上面的時候),那就是bug和漏洞的根源。

寫諸如p++這樣的代碼時,腦中想像一下,像跳棋一樣,它跳到哪個格子去了?跳過去之後會怎樣?如果需要後續操作,要注意什麼?把這些都想清楚,纔好寫代碼。


以我的經驗,既然是c語言的數組,那麼他肯定要包含很多指針操作。所以我建議先學習計算機原理。搞清楚,計算機如何存儲對象,變數等。棧區,堆區,連續存儲和鏈式存儲。

理解了這些,你就會理解,數組是一段連續存儲空間。每個下標值代表偏移一個單位,也就是地址增加一個數組類型的所佔空間大小。

其實,這些原理符合所有語言特性。你必須理解,一個對象或者結構體,就是一段連續的存儲空間,如果程序需要訪問他,就要拿到他的首地址,然後通過偏移去依次訪問其成員。這裡的首地址有時是對象指針,有時是數組名稱,有時用取地址符號。


學學彙編吧,學完彙編,理解C語言的指針和數組就很easy樂


數組非常有用,比如在數碼管顯示的時候,把要顯示的筆畫存入數組,直接索引數組就可以了


排坐坐喫果果。kid[]=3,5,4定義兒童數組,序號0,1,2小朋友的年齡分別是3,5,4

kid[1]的值就是4


推薦閱讀:
相關文章