2011-01-28 111 views
11

如果我有一個指向一個字符串變量array of chars的指針,有沒有打字之間的差異:C++ - 的char *與字符串*

char *name = "name"; 

而且,

string name = "name"; 
+0

什麼類型在這個例子中「字符串」? – Nick 2011-01-28 09:09:51

+12

`string * name =「name」;`不會編譯。 – Naveen 2011-01-28 09:09:53

+1

Dupe of:http://stackoverflow.com/questions/801209/c-char-vs-stdstring(一旦語法錯誤被修復)? – Flexo 2011-01-28 09:10:34

回答

28

是的,有一個區別。主要是因爲你可以修改你的字符串,但你不能修改你的第一個版本 - 但C++編譯器甚至不會警告你,如果你嘗試這是禁止的。

所以總是使用第二個版本。

如果你需要使用一個字符指針,無論出於何種原因,使其const

char const* str = "name"; 

現在,如果你嘗試修改的str內容,編譯器將禁止這個(正確)。您還應該將編譯器的警告級別提高一級:然後它會警告您的第一個代碼(即char* str = "name")是合法的,但不推薦使用。

+2

@Konrad魯道夫。當你說「你的字符串變量不應該是一個指針」時,爲什麼?謝謝 – Simplicity 2011-01-28 09:19:23

+2

@ user588855:因爲`std :: string`已經在內部管理`char *`指針了,所以你只需要將它作爲普通對象來使用。儘管如此,爲了避免昂貴的副本,如果將它用作函數參數,並且不需要在函數內部修改,請記住通過`const`引用(`const string&`)傳遞它。 – 2011-01-28 09:24:58

0

是的,char*是指向一個字符數組的指針,它是一個字符串。 string *是指向std::string(這是很少使用)的數組的指針。

string *name = "name"; 

「名」是一個const char*,它永遠不會被轉換爲std::string*。這將導致編譯錯誤。

有效聲明:

string name = "name"; 

const char* name = "name"; // char* name = "name" is valid, but deprecated 
8

是的,第二個是無效的C++! (它不會編譯)。

您可以創建一個在許多方面string,但一個方法如下:

string name = "name"; 

注意,沒有必要爲*,因爲我們並不需要把它聲明爲一個指針。

-1
string *name = "name"; 

在GCC中不編譯。

8

對於初學者來說,你可能想改變

string *name = "name"; 

閱讀

string name = "name"; 

第一個版本將無法編譯,因爲string*char*是完全不同的類型。

stringchar*之間的區別在於char*只是指向序列的指針。這種操作字符串的方法基於C編程語言,並且是以C++編碼字符串的本地方式。 C字符串的工作有點棘手 - 您需要確保爲它們正確分配空間,以避免走出它們佔用的緩衝區的末端,將它們放入可變內存以避免出現分段錯誤等。主要功能操縱他們在<cstring>。大多數C++程序員建議不要使用C風格的字符串,因爲它們本質上難以使用,但是它們仍然支持向後兼容性和作爲低級API可以構建的「最低公分母」。

C++風格string是封裝字符串的對象。其內存管理的細節對用戶不可見(儘管可以保證所有的內存都是連續的)。它使用運算符重載來使像串聯這樣的常用操作更易於使用,並且還支持設計用於執行諸如搜索,替換,子串等高級操作的若干成員函數。它們也被設計爲與STL算法交互操作,儘管C風格的字符串也可以做到這一點。

總之,作爲一名C++程序員,您最好使用string類型。它更安全,更易於使用。瞭解C風格的字符串還是很好的,因爲在你的編程生涯中你肯定會遇到它們,但是最好不要在你的程序中使用它們,除非有令人信服的理由才能使用string

4

char* name = "name"應該是無效的,但是在大多數系統上進行編譯,以便在沒有const的情況下向後兼容舊版本,並且如果沒有編譯,會破壞大量遺留代碼。它通常會收到警告。

危險是你得到一個指向可寫入數據的指針(根據C++的規則可寫),但是如果你真的試圖寫入它,你會調用Undefined Behavior,並且語言規則應該試圖保護你儘可能合理。

正確的結構是

const char * name = "name"; 

這沒有什麼錯以上,即使在C++中。使用字符串並不總是更正確。

你的第二個說法確實應該

std::string name = "name"; 

串因此std下在標準庫中定義的類(實際上是一個的basic_string<char,char_traits<char>,allocator<char>的typedef)(如在basic_string的,char_traits和分配器)

有很多使用字符串比使用char數組更好的場景。舉個例子,你可以修改它。所以

name[0] = 'N'; 

(轉換的第一個字母爲大寫)是字符串,而不是用的char *(未定義行爲)或爲const char *(不會編譯)有效。你可以修改字符串,如果你有char name[] = "name";

但是,如果想要追加一個字符到字符串,std :: string結構是唯一一個可以讓你做到這一點乾淨。使用舊的C API,你將不得不使用strcat(),但除非你已經分配足夠的內存來做這件事,否則這將是無效的。

std :: string爲你管理內存,所以你不必調用malloc()等。實際上,allocator是第三個模板參數,它管理着下面的內存 - basic_string提出了它需要多少內存的請求,但是與實際使用的內存分配技術分離,所以你可以使用內存池等來提高效率,即使使用std ::串。

另外的basic_string實際上並不執行很多都是做,而不是通過char_traits字符串操作。 (這使得它可以使用專業的C函數,在其下進行優化)。因此

的std :: string是當你正在處理構造和在運行時(而不僅僅是文字)傳來傳動態字符串來管理你的字符串的最佳方式。

你很少會使用字符串*(一個指向字符串)。如果你這樣做,它將是一個指向對象的指針,就像任何其他指針一樣。你不能像你那樣分配它。

1

C++串類封裝炭類C的字符串組成。這是一個更方便(http://www.cplusplus.com/reference/string/string/)。

遺留你總是可以「提取」從字符串變量字符指針來處理它作爲字符指針:

char * cstr; 
    string str ("Please split this phrase into tokens"); 
    cstr = new char [str.size()+1]; 
    strcpy (cstr, str.c_str()); //here str.c_str() generate null terminated char* pointer 
    //str.data() is equivalent, but without null on end