6.6 指針數(shù)組
前面介紹了指向不同類(lèi)型變量的指針的定義和使用,我們可以讓指針指向某類(lèi)變量,并替代該變量在程序中使用;我們也可以讓指針指向一維、二維數(shù)組或字符數(shù)組,來(lái)替代這些數(shù)組在程序中使用,給我們?cè)诰幊虝r(shí)帶來(lái)許多方便。下面我們定義一種特殊的數(shù)組,這類(lèi)數(shù)組存放的全部是指針,分別用于指向某類(lèi)的變量,以替代這些變量在程序中的使用,增加靈活性。指針數(shù)組定義形式:
類(lèi)型標(biāo)識(shí)*數(shù)組名[數(shù)組長(zhǎng)度]
例如: char *str[4];
由于[ ] 比*優(yōu)先權(quán)高,所以首先是數(shù)組形式str[4 ],然后才是與“*”的結(jié)合。這樣一來(lái)指針數(shù)組包含4個(gè)指針str [0]、str[1]、str[2]、str[3],各自指向字符類(lèi)型的變量。例如: int *ptr[5]; 該指針數(shù)組包含5個(gè)指針ptr[0]、ptr[1]、ptr[2]、ptr[3]、ptr[4],各自指向整型類(lèi)型的變量。
[例6-22] 針對(duì)指針數(shù)組的應(yīng)用,我們分別用指針數(shù)組的各指針指向字符串?dāng)?shù)組、指向一維整型數(shù)組、指向二維整型數(shù)組。
#include
#include
main( )
{
char *ptr1[4]={"china","chengdu","sichuang","chongqin"};
/* 指針數(shù)組p t r 1 的4個(gè)指針?lè)謩e依此指向4個(gè)字符串* /
int i,*ptr2[3],a[3]={1,2,3},b[3][2]={1,2,3,4,5,6};
for (i=0;i<4;i++)
printf("\n%s",ptr1[i]); /* 依此輸出p t r 1 數(shù)組4個(gè)指針指向的4個(gè)字符串* /
printf("\n");
for(i=0; i < 3; i ++)
ptr2[i]=&a[i]; /*將整型一維數(shù)組a的3個(gè)元素的地址傳遞給指針數(shù)組ptr2*/
for(i = 0; i < 3; i ++) / * 依此輸出ptr2 所指向的3個(gè)整型變量的值* /
printf("%4d", *ptr2[i]);
printf("\n");
for(i = 0; i < 3; i ++)
ptr2[i]=b[i]; /*傳遞二維數(shù)組b的每行首地址給指針數(shù)組的4 個(gè)指針* /
for(i = 0; i < 3; i ++) / * 按行輸出* /
printf("%4d %4d\n", *ptr2[i], *ptr2[i] + 1);
}
程序中指針數(shù)組與所指對(duì)象的關(guān)系如圖6 - 1 2所示。
ptr1指針數(shù)組中的4個(gè)指針?lè)謩e指向4個(gè)字符串,如圖6 - 11的a)所示,程序中依此輸出;ptr2指針數(shù)組共有3個(gè)指針,若將整型一維數(shù)組a中各元素地址分別傳遞給指針數(shù)組的各指針,則ptr2[0]就指向a[0];ptr2[1]就指向a[1];ptr2[2]就指向a[2]。若將二維數(shù)組各行的首地址分別傳遞給指針數(shù)組的各指針,如圖6 - 11 b)所示,這樣一來(lái), ptr2[0]就指向了b數(shù)組的第0行,該行有兩個(gè)元素,其地址為ptr2[0]與ptr2[0] + 1;相應(yīng)指針數(shù)組第i個(gè)元素ptr2[i]指向的b數(shù)組的第i行兩個(gè)元素地址分別為ptr2[i]與ptr[i] + 1。
運(yùn)行程序:
china
chengdu
sichuang
chongqin
1 2 3
1 2
2 4
5 6
在處理二維字符數(shù)組時(shí),我們可以把二維字符數(shù)組看成是由多個(gè)一維字符數(shù)組構(gòu)成,也就是說(shuō)看成是多個(gè)字符串構(gòu)成的二維字符數(shù)組,或稱(chēng)為字符串?dāng)?shù)組。指針數(shù)組對(duì)于解決這類(lèi)問(wèn)題(當(dāng)然也可以解決其它問(wèn)題)提供了更加靈活方便的操作。有一點(diǎn)需要說(shuō)明,若定義一個(gè)指針數(shù)組后,指針數(shù)組各元素的取值(即地址)要注意安全性。
如定義指針數(shù)組:
char *ptr[3];
我們說(shuō)該數(shù)組包含三個(gè)指針,但指針的指向是不確定的,指針現(xiàn)在可能指向內(nèi)存的任一地址。假定現(xiàn)在作語(yǔ)句: scanf("%s", ptr[ i ] ), 則輸入的字符串在內(nèi)存的存放其地址由ptr[i]決定。除非給指針數(shù)組元素賦值安全的地址。
[例6-23] 定義字符指針數(shù)組,包含5個(gè)數(shù)組元素。同時(shí)再定義一個(gè)二維字符數(shù)組其數(shù)組大小為5 * 1 0,即5行1 0列,可存放5個(gè)字符串。若將各字符串的首地址傳遞給指針數(shù)組各元素,那么指針數(shù)組就成為名副其實(shí)的字符串?dāng)?shù)組。下面對(duì)各字符串進(jìn)行按字典排序。
在字符串的處理函數(shù)中, strcmp(str1, str2)函數(shù)就可以對(duì)兩個(gè)字符串進(jìn)行比較,函數(shù)的返回值> 0、= 0、< 0分別表示串str1大于str2、str1等于str2、str1小于str2。再利用strcpy( )函數(shù)實(shí)現(xiàn)兩個(gè)串的復(fù)制。下面選用冒泡排序法。
#include
#include
#include
main( )
{
char *ptr1[4],str[4][20],temp[20];
/ *定義指針數(shù)組、二維字符數(shù)組、用于交換的一維字符數(shù)組* /
int i,j;
for(i=0;i<4;i++)
gets(str[i]); / * 輸入4個(gè)字符串* /
printf("\n");
for(i = 0; i < 4; i ++)
ptr1[i] = str[i]; / * 將二維字符數(shù)組各行的首地址傳遞給指針數(shù)組的各指針* /
printf("original string:\n");
for(i = 0; i < 4; i ++) /*按行輸出原始各字符串* /
printf("%s\n", ptr1[i]);
printf("ordinal string:\n");
for(i = 0; i < 3; i ++) /* 冒泡排序*/
for(j=0; j < 4 - i - 1; j ++)
if( strcmp( ptr1[j], ptr1[j+1])>0)
{
strcpy(temp,ptr1[j]);
strcpy(ptr1[j], ptr1[j+1]);
strcpy(ptr1[j+1], temp);
}
for( i=0;i<4;i++) / *輸出排序后的字符串* /
printf("%s\n" , ptr1[i]);
}
運(yùn)行程序:
jkjkdkddfs
fhfgkjkfgkf
hkfgkgfkklg
jjkdjdk
original string:
jkjkdkddfs
fhfgkjkfgkf
hkfgkgfkklg
jjkdjdk
ordinal string:
fhfgkjkfgkf
hkfgkgfkklg
jjkdjdk
jkjkdkddfs
程序中一定要注意指針的正確使用。一旦將二維字符數(shù)組的各行首地址傳遞給指針數(shù)組的各指針,則相當(dāng)于給指針?lè)峙淞税踩刹僮鞯牡刂?,地址空間大小由二維字符數(shù)組來(lái)決定。當(dāng)然也可由編譯系統(tǒng)為指針?lè)峙涞刂酚糜谧址拇娣拧?BR> [例6-24] 利用malloc( )函數(shù)為指針?lè)峙浯鎯?chǔ)空間,實(shí)現(xiàn)字符串的排序。
#include
#include
#include
main( )
{
char *ptr1[4],*temp;
int i,j;
for (i=0;i<4;i++)
{
ptr1[i] = malloc(20); / *為指針數(shù)組各指針?lè)峙? 0字節(jié)的存儲(chǔ)空間* /
gets(ptr1[i]);
}
printf("\n");
printf("original string:\n");
for(i=0; i<4;i++)
printf("%s\n",ptr1[i]);
printf("ordinal string:\n");
for(i=0;i<3;i ++)
for(j=0;j<4-i-1;j++)
if(strcmp(ptr1[j],ptr1[j+1])>0)
{
temp = ptr1[j]; /*利用指向字符串的指針,進(jìn)行指針地址的交換*/
ptr1[j] = ptr1[j + 1];
ptr1[j+1] = temp;
}
for( i=0;i<4;i++) / *字符串輸出* /
printf("%s\n" , ptr1[i]);
}
運(yùn)行程序,其結(jié)果與上述例6 - 2 3完全相同。
前面介紹了指向不同類(lèi)型變量的指針的定義和使用,我們可以讓指針指向某類(lèi)變量,并替代該變量在程序中使用;我們也可以讓指針指向一維、二維數(shù)組或字符數(shù)組,來(lái)替代這些數(shù)組在程序中使用,給我們?cè)诰幊虝r(shí)帶來(lái)許多方便。下面我們定義一種特殊的數(shù)組,這類(lèi)數(shù)組存放的全部是指針,分別用于指向某類(lèi)的變量,以替代這些變量在程序中的使用,增加靈活性。指針數(shù)組定義形式:
類(lèi)型標(biāo)識(shí)*數(shù)組名[數(shù)組長(zhǎng)度]
例如: char *str[4];
由于[ ] 比*優(yōu)先權(quán)高,所以首先是數(shù)組形式str[4 ],然后才是與“*”的結(jié)合。這樣一來(lái)指針數(shù)組包含4個(gè)指針str [0]、str[1]、str[2]、str[3],各自指向字符類(lèi)型的變量。例如: int *ptr[5]; 該指針數(shù)組包含5個(gè)指針ptr[0]、ptr[1]、ptr[2]、ptr[3]、ptr[4],各自指向整型類(lèi)型的變量。
[例6-22] 針對(duì)指針數(shù)組的應(yīng)用,我們分別用指針數(shù)組的各指針指向字符串?dāng)?shù)組、指向一維整型數(shù)組、指向二維整型數(shù)組。
#include
#include
main( )
{
char *ptr1[4]={"china","chengdu","sichuang","chongqin"};
/* 指針數(shù)組p t r 1 的4個(gè)指針?lè)謩e依此指向4個(gè)字符串* /
int i,*ptr2[3],a[3]={1,2,3},b[3][2]={1,2,3,4,5,6};
for (i=0;i<4;i++)
printf("\n%s",ptr1[i]); /* 依此輸出p t r 1 數(shù)組4個(gè)指針指向的4個(gè)字符串* /
printf("\n");
for(i=0; i < 3; i ++)
ptr2[i]=&a[i]; /*將整型一維數(shù)組a的3個(gè)元素的地址傳遞給指針數(shù)組ptr2*/
for(i = 0; i < 3; i ++) / * 依此輸出ptr2 所指向的3個(gè)整型變量的值* /
printf("%4d", *ptr2[i]);
printf("\n");
for(i = 0; i < 3; i ++)
ptr2[i]=b[i]; /*傳遞二維數(shù)組b的每行首地址給指針數(shù)組的4 個(gè)指針* /
for(i = 0; i < 3; i ++) / * 按行輸出* /
printf("%4d %4d\n", *ptr2[i], *ptr2[i] + 1);
}
程序中指針數(shù)組與所指對(duì)象的關(guān)系如圖6 - 1 2所示。
ptr1指針數(shù)組中的4個(gè)指針?lè)謩e指向4個(gè)字符串,如圖6 - 11的a)所示,程序中依此輸出;ptr2指針數(shù)組共有3個(gè)指針,若將整型一維數(shù)組a中各元素地址分別傳遞給指針數(shù)組的各指針,則ptr2[0]就指向a[0];ptr2[1]就指向a[1];ptr2[2]就指向a[2]。若將二維數(shù)組各行的首地址分別傳遞給指針數(shù)組的各指針,如圖6 - 11 b)所示,這樣一來(lái), ptr2[0]就指向了b數(shù)組的第0行,該行有兩個(gè)元素,其地址為ptr2[0]與ptr2[0] + 1;相應(yīng)指針數(shù)組第i個(gè)元素ptr2[i]指向的b數(shù)組的第i行兩個(gè)元素地址分別為ptr2[i]與ptr[i] + 1。
運(yùn)行程序:
china
chengdu
sichuang
chongqin
1 2 3
1 2
2 4
5 6
在處理二維字符數(shù)組時(shí),我們可以把二維字符數(shù)組看成是由多個(gè)一維字符數(shù)組構(gòu)成,也就是說(shuō)看成是多個(gè)字符串構(gòu)成的二維字符數(shù)組,或稱(chēng)為字符串?dāng)?shù)組。指針數(shù)組對(duì)于解決這類(lèi)問(wèn)題(當(dāng)然也可以解決其它問(wèn)題)提供了更加靈活方便的操作。有一點(diǎn)需要說(shuō)明,若定義一個(gè)指針數(shù)組后,指針數(shù)組各元素的取值(即地址)要注意安全性。
如定義指針數(shù)組:
char *ptr[3];
我們說(shuō)該數(shù)組包含三個(gè)指針,但指針的指向是不確定的,指針現(xiàn)在可能指向內(nèi)存的任一地址。假定現(xiàn)在作語(yǔ)句: scanf("%s", ptr[ i ] ), 則輸入的字符串在內(nèi)存的存放其地址由ptr[i]決定。除非給指針數(shù)組元素賦值安全的地址。
[例6-23] 定義字符指針數(shù)組,包含5個(gè)數(shù)組元素。同時(shí)再定義一個(gè)二維字符數(shù)組其數(shù)組大小為5 * 1 0,即5行1 0列,可存放5個(gè)字符串。若將各字符串的首地址傳遞給指針數(shù)組各元素,那么指針數(shù)組就成為名副其實(shí)的字符串?dāng)?shù)組。下面對(duì)各字符串進(jìn)行按字典排序。
在字符串的處理函數(shù)中, strcmp(str1, str2)函數(shù)就可以對(duì)兩個(gè)字符串進(jìn)行比較,函數(shù)的返回值> 0、= 0、< 0分別表示串str1大于str2、str1等于str2、str1小于str2。再利用strcpy( )函數(shù)實(shí)現(xiàn)兩個(gè)串的復(fù)制。下面選用冒泡排序法。
#include
#include
#include
main( )
{
char *ptr1[4],str[4][20],temp[20];
/ *定義指針數(shù)組、二維字符數(shù)組、用于交換的一維字符數(shù)組* /
int i,j;
for(i=0;i<4;i++)
gets(str[i]); / * 輸入4個(gè)字符串* /
printf("\n");
for(i = 0; i < 4; i ++)
ptr1[i] = str[i]; / * 將二維字符數(shù)組各行的首地址傳遞給指針數(shù)組的各指針* /
printf("original string:\n");
for(i = 0; i < 4; i ++) /*按行輸出原始各字符串* /
printf("%s\n", ptr1[i]);
printf("ordinal string:\n");
for(i = 0; i < 3; i ++) /* 冒泡排序*/
for(j=0; j < 4 - i - 1; j ++)
if( strcmp( ptr1[j], ptr1[j+1])>0)
{
strcpy(temp,ptr1[j]);
strcpy(ptr1[j], ptr1[j+1]);
strcpy(ptr1[j+1], temp);
}
for( i=0;i<4;i++) / *輸出排序后的字符串* /
printf("%s\n" , ptr1[i]);
}
運(yùn)行程序:
jkjkdkddfs
fhfgkjkfgkf
hkfgkgfkklg
jjkdjdk
original string:
jkjkdkddfs
fhfgkjkfgkf
hkfgkgfkklg
jjkdjdk
ordinal string:
fhfgkjkfgkf
hkfgkgfkklg
jjkdjdk
jkjkdkddfs
程序中一定要注意指針的正確使用。一旦將二維字符數(shù)組的各行首地址傳遞給指針數(shù)組的各指針,則相當(dāng)于給指針?lè)峙淞税踩刹僮鞯牡刂?,地址空間大小由二維字符數(shù)組來(lái)決定。當(dāng)然也可由編譯系統(tǒng)為指針?lè)峙涞刂酚糜谧址拇娣拧?BR> [例6-24] 利用malloc( )函數(shù)為指針?lè)峙浯鎯?chǔ)空間,實(shí)現(xiàn)字符串的排序。
#include
#include
#include
main( )
{
char *ptr1[4],*temp;
int i,j;
for (i=0;i<4;i++)
{
ptr1[i] = malloc(20); / *為指針數(shù)組各指針?lè)峙? 0字節(jié)的存儲(chǔ)空間* /
gets(ptr1[i]);
}
printf("\n");
printf("original string:\n");
for(i=0; i<4;i++)
printf("%s\n",ptr1[i]);
printf("ordinal string:\n");
for(i=0;i<3;i ++)
for(j=0;j<4-i-1;j++)
if(strcmp(ptr1[j],ptr1[j+1])>0)
{
temp = ptr1[j]; /*利用指向字符串的指針,進(jìn)行指針地址的交換*/
ptr1[j] = ptr1[j + 1];
ptr1[j+1] = temp;
}
for( i=0;i<4;i++) / *字符串輸出* /
printf("%s\n" , ptr1[i]);
}
運(yùn)行程序,其結(jié)果與上述例6 - 2 3完全相同。

