【字符串】字符數組及其定義和初始化詳解


字符串的存儲方式有字符數組和字符指針。

因為字符串是由多個字符組成的序列,所以要想存儲一個字符串,可以先把它拆成一個個字符,然后分別對這些字符進行存儲,即通過字符數組存儲。字符數組是一個數組,且是存儲字符的數組,該數組中一個元素存放字符串的一個字符。

字符數組的定義

因為字符數組首先是一個數組,所以前面講的數組內容通通都適用。其次它是存放字符的數組,即數組的類型是char型。比如:

1 char name[10];

 

表示定義了10字節的連續內存空間。

1)如果字符串的長度大於10,那么就存在語法錯誤。這里需要注意的是,這里指的“字符串的長度”包括最后的‘\0’。也就是說,雖然系統會自動在字符串的結尾加‘\0’,但它不會自動為‘\0’開辟內存空間。所以在定義數組長度的時候一定要考慮‘\0’。

2)如果字符串的長度小於數組的長度,則只將字符串中的字符賦給數組中前面的元素,剩下的內存空間系統會自動用‘\0’填充。

字符數組的初始化

字符數組的初始化與數組的初始化一樣,要么定義時初始化,要么定義后初始化,下面寫一個程序來說明這個問題:

 1 #include <stdio.h>
 2 #include <stdlib.h>
 3 int main(void)
 4 {
 5     char a[10];
 6     a[0] = 'i'; a[1] = ' '; a[2] = 'l'; a[3] = 'o'; a[4] = 'v'; 
 7 //空格字符的單引號內一定要敲空格
 8     a[5] = 'e'; a[6] = ' '; a[7] = 'y'; a[8] = 'o'; a[9] = 'u'; 
 9 //空格字符的單引號內一定要敲空格
10     a[10] = '\0'; 
11     char b[10];
12     b[0] = 'i'; b[1] = ' '; b[2] = 'm'; b[3] = 'i'; b[4] = 's'; 
13 //空格字符的單引號內一定要敲空格
14     b[5] = 's'; b[6] = ' '; b[7] = 'y'; b[8] = 'o'; b[9] = 'u'; 
15 //空格字符的單引號內一定要敲空格
16     char c[] = "i believe you";
17     char d[] = {'i', ' ', 'l', 'i', 'k', 'e', ' ', 'y', 'o', 'u','\0'}; 
18 //空格字符的單引號內一定要敲空格
19     char e[] = {'H', 'e', 'l', 'l', 'o', ' ', 'W', 'o', 'r', 'l', 'd'}; 
20 //空格字符的單引號內一定要敲空格
21     char f[] = "上課睡覺覺, 下課打鬧鬧, 考試死翹翹";
22     char g[10] = "";
23     printf("a = %s\n", a);  //輸出字符串用%s, 輸出參數必須寫數組名
24     printf("b = %s\n", b);
25     printf("c = %s\n", c);
26     printf("d = %s\n", d);
27     printf("e = %s\n", e);
28     printf("f = %s\n", f);
29     printf("g = %s\n", g);
30     return 0;
31 }

首先要說明的是,這個程序只有在.cpp文件中才能運行,在.c文件中會有很多錯誤。因為我們在前面講過,C89標准規定變量的定義只能在程序的開頭,或者說定義變量的前面不能有其他非聲明或者非定義的語句。而.cpp文件是編寫C++程序的,C++向下完全兼容C,而且它對變量定義的位置有特殊要求,只要在使用位置之前即可。

數組a是先定義后初始化。一方面與以前講的數值型數組一樣,先定義后初始化必須一個一個地進行賦值,不能整體賦值;另一方面與以前講的數值型數組又不一樣,對於字符串,先定義后初始化也可以整體賦值,但是要調用strcpy函數,這點稍后再講。

總之上面這個程序中給數組a一個一個進行初始化的方式很麻煩。而且這樣寫需要注意:前面講過系統會在字符串的最后自動添加結束標識符‘\0’,但是當一個一個賦值時,系統不會自動添加‘\0’,必須手動添加。如果忘記添加,雖然語法上沒有錯誤,但是程序將無法達到我們想要的功能。數組b就是這樣的例子。

此外,空格字符必須要在單引號內"敲"一個空格,不能什么都不“敲”,什么都不“敲”就是語法錯誤。也不能多“敲”,因為一個單引號內只能放一個字符。“敲”多個空格就是多個字符了。

數組b就是最后沒有手動添加‘\0’的例子。程序是希望數組b輸出“i miss you”,但輸出結果是“i miss youi love you”.原因就是系統沒有在最后添加‘\0’。

雖然程序中對數組b的長度進行了限制,即長度為10,但是由於內存單元是連續的,對於字符串系統只要沒有遇到‘\0’,就會認為該字符串還沒有結束,就會一直往后找,直到遇到‘\0’為止。被找過的內存單元都會輸出,從而超過定義的10字節。

數組c是定義時初始化。定義時初始化可以整體賦值。整體賦值有一個明顯的優點——方便。定義初始化可以不用指定數組的長度,而先定義后初始化自必須要指定數組的長度,如數組a和數組b。不用指定數組長度有一個好處:不用人為確定需要多少字節的內存空間,系統會根據初始化的內容自動分配數量正好的內存空間。而且對於數組c的寫法系統會自動在最后添加標識符‘\0’,必須人為添加。忘記添加就會出現與數組b同樣的錯誤。從數組e的輸出結果可以看出這一點。

數組 f 是存儲漢字,漢字不能像數組 a 或數組 d 那樣分開一個一個賦值。因為一個漢字占 2 字節,若分開賦值,由於一個單引號內只能放一個字符,即一字節,所以將占 2 字節的漢字放進去當然就出錯了。因此如果用字符數組存儲漢字的話必須整體賦值,即要么定義時初始化,要么調用 strcpy 函數。

 數組 g 初始化為一對雙引號,表示該字符數組中 10 個元素的內容都為 '\0'。下面寫一個程序驗證一下:

1 # include <stdio.h>
2 int main(void)
3 {
4     char str[3] = "";
5     str[2] = 'a';
6     printf("str = %s\n", str);
7     return 0;
8 }

輸出結果是:

str =

程序中定義了一個長度為 3 的字符數組,然后給第三個元素賦值為 'a',然后將整個字符數組輸出。但是輸出結果什么都沒有,原因就是其直接初始化為一對雙引號,此時字符數組中所有元素都是 '\0'。所以雖然第三個元素為 'a',但因為第一個元素為 '\0',而 '\0' 是字符串的結束標志符,所以無法輸出。

需要注意的是,使用此種初始化方式時一定要指定數組的長度,否則默認數組長度為 1。

 

總結,字符數組與前面講的數值數組有一個很大的區別,即字符數組可以通過“%s”一次性全部輸出,而數值數組只能逐個輸出每個元素。
 
 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM