天天看點

C語言數組與指針學習總結

     工作之後最害怕的是對最基礎知識的考查,是以還是有必要随時回爐學習,溫故知新。今天再次回顧總結一下c語言數組相關知識。主要是學習《c語言陷阱與缺陷》的學習筆記。

       c語言數組值得注意的有兩點:

       1,c語言中隻有一維數組,而且數組的大小必須在編譯時期就确定下來(舊标準)。然而,c語言數組的元素可以是任意對象,包括數組。這樣就給多元數組的實作或者仿真提供了可能。

       2,對于數組,我們隻能夠做兩件事。一是擷取數組的大小,二是獲得指向數組下标為0的元素的指針。其他的任何操作雖說看起來像是數組,但是本質上其實都是基于指針的操作。

       以上兩天總結摘取自《c語言陷阱與缺陷》,讓我想起了之前自己看過的國外的一份c語言資料結構與算法的講義。其中關于c語言數組與指針的知識給了一個重點關注點的概括——除了作為sizeof的參數以外,其它時候c語言數組的名稱跟指向數組首元素的指針是等價的。

       關于c語言中數組的運算機制如何實作是關系到對數組了解的一個重點。其實,這就是要學會(或者說是記住)c語言數組聲明定義的形式以及含義。

       1,int a[3];

              定義了一個元素個數為3個的數組a,其中每個元素都是int類型。

       2, struct

{

       int p[4];

       double x;

}b[17];

定義了一個元素個數為17個的數組b,其中每個元素都是一個結構體。

       3,int a[12][31];

              聲明定義了一個數組a,該數組有12個元素,其中每個元素是一個擁有31個元素的數組,每個最小子元素的類型都是int。這個地方了解時候一定不能夠按照前面兩個例子的順序,從左到右一個個數字字元進行解析。需要記住的還是最前面的那一點,c語言中隻有一維數組,而數組名稱後面跟着的第一個數字次元就是數組的真實次元。除此之外,其他的參數則是數組元素的資訊描述。

       數組名稱與指向數組的指針的等價之處在兩種表示的等價,如果定義了一個數組a,那麼數組的下表為i的元素可以表述為:

       *(a + i) 或者a[i]

       實際上,後者隻是前者的一種常用的簡寫方式。

       而由于上面這種描述,其實a[i]和i[a]表示的含義一樣。編寫如下測試代碼;

#include"stdio.h"

int a[5] ={1,2,3,4,5,};

int main(void)

       printf("%d\n",a[3]);

       printf("%d\n",3[a]);

       return 0;

}

       其中,數組定義的時候我故意在最後的元素後面加上了一個逗号。其實,這并不是錯誤。本來我也不是很了解這種方式,在對了《unix程式設計藝術》一書之後才明白。其實,這算是c語言設計的一個優秀的特點,這種特征不僅友善數組元素的擴充時候的修改,而且友善數組的工具生成。程式的編譯以及運作記錄如下;

e:\workspace\01_程式設計語言\01_c語言\01_c語言陷阱與缺陷\exp02>gccexp02.c

e:\workspace\01_程式設計語言\01_c語言\01_c語言陷阱與缺陷\exp02>a

4

       由上面的驗證可以得出先前陳述的結論或者推論。

       接下來通過簡單的代碼,回顧二維數組與指針的關系基礎知識。編寫代碼如下:

int a[12][31];

int *p;

int i;

       p = a[4];

       printf("value of p: %p\n",p);

       printf("size of a[4]:%d\n",sizeof(a[4]));

       a[4][7] = 3;

       i = a[4][7];

       printf("value of i: %d\n",i);

       i = *(a[4] + 7);

       i = *(*(a + 4) + 7);

       編譯後,運作結果如下:

value of p:00405630

size of a[4]: 124

value of i: 3

       其中,a[4]的含義自然是代表數組a的下标為4的元素,而元素的為31個int類型對象。通過計算其占用的空間可以看出這一點。而進一步來看,其實a[4]應該是一個31個元素的數組的數組名。這樣,a[4]也就等同于這個數組的首位址。在程式中,我通過指針指派的方式輸出了這個位址數值。接下來的元素取值就值得去品味一下了:

       第一次i取值:使用了數組名後面加中括号指明偏移來實作;

       第二次i取值:進一步把第一步中的方式改成了指針取值的方式,通過首位址加偏移的方式。

       第三次i取值:把疊代着的一個數組進一步展開。從最終的形式上看,這種方式比使用下标取值的簡寫方式要難了解不少。

       最終i的三次輸出都是相同的,其實這也算是對三種方式等價的一個最基本的驗證。而把a指派給p是錯誤的,因為a的含義是一個指向“二維數組的指針”。在代碼中加入相應的代碼測試的時候,gcc編譯器會給出警告。不過,程式還是能夠編譯通過并運作。

繼續閱讀