C語言指標陣列的概念

一個陣列的元素值為指標則是指標陣列。 指標陣列是一組有序的指標的集合。 指標陣列的所有元素都必須是具有相同儲存型別和指向相同資料型別的指標變數。

C語言指標陣列的概念
C語言指標陣列的概念

指標陣列說明的一般形式為:

型別說明符 *陣列名[陣列長度]

其中型別說明符為指標值所指向的變數的型別。例如:

int *pa[3]

表示pa是一個指標陣列,它有三個陣列元素,每個元素值都是一個指標,指向整型變數。

【例10-33】通常可用一個指標陣列來指向一個二維陣列。指標陣列中的每個元素被賦予二維陣列每一行的首地址,因此也可理解為指向一個一維陣列。

main(){

int a[3][3]={1,2,3,4,5,6,7,8,9};

int *pa[3]={a[0],a[1],a[2]};

int *p=a[0];

int i;

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

printf("%d,%d,%d",a[i][2-i],*a[i],*(*(a+i)+i));

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

printf("%d,%d,%d",*pa[i],p[i],*(p+i));

}

本例程式中,pa是一個指標陣列,三個元素分別指向二維陣列a的各行。然後用迴圈語句輸出指定的陣列元素。其中*a[i]表示i行0列元素值;*(*(a+i)+i)表示i行i列的元素值;*pa[i]表示i行0列元素值;由於p與a[0]相同,故p[i]表示0行i列的值;*(p+i)表示0行i列的值。讀者可仔細領會元素值的各種不同的表示方法。

應該注意指標陣列和二維陣列指標變數的區別。這兩者雖然都可用來表示二維陣列,但是其表示方法和意義是不同的。

二維陣列指標變數是單個的變數,其一般形式中"(*指標變數名)"兩邊的括號不可少。而指標陣列型別表示的是多個指標(一組有序指標)在一般形式中"*指標陣列名"兩邊不能有括號。例如:

int (*p)[3];

表示一個指向二維陣列的'指標變數。該二維陣列的列數為3或分解為一維陣列的長度為3。

int *p[3]

表示p是一個指標陣列,有三個下標變數p[0],p[1],p[2]均為指標變數。

指標陣列也常用來表示一組字串,這時指標陣列的每個元素被賦予一個字串的首地址。指向字串的指標陣列的初始化更為簡單。例如在例10.32中即採用指標陣列來表示一組字串。其初始化賦值為:

char *name[]={"Illagal day",

"Monday",

"Tuesday",

"Wednesday",

"Thursday",

"Friday",

"Saturday",

"Sunday"

};

完成這個初始化賦值之後,name[0]即指向字串"Illegal day",name[1]指向"Monday"......。

指標陣列也可以用作函式引數。

【例10-34】指標陣列作指標型函式的引數。在本例主函式中,定義了一個指標陣列name,並對name 作了初始化賦值。其每個元素都指向一個字串。然後又以name作為實參呼叫指標型函式day_name,在呼叫時把陣列名name賦予形參變數name,輸入的整數i作為第二個實參賦予形參n。在day_ name函式中定義了兩個指標變數pp1和pp2,pp1被賦予name[0]的值(即*name),pp2被賦予name[n]的值即*(name+ n)。由條件表示式決定返回pp1或pp2指標給主函式中的指標變數ps。最後輸出i和ps的值。

main(){

static char *name[]={ "Illegal day",

"Monday",

"Tuesday",

"Wednesday",

"Thursday",

"Friday",

"Saturday",

"Sunday"

};

char *ps;

int i;

char *day_name(char *name[],int n);

printf("input Day No:");

scanf("%d",&i);

if(i<0) exit(1);

ps=day_name(name,i);

printf("Day No:%2d-->%s",i,ps);

}

char *day_name(char *name[],int n){

char *pp1,*pp2;

pp1=*name;

pp2=*(name+n);

return((n<1||n>7)? pp1:pp2);

}

【例10-35】輸入5個國名並按字母順序排列後輸出。現程式設計如下:

#include"string.h"

main(){

void sort(char *name[],int n);

void print(char *name[],int n);

static char *name[]={ "CHINA","AMERICA","AUSTRALIA","FRANCE","GERMAN"};

int n=5;

sort(name,n);

print(name,n);

}

void sort(char *name[],int n){

char *pt;

int i,j,k;

for(i=0;i<n-1;i++){

k=i;

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

if(strcmp(name[k],name[j])>0) k=j;

if(k!=i){

pt=name[i];

name[i]=name[k];

name[k]=pt;

}

}

}

void print(char *name[],int n){

int i;

for (i=0;i<n;i++) printf("%s",name[i]);

}

說明:

1) 在以前的例子中採用了普通的排序方法,逐個比較之後交換字串的位置。交換字串的物理位置是通過字串複製函式完成的。反覆的交換將使程式執行的速度很慢,同時由於各字串(國名)的長度不同,又增加了儲存管理的負擔。用指標陣列能很好地解決這些問題。把所有的字串存放在一個數組中,把這些字元陣列的首地址放在一個指標陣列中,當需要交換兩個字串時,只須交換指標陣列相應兩元素的內容(地址)即可,而不必交換字串本身。

2) 本程式定義了兩個函式,一個名為sort完成排序,其形參為指標陣列name,即為待排序的各字串陣列的指標。形參n為字串的個數。另一個函式名為print,用於排序後字串的輸出,其形參與sort的形參相同。主函式main中,定義了指標陣列name 並作了初始化賦值。然後分別呼叫sort函式和print函式完成排序和輸出。值得說明的是在sort函式中,對兩個字串比較,採用了strcmp函式,strcmp函式允許參與比較的字串以指標方式出現。name[k]和name[j]均為指標,因此是合法的。字串比較後需要交換時,只交換指標陣列元素的值,而不交換具體的字串,這樣將大大減少時間的開銷,提高了執行效率。