C++中的字元串
今天複習數據結構,寫程式碼時,遇到一個string比較的問題,查閱了大佬們的部落格後,在這裡做個總結記錄(並附上對應鏈接)。
本文,先闡述C++中char[],char*和string三者的區別和聯繫,然後說明C++中的字元串比較的問題。
先說區別與聯繫。
首先明確一個點,C語言中,並無string數據類型(C++也沒有)。在C語言中,字元串一般是通過 char[] 數組來存儲的, 而<string.h>這個頭文件里聲明的函數原型也全是針對char數組的種種操作。直到C++中才出現了string這個類(注意是類,不是類型)。這裡引用一個較為嚴謹的說法:
“C語言中有string類型變數嗎”
這裡的string有二義性。
(1)如果string是普通辭彙,「C語言中有字元類型變數嗎」,答,有。字元類型用char聲明。
char str[] = “This is a string”;
(2)如果string是專用辭彙,「C語言中有string類型變數嗎」,答,沒有。string是類,是class;不是類型,不是type。
類的聲明用構造函數初始化,或new聲明。
一、char [] 類型
#include <iostream> using namespace std; int main() { char a[10] = "123"; cout << a; return 0; } // 輸出:123,此程式在a[3]的位置自動寫入了'\0',終止符
又如:
#include <iostream> using namespace std; int main() { char a[10]; a[0] = 'A'; a[2] = 'C'; cout << a; return 0; } // 輸出:A
注意:這裡的char [] 數組,
如果是全局變數,靜態變數,一般編譯器(具體要依賴於具體所使用的編譯器和系統)會採用默認原則將內部的所有位置設置為0;
如果是局部變數,由於局部變數的記憶體分配是在棧上,如果未對char數組進行初始化的話,數組內的數據取決於此處原來的數據。同理,動態變數在堆上,同樣數據為任意值。
一般來說 全局變數、靜態變數處於數據區,默認初始化為0 (如果指定初始值,則為指定的值)
而局部變數處於堆棧區,其數值是隨機的,即當時記憶體中的值。
建議:不要利用編譯器的這種默認原則,而是應當顯示的指定,必要的初始化不是笨拙,而是規範。
二、char [] 和char*
1、字元串char*
char *str1="abcde"; //這是一個字元串常量,存儲在靜態存儲區,是只讀的。
const char *str1 = "abcde";
char const *str1 = "abcde"; //注意,這兩種寫法等價
//其中,str1是一個變數,代表的意思就是字元串的第一個字元的值
此處參照此部落格:
關於字元串常量&字元數組&字元常量://blog.csdn.net/wuwuku123/article/details/103575620
const char * 、char const * 、 char * const 三者的區別://blog.csdn.net/qq_40244176/article/details/80765975
*(str1++);//可行 *(str1+2)='f';//不可行
如:
char *str2=str1;
“abcde”存儲的區域沒有改變,只是將str1的地址複製給str2;
2、字元串數組:
char str3[]="abcde"; //str3是數組名,一個常量
str3++; //不可行
str3[2]='f';//可行
如:
char *str4=&str3;
上面語句是將”abcde”複製一遍,然後再複製給是str4;
三、char* 和 string
char是一個字元類型 C++的內置類型,char *是字元指針;
而string是一個字元容器,是一個擴展的模版類。
(一)、先解釋char*字元串和string對象的區別。
1、定義
string:string是C++STL當中的一個容器,對其進行了封裝,所以操作起來非常方便。
char*:char*是一個指針,可以指向一個字元串數組,至於這個數組可以在棧上分配,也可以在堆上分配,堆得話就要你手動釋放了。
2、區別:
string的記憶體管理是由系統處理,除非系統記憶體池用完,不然不會出現這種記憶體問題。
char*的記憶體管理由用戶自己處理,很容易出現記憶體不足的問題。
當我們要存一個串,但是不知道其他需要多少記憶體時,用string來處理就最好不過了。
當你知道了存儲的記憶體的時候,可以用char*,但是不如用string的好,用指針總會有隱患。
用string還可以使用各種成員函數來處理串的每一個字元,方便處理。
用char*處理串,就不如string的方便了,沒有相應的函數來直接調用,而是要自己編寫函數來完成串的處理,而且處理過程中用指針還很容易出現記憶體問題。
char* s = “string”; 的內容是不可以改的;chars[10] = “string” 的內容是可以改的。
3、注意:
當我們定義了一個string,就不能用scanf(“%s”,s)和printf(“%s”,s)輸入輸出。主要是因為%s要求後面是對象的首地址。