高一課程C語言>字元陣列


字元陣列

用來存放字元量的陣列稱為字元陣列。

bullet_19.gif字元陣列的定義

形式與前面介紹的數值陣列相同。

例如:

    char c[10];

由於字元型和整型通用,也可以定義為int c[10]但這時每個陣列元素占2個位元組的記憶體單元。

字元陣列也可以是二維或多維陣列。

例如:

    char c[5][10];

即為二維字元陣列。

bullet_19.gif字元陣列的初始化

字元陣列也允許在定義時作初始化賦值。

例如:

    char c[10]={‘c’, ‘  ’, ‘p’, ‘r’, ‘o’, ‘g’, ‘r’, ‘a’,’m’};

賦值後各元素的值為:

    陣列C    c[0]的值為c

c[1]的值為

c[2]的值為p

c[3]的值為r

c[4]的值為0

c[5]的值為g

c[6]的值為r

c[7]的值為a

c[8]的值為m

其中c[9]未賦值,由的值為p系統自動賦予0值。

當對全體元素賦初值時也可以省去長度說明。

例如:

    char c[]={`c`,` `,`p`,`r`,`o`,`g`,`r`,`a`,`m`};

這時C陣列的長度自動定為9

bullet_19.gif字元陣列的引用

【例1

#include<stdio.h>

main()

{

      int i,j;

      char a[][5]={{'B','A','S','I','C',},{'d','B','A','S','E'}};

      for(i=0;i<=1;i++)

        {

            for(j=0;j<=4;j++)

                printf("%c",a[i][j]);

            printf("\n");

        }

}

本例的二維字元陣列由於在初始化時全部元素都賦以初值,因此一維下標的長度可以不加以說明。

bullet_19.gif字串和字串結束標誌

在C語言中沒有專門的字串變數,通常用一個字元陣列來存放一個字串。前面介紹字串常量時,已說明字串總是以'\0'作為串的結束符。因此當把一個字串存入一個陣列時,也把結束符'\0'存入陣列,並以此作為該字串是否結束的標誌。有了'\0'標誌後,就不必再用字元陣列的長度來判斷字串的長度了。

C語言允許用字串的方式對陣列作初始化賦值。

例如:

    char c[]={'c', ' ','p','r','o','g','r','a','m'};

可寫為:

        char c[]={"C program"};

    或去掉{}寫為:

        char c[]="C program";

用字串方式賦值比用字元逐個賦值要多占一個位元組, 用於存放字串結束標誌'\0'。上面的陣列c在記憶體中的實際存放情況為:

C

' '

p

r

o

g

r

a

m

\0

    \0'是由C編譯系統自動加上的。由於採用了\0'標誌,所以在用字串賦初值時一般無須指定陣列的長度, 而由系統自行處理。

bullet_19.gif字元陣列的輸入輸出

在採用字串方式後,字元陣列的輸入輸出將變得簡單方便。

除了上述用字串賦初值的辦法外,還可用printf函數和scanf函數一次性輸出輸入一個字元陣列中的字串,而不必使用迴圈語句逐個地輸入輸出每個字元。

【例 2

#include<stdio.h>

main()

{

  char c[]="BASIC\ndBASE";

  printf("%s\n",c);

}

注意在本例的printf函數中,使用的格式字串為%s,表示輸出的是一個字串。而在輸出表列中給出陣列名稱則可。不能寫為:printf("%s",c[]);

【例 3】

#include<stdio.h>

main()

{

  char st[15];

  printf("input string:\n");

  scanf("%s",st);

  printf("%s\n",st);

}

本例中由於定義陣列長度為15,因此輸入的字串長度必須小於15,以留出一個位元組用於存放字串結束標誌`\0`。應該說明的是,對一個字元陣列,如果不作初始化賦值,則必須說明陣列長度。還應該特別注意的是,當用scanf函數輸入字串時,字串中不能含有空格,否則將以空格作為串的結束符。

