字符串是以ASCII字符NUL結尾的字符序列。
ASCII字符NUL表示為\0.字符串通常存儲在數組或者從堆上分配的內存中。只是,並不是全部的字符數組都是字符串,字符數組可能沒有NUL字符。
字符數組也用來表示布爾值等小的整數單元,以節省內存空間。
C中有兩種類型的字符串:
單字節字符串
由char數據類型組成的序列
寬字符串
由wchar_t數據類型組成的序列
wchar_t數據類型用來表示寬字符,要么是16位寬。要么是32位寬。這兩種字符串都以NUL結尾。能夠在string.h中找到單字節字符串函數。而在wchar.h中找到寬字符串函數。寬字符主要用於非拉丁字符集,對於支持外語的應用程序非常實用,
字符串的長度是字符串中除了NUL字符外的字符數。為字符串分配內存的時候,要記住為全部的字符加上NUL字符分配足夠的空間。
NULL和NUL不一樣。NULL用來表示特殊的指針,通常定義為((void*)0)。而NUL是一個char,定義為\0,兩者不能混用!
字符常量是單引號引起來的字符序列。
字符常量通常由一個字符組成。也能夠包括多個字符,比方轉義字符。
在C中,它們的類型是int,例如以下所看到的:
printf("%d\n",sizeof(char)); printf("%d\n",sizeof('A')); //output //1 //4
字符串聲明
聲明字符串的方法有三種:字面量,字符數組。和字符指針。
字符串字面量是用雙引號引起來的字符序列,經常使用來進行初始化,他們位於字符串字面量池中。<span style="color:#ff0000;">這和單引號引起來的字符不一樣!</span>
以下是一個字符數組的樣例:
char header[32];
以下是字符指針:
char *header;
字符串字面量池
定義字符量一般會將其分配到字面量池中。這個內存區域保存了組成字符串的字符序列。
多次會用到同一個字面量時,字面量池一般會僅僅有一個副本。這樣能夠降低應用程序占用的內存。
通常覺得字面量是不可變的,因此僅僅有一份副本不會有什么問題。
字符串字面量一般分配在僅僅讀區域中,所以是不可變的。字符串字面量在哪里使用。或者他是全局,靜態或者局部都無所謂,從這個角度講。字符串字面量不存在作用域的概念。
在大部分編譯器中。我們將字符串字面量看做常量。無法改動字符串。
可是GCC編譯器容許字符串字面量能夠改動。
char *header = "Sound"; *header = 'L'; printf("%s\n",header); //output //Lound
這樣就會改變字符串,不是我們預期的結果。因此應該避免這樣做。像以下這樣把變量聲明為常量能夠解決一部分問題。不論什么改動都會造成編譯時錯誤:
const char *header = "Sound";
字符串初始化
初始化字符串採用的方法取決於變量是被聲明為字符數組還是字符指針,字符串所用的內存要么是指針指向的一塊內存。我們都能夠用字符串字面量或者一些列字符初始化字符串,或者從別的地方(標准輸入)得到字符。
初始化char數組
我們能夠用初始化操作符初始化char數組。在下例中。header數組被初始化為字符串字面量中所包括的字符:
char header[] = "Media Player";
字符量"Media Player"的長度為12,表示這個字面量須要13個字節,我們就要為數組分配13個字節來持有字符串。初始化操作會把這些字符拷貝到數組中,以NUL結尾。
我們也能夠用strcpy函數來初始化數組。
初始化char指針
用動態內存分配來初始化char指針。
char *header; char *header = (char*)malloc(strlen("Media Player")+1);
注意不要用sizeof操作符,而要用strlen函數來確定已有字符串的長度,sizeo操作符會返回數組和指針的長度,而不是字符串的長度。