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,函數值為 一負數;
想看清晰的戳這裡>> //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