c++有兩種處理字串的方式,除了沿用c風格字串,另一種方法是借助用string class
庫。
字串是一系列儲存在連續記憶體位元組中的字元(每個字元對應乙個位元組),所以可以將字串儲存在字元陣列中。以下四種宣告方式都是字元陣列,但是只有第乙個不是字串,其中無效字元(null character)'\0'
(其在機器字符集ascii中對應的整數值是0)起了關鍵作用。字元陣列c
使用字串常量(即雙引號引用的字串)將字元陣列初始化為字串,比字元陣列b
的宣告更簡潔,並且隱含乙個結尾無效字元'\0'
。甚至可以省略陣列宣告中的陣列大小,讓編譯器來統計字元個數,如字元陣列d
,得到的陣列大小等於字串長度加一。
c和c++的大多數表示式將字元陣列名、字元指標和字串常量都解讀為字串首字元的位址(即為字串的位址)1char a[3] = ; // not a string
char b[5] = ; // a string
char c[5] = "ok"; // same as b
char d = "ok"; // let the compiler count
,並做相同處理。以c++的cout
為例,將字元位址傳遞給cout
後,cout
認為該字元位址是字串的位址,列印出從該位址開始的每個字元,直到遇到第乙個無效字元'\0'
。如以下**示例所示,將字元陣列a
傳遞給cout
後,除了明確給出的3個字元,還列印出來一些亂碼,而且使用strlen()
函式得到的字串長度也大於明確給出的字元陣列大小。相比之下,字元陣列b
是乙個字串,字串長度是無效字元前的字元數量,即2,而陣列大小是5。
輸出#include
#include
// for strlen() function
using
namespace std;
intmain
(int argc,
char
const
*ar**)
;// not a string
char b[5]
=;// a string
cout <<
"array of chars a: "
<< a <<
'\n'
; cout <<
"array of chars b: "
<< b <<
'\n'
; cout <<
"sizeof(a): "
<<
sizeof
(a)<<
'\n'
; cout <<
"sizeof(b): "
<<
sizeof
(b)<<
'\n'
; cout <<
"strlen(a): "
<<
strlen
(a)<<
'\n'
; cout <<
"strlen(b): "
<<
strlen
(b)<<
'\n'
;return0;
}
字串的長度由結尾的無效字元決定。對於c語言風格字串,可以使用標準庫array of chars a: odd��x��<0x7f>
array of chars b: ok
sizeof(a): 3
sizeof(b): 5
strlen(a): 9
strlen(b): 2
或
裡的函式strlen
來求字串長度,**示例如下:
如果使用c++的int
strlen
(const
char
* s)
return i;
}
string class
,可以使用其成員函式std::string::size
或std::string::length
返回字串長度。
由於c和c++的大多數表示式將字元陣列、字元指標和字串常量當作字串首字元的位址,用字串常量初始化字元常量指標時const char * ps = "hello"
,實際上將字串常量"hello"
所代表的字串位址賦值給ps
。記憶體中有一塊專門的空間,用來存放所有字串常量。從以下**示例的輸出二可以看出存放字串常量的記憶體區和存放字元陣列的記憶體區相差很遠。並且由於字串常量是常量,所以在宣告中使用修飾符const
,明確不能對該字元指標所指的整個字串記憶體空間的內容進行修改。
輸出一(取消#include
using
namespace std;
intmain
(int argc,
char
const
*ar**)
main()
函式第1、2和4行注釋,編譯報錯)
如果沒有使用修飾符string_constant.cpp:6:17: warning: iso c++11 does not allow conversion from string literal to 'char *'
[-wwritable-strings]
char *ps1 = "hello";
^string_constant.cpp:9:12: error: read-only variable is not assignable
ps2[0] = 'w';
~~~~~~ ^
const
,初始化時會進行隱含轉換,將不能修改的字串常量轉化為可以賦值的字串。c++明確反對用字串常量初始化字元指標char *
,編譯不通過,警告資訊如上面的輸出一所示。而嘗試通過字元常量指標const char *
修改字串常量所導致的編譯錯誤資訊很常見:唯讀變數不可賦值。
輸出二
通常情況下,address of string constant "hello": 0x102e7af0c
address of character array "there": 0x7ffeecd88a82
cout
接收到指標,相應列印出位址。但是當cout
接收到字元指標char *
時,cout
列印出指標所指向的整個字串。所以如果想顯示字串位址,需要進行型別轉換(type cast),比如轉換成void *
或int *
。
shell輸出#include
#include
intmain
(int argc,
char
const
*ar**)
c++ primer plus 6th edition by stephen prata ↩︎user@laptop c/c++ % clang string_constant.c
user@laptop c/c++ % ./a.out
hello, world
zsh: bus error ./a.out
C C 字串常量 字元陣列和字元指標
通常,如果在程式中定義了乙個字串,那麼為了節省記憶體,會把相同的字串儲存到乙個單獨的 相同的位置,此時如果用多個字元指標指向它,那麼指標的值會相同。常量字串位於c c 的文字常量區,在程式結束以後由系統釋放。char p string1 example char p string2 example ...
C C 字串和字元陣列
c語言中沒有專門的字串變數,如果要將乙個字串存放在變數中,必須使用字元陣列,即用乙個字元型陣列來存放乙個字串,陣列中每乙個元素存放乙個字元。1 定義 char c 10 字元型與整型互相通用,因此 int c 10 也可以定義字元陣列。但由於兩種型別分配位元組不同,用整型來定義會浪費空間,另外這樣定...
C 字元 字串 字元陣列 字串指標 指標陣列
一 c 字元 字串 字元陣列 字串指標 指標陣列 前言 一 字元指標 字元陣列 二 字串指標 三 字串 指標陣列 四 常用方法 參考為了深入理解c 並時常回顧學過的知識點,對c 知識點進行記錄總結。參考1字元指標的儲存方式 字元指標變數本身是乙個變數,用於存放字元 字串的首位址。字串本身是存放在以該...