2016年12月12日 星期一

陣列 (Arrays) (編輯中)

陣列觀念

ξ陣列是資料結構中的重要主題,是由一群具有相同名稱及相同型別的記憶體位置相關資料項所組成的資料結構。

ξ陣列(arrays)和結構(struct)都屬於「靜態」的資料結構,它們在程式執行期間的大小並不會改變。

ξ屬於「動態」的資料結構有:串列、佇列、堆疊和樹,它們都可以在程式執行期間改變大小。

ξ若要引用陣列的某個位置或元素(elements),我們必須指定陣列名稱,以及此元素在陣列中的位置編號 (position number)

ξ我們可以使用陣列名稱,並且在後面接著一個放有位置編號的中括號[ ],來引用任何一個元素。

ξ 每個陣列中的第一個元素均是第零個元素 (zeroth element)。例如有一個陣列a,它的第一個元素是a[0],第二個元素稱是a[1],第七個元素稱為a[6],用一般化的表示式來說,陣列a當中的第i個元素是 a[i - 1],其中[]內的i-1就是所謂的位置編號 (position number),正式名稱為下標 (subscript) 索引 (index),且必須是整數或整數運算式。
note
如果在程式中使用運算式當作下標,就會以此運算式運算之後的值當作下標值。
  Ex.假設x=5, y=6底下的敘述式 a[ x + y ] += 2; 將會為陣列中的元素a[11]加上2。

ξ 陣列名稱如同變數的命名規則,只能夠使用字母、數字和底線, 但名稱不能以數字開頭。

ξ 事實上,對c語言而言,陣列的[ ]也是運算子,它的運算優先順序與函式的呼叫運算子( ),是相同的,也就是放在函式後面,用來呼叫函式的括號。(可以參考下面圖之表格)


定義陣列

ξ陣列會佔用記憶體空間。(撰寫者需要指定每個陣列所需要的元素型別和元素個數,電腦會依此來預留適當的記憶體空間大小。)

ξ要告訴電腦預留空間給具有10個元素的整數陣列a,你可以使用以下的定義方式:
      int a[ 10 ];

陣列的初始值

ξ沒有給定陣列任何初始值的情況下,陣列並不會自動地將初始值設定為零
      int a[ 10 ] ;
      輸出結果會是:


ξ陣列中的元素可以在陣列宣告的同時,就指定初始值,其方式就是在宣告之後加上一個等號和大括號包住的一串初始值 (initializers) 串列。
      int a[ 10 ] = { 32, 26, 54, 43, 22, 12, 90, 37, 41, 33 };
      輸出結果會是:


ξ如果給定的初始值的個數小於陣列的元素個數,則剩下的元素將自動指定初始值為零。
      int a[ 10 ] = { 32, 26, 54, 43, 22, 12, 90 };
      輸出結果會是:


ξ如果設定的初始值數目比宣告的陣列元素還多時,compiler就會出錯。

ξ如果在一個有初始值串列的定義上省略陣列的大小,則此陣列的元素個數將等於初始值串列上的元素個數。
      int a[  ] = { 32265443, 221290 };
      將會產生一個具有7個元素的陣列。

以define給予陣列大小的方法

ξ利用#define前置處理器命令來給予陣列的大小:
      #define 符號常數 欲代換的數值
      #define size 5
define→定義一個符號常數 (symbolic constant) (指size),其值為5。
note
前置處理器命令不屬於C敘述式
符號常數不是變數,編譯器不會為其預留記憶體空間,故若在一個可執行的C敘述式中,指定某個數值給符號常數,則會發生編譯錯誤的情形。

ξ符號常數是一個識別字,它會在程式編譯之前,由C的前置處理器將它代換成代換文字 (replacement text)。 所以,如果在程式碼執行的過程中遇到了剛剛所定義的符號常數時,會自動把他代換成剛才所給予的數值。


ξ利用符號常數來指定陣列的大小,將可以使程式更具擴充性 (scalable)。為何說他可以更具有擴充性呢? 因為當我們要改變陣列大小時,我們只要將
       #define size 5
的size後方的數字5直接做改變即可!但,如果不是使用這種寫法,當我們要修改陣列大小時,for loop迴圈的條件要跟著修改,如此一來,是不是變得比較複雜些呢?

範例


沒有留言:

張貼留言