例如當輸入的字串中含有空格時,運行情況為:

    input string:

        this is a book

輸出為:

this

從輸出結果可以看出空格以後的字元都未能輸出。為了避免這種情況,可多設幾個字元陣列分段存放含空格的串。

程式可改寫如下:

【例 4】

#include<stdio.h>

main()

{

  char st1[6],st2[6],st3[6],st4[6];

  printf("input string:\n");

  scanf("%s%s%s%s",st1,st2,st3,st4);

  printf("%s %s %s %s\n",st1,st2,st3,st4);

}

    本程式分別設了四個陣列, 輸入的一行字元的空格分段分別裝入四個陣列。然後分別輸出這四個陣列中的字串。

在前面介紹過,scanf的各輸入項必須以位址方式出現,如 &a,&b等。但在前例中卻是以陣列名稱方式出現的,這是為什麼呢?

這是由於在C語言中規定,陣列名稱就代表了該陣列的首位址。整個陣列是以首位址開頭的一塊連續的記憶體單元。

如有字元陣列char c[10],在記憶體可表示如圖。

C[0]

C[1]

C[2]

C[3]

C[4]

C[5]

C[6]

C[7]

C[8]

C[9]

位址     2000           2001               .....                                        .......                                                                       2010

設陣列c的首位址為2000,也就是說c[0]單元位址為2000。則陣列名稱c就代表這個首地址。因此在c前面不能再加位址運算符&。如寫作scanf("%s",&c);則是錯誤的。 在執行函數printf("%s",c) 時,按陣列名稱c找到首位址,然後逐個輸出陣列中各個字元直到遇到字串終止標誌'\0'為止。

bullet_19.gif字串處理函數

C語言提供了豐富的字串處理函數, 大致可分為字串的輸入、輸出、合併、修改、比較、轉換、複製、搜索幾類。 使用這些函數可大大減輕程式的負擔。用於輸入輸出的字串函數,在使用前應包含頭檔<stdio.h>,使用其他字串函數則應包含頭檔<string.h>

下面介紹幾個最常用的字串函數。

1.  字串輸出函數 puts

   格式:  puts (字元陣列名稱)

   功能:把字元陣列中的字串輸出到顯示器。 即在螢幕上顯示該字串。

【例 5】

#include<stdio.h>

main()

{

  char c[]="BASIC\ndBASE";

  puts(c);

}

    從程式中可以看出puts函數中可以使用轉義字元,因此輸出結果成為兩行。puts函數完全可以由printf函數取代。當需要按一定格式輸出時,通常使用printf函數。

2.   字串輸入函數gets

   格式:  gets  (字元陣列名稱)

   功能:從標準輸入設備鍵盤上輸入一個字串。

 本函數得到一個函數值,即為該字元陣列的首位址。

【例 5】

#include<stdio.h>

main()

{

  char st[15];

  printf("input string:\n");

  gets(st);

  puts(st);

}

    可以看出當輸入的字串中含有空格時,輸出仍為全部字串。說明gets函數並不以空格作為字串輸入結束的標誌,而只以回車作為輸入結束。這是與scanf函數不同的。

3.  字元串連接函數strcat

   格式:  strcat (字元陣列名稱1,字元陣列名稱2)

   功能:把字元陣列2中的字串連接到字元陣列1 中字串的後面,並刪去字串1後的串標誌\0。本函數返回值是字元陣列1的首位址。

【例 6】

#include<stdio.h>

#include<string.h>

main()

{

  static char st1[30]="My name is ";

  int st2[10];

  printf("input your name:\n");

  gets(st2);

  strcat(st1,st2);

  puts(st1);

}

 

    本程式把初始化賦值的字元陣列與動態賦值的字元串連接起來。要注意的是,字元陣列1應定義足夠的長度,否則不能全部裝入被連接的字串。

