簡體   English   中英

C++中string和char[]類型的區別

[英]Difference between string and char[] types in C++

我知道一點 C,現在我正在研究 C++。 我習慣於使用字符數組來處理 C 字符串,但是當我查看 C++ 代碼時,我看到有使用字符串類型和字符數組的示例:

#include <iostream>
#include <string>
using namespace std;

int main () {
  string mystr;
  cout << "What's your name? ";
  getline (cin, mystr);
  cout << "Hello " << mystr << ".\n";
  cout << "What is your favorite team? ";
  getline (cin, mystr);
  cout << "I like " << mystr << " too!\n";
  return 0;
}

#include <iostream>
using namespace std;

int main () {
  char name[256], title[256];

  cout << "Enter your name: ";
  cin.getline (name,256);

  cout << "Enter your favourite movie: ";
  cin.getline (title,256);

  cout << name << "'s favourite movie is " << title;

  return 0;
}

(兩個例子都來自http://www.cplusplus.com

我想這是一個被廣泛詢問和回答(顯而易見?)的問題,但如果有人能告訴我在 C++ 中處理字符串的兩種方式之間的確切區別是什么,那就太好了(性能、API 集成、每種方式的方式)更好的, ...)。

謝謝你。

char 數組就是這樣 - 一個字符數組:

  • 如果在堆棧上分配(如您的示例中),它將始終占用例如。 256 字節,無論它包含多長的文本
  • 如果在堆上分配(使用 malloc() 或 new char[]),您負責之后釋放內存,並且您將始終擁有堆分配的開銷。
  • 如果將超過 256 個字符的文本復制到數組中,它可能會崩潰、產生丑陋的斷言消息或在程序的其他地方導致無法解釋的(錯誤)行為。
  • 要確定文本的長度,必須逐個字符地掃描數組以獲取 \\0 字符。

字符串是一個包含字符數組的類,但會自動為您管理它。 大多數字符串實現都有一個由 16 個字符組成的內置數組(因此短字符串不會對堆造成碎片),並將堆用於更長的字符串。

您可以像這樣訪問字符串的字符數組:

std::string myString = "Hello World";
const char *myStringChars = myString.c_str();

C++ 字符串可以包含嵌入的 \\0 字符,無需計算就知道它們的長度,比短文本的堆分配字符數組更快,並保護您免受緩沖區溢出的影響。 此外,它們更具可讀性和更易於使用。


然而,C++ 字符串並不(非常)適合跨 DLL 邊界使用,因為這將要求此類 DLL 函數的任何用戶確保他使用完全相同的編譯器和 C++ 運行時實現,以免他的字符串類冒着不同行為的風險。

通常,字符串類也會在調用堆上釋放其堆內存,因此如果您使用的是運行時的共享(.dll 或 .so)版本,它只能再次釋放內存。

簡而言之:在所有內部函數和方法中使用 C++ 字符串。 如果您曾經編寫過 .dll 或 .so,請在公共(dll/so-exposed)函數中使用 C 字符串。

Arkaitz 認為string是托管類型是正確的。 這對來說意味着您永遠不必擔心字符串有多長,也不必擔心釋放或重新分配字符串的內存。

另一方面,上述情況中的char[]表示法將字符緩沖區限制為恰好 256 個字符。 如果您嘗試將超過 256 個字符寫入該緩沖區,則充其量您將覆蓋程序“擁有”的其他內存。 最壞的情況是,您會嘗試覆蓋不屬於您的內存,而您的操作系統會當場殺死您的程序。

底線? 字符串對程序員更友好,char[] 對計算機來說效率更高。

嗯,string 類型是一個完全托管的字符串類,而 char[] 仍然是它在 C 中的樣子,一個字節數組,代表一個字符串給你。

就 API 和標准庫而言,一切都是根據字符串而不是 char[] 實現的,但是 libc 中仍有許多函數接收 char[],因此您可能需要將它用於那些,除此之外我會始終使用 std::string。

在效率方面,非托管內存的原始緩沖區對於很多事情來說幾乎總是更快,但是考慮到比較字符串,例如,std::string 總是有大小可以先檢查它,而使用 char[] 你需要逐字比較。

除了與舊代碼的兼容性之外,我個人看不出有任何理由想要使用 char* 或 char[]。 std::string 並不比使用 c 字符串慢,只是它會為您處理重新分配。 您可以在創建時設置它的大小,從而避免重新分配(如果需要)。 它的索引運算符 ([]) 提供恆定時間訪問(並且在任何意義上都與使用 c 字符串索引器完全相同)。 使用 at 方法也可以為您提供邊界檢查的安全性,除非您編寫它,否則您無法使用 c 字符串獲得這種安全性。 您的編譯器通常會優化發布模式下的索引器使用。 很容易弄亂 c 字符串; 諸如刪除與刪除 []、異常安全,甚至如何重新分配 c 字符串之類的事情。

當您必須處理高級概念(例如使用 COW 字符串和用於 MT 的非 COW 等)時,您將需要 std::string。

如果您擔心副本,只要您盡可能使用引用和常量引用,您就不會因副本而產生任何開銷,這與您使用 c 字符串所做的事情相同。

將 (char *) 視為 string.begin()。 本質區別在於 (char *) 是一個迭代器,而 std::string 是一個容器。 如果您堅持使用基本字符串,則 (char *) 將為您提供 std::string::iterator 的功能。 當您想要迭代器的好處以及與 C 的兼容性時,您可以使用 (char *),但這是例外而不是規則。 與往常一樣,請注意迭代器失效。 當人們說 (char *) 不安全時,這就是他們的意思。 它與任何其他 C++ 迭代器一樣安全。

字符串具有輔助函數並自動管理字符數組。 您可以連接字符串,對於 char 數組,您需要將其復制到新數組中,字符串可以在運行時更改其長度。 字符數組比字符串更難管理,某些函數可能只接受字符串作為輸入,需要您將數組轉換為字符串。 最好使用字符串,它們是為了您不必使用數組而制作的。 如果數組客觀上更好,我們就不會有字符串。

區別之一是空終止 (\\0)。

在 C 和 C++ 中,char* 或 char[] 將使用指向單個字符的指針作為參數,並沿着內存進行跟蹤,直到達到 0 內存值(通常稱為空終止符)。

C++ 字符串可以包含嵌入的 \\0 字符,無需計算即可知道它們的長度。

#include<stdio.h>
#include<string.h>
#include<iostream>

using namespace std;

void NullTerminatedString(string str){
   int NUll_term = 3;
   str[NUll_term] = '\0';       // specific character is kept as NULL in string
   cout << str << endl <<endl <<endl;
}

void NullTerminatedChar(char *str){
   int NUll_term = 3;
   str[NUll_term] = 0;     // from specific, all the character are removed 
   cout << str << endl;
}

int main(){
  string str = "Feels Happy";
  printf("string = %s\n", str.c_str());
  printf("strlen = %d\n", strlen(str.c_str()));  
  printf("size = %d\n", str.size());  
  printf("sizeof = %d\n", sizeof(str)); // sizeof std::string class  and compiler dependent
  NullTerminatedString(str);


  char str1[12] = "Feels Happy";
  printf("char[] = %s\n", str1);
  printf("strlen = %d\n", strlen(str1));
  printf("sizeof = %d\n", sizeof(str1));    // sizeof char array
  NullTerminatedChar(str1);
  return 0;
}

輸出:

strlen = 11
size = 11
sizeof = 32  
Fee s Happy


strlen = 11
sizeof = 12
Fee

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM