2014-01-20 103 views
1

做這兩個選項有什麼區別,爲什麼在C++中不推薦使用第二種類型?char array []和char *數組有什麼區別?

char hello[] = {'h', 'e', 'l', 'l', 'o', '\0'}; 

char *hello = "hello"; 

但在正確的C++第二個應該是:

const char *hello = "hello"; 

對於我猜你是永遠不會改變「你好」,但你爲什麼不能,如果你改變這種記憶的大部分想要?

+0

正確的C++應該是'std :: string hello =「hello」'。 –

+3

這只是如果你想使用std類,C++中的字符串不必使用字符串類 – OnlyJoe

+0

你在問C++中表示字符串文字的方法。雖然你仍然**可以執行'char []'和'char *',C++中的propper方式是使用'string'庫。 http://stackoverflow.com/questions/10022117/why-should-one-use-stdstring-over-c-style-strings-in-c 簡而言之:沒有真正的理由留在'char'表中比使用舊代碼,你沒有真正的選擇。 –

回答

4

char hello[] = {'h', 'e', 'l', 'l', 'o', '\0'};

這產生在可寫存儲器6個字節的陣列(在棧上,如果這是一個函數內,在一個數據段,如果直接在全局範圍內或內部的命名空間),以用這些字符中的每一個的ASCII碼依次初始化。

char * hello =「hello」;

"hello"字符串文字,這通常表示:

  • 加載程序到內存中,並開始運行將有複製文本「hello \ 0的OS加載程序代碼「從可執行映像轉換爲某些內存,然後將其設置爲只讀,並且

  • 一個名爲」hello「的單獨變量 - 無論大小指針在您的程序中(例如(如果上面的行出現在函數內部)或可寫內存段(如果該行在全局或命名空間範圍內),則會在堆棧中存在4個字節(對於32位應用程序爲8個字節)以前的文本數據將被複制到hello指針中。

  • 您可以將hello更改爲指向其他地方(例如指向另一種語言的等效文本),但通常不應嘗試更改上述代碼指向的字符串字面值hello ...請參閱下文。

但在正確的C++中的第二應該是:

常量字符*你好= 「你好」;

是的 - 那太好了。爲了向後兼容,C++在歷史上允許非const指向字符串文字的指針,但實際上修改它們並不保證是可能的。一些編譯器總是或者可以選擇的(當被命令行參數詢問時),將字符串文字放在可寫內存中。但是,即使它們是可寫的,改變它們也會導致很多錯誤。假設你有一個像這樣和編譯器標誌代碼,允許它來編譯:

然後一些完全無關的代碼,這是否......

std::cout << "this is the " << (x ? "start": "end"); 

...可能開始打印「結束」,如果所有提到「結束」的內容都共享相同的內存 - 這是一種常見的理想優化。關閉此功能可能非常浪費,雖然它允許此hackery在不相關的文本使用方面使用較少的意外副作用,但當if (s == "end")可能實際上並未比較s"end"時,仍然很難推斷代碼和調試。

1

當您使用[]您創建一個數組是一個項目的集合,在這種情況下的字符。你可能知道,使用*會創建一個可能看起來是相同的東西,但只是一個單一的值(內存地址)的指針。

本質上,該數組創建一個與數據一樣大的變量,因爲指針只是創建一個包含字符串常量的內存位置的8字節變量。

0

如果你願意,你可以改變一個字符串,只需使用

char hello[] = "Hello"; 

這是合法的,確切指的是與您的第一個語句。您也可以保留額外的空間,因爲你寫,你可能希望存儲後,一個更大的字符串:

char hello[100] = "Hello"; 
0

是什麼做的這兩個選項

第一個聲明的區別包含這些字符的數組。第二個聲明一個指向字符串的指針:一個包含相同字符的靜態常量數組。或者它會,如果你被允許這樣做。

爲什麼C++中不推薦使用第二種類型?

它不是:它是禁止的,因爲字符串文字是常量。在C++ 11之前,它被允許但不贊成使用,以避免破壞沒有使用const的古代代碼。在任何一種情況下,嘗試修改文字都會導致未定義的行爲。

爲什麼你不能改變這個記憶如果你想?

因爲字符串文字是不變的。如果你想要一些你可以改變的內存,你必須創建你自己的數組。

相關問題