數組、指針、數組指針和指針數組怎樣理解


本文由 babystep原創,禁止轉載!

本文通過語言加代碼的方式,力圖完全理解指針、數組、指針數組和數組指針這四個東西,尤其是指針數組和數組指針,每次用起來都得重新搜索是啥意思,所以這次決定用一篇博客說明白。

數組和指針經常用,但是理解時候容易有偏差,導致不能理解指針數組和數組指針的區別,所以建議讀者一步一步詳細閱讀。對數組和指針有好的理解,可以直接調到指針數組和數組指針部分。


數組: 內存空間中一段連續的內存。例如 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數據類型。

指針變量是變量,所以可以給指針變量賦值,如下:

int *p;
int a[5];
p = a;//正確

說明數組指針和指針數組之前,先回顧下上面。

//請問下面語句對嗎?為什么
char s[]="hello";
char *p = "wolrd";
s = p;

首先char s[] = "hello";是對的,這是c語言中數組變量的典型初始化方法。但是char *p = "world"為什么也可以?這是因為”world“常量字符串實際上是一個常量指針,指針指向的地方是字符串首字符。因此自然可以賦值給p。
第三句錯誤,上文已經講了,s是數組變量,數組的首地址,而不是指針變量,所以是常量,不能給賦值。

接下來說明指針數組和數組指針

顧名思義,指針數組是數組,只不過數組的元素是指針;數組指針是指針,只不過指向的對象是數組。

//請問下面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,地址移動其數組大小的距離。
}

例子還是有點少,希望有點幫助吧。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM