數組、指針、數組指針、指針數組

一、類型 T 的指針和類型 T 的數組並非同種類型。

    常常聽說 char c[] 和 char *c 是一樣的。
    然而實際上並非如此。數組定義 char c[10] 請求預留 10 個字符的位置, 並用名稱 “c” 表示。也就是說, 有一個稱爲 “c” 的位置, 可以放入 10 個字符。而指針申明 char *p, 請求一個位置放置一個指針, 用名稱 “p” 表示。這個指針幾乎可以指向任何位置: 任何字符和任何連續的字符, 或者哪裏也不指。

    

#include<iostream>
using namespace std;


int main(){
	char c[10]="licongqi";
	char *p = "licongqi";
	char a;
	a = c[0];
	a = c[3];
	a = p[3];
	cout<<c<<endl<<*p<<endl;
	return 0;
}


    根據 X 是數組還是指針, 類似 X[3] 這樣的引用會生成不同的代碼。以上面的聲明爲例, 當編譯器看到表達式 c[3] 的時候, 它生成代碼從 c 的位置開始跳過 3 個, 然後取出那個字符. 如果它看到 p[3], 它生成代碼找到“p” 的位置, 取出其中的指針值, 在指針上加 3 然後取出指向的字符。換言之, c[3]是名爲 c 的對象 (的起始位置) 之後 3 個位置的值, 而p[3] 是 p 指向的對象的 3 個位置之後的值. 在上例中, c[3] 和 p[3] , 編譯器到達那裏的途徑不盡相同。本質的區別在於類似 c 的數組和類似 p 的指針一旦在表達式中出現就會按照不同的方法計算, 不論它們是否有下標。

下面是訪問c[0]、c[3]和p[3]對應的彙編代碼。
8:        a = c[0];
004011AE   mov         cl,byte ptr [ebp-0Ch]
004011B1   mov         byte ptr [ebp-14h],cl
9:        a = c[3];
004011B4   mov         dl,byte ptr [ebp-9]
004011B7   mov         byte ptr [ebp-14h],dl
10:       a = p[3];
004011BA   mov         eax,dword ptr [ebp-10h]
004011BD   mov         cl,byte ptr [eax+3]
004011C0   mov         byte ptr [ebp-14h],cl

    數組和指針的區別是什麼?
    數組自動分配空間, 但是不能重分配或改變大小。指針必須明確賦值以指向分配的空間 (可能使用 malloc), 但是可以隨意重新賦值 (指向不同的對象), 同時除了表示一個內存塊的基址之外, 還有許多其它的用途。由於數組和指針所謂的等價性, 數組和指針經常看起來可以互換, 而事實上指向 malloc 分配的內存塊的指針通常被看作一個真正的數組(也可以用[]引用)。但是, 要小心 sizeof。

二、指針數組和數組指針大不相同

指針數組,按字面意思理解,就是一個數組,其中的元素是指針。

例如 int *arr[10];聲明瞭一個數組,數組大小爲10,數組中元素的類型爲int *,若要操作數組中的元素,需要取下標。

而數組指針,則是一個指針,它指向的是一個數組。

例如int (*p)[10];聲明瞭一個指針,該指針指向一個大小爲10,元素類型爲int的指針。 在使用下標或增量時, 會跳過整個數組, 通常只在操作數組的數組時有用。

#include<iostream>
using namespace std;

int main(){
	int *arr[10];
	cout<<"size of arr:"<<sizeof(arr)<<endl;
	int (*p)[10];
	cout<<"size of p:"<<sizeof(p)<<endl;
	return 0;
}


從程序的運行結果可以證明上述說明。我們只需要按照數組和指針的用法進行操作就好,使用之前記得初始化。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章