字符常量是由一對單撇號括起來的單個字符,如 'a'、'D'、'?'、'$'。在 C 語言中,除了字符常量外還有字符串常量,顧名思義就是多個“字符”串在一起。與字符常量有所不同,字符串常量是用“雙撇號”括起來的多個字符的序列,如"How are you"、"I love you"、"你好"。當然,只要是“雙撇號”括起來的,就算只有一個字符也叫字符串,如"a"。字符常量 'a'與字符串常量"a"是不同的。
一個字符在內存中只占一字節,而字符串本質上是多個字符組成的字符數組。C語言規定,在每個字符串常量的結尾,系統會自動加一個字符'\0'作為該字符串的”結束標識符“,系統據此判斷字符串是否結束。這里要強調一點,結束標識符是系統自動加上的,不是用戶自己加的。
'\0' 是 ASCII 碼為 0 的字符,它不會引起任何控制動作,也不是一個可以顯示的字符。比如字符串常量"CHINA",表面上看它只有 5 個字符,但實際上它在內存中占 6 字節,'C'、'H'、'I'、'N'、'A'、'\0' 各占一字節。如果要輸出該字符串,'\0' 不會輸出。也就是說,雖然實際上總共有 6 個字符,'\0' 也包括在其中,但輸出時 '\0' 不會輸出。系統從第一個字符 'C' 開始逐個輸出字符,直到遇到 '\0',則表示該字符串結束,停止輸出。也就是說,在字符串常量中,如果“雙撇號”中能看見的字符有 n 個,那么該字符串在內存中所占的內存空間為 n+1 字節。
下面寫程序驗證一下:
1 #include <stdio.h> 2 int main(void) 3 { 4 printf("%d\x20", sizeof(""));//\x20 輸出控制符 表示空格 5 printf("%d\x20", sizeof("a")); 6 printf("%d\x20", sizeof("CHINA")); 7 printf("%d\x20", sizeof("How are you")); 8 printf("%d\x20", sizeof("I love you")); 9 printf("%d\n", sizeof("你好")); 10 return 0; 11 }
輸出結果:
第一個“雙撇號”中什么都不寫,則只有 '\0' 一個字符,所以只占一字節。
第二個"a"中有 1 個可見字符,占 2 字節。
第三個"CHINA"有 5 個可見字符,占 6 字節。
第四個"How are you"中,空格也是字符,也算是可見的,所以總共有 11 個可見字符,共占 12 字節。
第五個"I love you"共 10 個可見字符,占 11 字節。
第六個"你好"為什么占 5 字節?有 2 個可見字符不是應該占3字節嗎?C 語言規定,1 個英文字符占 1 字節,而 1個 中文字符占 2 字節,就算是中文的標點符號也是占 2 字節。所以兩個漢字占 4 字節,加上 '\0' 總共是 5 字節。
不能將一個字符串常量賦給一個字符變量
為什么不能將一個字符串常量賦給一個字符變量?可以從兩個方面作出解釋:
- 前面講過,字符變量用 char 定義。一個字符變量中只能存放一個字符。而字符串一般都有好多字符,占多字節。所以不能將多個字符賦給只占一字節的變量。那么如果字符串常量的雙撇號內什么都不寫,此時就只有一個字符 '\0',那么此時可不可以將它賦給字符變量?不可以!原因看下面第二點。
- 字符串是指一系列字符的組合。在 C 語言中,字符變量的類型用 char 定義。我們這里講的是數據類型,但是字符串不屬於數據類型,也就不存在字符串變量。一種類型的變量要想存儲某個對象,必須能兼容該對象的數據類型,而字符串連數據類型都算不上,又怎么能將它賦給字符變量呢?所以在 C 語言中,任何數據類型都不可以直接存儲一個字符串。那么字符串如何存儲?在 C 語言中,字符串有兩種存儲方式,一種是通過字符數組存儲,另一種是通過字符指針存儲。