![](/img/trans.png)
[英]what is the difference between string a=“hello” and string a=(char *)“hello” in c++?
[英]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 數組就是這樣 - 一個字符數組:
字符串是一個包含字符數組的類,但會自動為您管理它。 大多數字符串實現都有一個由 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.