引言:在c++中,對於字串的操作,我們常使用 string 類,使用起來極其方便,所有常常會用到的對字串的操作均已封裝好。但是,在c中,字串我們使用字元陣列來實現,而且如果不搞清楚字元陣列與字串之間的關係,常常會出現一些無法解釋的問題。筆者之前一直對兩者之間的關係有所疑惑,最近查閱相關資料,終於搞清楚,現整理出來。雖然這個不算什麼大問題,但是不徹底搞清楚就是覺得心裡不爽~希望各位看官批評指正。
首先,在這裡寫下字元陣列最簡單的定義並初始化的方法:
char str[10]=;
在這裡只需注意以下幾點:
1.「hello!」陣列元素個數為6個,它的個數必須小於定義陣列的陣列大小即10。
2.其餘已被申請但未被賦值的記憶體均被賦值為 '\0'(ascii:0),也就是說現在str陣列中記憶體賦值情況如下: 位址
內容str
'h'str+1
'e'str+2
'l'...
'l'...
'o'...
'!'str+6
'\0'
str+7
'\0'
str+8
'\0'
str+9
'\0'
3.'\0'與ascii中 space 的區別:
ascii中0~31為「非列印控制字元」,其中例如 0號對應的』\0『 ,13號對應的回車鍵,將它們按字元的形式列印到螢幕上的時候均為「 」,它和空格 「 」 是有本質上的區別。空格對應的ascii為32號,它屬於「列印字元」,只不過空格在螢幕上的表現形式也為 「 」 ,與無法列印的非列印控制字元顯示的效果一樣罷了。』\0『僅僅作為乙個字串結束標誌存在著,它的作用就是乙個標誌!
接下來,談一下c語言中的字串:
同樣地,先寫一下字串最簡單的宣告定義方式,
1. char str=;
2. char str="hello world !";
以上兩種方式等價。但是下面這種方式是錯誤的!
3. char str;
str="hello world !";
為什麼第三種方式是錯的呢?這就需要了解在執行前兩種方式的語句時,計算機做了什麼。首先當我們指明要賦的值為"hello world !"時,計算機會在記憶體中開闢乙個能夠裝下這個值的記憶體空間,這也就是為什麼str的「」中不需要寫乙個具體數值的原因,需要多大計算機已經幫你算好。而如果我們採用第三種方式,會報這樣的錯:「storage size of 'str' isn't known」 意思就是大小不明。
但是如果想要在宣告這個字串時並不賦值的話,可以採用下面這種方式:
4. char * str;
str="hello world !";
當然,更直接的方式:char *str="hello world !";
也是允許的。
那麼,為什麼第四種方式又是可行的呢?執行這條語句的時候,計算機同樣為"hello world !"開闢了一定大小記憶體空間
,但是這條語句是將這個記憶體空間的首位址賦值給str指標,執行 char str 語句後,雖然str也是乙個指標型別,但是任何陣列名的那個指標都是乙個常指標!!!!跟其他常量一樣,它是不能再被賦值的!用以下方式可以證明:
char *str="hello world !"
;str++;
printf("%c",*str);//結果輸出為』e『
而採用以下方式,直接報錯。原因就是下面的str為常指標,不能被重新賦值,也就是str++;是錯誤的。
char str="hello world !";
str++;
printf("%c",*str);
但是第4種利用指標的寫法也有它的侷限性,以下面的**為例:
char *str="hello!";
str[0]=str[1];
printf("%s",str);
執行以上**時,程式會崩潰掉,而如果將第一句改為 char str="hello!"; 程式就可以正常執行,其中的原因涉及到計算機內部儲存器的工作方式。
(這部分**
使用 char *str 的情況下計算機操作的步驟:
計算機做的步驟:
1. 計算機載入字串字面值:
當計算機把程式載入儲存器時,會把所有常數值(如字串常量"hello!")放到常量儲存區,這部分儲存器是唯讀的。
2. 程式在棧上建立str 變數
棧是儲存器中計算機用來儲存區域性變數的部分,區域性變數也就是位於函式內部的變數,str 變數就在這個地方。
3. str 變數設為"hello!"的位址
str 變數將會儲存字串字面值"hello!
"的位址。為了防止修改,字串字面值通常儲存在唯讀儲存器中。
4. 計算機試圖修改字串
程式試圖修改str 變數指向的字串中的內容時就會失敗,因為字串是唯讀的。
使用 char str
的情況下計算機操作的步驟:
1. 計算機載入字串字面值:
當計算機把程式載入儲存器時,會把所有常數值(如字串常量"hello!")放到常量儲存區,這部分儲存器是唯讀的。
2. 程式在棧上新建了乙個陣列
我們宣告了陣列,所以程式會建立乙個足夠大的陣列來儲存字串"hello!"
3. 程式初始化陣列
除了為陣列分配空間,程式還會把字串字面值"hello!
"的內容複製到棧上。
所以,使用指標方式宣告的字串值無法改變。
最後補充一下剛剛提到的'\0'相關的問題。
char str="hello";
char str1=;
printf("%d\n",sizeof(str));
printf("%d\n",sizeof(str1));
結果:6 5
造成差異的原因就是str被以字串的形式賦值,它內部的元素其實為'h','e','l','l','o'
,'\0' 共6個,而str1只是乙個單純的字元陣列。
另外c語言中printf("%s",str);提供了按字串形式輸出的控制符號』%s『,將以上的str和str1按這種方式輸出。
printf("%s\n",str);
printf("%s\n",str1);
輸出str1的時候可能會跟著一些亂碼,原因就是以str1為首位址的接下來幾塊記憶體單元中沒有'\0',雖然我們未使用的記憶體中的值應該為'\0',但是這並不一定。而另一種寫法:char str[10]=
; 它的輸出結果中絕對不會夾雜亂碼,因為未被賦值的記憶體會被計算機主動賦值為'\0',這也算是在設計上的巧妙。
以上就是我今天整理的一些c中字串和字元陣列的一些需要特別注意的點,歡迎各位批評指正~
c語言中的字元陣列與字串
一 字元陣列的定義 一維字元陣列 用於儲存和處理1個字串,其定義格式與一維數值陣列一樣。char str 20 二維字元陣列 用於同時儲存和處理多個字串,其定義格式與二維數值陣列一樣。char country 10 20 country 第i個字串 二 字元陣列的初始化 字元陣列的初始化.1.可以通...
c語言中的字串與字元陣列
1 字元陣列的定義與初始化 字元陣列的初始化,最容易理解的方式就是逐個字元賦給陣列中各元素。char str 10 即把10個字元分別賦給str 0 到str 9 10個元素 如果花括號中提供的字元個數大於陣列長度,則按語法錯誤處理 若小於陣列長度,則只將這些字元陣列中前面那些元素,其餘的元素自動定...
c語言中的字元陣列與字串
字元陣列的初始化,最容易理解的方式就是逐個字元賦給陣列中各元素。char str 10 即把10個字元分別賦給str 0 到str 9 10個元素 如果花括號中提供的字元個數大於陣列長度,則按語法錯誤處理 若小於陣列長度,則只將這些字元陣列中前面那些元素,其餘的元素自動定為空字元 即 0 2 字元陣...