4.字串拷貝函數strcpy

   格式:  strcpy (字元陣列名稱1,字元陣列名稱2)

   功能:把字元陣列2中的字串拷貝到字元陣列1中。串結束標誌\0也一同拷貝。字元數名2,也可以是一個字串常量。這時相當於把一個字串賦予一個字元陣列。

【例7.15

#include<stdio.h>

#include<string.h>

main()

{

  char st1[15],st2[]="C Language";

  strcpy(st1,st2);

  puts(st1);printf("\n");

}

本函數要求字元陣列1應有足夠的長度,否則不能全部裝入所拷貝的字串。

5. 字串比較函數strcmp

   格式:  strcmp(字元陣列名稱1,字元陣列名稱2)

   功能:按照ASCII碼順序比較兩個陣列中的字串,並由函數返回值返回比較結果。

          字串1=字串2,返回值=0

               字串2〉字串2,返回值〉0

               字串1〈字串2,返回值〈0

本函數也可用於比較兩個字串常量,或比較陣列和字串常量。

【例 7

#include<stdio.h>

#include<string.h>

main()

{

      int k;

      static char st1[15],st2[]="C Language";

      printf("input a string:\n");

      gets(st1);

      k=strcmp(st1,st2);

      if(k==0) printf("st1=st2\n");

      if(k>0) printf("st1>st2\n");

      if(k<0) printf("st1<st2\n");

}

 

本程式中把輸入的字串和陣列st2中的串比較,比較結果返回到k中,根據k值再輸出結果提示串。當輸入為dbase時,由ASCII 碼可知dBASE大於C Languagek0,輸出結果st1>st2

6. 測字串長度函數strlen

   格式:  strlen(字元陣列名稱)

   功能:測字串的實際長度(不含字串結束標誌\0) 並作為函數返回值。

#include<stdio.h>

#include<string.h>

main()

{

       int k;

      static char st[]="C language";

      k=strlen(st);

      printf("The lenth of the string is %d\n",k);

}


【例 9】輸入五個國家的名稱按字母順序排列輸出。

    本題程式思路如下:五個國家名應由一個二維字元陣列來處理。然而C語言規定可以把一個二維陣列當成多個一維陣列處理。 因此本題又可以按五個一維陣列處理, 而每一個一維陣列就是一個國家名字串。用字串比較函數比較各一維陣列的大小,並排序,輸出結果即可。

程式如下:

#include<stdio.h>

#include<string.h>

main()

{

    char st[20],cs[5][20];

    int i,j,p;

    printf("input country's name:\n");

    for(i=0;i<5;i++)

      gets(cs[i]);

    printf("\n");

    for(i=0;i<5;i++)

      { p=i;strcpy(st,cs[i]);

     for(j=i+1;j<5;j++)

      if(strcmp(cs[j],st)<0) {p=j;strcpy(st,cs[j]);}

    if(p!=i)

      {

     strcpy(st,cs[i]);

     strcpy(cs[i],cs[p]);

     strcpy(cs[p],st);

      }

    puts(cs[i]);}printf("\n");

}

本程式的第一個for語句中,用gets函數輸入五個國家名字串。上面說過C語言允許把一個二維陣列按多個一維陣列處理,本程式說明cs[5][20]為二維字元陣列,可分為五個一維陣列cs[0]cs[1]cs[2]cs[3]cs[4]。因此在gets函數中使用cs[i]是合法的。 在第二個for語句中又嵌套了一個for語句組成雙重迴圈。這個雙重迴圈完成按字母順序排序的工作。在外層迴圈中把字元陣列cs[i]中的國名字串拷貝到陣列st中,並把下標i賦予P。進入內層迴圈後,把stcs[i]以後的各字串作比較,若有比st小者則把該字串拷貝到st中,並把其下標賦予p。內迴圈完成後如p不等於i說明有比cs[i]更小的字串出現,因此交換cs[i]st的內容。至此已確定了陣列cs的第i號元素的排序值。然後輸出該字串。在外迴圈全部完成之後即完成全部排序和輸出。