[摘 要] 指針是C語言的重要內容,正確而靈活地使用它,可以幫助我們解決許多實際問題。本文介紹了指針變量的定義與指針運算符, 并且通過例題講解復雜指針的應用,以使讀者進一步理解、掌握。
[關鍵詞] C語言;指針;應用
doi : 10 . 3969 / j . issn . 1673 - 0194 . 2010 . 04 . 044
[中圖分類號]TP312 [文獻標識碼]A [文章編號]1673 - 0194(2010)04 - 0126 - 03
指針是C語言中最具特色的內容 ,也是學習C語言的一個難點。正確而靈活地運用它,可以有效地表示復雜的數據類型 。掌握指針的應用,可以使程序簡潔、緊湊、高效。筆者在從事C語言教學中發現很多同學在學習指針時非常困難,對學習內容一知半解。筆者將從指針變量的定義及指針的應用方面闡述C語言中的指針。
一、指針變量定義
用戶在程序中使用任何類型的變量時都必須遵循先定義后使用的原則,其定義方式如下:
類型標識符*標識符 ; ( 如 int *p; ) ,即在定義指針變量時, 既要說明它是一個指針 ,同時也要說明該指針是指向哪種類型數據的指針。由于指針變量的值只能是個地址,因此我們在引用指針時一定要注意,即對其賦值只能是地址值,而不能是其他類型的變量。
二、指針運算符
(1) 求地址運算符,返回操作數的地址,即變量在計算機內的位置。
(2) *取內容運算符。返回操作數所指變量的值。但是*運算符在指針定義時表示將后邊的變量定義為指針類型。所以在遇到該運算符時應注意區分是定義還是取存儲單元的內容。
例如:int *p;//這是定義指針變量p
int i=5;
p=i;//取I所對應的地址值,并賦值給p
j=*p;//這是將指針p所指的存儲單元的值5取出來賦值給j
三、指針的應用
1. 簡單的指向變量的指針和指向指針的指針
(1)簡單的指向變量的指針。
一般形式:數據類型標識符 *指針變量名;
main()
{ int *p1,*p2,a=1,b[3]={1,2,3};//定義了2個指向整型變量的指針p1,p2
p1=a; //把數值a的地址賦給p
p2=b;//把數組b的首地址賦給p
printf(“%d”,*p1);//通過指針p1輸出數值a的值;
for (i=0;i<3;i++)
printf(“%d”,p2++); }//通過指針p2輸出數組b的值;
(2)指向指針的指針。
一般形式:數據類型標識符 **指針變量名;
main()
{ char *a[]={“Basic”,”C”,”VFP”,”Java”}, **p;//a為指針數組并初始化
inti;
for(i=0;i<4;i++)
p=a+i;//把指針數組a的地址賦給p ;
printf(“%s\”,*p); }//通過指針P輸出字符串
2. 指針數組和指向一維數組的指針變量
(1)指針數組。
一般形式:類型標識符 *數組名〔數組長度說明〕; 其每一個元素均為指針變量。
main()
{static char a[5][5]={“VC”,”JAVA”,”C”,”VFP”,”VB”},*p[5];
inti;
for(i=0;i<5;i++)
{p[i]=a[i]; //把數組每行的首地址賦給指針數組p
printf(“%s\”,p[i]);} } //通過p輸出字符串
(2) 指向一維數組的指針變量。
一般形式:類型標識符 (*數組名)〔數組長度說明〕; 因為運算符[?]的優先級高于*,所以用圓括號()將*與指針變量名括起來以改變運算符的優先級順序,使*先作用于指針變量,然后再與[?]結合,形成指向一維數組的指針變量。
例: void main()
{ int b[3][5]={1,3,6,4,5,9,7,23,56,10,0,8,33,2,11};
int (*p)[5]=b;//定義一個指針變量p指向包含5個整型數值的數組b
for(i=0;i<3;i++)
{for(j=0;j<5;j++)
printf(“%d”, *(*(p+i)+j)); }
}
指向一維數組的指針變量,實際上是指向一維數組元素的指針變量。可以利用指向一維數組的指針變量,完成數組數據的操作處理,
int a[10],*p; /*若數組為int型,則指針應指向int型*/
C語言規定數組名中代表數組的首地址,所以下列兩條語句是等價的。
p=a[0];
p=a;
通過指針可以引用數組元素,例p+i和a+i就是a[i]的地址
*(p+i)或*(a+i)是p+i或 a+i所指向的數組元素a[i].
main()
{ float a [3]={1.0,2.0,3.0},*p;
int i;
p =a;
for(i=0;i<3;i++)
printf(\"%f \",*(p+i)); }
3. 指向函數的指針、返回指針值的函數與函數指針數組
(1)指向函數的指針。
一般形式:數據類型標識符(*指針變量名)();
指針變量名兩邊的括號不能省略,表示指針變量名先與*結合,是一個指針變量,再與后邊的括號結合,表示此指針變量指向函數,前面的數據類型標識符是函數的返回值。
數據類型標識符是指函數返回值的類型。(*指針變量名)()表示定義一個指向函數的指針變量,它不是固定指向哪一個函數的,只是表示定義了這樣一個類型的變量,是專門用來存放函數的入口地址的。
#include
int min(int m,int n)
{ if (m return m; else return n;} main() {int (*p)(); //說明p是指向函數的指針 int a,b,c; p=min;//使p指向函數min的首地址 scanf(“%d%d”,a,b); c=(*p)(a,b);//執行p所指的函數 printf(“%d%d%d”,a,b,c);} (2)返回指針值的函數。 一般形式:類型標識符 *函數名(參數表) 形參說明 { 函數體 } main() { static float score[][4]={{60,70,84,98,},{58,96,67,86},{74,82,87,65}}; folat *score();//說明一個函數score,函數的返回值是指向浮點型變量的指針 float *p;//說明指針變量p int i,m; scanf(“%d”,m); p=search(score,m);//調用函數search,函數的返回值為指針類型 for(i=0,i<4;i++) printf(“%f\”,*(p+i));} float*search(pointer,n) //定義一個返回指針值的函數search float(*pointer)[4]; //說明形參pointer是一個指向一維數組的指針變量 int n; { float *pt; pt=*(pointer+n); return(pt);} (3)函數指針數組。 一般形式:函數返回值類型 (*數組名[])( ) 函數指針數組是一個其元素是函數指針的數組。也就是說,此數據結構是是一個數組,且其元素是一個指向函數入口地址的指針。 #include int?sub(int a,int b) {return a-b;} int add(int a,int b) {return a+b;} int mul(int a,int b) {return a*b;} void main() {int(*pfunc[])(int,int)={sub,add,mul};//函數指針數組的聲明與初始化 printf(\"10 sub 5 is:%d\\",pfunc[0](10,5));//調用相應函數 printf(\"10 add 5 is: %d\\",pfunc[1](10,5));//調用相應函數 printf(\"10 mul 5 is:%d\\",pfunc[2](10,5));//調用相應函數 } 四、結束語 總之,指針的概念比較復雜,使用也比較靈活,因此初學時常會出錯,我們應該多思考、多比較、多上機,在實踐中掌握它,這樣才能更好地理解并運用這種數據,編制質量高的程序和軟件。 主要參考文獻 [1] 譚浩強. C語言程序設計[M]. 第2版. 北京:清華大學出版社,1999. [2] 廖雷. C語言程序設計[M]. 第2版. 北京:高等教育出版社,2003.