摘要:首先介紹了C語言中指針的有關概念,然后運用指針實現了一個鏈表程序,針對初學者在實現該程序時常見的一些錯誤,分析了錯誤出現的原因,并對這些錯誤進行了更正。
關鍵詞:C語言;程序;指針;鏈表
中圖分類號:TP312文獻標識碼:A文章編號:1009-3044(2010)01-244-03
Application of Pointer in C Language
ZHANG Bin-lian
(School of Information Management and Engineering, Jishou University, Zhangjiajie 427000, China)
Abstract: First introduced concept of pointer in C language, then designed a link-list program by using pointer. For some common errors appeared when beginners designed program with C language, analyzed the wrong reasons and corrected these errors.
Key words: C language; program; pointer; link-list
指針是C語言的一個重要概念,在C語言中被廣泛的使用,它和數組、字符串、函數間數據傳遞有著密不可分的聯系。在某些場合,指針是運算得以解決的唯一途徑,它可以有效的表示和實現復雜的數據結構。正確掌握指針的應用,可以使程序簡潔、緊湊、高效。由于指針的概念比較復雜,使用比較靈活,所以初學時常會出現錯誤,而一般教材中講述指針相關內容是從語法和用法著手,并沒有對實際程序中的錯誤進行分析。因此對于初學者,有必要根據實際程序對指針的相關概念和使用時常見的一些錯誤進行分析。本文將先介紹指針及指針的類型,然后分析幾種初學者在使用指針實現單鏈表操作時出現的錯誤,并對這些錯誤進行分析更正。
1 指針的相關概念
1.1 定義
指針是某一個實體的地址。當我們要訪問某一變量是,如果不是直接通過變量名來進行,而是通過存放變量地址的指針見解進行,稱為“間接訪問”。C語言中處理一個變量、一個數組、一個函數、一個文件時,需要由操作系統把這些量調入內存的不同存儲單元中,每一個存儲單元都有一個地址,指針變量是用于存放某一類型變量的地址的變量。
1.2 指針的類型及應用
1) 指向簡單變量的指針
指針所指的數據類可以是簡單的數據類型。
2) 指向數組的指針
指針所指的數組既可以是一維數組,也可以是多維數組。
例:void main()
{int arr[3] = {1,2,3};
int *p;
for (p = arr; p < arr + 3; p++)
printf (\" %d \", *P);
}
程序中指針p指向了數組arr的首地址,通過p++來訪問a數組的每一元素。
3) 指針數組
指針數組是指數組元素是由指針變量組成的。定義如:int *p[2],其中指針數組p包含兩個元素,每個元素是指向整型數據指針。
例:void main()
{int *p[2],i;
int arr[2] [ 2 ]={1,2,3,4};
for (i = 0;i<2;i++) p [i] = a [i];
printf (\"% d\\",*(p[0]+1));
}
程序中p是一個指針數組,通過for循環語句給指針數組中的每個指針變量賦值,p[0]的初值為二維數組a的首地址,*(p[0]+1)便是元素a[0][1],因此程序輸出2。
4) 指向指針的指針
指向指針的指針是指指針變量指向的是某個指針的地址,定義如:int **P。
例:void main ()
{ int **P,i;
int arr[2][2]={1,2,3,4};
p = a;
for (i = 0;i<2;i++)
printf(\" %d\\",*(*(p+1)+i));
}
程序中指針p指向二維數組a的首地址,p+1指向數組a的第二行,*(p+1)為第二行第一個元素的地址,**(p+1)為數組第二行的第一個元素,*(p+1)+1為第二行第二個元素的地址,*(*(p+1)+1)為數組第二行的第二個元素,因此程序輸出3和4。
5) 指向函數的指針
指針變量指向函數的首地址,然后通過該指針變量調用該函數。定義如:int (*p) ()。
例:int max (int a,int b)
{int c;
if (a>b) c=a;else c=b;
return (c);
}
void main ()
{int(*p)();int a,b;
p=max;scanf (\"% d,%d\", a, b);
printf(\"max=%d\\",(*p)(a,b));
}
程序中int(*p)()定義了一個指向函數的指針變量p,函數名max代表了函數max()的入口地址,把p=max,指針p就指向了函數max,(*p)(a,b)是通過p調用函數max。
2 指針應用實例錯誤分析
2.1 鏈表應用程序
為了分析使用指針時常見的錯誤,我們寫了一個鏈表程序,具體包括生成鏈表和求鏈表長度兩個功能,程序代碼如下:
# include
# include
struct LNode
{ int data;
struct LNode *next;
} Node; /*定義結點*/
void CreateList(struct LNode *L) /*建立鏈表的函數*/
{ struct LNode * p , * q;q=L;
int num; printf (\"Input data of Node(-1 means end):\"); scanf (\"%d\",num);
while(num!=-1) /*輸入-1時結束*/
{ p = (struct LNode *) malloc (sizeof (Node));
p->data=num; q->next=p; q=q->next; scanf (\"%d\",num);
}
}
int ListLength ( struct LNode * L) /*求鏈表長度的函數*/
{ int i=0;struct LNode *q;q=L;
while (q){i++; p=p->next;} return (i);
}
void main()
{ struct LNode * head;int len;
head=(struct LNode *)malloc(sizeof(Node));
CreateList(head);len= ListLength ( head);
Printf(\"The length of List is % d\",len)
}
2.2 常見錯誤分析
對于以上程序,初學者常見的錯誤有:
1) 指針沒有指向任何內容就當作函數實參調用函數
有些初學者在調用CreateList(head)時沒有對實參head賦值,只是聲明了head是結構體指針。這時雖然實參和形參的類型相同,但實參沒有指向任何具體的內存空間。如
void main()
{ struct LNode * head;int len;
CreateList(head); len= ListLength (head);
printf(\"The length of List is % d\",len)
}
以上程序中head是一個指針,它并沒有指向任何位置,更沒有指向一個具體的結點,則調用CreateList(head)后參數L也和head一樣,函數中q=L之后q->next=p不能正確執行。
2) 指針運算錯誤
在定義ListLength(struct LNode * L)時,將while循環中p指針指向下一個結點寫成p++。
int ListLength ( struct LNode * L)
{ int i=0;struct LNode *q;q=L;
while (q){i++; p++;} return (i);
}
p++只能用在p指向一段連續的空間時,p指向下一個元素時用。在此程序中,p是指向鏈表中的某個結點,結點是動態分配的,結點與結點之間在空間上并不一定是連續的,所以p++之后,p并不一定指向下一個結點,所以下一個結點和下一個空間是完全不同的兩個概念。正確的寫法應該是“p=p->next;”。
3) 錯誤的指針賦值
void CreateList(struct LNode *L)
{ struct LNode * p, * q; q=*L;
int num; printf (\"Input data of Node(-1 means end):\"); scanf (\"%d\",num);
while(num!=-1)
{ p = (struct LNode *) malloc (sizeof (Node));
p->data=num; q->next=*p;q=q->next; scanf (\"%d\",num);
}
}
struct LNode *L說明L是指向結構體的指針,q也如此。*L是引用L指向內容,q=*L是把L指向的結構體賦給了一個指針變量,賦值號兩邊的類型不一致。q->next=*p也是如此。正確的應該是q=L和q->next=p。
3 總結
指針是C語言的精髓,也是C語音學習的重點。指針數據類型使高級語言程序員可以按地址操作計算機內存,靈活實現一些特定功能;還可以使用指針方便地表達復雜的數據結構,使程序簡潔、高效、緊湊。本文以實際鏈表操作為例,針對初學者在使用指針時經常出現的一些錯誤進行分析,希望能使初學者更快掌握指針的本質和用法。
參考文獻:
[1] 張琳梅,尚永強.淺談C語言中的指針[J].電腦知識與技術,2008(35):2546-2549.
[2] 譚浩強.C程序設計[M].北京:清華大學出版社,2005.
[3] 盧有杰,吳煒煜.C語言高級程序設計[M].北京:清華大學出版社,1999.