1. 程式人生 > >C語言字元陣列超細講解

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