田維蓮 羊巍 六盤水師范學院
C語言程序設計教學中,指針的教學是重難點;此時,學生已經學了函數、數組及結構體等內容,而在指針與函數、指針與結構體及文件的教學中,都需要學生對指針有著深刻的理解與掌握,同時,在其后續課程數據結構中,對指針有很高要求,學生如果不掌握指針并靈活運用,很多算法的實現無從談起。另一方面,指針的教學比較難,指針涉及機器硬件,不好抽象,教學中,常常要圖示大量的內存圖,學生往往會陷入內存細節,而忽視程序的邏輯與指針概念本身的清晰理解;筆者在多年的教學實踐中,認為應該對指針的教學幾個要點作一些梳理,通過示例強調在教學中幾個比較關鍵的知識點,同時,引入幾個新概念或新的理解方式,幫助學生理解、掌握運用指針。
上述程序片段中,聲明了4個變量,在教學中應該明確有關的3個問題:
1.變量與對象的關聯方式
變量i保存對象2,而類型為int *的變量p保存值為i的內存地址的對象&i,我們可能更關心的是變量p與對象2的關聯,應該明確,變量i與對象2是直接關聯,變量p與對象2是間接關聯,變量p通過保存變量i的地址而與對象2關聯,可以通過間接尋址運算符*取得變量i的值(即對象2),但此時應注意,語句int * p = &i 中的符號“*”不是間接尋址運算符,其作用是編譯時,告訴編譯器,變量p是一個類型為int *的指針(引用)變量,變量p可以和類型為int的變量通過賦值的形式發生關聯,即p = &i。
2.C語言中量(常量與變量)的分類
可以明確,C語言中,從上述變量與對象的關聯方式來說,變量分為兩類,一類為值類型變量,其保存的是非地址值的值對象(如變量i),另一類為引用(指針)類型變量(如變量p),其保存的值是內存地址,但要注意,*p是變量i 的別名(也就是說,在變量i的作用域范圍內,凡是出現變量i的地方,均可用*p替換。),*p是左值,通過*p可以對變量i 的值進行讀寫,對*p進行賦值操作,等同于對變量i進行賦值操作。
對于C語言中的值常量而言,也可以分為兩類,一類是地址值,我們稱其為引用(指針)類型,另一類常量稱為值類型。
3.指針變量的使用
C語言中,要使用指針變量,要有一個前提,指針變量要么和一個變量發生關聯(如語句:int *p = &i;使得指針變量p和變量i發生了關聯),要么指針變量有一個非空的合法地址值(如語句:int*q = (int *)malloc(sizeof(int) * 2;使得變量q得到了一個類型為int *的,由函數malloc分配的連續內存地址的首地址值)。
指針變量t被初始化為NULL,稱t為空指針,t的值NULL(宏NULL在stdio.h和stdlib.h等頭文件中均有定義)是一個區別于任何有效指針值的特殊值,這表明t“不指向任何地方”;若指針變量t沒有初始化,則這個指針變量就成懸空指針,這表明t是一個“不知道指向哪里”的指針,若是通過空指針或懸空指針訪問內存,程序要么崩潰,要么出現難以預料的結果,為此,應該強調,一個良好的編程習慣是,將暫時不用的指針變量在聲明時立即初始化為NULL,這樣可以清出程序中的懸空指針,同時在使用指針變量應檢測其值是否為空,如上述的代碼片段中,對指針變量q的檢測(if(q))。
上述代碼片段中,意在展示通對指針處理數組,學生習慣使用的arr[i],實際上,最后arr[i]被編譯成為*(arr+i),也就是說arr[i]等價于*(arr+i),同理*(p+i)等價于p[i];同時,在教學中,應該強調,p、*p以及*arr是左值,而arr不是,數組名arr是一個類型為int *const的指針常量,其值為數組arr中首元素(arr[0])的地址值,另一個問題是,arr[5]非法,而&arr[5]卻合法,雖然,arr[5]不存在,但是,對arr[5]取地址是可以的,實際上,&arr[5]等價于&*(arr + 5),而&*(arr + 5)就是(arr + 5),(arr + 5)是一個類型為int *的地址值。
上述示例代碼片段中,函數total_score的作用:將結構體c的成員scores中前size-1項數組元素進行加總并返回。將類型為class*的指針作為函數的參數是一種高效的作法,這樣作避免了實參向形參傳值時,數組scores被復制,學生可能會疑問:設計一個函數原型為int total_score(class cl)的函數來做同樣的事也可以高效完成,因為,形參cl的成員scores是一個數組名,當調用發生時,復制給形參cl的成員scores的值不就是個地址嗎,實參的數組沒有被復制,實參和形參共享同一個數組?應該強調的是,在C語言中,對結構體進行復制時,結構體中的數組成員也被復制,而非兩個結構體共享同一個數組,因此,將類型為class結構體作為函數的參數的做法低效。
函數no_pass將結構體c數組成員中,值小于60的數組元素下標標記于另一個結構體nopass中,并返回nopass。此處,學生可能會有疑問:應該返回一個指向nopass的指針,而非結構體nopass,這樣可以避免調用no_pass函數,取返回值時,未發生的結構體數組成員被復制,因而高效。在這個地方,可以強調,C語言中,返回一個指向局部自動變量的指針是致命的,一旦no_pass函數執行完畢,其所占據的內存空間隨即被回收,結構體nopass不存在了,指向nopass的指針變成了指向一個不存在的對象的指針,在no_pass函數外部使用該指針,程序可能會崩潰或出現無法預知結果。因此,no_pass函數的處理方式是正確而又明智的,這種處理方式避免了“返回一個指向局部自動變量的指針”的錯誤。
上述的示例代碼中,學生可能會有疑問:程序為什么報錯?筆者認為,要從幾個方面說起,一方面,”Hello”到底是什么?如果回答,”Hello”是字符串。那么這個回答是含混不清的。首先,”Hello”是字符串字面量(一些教材又稱為字符串常量,并解譯:常量就是不能被改變的量,于是修改字符串常量程序會報錯,這樣的解譯實際上沒有把問題說清楚。),字符串字面量就是字符串的在源程序中的字面表達;其次,”Hello”被保存于一片連續的內存空間中,字符’o’的后面被追加代表字符串結束的字符’ 主站蜘蛛池模板: 国产精品免费电影| 精品91自产拍在线| 欧美性精品不卡在线观看| 色婷婷丁香| 五月婷婷伊人网| 又爽又大又光又色的午夜视频| 成人无码一区二区三区视频在线观看 | 露脸国产精品自产在线播| 精品视频福利| 自拍偷拍欧美| 天天综合色天天综合网| 中文字幕欧美日韩高清| 韩国自拍偷自拍亚洲精品| 国产美女叼嘿视频免费看| 丰满人妻一区二区三区视频| 亚洲AV无码乱码在线观看代蜜桃| 青青草国产精品久久久久| 国产精品短篇二区| 丝袜久久剧情精品国产| 国产亚洲视频在线观看| 成人伊人色一区二区三区| 成年人久久黄色网站| 亚洲成人播放| 91系列在线观看| 欧美精品1区2区| 美女内射视频WWW网站午夜 | 欧美激情福利| 亚洲天堂2014| 国产亚洲第一页| 全部免费毛片免费播放| 国产资源站| 四虎永久在线精品国产免费 | 欧美福利在线播放| 九色视频一区| 国产在线视频自拍| 国产精品成人一区二区| 国产一级裸网站| 国产免费黄| 精品国产欧美精品v| 无码电影在线观看| 特级精品毛片免费观看| 国产91在线|日本| 久久毛片网| 国产在线观看第二页| 精品欧美日韩国产日漫一区不卡| 日本草草视频在线观看| AV无码无在线观看免费| 波多野结衣在线一区二区| 欧美日韩午夜| 激情国产精品一区| 无码精品国产VA在线观看DVD| 久久99国产视频| 一级一级特黄女人精品毛片| 免费无码又爽又刺激高| 国产亚洲精品精品精品| 欧美成一级| 久久精品人人做人人爽97| 久久一级电影| 4虎影视国产在线观看精品| 美女被狂躁www在线观看| 精品福利一区二区免费视频| 欧美一区二区丝袜高跟鞋| 91久久偷偷做嫩草影院电| 欧美午夜网| 拍国产真实乱人偷精品| 国产成人高清精品免费5388| 国内精品一区二区在线观看| 成人伊人色一区二区三区| 久草性视频| 操国产美女| 亚洲欧美激情小说另类| 伊人91视频| 欧美曰批视频免费播放免费| 91视频首页| 在线国产资源| 亚洲成肉网| 久久精品无码一区二区日韩免费| 国产美女自慰在线观看| 2021国产精品自产拍在线观看| 国产在线观看高清不卡| 草逼视频国产| 婷婷综合在线观看丁香|