999精品在线视频,手机成人午夜在线视频,久久不卡国产精品无码,中日无码在线观看,成人av手机在线观看,日韩精品亚洲一区中文字幕,亚洲av无码人妻,四虎国产在线观看 ?

C語言指針教學難點透析

2017-02-25 07:10:08張憶文
計算機教育 2017年1期
關鍵詞:定義

張憶文

(華僑大學 計算機科學與技術學院,福建 廈門 361021)

C語言指針教學難點透析

張憶文

(華僑大學 計算機科學與技術學院,福建 廈門 361021)

指針既是C語言的重點,又是教學難點。文章從指針的基本概念入手,由淺入深地討論指針教學的重點與難點,重點介紹指向數(shù)組元素的指針、指向數(shù)組的指針、指針數(shù)組、指針函數(shù)以及函數(shù)指針變量等容易混淆的概念,通過應用實例揭示它們之間的區(qū)別,進而闡釋指針的實質。

C語言;指針;函數(shù);數(shù)組

0 引 言

C語言程序設計在計算機程序設計語言中占有重要的一席之地,它以語法簡潔緊湊、程序精煉、運算符和數(shù)據(jù)結構豐富、編程靈活、可移植性好而著稱[1]。然而由于教科書內容僵化、過于抽象,且授課的對象往往是大學低年級學生,造成某些知識點難以理解,甚至理解錯誤。其中,C語言指針教學就是公認的教學難點[2],因為指針是C語言的一大特色,用途極其廣泛,所以,如何讓學生透徹地理解指針,避免在使用過程中不犯錯誤或者少犯錯誤,是C語言教學中的一個重要問題。

1 指針的基本概念

1.1 指針變量的定義

所謂指針是指變量在內存中的地址,是一個常量,其實質是對地址的操作實現(xiàn)對數(shù)據(jù)的操作。“&”和“*”是指針的兩個最基本的運算符。“&”是取地址運算符,也就是將變量在內存的地址取出來,其結合性為自右向左。“*”是取內容運算符,也就是將指針變量所指向變量的值取出,其結合性為自左向右。用來存放指針(地址)的變量成為指針變量。其定義如下:

類型標識符 *指針變量名表;

例如:

void main( ){

(1) int i=20;

(2) int *p;

(3) p=&i;

(4) printf(“i address is %x p address is %x *p=%d”,&i,&p,*p);}

語句(2)定義了指針變量p,語句(3)對指針變量p進行初始化,使它指向普通變量i。注意到語句(2)指針定義中的“*”不是指針運算符,不進行任何運算,它僅僅是標志所定義的變量為指針變量。運行程序可知, i address is 0018FF44,p address is 0018FF40,*p=20。普通變量i和指針變量p的關系如圖1所示。

圖1 普通變量i與指針變量p

從圖1可以看出指針變量p的值為普通變量i的地址,也就是說指針變量p指向了普通變量i。普通變量i的值為20。指針變量和普通變量都是變量,其在內存中都占據(jù)一定的空間,例如:指針變量p在內存的地址為0018FF40,而普通變量i在內存的地址為0018FF44。指針變量與普通變量的最大區(qū)別就是:指針變量所存儲的內容是其他變量地址,而普通變量所存儲的內容是值。

1.2 指針變量的引用

指針變量的使用要注意以下幾點:

(1) 必須先定義,后使用。

(2)對指針變量的操作,其類型要一致。例如int i=50;char *p=&i;這個操作就是非法的,因為普通變量i其類型是整形,而指針變量p其類型為字符型,這兩個變量的類型不匹配。

(3)不能將數(shù)值直接賦值給指針變量,例如int *p=62353;這個語句也是非法的,因為指針變量只能存儲其他變量的地址。

(4)指針變量在使用之前必須對其進行初始化,例如 int *p;printf(“*p is %d”);這個操作是非法的,因為沒有對指針變量進行初始化,也就是說指針變量沒有所指。

(5)指針變量可以進行算術運算,例如 int a[5]={0,1,2,3,4}; int *p=a; p+3;語句p+3不是指針變量p的值簡單加3,而是使指針變量p指向a[3],假設一個int占用4個字節(jié)(不同的編譯器,所占用的字節(jié)不一樣),p+3相當于移動了12個字節(jié)。

(6)注意const int *p;int const *p; const int const *p;三者的區(qū)別。const int *p表示值不變地址可變,也就是說不能利用指針變量p對其所指向的對象的值進行修改,但指針變量p可以指向同類型的其他變量。int const *p表示地址不變,值可變,也就是說可以利用指針變量p對其所指向的對象的值進行修改,但指針變量p不能指向同類型的其他變量。const int const *p表示值不變,地址也不變,也就是說不能利用指針變量p對其所指向的對象的值進行修改,也不能使指針變量p指向同類型的其他變量。

