指標與陣列是C語言中很重要的兩個概念,它們之間有著密切的關係,利用這種關係,可以增強處理陣列的靈活性,加快執行速度,本文著重討論指標與陣列之間的聯絡及在程式設計中的應用。 1.指標與陣列的關係 當一個指標變數被初始化成陣列名時,就說該指標變數指向了陣列。如: char str[20], *ptr; ptr=str; ptr被置為陣列str的第一個元素的地址,因為陣列名就是該陣列的首地址,也是陣列第一個元素的地址。此時可以認為指標ptr就是陣列str(反之不成立),這樣原來對陣列的處理都可以用指標來實現。如對陣列元素的訪問,既可以用下標變數訪問,也可以用指標訪問。 2.指向陣列元素的指標 若有如下定義: int a[10], *pa; pa=a; 則p=&a[0]是將陣列第1個元素的地址賦給了指標變數p。 實際上,C語言中陣列名就是陣列的首地址,所以第一個元素的地址可以用兩種方法獲得:p=&a[0]或p=a。 這兩種方法在形式上相像,其區別在於:pa是指標變數,a是陣列名。值得注意的是:pa是一個可以變化的指標變數,而a是一個常數。因為陣列一經被說明,陣列的地址也就是固定的,因此a是不能變化的,不允許使用a++、++a或語句a+=10,而pa++、++pa、pa+=10則是正確的。由此可見,此時指標與陣列融為一體。 3.指標與一維陣列 理解指標與一維陣列的關係,首先要了解在編譯系統中,一維陣列的儲存組織形式和對陣列元素的訪問方法。 一維陣列是一個線形表,它被存放在一片連續的記憶體單元中。C語言對陣列的訪問是透過陣列名(陣列的起始地址)加上相對於起始地址的相對量(由下標變數給出),得到要訪問的陣列元素的單元地址,然後再對計算出的單元地址的內容進行訪問。通常把資料型別所佔單元的位元組個數稱為擴大因子。 實際上編譯系統將陣列元素的形式a[i]轉換成*(a+i),然後才進行運算。對於一般陣列元素的形式:<陣列名>[<下標表達式>],編譯程式將其轉換成:*(<陣列名>+<下標表達式>),其中下標表達式為:下標表達式*擴大因子。整個式子計算結果是一個記憶體地址,最後的結果為:*<地址>=<地址所對應單元的地址的內容>。由此可見,C語言對陣列的處理,實際上是轉換成指標地址的運算。 陣列與指標暗中結合在一起。因此,任何能由下標完成的操作,都可以用指標來實現,一個不帶下標的陣列名就是一個指向該陣列的指標。 4.指標與多維陣列 用指標變數可以指向一維陣列,也可以指向多維陣列。但在概念上和使用上,多維陣列的指標比一維陣列的指標要複雜一些。 例如,在一個三維陣列中,引用元素c[i][j][k]的地址計算最終將換成:*(*(*(c+i)+j)+k)。瞭解了多維陣列的儲存形式和訪問多維陣列元素的內部轉換公式後,再看當一個指標變數指向多維陣列及其元素的情況。 1 指向陣列元素的指標變數 若有如下說明: int a[3][4]; int *p; p=a; p是指向整型變數的指標;p=a使p指向整型二維陣列a的首地址。 *(*(p+1)+2)表示取a[1][2]的內容;*p表示取a[0][1]的內容,因為p是指向整型變數的指標;p++表示p的內容加1,即p中存放的地址增加一個整型量的位元組數2,從而使p指向下一個整型量a[0][1]。 2 指向由j個整陣列成的一維陣列的指標變數 當指標變數p不是指向整型變數,而是指向一個包含j個元素的一維陣列。如果p=a[0],則p++不是指向a[0][1],而是指向a[1]。這時p的增值以一維陣列的長度為單位。 5.指標與字元陣列 C語言中許多字串操作都是由指向字元陣列的指標及指標的運算來實現的。因為對於字串來說,一般都是嚴格的順序存取方式,使用指標可以打破這種存取方式,更為靈活地處理字串。 另外由於字串以′\0′作為結束符,而′\0′的ASCII碼是0,它正好是C語言的邏輯假值,所以可以直接用它作為判斷字串結束的條件,而不需要用字串的長度來判斷。C語言中類似的字串處理函式都是用指標來完成,使程式執行速度更快、效率更高,而且更易於理解。
指標與陣列是C語言中很重要的兩個概念,它們之間有著密切的關係,利用這種關係,可以增強處理陣列的靈活性,加快執行速度,本文著重討論指標與陣列之間的聯絡及在程式設計中的應用。 1.指標與陣列的關係 當一個指標變數被初始化成陣列名時,就說該指標變數指向了陣列。如: char str[20], *ptr; ptr=str; ptr被置為陣列str的第一個元素的地址,因為陣列名就是該陣列的首地址,也是陣列第一個元素的地址。此時可以認為指標ptr就是陣列str(反之不成立),這樣原來對陣列的處理都可以用指標來實現。如對陣列元素的訪問,既可以用下標變數訪問,也可以用指標訪問。 2.指向陣列元素的指標 若有如下定義: int a[10], *pa; pa=a; 則p=&a[0]是將陣列第1個元素的地址賦給了指標變數p。 實際上,C語言中陣列名就是陣列的首地址,所以第一個元素的地址可以用兩種方法獲得:p=&a[0]或p=a。 這兩種方法在形式上相像,其區別在於:pa是指標變數,a是陣列名。值得注意的是:pa是一個可以變化的指標變數,而a是一個常數。因為陣列一經被說明,陣列的地址也就是固定的,因此a是不能變化的,不允許使用a++、++a或語句a+=10,而pa++、++pa、pa+=10則是正確的。由此可見,此時指標與陣列融為一體。 3.指標與一維陣列 理解指標與一維陣列的關係,首先要了解在編譯系統中,一維陣列的儲存組織形式和對陣列元素的訪問方法。 一維陣列是一個線形表,它被存放在一片連續的記憶體單元中。C語言對陣列的訪問是透過陣列名(陣列的起始地址)加上相對於起始地址的相對量(由下標變數給出),得到要訪問的陣列元素的單元地址,然後再對計算出的單元地址的內容進行訪問。通常把資料型別所佔單元的位元組個數稱為擴大因子。 實際上編譯系統將陣列元素的形式a[i]轉換成*(a+i),然後才進行運算。對於一般陣列元素的形式:<陣列名>[<下標表達式>],編譯程式將其轉換成:*(<陣列名>+<下標表達式>),其中下標表達式為:下標表達式*擴大因子。整個式子計算結果是一個記憶體地址,最後的結果為:*<地址>=<地址所對應單元的地址的內容>。由此可見,C語言對陣列的處理,實際上是轉換成指標地址的運算。 陣列與指標暗中結合在一起。因此,任何能由下標完成的操作,都可以用指標來實現,一個不帶下標的陣列名就是一個指向該陣列的指標。 4.指標與多維陣列 用指標變數可以指向一維陣列,也可以指向多維陣列。但在概念上和使用上,多維陣列的指標比一維陣列的指標要複雜一些。 例如,在一個三維陣列中,引用元素c[i][j][k]的地址計算最終將換成:*(*(*(c+i)+j)+k)。瞭解了多維陣列的儲存形式和訪問多維陣列元素的內部轉換公式後,再看當一個指標變數指向多維陣列及其元素的情況。 1 指向陣列元素的指標變數 若有如下說明: int a[3][4]; int *p; p=a; p是指向整型變數的指標;p=a使p指向整型二維陣列a的首地址。 *(*(p+1)+2)表示取a[1][2]的內容;*p表示取a[0][1]的內容,因為p是指向整型變數的指標;p++表示p的內容加1,即p中存放的地址增加一個整型量的位元組數2,從而使p指向下一個整型量a[0][1]。 2 指向由j個整陣列成的一維陣列的指標變數 當指標變數p不是指向整型變數,而是指向一個包含j個元素的一維陣列。如果p=a[0],則p++不是指向a[0][1],而是指向a[1]。這時p的增值以一維陣列的長度為單位。 5.指標與字元陣列 C語言中許多字串操作都是由指向字元陣列的指標及指標的運算來實現的。因為對於字串來說,一般都是嚴格的順序存取方式,使用指標可以打破這種存取方式,更為靈活地處理字串。 另外由於字串以′\0′作為結束符,而′\0′的ASCII碼是0,它正好是C語言的邏輯假值,所以可以直接用它作為判斷字串結束的條件,而不需要用字串的長度來判斷。C語言中類似的字串處理函式都是用指標來完成,使程式執行速度更快、效率更高,而且更易於理解。