在最早學C語言的時候,char *與char []是最讓我頭疼的幾個問題之一。
字串數組和字串指標是截然不同的兩個東西,如果不去在意它們之間的不同,而混合使用,可能會帶來很多麻煩。讓我們從這兩個東西建立的過程說起。
當我們進行字串數組的定義時
char str[] = "abc";
其實我們做了兩件事:
1. 建立了一個新的字串。
2. 建立了一個名叫“str”的變數儲存字串的首地址。
而當我們進行字串指標的定義時
char* str = "abc";
我們只是定義了一個指標指向字串“abc”的首地址。
等等,難道我們不需要建立字串"abc"嗎?
在C語言中,當程式開始運行時,程式會將所有用到的literal string(不知道中文怎麼說)自動載入進記憶體中,所以字串指標實際指向的是在程式開始運行時就已經在記憶體中建立的“abc”的首地址。
我們來做一個實驗
#include <stdio.h>int main(int argc, char *argv[]){ char *s1 = "abc"; char *s2 = "abc"; char ss[] = "abc"; printf("%p\n", s1); printf("%p\n", s2); printf("%p\n", ss); return 0;}
在我的PC中,該程式的運行結果是
0x80485d0
0x80485d0
0xbfc2df64
可以發現字串指標s1,s2實際指向了同一個地址。
我們常說literal string是不能更改的。當我用char *ss = "abc"定義了一字串指標,如果在程式中試圖更新ss,程式就會出錯,這是因為literal string是存放在constant記憶體區,是不能被更改的。如果我們建立的字串有可能被更改,那麼需要先對literal string做一份拷貝,再將指標指向這個拷貝的首地址。即使用字串數組的定義方式:char ss[] = "abc";
一個好的編程習慣是當我們使用字串指標的定義時使用const限定符: const char* ss = "abc"; 這樣如果程式試圖更改這個變數,在編譯時間就會給出錯誤。