char*p,表示p是指向字符串的指針
char arr[],表示arr是一個字符串數組
string s,表示s是一個string類的對象,有自己的成員變量和成員函數,和前兩者的區別較大,在下一篇博文中詳細討論
通過下面的例子來看char*與char[]的區別:
例子1:
對比下面兩個函數:
char* get_str1() { char str[] = {"abcd"}; return str; } char* get_str2() { char *str = {"abcd"}; return str; }
可以發現,函數get_str1編譯時有警告信息:(warning C4172: 返回局部變量或臨時變量的地址),這種寫法是不對的,盡管編譯能通過,可以運行,但是運行的結果不對,亂碼了;但是函數get_str2,即char*,就正確了。
這是因為:
在函數get_str1中,char str[] = { "abcd" },定義的是一個局部變量,該函數返回的是內部局部字符數組str的地址,當函數調用之后該數組被銷毀,所以返回的指針是一個已經釋放了空間的指針,指向的值不定。
在函數get_str2中,char* str = { "abcd" },先定義一個字符串常量“abcd“,再將指針str指向它,返回值是這個指針,由於字符串常量在編譯時分配內存,只有程序退出時才被銷毀,所以返回它的地址沒有問題。
例子2:
1)char s[5];
s = "abcd"; //錯誤
2)char *s;
s = "abcd"; //正確
1編譯不通過但是2編譯通過。這是因為在1中,s是數組名,當成是常量指針,不可以作為左值修改;而2中s是一個指針變量,可以將其指向一個字符串常量。
總的來說
1)
char str[] = { "abcd" },str在棧上申請空間,將常量內容復制進來
char *str = {"abcd"},str指向該常量的地址
2)
char str[] = { "abcd" },sizeof(str) = 5,strlen(str) = 4
char *str = {"abcd"},sizeof(str) = 4(x86)或者8(x64),strlen = 4
注:指針的sizeof運算結果都是4