摘 要: 針對指針這一C語言學習的難點和重點,介紹了變量數據類型與變量存儲區(qū)大小的關系、指針數據類型與指針移動量的關系。以變量的指針、一維數組指針、行指針、結構變量的指針為例,采用對比的方法,介紹了使用指針存取的步驟和語句,并在此基礎上,給出了一種對指針語法規(guī)則的理解和學習使用指針的方法。
關鍵詞: C語言; 指針; 數據類型; 語法規(guī)則
中圖分類號:TP311 文獻標志碼:A 文章編號:1006-8228(2012)12-39-02
Discussion on learning of pointer in C language
Xuan Zheng1, Zhao Junxuan2
(1. School of Electrical and Automation Engineering, Hefei University of Technology, Hefei, Anhui 230009, China;
2. School of Engineering, Anhui Agricultural University)
Abstract: Pointer is an emphasis and a difficulty in C language learning. First the relationships between data type of variable and the variable memory size, pointer data type and the pointer movement are introduced. Then taking pointer variable, one-dimensional array pointer, line pointer and structure pointer variable as examples, the usage of pointer access steps and statement is presented by comparative method. A method of individual understanding on pointer syntax rule and using pointer is put forward.
Key words: C language; pointer; date type; syntax rule
0 引言
C語言是功能強大的編程語言,在大一下“C語言程序設計”課程中,筆者接觸到指針,當時覺得指針本事不小,但理解不了其功能和語法規(guī)則,后通過“微機原理及應用”和“單片機原理及應用”等課程的學習,特別是在掌握了CPU尋址方式后,對指針的使用有了深入的理解。
指針變量(簡稱指針)是一種特殊的變量,是用來存放地址的變量。當在程序中定義了
int i,*ip;char c,*cp;float f,*fp;double d,*dp;
計算機(本文程序運行環(huán)境)就會給變量i分配地址連續(xù)的2個字節(jié)單元的存儲區(qū),i存儲區(qū)的起始地址為i;給變量c分配1個字節(jié)單元的存儲區(qū),c存儲區(qū)的起始地址為c;給變量f分配4個地址連續(xù)的字節(jié)單元的存儲區(qū),f存儲區(qū)的起始地址為f;給變量d分配8個地址連續(xù)的字節(jié)單元的存儲區(qū),d存儲區(qū)的起始地址為d。顯然變量的存儲區(qū)大小與定義時的數據類型存儲長度相一致。給指針變量ip、cp、fp、dp各分配2個連續(xù)的字節(jié)單元的存儲區(qū)。實際上,指針的數據類型并不控制指針變量存儲區(qū)大小,而是控制指針增1(或減1)操作移動量。如:ip++運行時會使指針ip從當前的位置朝地址增大的方向移動2個字節(jié);cp++移動1個字節(jié)單元;fp++移動4個字節(jié)單元;dp++移動8個字節(jié)單元。放到數組中看,即指向下一個數組元素。
1 變量與變量的指針
變量是用來存放單獨一個數據的。在編程中,一般根據要存放的數據類型來定義同類型的變量。例如:要存放數據+1257,安排變量x,則程序可為
例1:
int x=+1257; //定義整型變量x,并賦值
x+=5; //數據處理,通過變量名實現(xiàn)讀寫
換成變量的指針去完成,則程序可為
int x+=1257,*ip; //定義整型變量x和整型指針ip
ip=x; //將x地址送ip,ip成為x的指針
*p+=5; //數據處理,通過變量指針實現(xiàn)讀寫[1]
前者是通過變量名對其存儲區(qū)進行讀寫操作,我們理解與CPU直接尋址方式相對應;后者通過變量x的指針ip對其存儲區(qū)進行讀寫,理解為間接尋址方式[2]。由于變量只存放一個數據,所以我們理解其指針的移動無實際意義。學習中遇到的另一個問題是:變量指針作為函數的參數,對實參值的影響。
例2:
int sum1(int a,int b)
{ a=abs(a); b=abs(b); return(a+b);
}
main()
{ int x=+59,y=-67,z1,z2;
z1=sum1(x,y); z2=x+y;
printf(“%d,%d”,z1,z2); //輸出126,-8
}
換成用變量的指針作為函數參數,程序可為
int sum2(int *ap,int *bp)
{ *ap=abs(*ap); *bp=abs(*bp); return(*ap+*bp);
}
main()
{ int x=+59,y=-67,z1,z2;
z1=sum2(x,y); z2=x+y;
printf(“%d,%d”,z1,z2); //輸出126,126
}
程序中將x、y的地址傳給了函數sum2形參,在sum2里并沒有改變x、y的存儲區(qū)的位置(地址),而是改變了x、y存儲區(qū)的內容。因此我們理解:只要指針作為函數形參,并在函數體里又對指針所指的存儲區(qū)有賦值操作,那么將會影響實參的值[3]。
2 一維數組與一維數組的指針
一維數組用來存放一批同類型數據。例如:有10,20,30,40,50這么一批數據要存放,計劃用a數組。程序可為
例3:
int a[]={10,20,30,40,50};
for (int i=0; i<5; i++)
a[i]=a[i]+5; //通過數組元素下標實現(xiàn)讀寫操作
若換成數組的指針去完成,程序可為:
int *arrayp; //定義同數據類型的指針變量
arrayp=a[0]; //指針賦值
//arrayp成為數組a的指針,當前指向a數組的0號元素
for (int i=0; i<5; i++)
{ *arrayp=*arrayp+5; //通過指針實現(xiàn)讀寫操作
arrayp++; } //指針加1操作,指向下一個元素
由于這一批數據在內存連續(xù)存放,所以指針移動有實際意義。這里每次循環(huán)都采用*arrayp訪問,但是在不同的循環(huán)次數中,arrayp指向是不同的。
3 二維數組與行指針
在C語言中,二維數組的數據按行存放[4]。若以行起始單元作為參考點,則該行中的各元素的偏離參考點的字節(jié)數=所在列號*數據類型存儲長度;各元素地址=所在列號*數據類型存儲長度+所在行起始單元的地址。因此,使用行指針對每一行各元素的訪問,相當于對一維數組各元素的訪問。
例4:
二維數組內容如圖1所示,現(xiàn)要將各數據加上10處理,計劃用arrayb存放。
程序可為:
int arrayb[3][]={{10,20,30,40,50},
{15,25,35,45,55},{16,26,36,46,56}};
int i,j;
for(i=0; i<3; i++)
for(j=0; j++; j<5)
arrayb[i][j]=arrayb[i][j]+10;
換成行指針去完成,程序可為:
int i,j,(*arraybp)[5];
p=arrayb[0]; //指向起始行
for(i=0; i<3; i++)
for(j=0; j++; j<5)
{ *(*arraybp+j)=*(*arraybp+j)+10;
arraybp++; //行指針移動一行
}[5]
我們理解行指針arraybp存儲區(qū)里存放的是行地址,(*arraybp)取出的是該行第一個(0號)元素的地址。
4 結構變量與結構變量的指針
結構變量用來存放若干不同類型的數據。因此,結構變量的數據類型為用戶定義型,即結構的各成員數據類型由用戶根據實際情況定義。例如定義的結構類型如下:
struct person
{ int no;
char name[8];
int math;
int power; };
現(xiàn)要存放該類型數據09110,王靜靜,85,90,并要對后2個成員數據求平均數。程序可為:
struct person aa={09110,王靜,85,90};
int avg;
avg=(aa.math+aa.power)/2;
換成結構指針去完成,程序可為:
struct person *aap;
aap=aa; //aap成為aa的指針
avg=(aap→math+aap→power)/2;
同樣,我們認為aap指針移動無實際意義。結構變量和結構變量的指針作為函數參數意義不一樣。上例結構變量aa(由struct person aa定義)作為實參傳給形參的是一批數據09110,王靜靜,85,9009110;而結構變量指針aap(由struct person *aap定義)作為實參傳給形參的是存放這一批數據09110,王靜靜,85,9009110存儲區(qū)的起始地址。同變量指針作為函數參數一樣,在函數里對指針所指區(qū)域有賦值操作,會影響原始數據。
5 結構數組與結構數組的指針
結構數組用來存放一批若干不同類型的數據。若有一批struct person類型數據,在程序設計中可安排該類型數組存放。
例5:
struct person arrays[]={{09110,王靜靜,85,90},
{09111,張一川,95,97},{09112,石金琳,78,65}};
要將各元素的math成員的值乘以80℅,程序可為:
For (int i=0;i<3;i++)
arrays[i].math=arrays[i]*0.8;
換成結構數組的指針完成,程序如下:
struct person *sp;
sp=arrays[0]; //sp指向0號元素
for (int i=0; i<3; i++)
{ sp→math=sp→math*0.8;
sp++; } //移動結構指針
注意這里的sp++,其實際意義是指向下一個數組元素,而不是指向下一個結構成員。
6 結束語
采用這種對比方法學習指針,能正確建立指針概念,即定義同類型指針,要先給指針賦值確定指針指向,再通過指針對所指的存儲區(qū)進行讀寫操作、理解撥動指針的意義等;對指針加1操作可以通過輸出指針當前值來幫助理解。此外,還能加深理解數據的存放形式,即數據是借助于變量、數組、結構變量、結構數組的存儲區(qū)存入內存。
參考文獻:
[1] 孫力.C語言程序設計[M].中國農業(yè)出版社,2008.
[2] 宋振方等.以管理者視角突破C++指針教學難點[J].現(xiàn)代計算機,
2011.2:66-68
[3] 譚浩強.C程序設計題解與上機指導[M].清華大學出版社,1999.
[4] 譚浩強.C程序設計教程(第二版)[M].清華大學出版社,1999.
[5]付喜梅.淺析C語言中指針與數組[J].電腦開發(fā)與應用,2011.10:
29-32