本文由 babystep原創,禁止轉載!數組
本文經過語言加代碼的方式,力圖徹底理解指針、數組、指針數組和數組指針這四個東西,尤爲是指針數組和數組指針,每次用起來都得從新搜索是啥意思,因此此次決定用一篇博客說明白。url
數組和指針常常用,可是理解時候容易有誤差,致使不能理解指針數組和數組指針的區別,因此建議讀者一步一步詳細閱讀。對數組和指針有好的理解,能夠直接調到指針數組和數組指針部分。.net
數組: 內存空間中一段連續的內存。例如 int a[5]; a是一段連續5個int大小內存片斷的首地址,首地址這點很關鍵,關鍵在哪裏?關鍵在這說明a是常量,而不是變量。因此,雖然a是地址,但它就是那5個int片斷的首地址,你能夠改變這個首地址中存放的東西,可是不能改變這個地址,也就是說不能改變a。以下作法是錯誤的:指針
int *p; int a[5]; a = p; //錯誤,a是常量
指針: 是一個變量,這個變量的內容是一個地址,這個地址指向其餘地方。什麼是指向呢?指向的意思就是指針變量所保存的其餘地址單元中所存放的數據類型。例如 int *p; p自己就是一個地址,32位系統下是4個字節,64位系統下是8個字節。它指向的數據類型用前面的int來講明,因此咱們稱p指向int數據類型。code
指針變量是變量,因此能夠給指針變量賦值,以下:對象
int *p; int a[5]; p = a;//正確
說明數組指針和指針數組以前,先回顧下上面。blog
//請問下面語句對嗎?爲何 char s[]="hello"; char *p = "wolrd"; s = p;
首先char s[] = "hello";
是對的,這是c語言中數組變量的典型初始化方法。可是char *p = "world"
爲何也能夠?這是由於」world「常量字符串其實是一個常量指針,指針指向的地方是字符串首字符。所以天然能夠賦值給p。 第三句錯誤,上文已經講了,s是數組變量,數組的首地址,而不是指針變量,因此是常量,不能給賦值。內存
接下來講明指針數組和數組指針字符串
顧名思義,指針數組是數組,只不過數組的元素是指針;數組指針是指針,只不過指向的對象是數組。get
//請問下面p是是數組指針仍是指針數組 int (*p)[5]; //答案是 數組指針。這是由於'*'的優先級小於[],只能用括號來增長優先級,因此括起來的p首先與* //結合,被認爲是指針,指向一維數組,大小爲5個int。 int a[5]; p = a;//錯誤,a是數組,p是數組指針 p = &a;//正確。 /*--------------------------------------------------------*/ //相對應的,指針數組以下,p先與[]結合,說明p是數組變量而不是指針變量 int *p[3]; int a[3][5]; p = a; //錯誤,數組變量是地址常量,不能賦值 p[0] = a[0];
由c語言知識知道,數組變量名是一個地址常量,這個地址常量表示的大小是隨數組變化而變化的。舉例來來理解:
int a[5]; //那麼a就是&a[0] //a+1實際是 &a[1] int a[3][4];//稍微複雜點,a實際是a[0],a[0]是什麼呢,是一維數組(矩陣的第一行)int [4] //所以,a+1 就等於 a[1],是第二行一維數組的地址
理解了上面,定義
int a[3][4]; int b[3][4]={0}; //要用指針數組和數組指針表示二維數組a,該怎麼作? //指針數組作法:指針數組有三個元素,分別爲三行的首地址 int *p[3]; for (int i=0;i<3;i++) { p[i]=a[i]; for(int j=0;j<4;j++) p[i][j]=b[i][j]; //完成賦值 } //數組指針作法:由於c語言約定最右邊的下標爲低維,即a[3][4]中4爲低維,存儲元素過程是從低維到 //高維,二維狀況下是一行一行存儲,因此須要知道列數 int (*p)[4]; p=a; //至關於p = a[0]; for(int i=0;i<3;i++) { for(int j=0;j<4;j++) (*p)[j] = b[i][j]; p++; //由於是數組指針,因此每自加1,地址移動其數組大小的距離。 }
例子仍是有點少,但願有點幫助吧。