2 指針與數(shù)組

數(shù)組是C語言中的一個重要構造類型,是具有相同數(shù)據(jù)類型的有序數(shù)據(jù)集合。數(shù)組中的每個元素都在內存中占用存儲單元,且每個存儲單元占據(jù)的存儲空間都是相同的。數(shù)組名代表數(shù)組元素的首地址,可以將其直接賦值給相同數(shù)據(jù)類型的指針變量。在指針的教學過程中,必須注意指向數(shù)組元素的指針、指向指針的指針、指向數(shù)組的指針、指針數(shù)組等概念的區(qū)別與聯(lián)系。

2.1 指向數(shù)組元素的指針

指向數(shù)組元素的指針變量的定義與以前的指針變量的定義一樣,但要確保數(shù)組的類型與指針變量的類型一致。例如:

以上的兩條語句定義了指向一維數(shù)組a的元素的指針變量p,并且對指針變量p進行初始化,使其指向數(shù)組的首元素a[0]。接下來我們就可以使用指針變量p訪問數(shù)組元素。例如p+1指向元素a[1],注意p+1不是將p的數(shù)值簡單加1,而是使其指向當前元素的下一元素。所以*(p+1)與a[1]等價。更一般化,p+i (0≤i≤4)表示指針變量p指向數(shù)組的a[i]元素,所以*(p+i)與a[i]等價。當然也可以直接用數(shù)組名直接訪問數(shù)組元素,因為數(shù)組名代表數(shù)組首元素的地址,所以有*(a+i)與*(p+i)等價。

以上介紹了用指針變量訪問一維數(shù)組元素,接下來介紹指針變量訪問二維數(shù)組元素。例如:

想要訪問二維數(shù)組中的元素a[2][3],可以用如下的方法:

(1)直接用數(shù)組下標a[2][3];

(2)用一維數(shù)組名a訪問:*(a[2]+3)或*(a[0]+11)或*(a[3]-1];

(3)用二維數(shù)組名a訪問,只要將(2)中的一維數(shù)組名改成相應的二維數(shù)組名即可:*(*(a+2)+3)或*(*(a+0)+11)或*(*(a+3)-1);

(4)用指針變量p訪問:*(*(p+2)+3)或*(*(p+0)+11)或*(*(p+3)-1)等等。

2.2 指向指針的指針

指向指針的指針是指一個指針變量指向了另外一個指針變量,常稱為多級間址。例如:

語句(1)、(2)、(3)定義了指向指針的指針變量q并且對其進行初始化,指針變量q指向了指針變量p,而指針變量p指向了普通變量i。 運行程序可知,i address is 0018FF34,p address is 0018FF30,q address is 0018FF2C,p=0018FF34,q=0018FF30,*p= 20,**q=20。普通變量i、指針變量p和指向指針的指針變量q的關系如圖2所示。

圖2 指向指針的指針變量關系

從圖2可以看出指向指針的指針變量q的值為指針變量p的地址,也就是說指向指針的指針變量q指向了指針變量p。指針變量p的值為普通變量i的地址,也就是說指針變量p指向了普通變量i。*q指向了普通變量i,因此,**q的值就是i的值等于20。

2.3 指向數(shù)組的指針

指向數(shù)組的指針是數(shù)組名的指針,即數(shù)組首元素的指針,其實質為指針。接下來的實例將介紹指向一維數(shù)組的指針。

void main( ){

(1) int a[]={10,20,30,40,50};

(2) int (*p)[5];

(3) p=&a;

(4) printf(“%d ”, *(*p+3) );

(5) int b[2][4]={{0,1,2,3},{4,5,6,7}};

(6) printf(“%d ”, *(*(b+1)+3) );}

語句(2)聲明p是一個指向一維數(shù)組的指針,且所指向的一維數(shù)組的長度為5,其實質相當于二級間址。語句(3)將p初始化,使其指向一維數(shù)組a。*p的值和a的值一樣,都指向a[0],(*p+3)指向a[3],所以語句(4)的輸出結果為40。注意語句(3)不可以寫成p=a,因為盡管a是數(shù)組名代表數(shù)組元素的首地址,但其與數(shù)組名的地址是兩回事。實際上,二維數(shù)組名就是一個指向一維數(shù)組的指針,所以語句(6)的輸出結果為7。接下來的實例將介紹指向二維數(shù)組的指針。

