C語言基礎:指針與數組

C語言基礎:指針與數組

來自專欄 編程外星人

一、指針與數組的關係

其實,指針與數組變數並沒有本質的區別,指針變數就是數組變數,而數組變數也是指針變數。為什麼這麼說呢?我們來看看面代碼,定義一個數組array和一個指向這個數組首元素的地址的指針p,還有將數組變數直接賦值給了一個指針變數p1:

int array[4] = { 0, 1, 2, 3 };int *p = &array[0];int *p1 = array;for (int i = 0; i < 4; i++){ printf("%d %d %d
", array[i], p[i], p1[i]);}0 0 01 1 12 2 23 3 3

從運行結果中我們可以看到定義的指針和數組其實工並沒有什麼區別,這三個變數在內存中所處的位置如下

對於上面程序我們需要說明的是int *p = &array[0];表示的是將數組變數中的第一個元素的地址賦值給指針變數p,而int *p1 = array;的表示的是將數組變數的值賦值給p指針p21。這兩個語句的結果都是一樣的,這是因為在C語言中數組變數的值就是這個數組中第一個元素的地址,也就是這個數組的首地址。注意:array是一個地址,它表示的是這個數組的首地址,而&array[0]所表示的是這個數組的第一個元素所在的地址,也同樣是這個數組的首地址,所以這兩個地址的值是相同的。 而對於指針類型變數p和p1來說它們所表示的是一個地址,所以我們可以用取數組元素的方式來對這個指針做取數組元素操作例如p[0]、p[1]、[2]和p1[0]、p1[1]、p1[2]這樣的語句都是合法的。同理,我們知道 & 符是對變數取地址,而 * 是對指針地址反取變數,所以*p就表示的是數組中第一個元素變數的值,例如*p的值為0。

二、指針的算數運算

在上面例子中我們已經知道了指針與數組的關係接下來我們來看一看指針的四則運算。指針變數與其它變數一樣,也可以進行四則運算,但通常我們只對指針做加法和減法運算。例如我們可以將指針先指向一個數組,然後再對其做加法運算

char array[6] = "hello";char *p = array;printf("%c", *p);printf("%c", *(p + 1));printf("%c", *(p + 2));printf("%c", *(p + 3));printf("%c", *(p + 4));hello

我們來分析一下上面例子中指針變數的運算過程,由於p是一個指針型變數,它指向了一個數組,也就是說p這個指針變數中存放了一個內存地址,這個地址就是數組array首個元素的地址,也就是array[0]的地址,對指針進行p+1操作時, p+1表示的也同樣是一個指針,它指向數組中第二個變數array[1]。同理當執行p+2時,p+2也表示一個指針,它指向的是是array[2],p+3指向array[3]。p+4指向array[4]。因為它們都表示的是指針,所以我們可以對它們做取變數操作,也就是使用 * 來根據它們所指向的地址取出這些變數。上面程序還可以使用循環來實現:

char array[6] = "hello";char *p = array;for (int i = 0; i < 5; i++){ printf("%c", *(p + i));}hello

我們使用變數i來對指針做加法運算,然後再通過循環將其顯示出來。我們現在再通過數組與指針在內存中的關係來看看這一過程:

同樣的,我們也可以對指針p做++操作,從而達到指向下一個數組元素的目的。例如我們使用針指來實現一個字元串拷貝的功能:

char source[6] = "hello";char target[6];char *s = source;char *t = target;while (*s != ){ *t++ = *s++;}*t = ;printf("%s
", target);hello

對於上面的例子我們一定要注意運算符的優先順序,什麼時候加小括弧,什麼時候不加括弧。

注意:在C語言中對指針的加減實際上是對指針類型佔用位元組數的加減。也就是說,對於字元型指針的+1表示指針增加一個的位元組的地址;而對於short型的指針+1表示增加2個位元組的地址;對於int型的地址對其+1表示增加4個位元組的地址等等。

另外,通常情況下我們只能對指針變數做加法和減法操作,而其它的運算是不可以用在指針變數上的,例如我們不能直接對指針變數做乘法和除法運算,但可以通過使用類型轉換的辦法將其轉為一個整數,對其做完運算之後再將其轉為指針變數。有興趣的讀者可以參見《C語言深處》

關於指針的減法與加法類似,這裡不再贅述。

歡迎關注公眾號:編程外星人

推薦閱讀:

字元串字面值傳入函數時候是用什麼形式?
為什麼 C 語言源程序最後一行要是一個空行?
Windows 下進行 C/C++ 開發,Eclipse 和 Visual Studio 哪個好?從編譯速度、UI、方便程度上如何比較?
c/c++中簡單加法出現奇怪的錯誤?
C++ 函數返回局部變數的std::move()問題?

TAG:編程 | C編程語言 | CC |