# 13.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\n",a[i][2-i],*a[i],*(*(a+i)+i));
for(i=0;i<3;i++)
printf("%d,%d,%d\n",*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:\n");
scanf("%d",&i);
if(i<0) exit(1);
ps=day_name(name,i);
printf("Day No:%2d-->%s\n",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\n",name[i]);
}
~~~
說明:
1) 在以前的例子中采用了普通的排序方法,逐個比較之后交換字符串的位置。交換字符串的物理位置是通過字符串復制函數完成的。反復的交換將使程序執行的速度很慢,同時由于各字符串(國名)的長度不同,又增加了存儲管理的負擔。用指針數組能很好地解決這些問題。把所有的字符串存放在一個數組中,把這些字符數組的首地址放在一個指針數組中,當需要交換兩個字符串時,只須交換指針數組相應兩元素的內容(地址)即可,而不必交換字符串本身。
2) 本程序定義了兩個函數,一個名為sort完成排序,其形參為指針數組name,即為待排序的各字符串數組的指針。形參n為字符串的個數。另一個函數名為print,用于排序后字符串的輸出,其形參與sort的形參相同。主函數main中,定義了指針數組name 并作了初始化賦值。然后分別調用sort函數和print函數完成排序和輸出。值得說明的是在sort函數中,對兩個字符串比較,采用了strcmp函數,strcmp函數允許參與比較的字符串以指針方式出現。name[k]和name[j]均為指針,因此是合法的。字符串比較后需要交換時,只交換指針數組元素的值,而不交換具體的字符串,這樣將大大減少時間的開銷,提高了運行效率。
- 前言
- 一. C語言概述
- 1.C語言的發展及其版本
- 2.C語言工作原理和運行機制
- 3.C語言編譯器(開發工具|IDE)推薦
- 4.C語言的特點
- 5.第一個C語言程序
- 6.C語言輸出函數(printf)和輸入函數(scanf)
- 7.C語言程序的結構特點
- 8.C語言字符集
- 9.C語言詞匯
- 二. C語言算法
- 1.什么是算法|算法的概念
- 2.簡單的C語言算法舉例
- 3.C語言算法的特性
- 4.用流程圖表示算法
- 5.三種基本結構的流程圖
- 6.用N-S流程圖表示算法
- 7.用計算機語言表示算法
- 三. 數據類型和運算符
- 1.C語言的數據類型
- 2.C語言常量與變量
- 3.C語言整型數據
- 4.C語言實型數據
- 5.C語言字符型數據
- 6.C語言變量賦初值
- 7.C語言數據類型轉換
- 8.C語言算術運算符和算術表達式
- 9.C語言賦值運算符和賦值表達式
- 10.C語言逗號運算符和逗號表達式
- 四. 順序程序設計
- 1.C語言語句概述
- 2.C語言賦值語句詳解
- 3.C語言數據的輸入輸出
- 4.C語言字符的輸入輸出
- 7.C語言順序結構程序設計舉例
- 五. 分支結構
- 1.C語言關系運算符和表達式
- 2.C語言邏輯運算符和表達式
- 3.C語言if語句詳解
- 4.C語言switch語句的用法詳解
- 5.C語言條件運算符和條件表達式
- 6.C語言分支結構程序舉例
- 六. 循環控制
- 1.C語言循環控制概述
- 2.C語言goto語句以及用goto語句構成循環
- 3.C語言while語句的用法
- 4.C語言do-while語句的用法
- 5.C語言for語句用法詳解
- 6.C語言幾種循環的比較
- 7.C語言break和continue語句的用法
- 8.C語言循環控制程序舉例
- 七. C語言數組
- 1.C語言一維數組的定義和引用
- 2.C語言二維數組的定義和引用
- 3.C語言字符數組及其應用
- 4.C語言常用字符串處理函數
- 5.C語言數組應用舉例
- 6.C語言數組小結
- 八. C語言函數
- 1.C語言函數概述
- 2.C語言函數的定義
- 3.C語言函數的參數和返回值
- 4.C語言函數的調用
- 5.C語言函數的嵌套調用
- 6.C語言函數的遞歸調用
- 7.C語言數組作為函數參數
- 8.C語言局部變量和全局變量
- 9.C語言變量的存儲類別
- 九. 預處理命令
- 1.C語言預處理概述
- 2.C語言無參數宏定義
- 3.C語言帶參數宏定義
- 4.C語言文件包含命令
- 5.C語言條件編譯詳解
- 6.C語言預處理指令總結
- 十. C語言指針
- 1.C語言指針的概念
- 2.C語言指針變量
- 3.C語言指針變量作為函數參數
- 4.C語言指針變量的運算
- 5.C語言數組指針
- 6.C語言通過指針引用數組
- 7.C語言數組名作函數參數
- 8.C語言指向多維數組的指針
- 9.C語言字符串指針
- 10.C語言字符串指針變量與字符數組的區別
- 11.C語言函數指針變量
- 12.C語言指針型函數
- 13.C語言指針數組的概念
- 14.C語言指向指針的指針
- 15.C語言main函數參數
- 16.關于指針的總結
- 十一. 結構體和共用體
- 1.C語言結構體的定義
- 2.C語言結構類型變量的說明
- 3.C語言結構變量成員的表示方法
- 4.C語言結構變量的賦值
- 5.C語言結構變量的初始化
- 6.C語言結構體數組的定義
- 7.C語言指向結構體變量的指針
- 8.C語言指向結構體數組的指針
- 9.C語言結構體指針變量作函數參數
- 10.C語言動態存儲分配
- 11.C語言鏈表的概念
- 12.C語言枚舉類型
- 13.C語言類型定義符typedef
- 十二. 位運算
- 1.C語言位運算符詳解
- 2.C語言位域(位段)
- 3.關于位運算的總結
- 十三. 文件操作
- 1.C語言文件概述
- 2.C語言文件指針
- 3.C語言文件的打開與關閉
- 4.C語言文件的讀寫
- 5.C語言文件的隨機讀寫
- 6.C語言文件檢測函數
- 7.C語言庫文件(頭文件)有哪些
- 8.文件操作小結