C語言字元陣列超細講解
看到標題,有不少朋友會想:字元陣列不也是陣列嗎?為什麼要單獨拿出來講哩?莫非它是朵奇葩?
哈哈,確實,一起來認識一下這朵陣列界的奇葩吧!
一、字元陣列的定義、引用、初始化
大家好!我是字元陣列,看我的名字就知道啦,我是由字元型元素構成噠! 我的定義方式和元素引用方式和一般陣列相同哦,我們可是一家人哦!
|
char line [80];
這是定義了一個長度為 80 的一維字元陣列。
char m [2] [3];
這是定義了一個 2 行 3 列的二維字元陣列。
printf ("%c", line [2]);
這是在應用陣列元素。
so easy!
字元的初始化方法可以分為兩種:
(1) 將字元逐個賦給陣列中的每個元素;
char c [5] = {'c', 'h', 'i', 'n', 'a'};
這是把5個字元分別賦給 c [0] ~ c [4] 這 5 個元素中。
(2) 直接用字串常量給陣列賦初值。
char c [6] = "china";
看到這個例子,又有好奇的小夥伴發問了:china 這不只有5個字元嗎?為啥前面寫著 6 ?
實驗檢驗真知,讓我們把 5 和 6 都執行一下:
當括號裡面寫成 5 時,程式就會被報錯!
當括號裡面寫成 6 時,程式就會正常!
有些小夥伴的頭上是不是出現了許多問號呢?
先彆著急,下面小編就會把謎底揭開。
敲黑板!我們要知道:無論用以上哪種方法進行初始化,如果提供的字元個數大於陣列長度,系統就會進行語法錯誤處理,比如上面的情況;如果提供的字元個數小於陣列長度,則只會給前面幾個元素賦值,剩下的自動設定為0,即 ’\0‘。
給你吃個栗子:
char a [10] = {'c', 'h', 'i', 'n', 'a'}
這裡我們定義了10個長度,但只給 5 個元素賦值,那麼這個陣列的狀態就會是:
c | h | i | n | a | \0 | \0 | \0 | \0 | \0 |
二、字串和字串結束的標誌
現在就是揭示謎底的時候啦!
首先我們區分一下“字元常量”和“字串常量”:
字元常量(一顆山楂) | 字串常量(簡稱:字串)(一串糖葫蘆) |
用單引號括起來 | 用雙引號括起來 |
一個字元 | 一串字元 |
不必有結束字元 '\0' | 要有結束字元 '\0' |
回到前面:
char c [6] = "china"
這裡的"china"就是一個字串,
C語言約定用'\0'作為字串的結束標誌,它佔記憶體空間。這裡的"china"的有效長度為 5 ,但實際上還有第 6 個字元'\0'。
也就是說,當遇到'\0'時,表示字串結束,由它前面的字元組成字串。
在程式中,常用'\0'來判斷字串是否結束,因此所定義的字元陣列長度應該大於字串的實際長度,這樣才足以存放相應的字串,這就是前面為什麼寫 6 而不是 5 的原因,當然,寫 7 也是沒有問題的。
注意:'\0'是代表ASCII碼值為 0 的字元,是一個不可顯示的字元,表示一個“空字元”,也就是說它什麼也沒有,只是一個可供識別的標誌。
三、字元陣列的輸入和輸出
首先說下賦值語句,注意,賦值 ≠ 初始化!
和整型陣列等一樣,字元陣列是不能用賦值語句整體賦值,如下程式碼是錯誤的!!!
char str [12]; str [12] = "the string";
對於一般陣列而言,輸入和輸出的時候只能對陣列元素一個一個進行;
而對於字元陣列,就顯得神通廣大了,它不僅可以逐個輸入輸出,還可以整體輸入輸出!
(1) 逐個字元輸入/輸出
① 使用 scanf 進行輸入,使用 printf 進行輸出,這個時候,要使用格式符 “%c”;
for (i = 0; i < 10; i++) scanf ("%c", &str [i]); //逐個輸入 for (i = 0; i < 10; i++) printf ("%c", str [i]); //逐個輸出
注意:輸入的時候不要丟掉 “&” 哦!
②使用 getchar() 和 putchar() 函式。
for (i = 0; i < 10; i++) str [i] = getchar (); //逐個輸入 for (i = 0; i < 10; i++) putchar (str [i]); //逐個輸出
(2) 字串整體輸入輸出
①使用 scanf 進行輸入,使用 printf 進行輸出,這個時候,要使用格式符 “%s”;
char str [6]; scanf ("%s", str) //整體輸入 printf ("%s", str) //整體輸出
注意:scanf 中的 str 代表 str 這個字元陣列的首地址,因此不加“&”!輸入時系統會自動在字串結尾加上結束符 '\0'。
也可以同時輸入多個字串,這個時候輸入的時候要用空格或者回車符號分隔開。
② 用字串處理函式 gets() 進行字串整串的輸入,puts() 進行字串整串的輸出
這種方法我們待會兒再講。
對於字元陣列的輸入和輸出,應當指出的是:
(1)輸出字元不包括'\0';
(2)用格式符"%s"時,輸出項應該是陣列名,不是陣列元素;
(3)當陣列長度大於字串實際長度時,也只能輸出到'\0'結束;
(4)如果陣列中包含一個以上的’\0‘時,遇到第一個’\0‘時結束輸出,比如:
四、字串函式
C語言有一批字串處理函式,其中 gets() 和 puts() 函式包含在標頭檔案<stdio.h>中,其餘的包含在<string.h>中。
下面,小編來介紹一下常用的 8 個字串函式。
(1)整行輸入函式 gets()
一般形式:gets(字元陣列),例如:
gets (str);
執行這個語句時,gets函式從鍵盤讀入一串字元,直至遇到換行符’\n‘為止;
字串輸入後,系統會自動用'\0'置於字串的尾部,以替代換行符。
(2)整行輸出函式 puts()
一般形式:puts(字元陣列),例如:
char str [] = "string"; puts (str);
這個函式的作用是將字串中的內容顯示在螢幕上,直到遇到第一個字串結束符'\0'時。停止輸出並自動換行。
用puts函式輸出的字串中可以出現轉義字元,用於實現某種格式的控制。例如:
(3)字串長度函式 strlen()
一般形式:strlen(字元陣列),例如:
char str[]="string"; strlen (str);
strlen ("string");
該函式用於統計字串開始到’\0‘的有效長度。
(4)字串連線函式 strcat()
一般形式:strcat(字元陣列1, 字元陣列2),例如:
char str1 [15]= "I am "; char str2 [] = “student”; strcat (str1, atr2);
這個函式的作用是將字元陣列 2 連線在字元陣列 1 上,就像嫁接一樣。
連線前後的情況如下:
連線前 | 連線後 | |
str1 |
I am \0\0\0\0\0\0\0\0\0\0 |
I am student\0\0\0 |
str2 | student\0 | student\0 |
注意:字元陣列1的長度要足夠大哦!
(5)字串複製函式 strcpy()
一般形式:strcpy(字元陣列1, 字元陣列2),例如:
char str[10]; strcpy (str, "china");
我們前面講到,不能用賦值語句對陣列整體賦值,那賦值的時候可以一個一個對元素賦值,但是這種方法很是繁瑣,而這裡的 strcpy 函式可以輕鬆搞定。
比如上面這段程式碼,就把str中的前 5 個字元賦值為了“china”。
這裡要說明一下:
在向字元陣列1中複製(或者“賦值”)時,字元陣列2中的結束標誌'\0'也被複制過去了,比如:
複製前 | 複製後 | |
str1 | abcdefg\0 | &&&\0efg\0 |
srr2 | &&&\0 | &&&\0 |
複製後的str1中出現了兩個'\0',則用 "printf("%s", str1)" 和 “puts(str1)” 輸出時,只會輸出“&&&”。
(6)字串比較函式 strcmp()
一般形式:strcmp(字元陣列1, 字元陣列2)
這裡的比較是比較什麼呢?長度?
No!
它的規則是:
對兩個字串自左向右逐個字元進行比較——按ASCII碼值大小比較,直到出現不同字元或者遇到'\0'為止。
注意:這裡比較 是ASCII碼值!
如果全部字元都相同,則認為相等;
若出現不同的字元,則以第一個不同的字元的比較結果為準;
● 如果字串1 = 字串2,函式值為 0;
● 如果字串1 > 字串2,函式值為一正數;
● 如果字串1 < 字串2,函式值為 一負數;
想看清晰的戳這裡>> https://www.bilibili.com/video/BV1764y1M78v/
(7)字串中的大寫字母換成小寫字母函式 strlwr()
strlwr中的“lwr”是lowercase(小寫)的縮寫,運用很簡單,如圖:
(8)字串中的大寫字母換成小寫字母函式 strupr()
strupr中的“upr”是uppercase(大寫)的縮寫。
學完這8中字串處理函式,是不是感覺站在了巨人的肩膀上,不過我們也要自己嘗試編寫這幾種函式哦。
五、二維的字元陣列
上面我們只介紹了陣列中只有一個字串的情況,那如果想儲存多個字串呢?
用一個雙引號“ ”括起來的字串可以被當做一個一維陣列,
而多個字串,也就是多個一維陣列,就需要二維陣列來存放。
因此,一個 m×n 的二維字元陣列可以存放 m 個字串,其中每個字串的長度不超過n-1(要保留一個位置存放'\0')。
比如:
c | h | i | n | a | \0 | \0 | \0 | \0 | \0 |
a | b | c | \0 | \0 | \0 | \0 | \0 | \0 | \0 |
好啦,吃了這麼多幹貨,是不是有些渴呢?下面我們用所學的知識編寫一個小程式:
問題描述:一個公司有若干員工。編寫一個程式,實現如下功能:輸入一個職工的姓名,要求查詢職工是否屬於該公司,並輸出相應的資訊。
小編思路:
1、首先建立二維字元陣列 w[100][10],用於存放公司中所有職工的名字,每個職工的員工名字都是一個一維陣列;同時建立一個一維字元陣列 name[10],用於存放要查詢的物件姓名;
2、接著來一個迴圈,將公司職工的姓名進行輸入;
3、再來一個迴圈,進行多次查詢的操作;
4、在查詢中,將要查詢的姓名與二維字元陣列中的姓名用字串函式 strcmp 一個一個作比較,如果迴圈後結果為0,則是公司職工,否則不是。
5、在這個程式中,因為要多次輸入,因此每次輸入前用 fflush(stdin)來清除緩衝區的內容(每次輸入後的回車符儲存在緩衝區)。
程式碼展示:
#include "stdio.h" #include "string.h" main () { char w [100][10]; int n = 1, i = 0, j, m; char name[10]; printf("請輸入該公司所有員工的姓名:\n"); while (n == 1) { printf("%d:", i+1); fflush(stdin); gets(w[i]); printf("如果要繼續輸入,請輸入數字1:"); fflush(stdin); scanf ("%d", &n); i++; } n = 1; while (n == 1) { printf("請輸入要查詢的姓名:"); fflush(stdin); gets(name); for (j = 0; j < i; j++) { m = strcmp(name, w[j]); if (m ==0) { break; } } if (m == 0) printf("該職工屬於該公司!"); else printf("該職工不屬於該公司!"); printf("如果要繼續查詢,請輸入數字1:"); fflush(stdin); scanf ("%d", &n); } }
本次的分享就到這裡啦,歡迎小夥伴前來交流!
預告:C語言字元陣列應用舉例
2020-04-28
16:55:04