void main( ){

(1) int a[2][3]={10,20,30,40,50,60};

(2) int (*p)[2][3];

(3) p=&a;

(4) printf(“%d ”, *(*(*p+1)+2));

語句(2)聲明p是一個指向二維數(shù)組的指針,且所指向的二維數(shù)組的第一維長度為2,第二維長度為3,其實質是指向二級指針的指針,相當于三級間址。語句(3)將p初始化,使其指向二維數(shù)組a。*p的值為a,(*p+1)指向一維數(shù)組a[1],*(*p+1)+2指向二維數(shù)組元素a[1][2],所以語句(4)的輸出結果為60。

2.4 指針數(shù)組

指針數(shù)組是指由若干個相同類型的指針組成的數(shù)組,其實質是數(shù)組。指針數(shù)組與普通數(shù)組的本質區(qū)別在于指針數(shù)組的元素是指針,而普通數(shù)組的元素是數(shù)值。指針數(shù)組與指向數(shù)組的指針的本質區(qū)別在于指針數(shù)組的實質是數(shù)組,而指向數(shù)組的指針其實質是指針。接下來的實例將介紹指針數(shù)組的定義及使用。

void main( ){

(1) char *p[4]={“apple”, “orange”, “pear”, “banana”};

(2) int i=2;

(3) printf(“%s ”, p[2]);}

語句(1)定義了指針數(shù)組p,它由4個元素(p[0]~p[3])組成,每個元素都是一個指向字符類型的指針。此外語句(1)還初始化了指針數(shù)組p,使p[0]的值指向字符串a(chǎn)pple的首地址,p[1]的值指向字符串orange的首地址,p[2]的值指向字符串pear的首地址,p[3]的值指向字符串banana的首地址。特別需要注意區(qū)分char *p[4]與char (*p)[4],前者是指針數(shù)組,后者是指向一維數(shù)組的指針。語句(3)輸出的結果為pear。

3 指針與函數(shù)

3.1 指針作為函數(shù)參數(shù)

整型、實型、字符型、數(shù)組、指針等都可以作為函數(shù)的參數(shù),但整型、實型、字符型等作為函數(shù)參數(shù)時,實參與形參間是單向的值傳遞,也就是說形參的值發(fā)生變化不會影響到實參。而指針作為參數(shù)時,實參與形參間是傳遞的是地址,也就是說實參與形參共享一個地址空間,如果形參的值發(fā)生改變,實參的值也會相應的改變。例如:

上述實例中,函數(shù)void swap(int *p, int *q)是以指針作為形參,其作用是交換兩個形參的值。在主函數(shù)中,定義了兩個整形變量a、b并且分別賦值為10、20;此外,還定義了兩個整形的指針變量pa、pb使其分別指向a和b。調用函數(shù)swap時,需要注意的是實參的類型和形參的類型必須一致,在調用函數(shù)swap之后,程序輸出a=20,b=10,說明以指針作為函數(shù)參數(shù),形參的值變化,相應的實參的值也發(fā)生改變。

3.2 指針函數(shù)

指針函數(shù)是指函數(shù)的返回值為指針類型,也就是說函數(shù)最后返回的是一個地址,而不是一個數(shù)值。指針函數(shù)的定義形式為:

類型標識符 *函數(shù)名(參數(shù)名){

函數(shù)體

以上實例中,首先定義了全局變量a,并且對其初始化,使其值為10;接下來定義了指針函數(shù)fun(),其返回類型為指向整型的指針,其參數(shù)列表為空。fun()函數(shù)的主要作用是返回全局變量a的地址。主函數(shù)首先定義了整型指針變量p,接下來對其初始化,使其指向fun()函數(shù),接著輸出p所指向對象的值,最終的運行結果為*p=10。注意到指針函數(shù)不能返回局部變量的地址,因為局部變量在程序執(zhí)行完成后,其所占用的內存空間會被系統(tǒng)回收。

3.3 函數(shù)指針變量

一個函數(shù)在內存中的起始地址就是該函數(shù)的指針。函數(shù)指針變量是用來存儲函數(shù)指針,通過函數(shù)指針變量可以調用函數(shù)。函數(shù)指針變量的定義如下:

類型標識符 (*指針變量名)(參數(shù)類型1,參數(shù)類型2,…,參數(shù)類型n);

例如:

以上實例中,首先定義了add函數(shù),其有兩個整型的參數(shù)a和b,add函數(shù)最終返回一個整型值,add函數(shù)的作用是求a與b的和。主函數(shù)首先定義了整型變量a和b,且分別對其初始化,a的值為5,b的值為10。語句int (*p_fun)(int,int);定義了函數(shù)指針變量p_fun。注意函數(shù)指針變量與指針函數(shù)的區(qū)別,int *p_fun(int,int)表示p_fun是指針函數(shù),其返回一個指向整型的指針。區(qū)別函數(shù)指針變量與指針函數(shù)主要看這二者在定義過程中“*”號是否用圓括號()括起來,有圓括號表示函數(shù)指針變量,沒有圓括號表示指針函數(shù)。接下來的語句p_fun=add;對函數(shù)指針變量進行初始化,使其指向add函數(shù)在內存中的首地址,注意到在C語言中函數(shù)名稱代表函數(shù)在內存的起始地址。接下來的語句輸出(*p_fun)(a,b)的值,其結果為15。注意到(*p_fun)(a,b)也可以寫成p_fun(a,b)。

4 結 論

總之,在C語言的教學中要注意結合實例講清以下幾點:①指向指針的指針其實質是二級間址;②指向數(shù)組的指針其實質是指針,而指針數(shù)組其實質是數(shù)組;③指針函數(shù)其實質是指針,而函數(shù)指針其實質為函數(shù)。

[1] 劉韶濤, 潘秀霞, 應暉. C語言程序設計[M]. 北京: 清華大學出版社, 2015.

[2] 趙輝, 馮東棟. C語言中指針的教學方法研究[J]. 福建電腦, 2011, 27(4): 187-188.

(編輯:彭遠紅)

1672-5913(2017)01-0155-04

G642

華僑大學引進人才科研啟動基金項目(2016BS104)。

張憶文,男,講師,研究方向為綠色計算、實時調度,zyw@hqu.edu.cn。

猜你喜歡
定義
以愛之名,定義成長
活用定義巧解統(tǒng)計概率解答題
例談橢圓的定義及其應用
題在書外 根在書中——圓錐曲線第三定義在教材和高考中的滲透
永遠不要用“起點”定義自己
海峽姐妹(2020年9期)2021-01-04 01:35:44
嚴昊:不定義終點 一直在路上
華人時刊(2020年13期)2020-09-25 08:21:32
定義“風格”
成功的定義
山東青年(2016年1期)2016-02-28 14:25:25
有壹手——重新定義快修連鎖
修辭學的重大定義
當代修辭學(2014年3期)2014-01-21 02:30:44
主站蜘蛛池模板: 亚洲精品无码久久毛片波多野吉| 久久美女精品| 依依成人精品无v国产| 欧美人人干| 美女被操91视频| 亚洲av无码成人专区| 国产精品999在线| 91最新精品视频发布页| 国产va视频| 91 九色视频丝袜| 国产又色又刺激高潮免费看| 久久无码av三级| 曰韩人妻一区二区三区| 中文字幕无码av专区久久| 97亚洲色综久久精品| 国产亚洲精品无码专| 国产精欧美一区二区三区| 国产aaaaa一级毛片| 久久久久无码精品| 国产丝袜丝视频在线观看| 亚卅精品无码久久毛片乌克兰| 国产第一页第二页| 青青国产视频| 亚洲天堂网视频| 热99re99首页精品亚洲五月天| 成人年鲁鲁在线观看视频| 99青青青精品视频在线| 色色中文字幕| 中文字幕在线播放不卡| 欧美色亚洲| 日韩亚洲高清一区二区| 国产一区免费在线观看| 免费在线国产一区二区三区精品| 无码免费的亚洲视频| 欧美一区二区精品久久久| 亚洲 欧美 日韩综合一区| 国产超碰一区二区三区| 99精品国产自在现线观看| 欧美国产综合色视频| 亚洲男人的天堂久久香蕉网| 欧美日韩第二页| 久草国产在线观看| 国产成人精品在线1区| 亚洲成在人线av品善网好看| 无码人妻免费| 成人福利在线免费观看| 在线欧美一区| 亚洲国产日韩视频观看| 国产精品99久久久| 日韩人妻精品一区| 亚洲国产日韩欧美在线| 久久久久亚洲av成人网人人软件| 丰满少妇αⅴ无码区| 538国产视频| 在线观看无码a∨| 国产精品视屏| 欧美国产日产一区二区| 亚洲人在线| 97成人在线观看| 在线色国产| 色呦呦手机在线精品| 精品国产一区二区三区在线观看| 亚洲AV免费一区二区三区| 国产白浆视频| 国产国产人成免费视频77777| 91精品免费久久久| 婷婷色一二三区波多野衣| 欧美日韩福利| 国产精品国产三级国产专业不| 精品少妇人妻无码久久| 国产精品xxx| 国产日韩丝袜一二三区| 国产女人在线视频| 欧美日韩成人| 97色婷婷成人综合在线观看| 欧美人在线一区二区三区| 国产门事件在线| 亚洲精品午夜天堂网页| 亚洲成年人片| 在线观看国产精品一区| 久久精品女人天堂aaa| 欧美国产精品不卡在线观看|