天天看點

C++字元數組與字元指針在運算時的差別

char *strPtr = "HELLO ";

char str[] = "HELLO ";

*(strPtr + 1) = 'B'; // 出錯

*(str + 1) = 'B'; // 正常執行

原因分析如下:

C++字元數組與字元指針在運算時的差別
C++字元數組與字元指針在運算時的差別
C++字元數組與字元指針在運算時的差別
C++字元數組與字元指針在運算時的差別

“HELLO”在記憶體中的存儲形式:

C++字元數組與字元指針在運算時的差別

 指針變量strPtr在記憶體中的存儲形式:(前面是記憶體的位址)

C++字元數組與字元指針在運算時的差別

冒号前面是記憶體的位址,後面存放的是具體内容。可以看出指針變量存儲的是"HELLO "的第一個字母的記憶體位址。

str數組在記憶體中的存儲形式: 

C++字元數組與字元指針在運算時的差別

 冒号前面是記憶體的位址,後面存放的是具體内容。可以看出字元數組中的每個元素存儲的是"HELLO "的每個字母的記憶體位址。

1,printf("%xd\n", &strPtr); // 輸出結果為:0x00C17BF0

2,printf("%xd\n", strPtr); // 輸出結果為:0x00907BF0

3,printf("%xd\n", &str); // 輸出結果為:0x001BA9F0

4,printf("%xd\n", str); // 輸出結果為:0x001BA9F0

上述1和2中輸出的結果不同是因為strPtr是一個變量,變量名作為表達式時實際是取這個變量中所存取的值。是以1是輸出strPtr這個變量的位址,而2是輸出strPtr這個變量存取的值。而3和4輸出的結果相同是因為str隻是數組名稱并不是一個變量。而數組名稱作為表達式時表示的就是這個數組第一個元素的位址。而&str表示的是整個數組在記憶體中占用的位址。它是一個指針數組,即char (*strArray)[6] = &str;strArray中的每個元素存取的值就是str這個數組各個元素的記憶體位址。這裡輸出時由于沒有指定輸出哪個元素,是以預設輸出了strArray的第一個元素。是以它與4的輸出結果相同。

從上可以看出,對數組str進行的運算實際是對其自身的記憶體位址進行的運算。即str+1實際是擷取了str這個數組的第2個元素的位址,而不是這個資料的第2個元素所存取的位址。擷取的結果為0x001BA9F1。而對指針strPtr進行的運算實際是對其所存儲的記憶體位址進行的運算。即strPtr+1實際是擷取的其存儲的記憶體位址進行加1。擷取的結果為0x00907BF1。是以,*(str + 1) = 'B';操作實際隻是改變了0x001BA9F這個位址中所存取的值,而*(strPtr + 1) = 'B';則是要改變0x00907BF1這個位址中所存取的值。而0x00907BF1這個位址中存取的是字面量的值,即常量的值,是不允許修改的。是以,執行*(strPtr + 1) = 'B';操作時會出錯。

繼續閱讀