C++」對char* 和 char「」區別

轉載(稍微添加了點東西):https://blog.csdn.net/u012611878/article/details/78291036

首先我們先看看他們之間的相同點

1、這兩種類型都可以對應一個字符串,比如:

char * a=”hello1”; 
char b[]=”hello2”;
printf(“a=%s, b=%s”, a, b);

其中a是一個指向char變量的指針,b則是一個char數組(字符數組),

其次 ,很多時候二者可以混用,像函數傳參數的時候,實參可以是char*,形參可以是 char[],比如:

void fun1(char b[])
{
printf(“%s”,b);
}
int main()
{
char *a=“HellowWorld”;
fun1(a);
}

反過來,實參可以是char[],形參可以是 char *也是可以的。

2、他們都是以'\\0'結尾;(注意不同的求長度函數對他們的處理不同,有的計算'\\0',有的沒有計算);

strlen()是取字符串除去結尾符 “\\0” 的長度;

sizeof()是包含‘\\0’的長度

存在即合理,char *和char[]肯定是有本質的不同

接下來查看他們的不同點:

1.char*是變量,值可以改變;

char[]是常量,值不能改變。

如下:

char * a=”string1”; 
char b[]=”string2”;
a=b; //OK
a=”string3”; //OK
b=a; //報錯!左邊操作數只讀
b=”string3” //報錯!左邊操作數只讀

解釋: a是一個char型指針變量,其值(指向)可以改變;

b是一個char型數組的名字,也是該數組首元素的地址,是常量,其值不可以改變 。

2、char[]對應的內存區域總是可寫,char*指向的符號常量不能寫

char *p = "sample";
*(p + 4) = '1';//程序會崩潰

崩潰的原因在於

char*定義的p是在棧中分配的一個指針,“sample”是一個在靜態區分配了一塊常量區,指針p指向了這塊常量去,常量去是無法進行數據的更改的,所有在試圖更改“sample”的時候程序會崩潰。

char a[] = "sample";
a[1] = 'b';
printf("a=%s\\n", a);

程序可以正常運行,可以發現數組a的值成功的被改成了“sbmple”

3.char * 和char[]的初始化操作有著根本區別:

測試代碼:
char *a=”Hello World”;
char b[]=”Hello World”;
printf(“%s, %d\\n”,”Hello World”, “Hello World”);
printf(“%s, %d %d\\n”, a, a, &a);
printf(“%s, %d %d\\n”, b, b, &b);

結果:

「C/C++」對char* 和 char「」區別

結果可見:儘管都對應了相同的字符串,但”Hellow World”的地址 和 a對應的地址相同,與b指向的地址有較大差異;&a 、&b都是在同一內存區域,且&b==b

根據c內存區域劃分知識,我們知道,局部變量都創建在棧區,而常量都創建在文字常量區,顯然,a、b都是棧區的變量,但是a指向了常量(字符串常量),b則指向了變量(字符數組),指向了自己(&b==b==&b[0])。

說明以下問題:

char * a=”string1”;實現了3個操作:

1、聲明一個char*變量(也就是聲明瞭一個指向char的指針變量)。

2、在內存中的文字常量區中開闢了一個空間存儲字符串常量”string1”。

3、返回這個區域的地址,作為值,賦給這個字符指針變量a

最終的結果:指針變量a指向了這一個字符串常量“string1”

(注意,如果這時候我們再執行:char * c=”string1”;則,c==a,實際上,只會執行上述步驟的1和3,因為這個常量已經在內存中創建)

char b[]=”string2”;則是實現了2個操作:

2、為該數組“賦值”,即將”string2”的每一個字符分別賦值給數組的每一個元素,存儲在棧上。

最終的結果:“數組的值”(注意不是b的值)等於”string2”,而不是b指向一個字符串常量

實際上, char * a=”string1”; 的寫法是不規範的!

因為a指向了即字符常量,一旦strcpy(a,”string2”)就糟糕了,試圖向只讀的內存區域寫入,程序會崩潰的!儘管VS下的編譯器不會警告,但如果你使用了語法嚴謹的Linux下的C編譯器GCC,或者在windows下使用MinGW編譯器就會得到警告。

所以,我們還是應當按照”類型相同賦值”的原則來寫代碼: const char * a=”string1”;

保證意外賦值語句不會通過編譯。

小結

const char * a=”string1” 
char b[]=”string2”;

1、a是const char 類型, b是char const類型

2、a是一個指針變量,a的值(指向)是可以改變的,但a只能指向(字符串)常量,指向的區域的內容不可改變;

3、b是一個指針常量,b的值(指向)不能變;但b指向的目標(數組b在內存中的區域)的內容是可變的

4、作為函數的聲明的參數的時候,char []是被當做char *來處理的!兩種形參聲明寫法完全等效!


分享到:


相關文章: