程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C >> 關於C >> 玩兒轉C語言:C語言中的字符和字符串

玩兒轉C語言:C語言中的字符和字符串

編輯:關於C

  在C語言中,利用單引號和雙引號分別表示字符和字符串,但在使用時,如果不能真正理解兩者的本質區別,有可能會出現一些詭異的現象。下面我將通過實驗,進行詳細分析:

1、字符特性試驗,代碼如下:


[cpp] 
char ch_1 = 'a'; 
char ch_2 = 'abcd'; 
 
int ch_value_1 = 'abcdef'; 
int ch_value_2 = 'abcd'; 
分析:
       編譯器vs2010:第3行error C2015: 常量中的字符太多;第2行warning C4305: “初始化”: 從“int”到“char”截斷。

當改為“int ch_value_1 = 'abc' ; ”後,系統錯誤消失。見下圖:

 

       可以看到,ch_1的數值是0x61(a的ascii值),ch_2數值是0x64(d的ascii值),而且他們可以被當做整數進行運算。在給ch_2賦值的時候,編譯器就會用後邊字符數值替換前邊的數值,直到最後一個。這只是vs2010的做法,其他編譯器是進行替換還是取第一個有效字符,需要試驗論證。同時,ch_value_1的值是“abc”的ascii值組合,最高字節用0填充;這就更能說明了字符本質是一個整數。

      但是也要看到第一次試驗失敗,編譯器並沒有把超過4個字節的字符常量進行截斷處理(類似於處理0x1234567890一樣),因為它的空間占用超過了整型數的空間(32位)。整型數(32位)的存儲空間可以容納多個字符(8位),一次有的C編譯器允許一個字符常量(或字符串常量)中包括多個字符,故用‘abcd’代替“abcd”有時不會報錯。“abcd”指:一個含‘a’、‘b’、‘c’、‘d’和‘\0’五個字符的連續只讀空間的首地址;‘abcd’一般沒有定義,大多數C編譯器認為:一個整數值,由‘a’、‘b’、‘c’、‘d’所代表的ascii值按照編譯器定義的方式組合得到。

2、字符串特性試驗,代碼如下:

 

分析:

      指針變量ch_ptr_1存儲的是字符串“testchar”的首地址,如果在內存窗口輸入這個地址,可以看到該字符串。

      指針變量ch_ptr_2的值就是人為給賦予的,是字符序列的ascii值,這再次印證了第一次試驗的結論。

      指針變量ch_ptr_3內容與ch_ptr_1相同,ch_ptr_4與ch_ptr_1不同,這是為什麼呢?

     該程序在編譯時沒有報錯,但是當執行line 17或line 18代碼之一時,就會出錯,系統不允許改變字符串的內容。

 

       單獨執行line 20沒有問題,說明字符串在系統內部是以一小段空間存儲,並且根據該空間地址來操作的,同時printf函數接收的形參也就是字符串首地址。

       其實,常量字符串在系統內部是存儲到“只讀數據段”中的,這個跟數組是不一樣的,數組裡邊的內容可以修改,但是常量字符串裡邊的內容不能修改。而且當定義兩個相同的常量字符串時,系統內部會優化成一個,因為不可修改,所以就只存儲了一次。這就是為什麼ch_ptr_1和ch_ptr_3的值是一樣的。但是,ch_ptr_4代表的字符串沒有被包含進去,盡管它是上一個字符串的子集,這是因為字符串內部是連續存儲的,根據‘\0’來確定字符串長度。而系統只有首地址信息,並沒有長度信息,如果ch_ptr_4也相同的話,就只能代表相同的字符串了,因為系統無法進行字符串子集的切斷,也不知道從哪裡切斷。 

綜上所述:

1、單引號括起來的字符:實際上代表一個整數,整數值就是這個字符的ASCII值大小,如‘a’跟97(十進制)的含義是嚴格一致的,甚至可以互換。 www.2cto.com

2、雙引號括起來的字符串:實際上代表一個指向無名數組起始字符的指針,這個無名數組被雙引號之間的字符串和一個字符‘\0’初始化,而且這個數組內部數據是只讀的,無法修改。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved