C語言-數組和指標之間的較量

來源:互聯網
上載者:User

1 使用背景
    當人們在學習編程時,可以看到大量的數組與指標互換的使用執行個體,比如下面的這個例子:
    char my_array[10];
    char *my_ptr;
    ...
    i = strlen(my_array);
    i = strlen(my_ptr);
    還有很多類似的語句:printf("%s %s", my_ptr, my_array);這些都展示了數組與指標的可混換性,所以人們很容易認為數組和指標基本上是一樣的。
    數組和指標是相同的嗎?答案是否定的,相信你也不會同意他們是一回事的說法。最常見的錯誤使用指標與數組的環境是這樣的:
    檔案1:
    int var[100];

    檔案2:
    extern int *var;

    檔案1定義了數組var,檔案2聲明了它為指標,對於那些認為C語言中數組和指標非常相似的觀點根深蒂固的程式員來說,會覺得這樣沒什麼不妥,但是當你在檔案2中使用var的時候會發現者根本行不通。話說兩個不同類型能直接互換嗎,這和下面使用有什麼分別?
    檔案1:
    int var;

    檔案2:
    extern float var; 
    指標就是指標,數組就是數組,他們只是在特定的場合下才用相同的功用,就因為這些功用的場合出現的極為頻繁才導致兩者混淆的思維。

2 聲明與定義
    定義:只能出現在一個地方,確定物件類型並分配記憶體,用於常見新的對象(int var[100])。
    聲明:可以出現多次,描述對象的類型,用於指代其他地方定義的對象,比如其他檔案中聲明的對象(extern int var[])。

    從上面的他們的定義可以看出,如果要區分定義和聲明很簡單,只要記住:聲明是普通聲明,說明的不是自身而是描述其他地方建立的對象,也不需要提供長度(多維陣列需要提供除最左面維度其他維度長度);定義是特殊的聲明,它為對象分配記憶體。

3 數組與指標的區別
   1)可修改的左值
     在C語言中,數組作為一個不可修改的左值,不能單獨出現在賦值或複合賦值符的左邊,但指標是可以修改的左值,可以出現在賦值或複合賦值符的左邊。
    
  2)extern char a[]與extern char a[100]是等價的原因是因為:他們都標識a是一個數組,也就是一個記憶體位址,數組內的成員可以從這個地址找到,編譯器也不需要知道數組的具體長度,因為通過偏離起始的便宜地址就可以辦到,而對於extern char *a來說,它會告訴編譯器p是一個指標,為了取得這個字元,必須先找到地址p的內容,把他作為字元的地址來取得這個字元,指標的訪問要領了的多,但是需要增加一次額外的提取。
     其實,這說明一個事實:數組名表示數組的地址,引用變數值時只需要取一次;而指標表示儲存變數值地址的地址,要得到變數的值需要取兩次。如果像extern char a[]與extern char *a定義和聲明變數,在extern char *a的檔案中使用a[i]將會被取值兩次,最後一次是將char數組中第i個元素的字元當做地址來取值,顯然這是錯誤的。
  3)指標儲存資料的地址,而數組儲存的是資料,這一點從2)即可知道,簡單的說:數組就是一個地址,指標就是一個地址的地址
  4)指標通常用於動態資料結構,相關函數為malloc()和free();數組通常用於儲存固定數目且資料類型相同的元素,隱式分配和刪除
  5)數組和指標都可以在他們的定義中用字串常量進行初始化,看上去一樣但底層的機制卻不相同。對於指標:是儲存了字串常量的地址;對於數組:是將字串常量拷貝到了申請的記憶體中。

4 數組與指標的共同點
  1)所有座位函數參數的數組總是可以通過編譯器轉換為指標,這一點可以在The C Programming Language第二版的99頁底部找到:
    char s[];
  and(和)
    char *s;
  are equivalent(是一樣的)...
    可以更確切的表示為:在函數參數的聲明中,數組名被編譯器當做指向該數組第一個元素的指標

  2)數組下表運算式總是可以改寫為帶位移量的指標運算式,這裡指的是運算式中,這與聲明可不同哦

  3)下標總是和指標的位移量相同,就是說用a[i]這樣形式訪問數組總被改寫成*(a+i)這樣的指標形式

5 函數數組形參為何當指標
    要回答這個問題可能需要更多的來瞭解編譯器,全面的語義檢查被可移植的C編譯器所排斥,其理由是把lint這樣的程式作為單獨的程式,對編譯器的效率會更高一些,其實,事實上現在很多現代的ANSI C編譯器在錯誤檢查方面都做了增強,這也說明了把lint程式自成一家的做法還是有相當的非議的。
    沒錯,吧作為形參的數組和指標等同起來是出於效率原因的考慮,在C語言中,所有的非數組形式的資料實參以傳值形式調用,其實就是做了一次拷貝給函數調用,拷貝數組的代價無論在時間還是空間上的開銷都可能是非常大的,其實就是這麼簡單。

6 總結
    學習C語言的同學都知道,數組與指標在C中的地位之高,他們倆的曖昧關係一直為人們津津樂道,或者說痛心疾首(如果你被他們折磨過),區分他們是學習C語言的重點內容,雖然接觸C已經有三年了,每次學習都還是挺有收穫的,再接再厲...
   
 

    

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.