楊英翔
摘 要:C語言是國內(nèi)外廣泛使用的一種計算機語言,C語言功能豐富、表達能力強、使用靈活方便、應用面廣、目標程序效率高、可移植性好,既具有高級語言的優(yōu)點,又具有低級語言的許多特點。
關鍵詞:C語言;教學
0 引言
C語言是國內(nèi)外廣泛使用的一種計算機語言,C語言功能豐富、表達能力強、使用靈活方便、應用面廣、目標程序效率高、可移植性好,既具有高級語言的優(yōu)點,又具有低級語言的許多特點。因此,C語言不僅是計算機專業(yè)學生的一門重要課程,也是高校中非計算機專業(yè)學生學習計算機知識的一門重要課程。
作者的C語言課都是在機房里進行的,學生可以人手一機。在C語言的教學過程中,精講多練,講練結合,依據(jù)學生的能力,采用以學生為主體逐步引導、啟發(fā)學生。即教師在課堂上起引導的作用,讓學生在機學習,邊學邊練,不斷發(fā)現(xiàn)問題,解決問題,循序漸進,逐步提高。這種方法打破了課堂教學和實驗教學的嚴格界線,在C語言的教學實踐中取得了良好的效果。
1 指針用法
指針通常指向一片存儲空間,而空間可采用靜態(tài)分配或動態(tài)分配。靜態(tài)分配是指在編寫C程序時已確定了存儲空間。如使用全局變量,static char a[size],則編譯器為變量a在程序運行時的數(shù)據(jù)區(qū)內(nèi)固定分配size字節(jié)的空間;如函數(shù)內(nèi)定義一個局部變量charb[size],則在執(zhí)行函數(shù)時,局部變量b在棧上分配size字節(jié)的存儲空間,函數(shù)調(diào)用結束時將自動釋放局部數(shù)組變量b的存儲空間。
動態(tài)分配是指調(diào)用庫函數(shù)malloc(size)在堆上分配size個字節(jié)的連續(xù)空間,調(diào)用結束后返回一個指向分配好的存儲空間的指針,編程時必須考慮到在使用完該存儲空間后調(diào)用對應的函數(shù)free( )來釋放掉。
在C編程時,一定要合理使用指針,否則很容易在執(zhí)行時出現(xiàn)各種錯誤。以下列出常見的幾個錯誤:
(1)在C程序中定義了一個指針變量,但沒有對其進行初始化,將該指針變量稱為“野指針”。如果此后對該指針變量所指的存儲空間進行操作,程序會出現(xiàn)嚴重的錯誤,因為,在定義指針變量后,指針變量的值是不確定的,即指針隨機指向某個內(nèi)存地址,此時的指針所指的內(nèi)存直接賦值操作,將該單元中原有的數(shù)據(jù)覆蓋,使該數(shù)據(jù)丟失,若指針指向的是系統(tǒng)的數(shù)據(jù)區(qū)中,會導致系統(tǒng)運行的異常甚至死機。因此,C編程時要及時把指針變量賦值,使指針有正確的指向。
(2)如用語句p = malloc(size)來分配空間,應對分配后的參數(shù)p進行檢查,如p為NULL則表示分配不到存儲空間,此時不能對p指向的空間操作;即使為p分配了空間,也要注意對該指針操作時不能超出其空間范圍。使用完后,一定要釋放該空間,否則可能引起存儲空間的耗盡。
(3)棧溢出。棧是在調(diào)用一個子函數(shù)時用來保存和恢復現(xiàn)場,以及傳遞參數(shù)和存放局部變量,但在執(zhí)行子函數(shù)時,如果其中的局部變量指針出現(xiàn)使用錯誤,則會發(fā)生棧溢出。例如在子函數(shù)中,有下列代碼:
char p[8];
strcpy(p,/Notice: This is a test pro-gram!0);
由于棧中為局部變量p只分配了8個字節(jié)空間,而strcpy()函數(shù)將覆蓋p指向的連續(xù)32個字節(jié)空間(包括字符串結束符-\ 0.),可能將棧中存放的函數(shù)返回地址等內(nèi)容重寫了,所以子函數(shù)執(zhí)行完后就無法返回到原來的函數(shù)繼續(xù)運行了。
(4)堆溢出。堆的使用與所在運行平臺的操作系統(tǒng)和編譯器有關,堆溢出也相對復雜。如程序為:
char *p;
p = (char*)malloc(8);
strcpy(p,/No-tice: This is a test program!0);
則執(zhí)行strcpy()時將覆蓋了緊跟在指針p指向的32個字節(jié)的內(nèi)容,引起堆溢出,程序運行無法正確。
(5)void的用法。void在定義某個函數(shù)時,表示該函數(shù)無返回值,但庫函數(shù)void malloc(size)除外,它并不表示malloc(size)無返回值[5],而表示函數(shù)的返回值可以轉(zhuǎn)換成任何類型的地址值(如char *,int *等)。void不能用來定義數(shù)值變量,但可以用void來定義指針變量,它的真實含義是可以將任何數(shù)據(jù)類型的地址賦給指針變量。
(6)區(qū)分數(shù)組和指針變量在使用過程中的不同,指針可以通過加減數(shù)值來移動它所指的位置,如p+=5;而數(shù)組名是不能移動的,如char k[20]; k++;對k的操作是錯誤的。
(7)指針移動時挪動的位移與指針所定義的類型相關,如a和b定義為:char *a;int *b;后續(xù)的語句:a+=10;b+=10;則表示a向后移動了10個字節(jié),而b向后移動了10個整型長度,即40個字節(jié)。指針變量在使用時要與定義的類型相一致,char c[10];int *d;d=c;此后對d的操作很可能造成混亂。
2 課堂教學中注意培養(yǎng)良好的編程習慣
(1)入門階段。分析和演示運行簡單的C程序,和學生一起對程序進行簡單修改,再演示運行,讓學生對C程序產(chǎn)生感性的認識,激發(fā)學生的學習興趣和熱情。這時需要注意在編寫C程序過程中的一些特定格式和語法要求,幫助學生養(yǎng)成良好的編程習慣。
(2)基礎階段。這時的學生應該已經(jīng)學習了算法、變量、表達式、語句、程序結構等C程序基礎知識。這一階段中,我會經(jīng)常提出一些簡單的問題,放手讓學生討論,逐步深入理解問題,逐步完善流程圖,然后把流程圖翻譯成標準的C程序,并進行試運行和調(diào)試。
這一階段中,可以以教材為線索,擴展介紹C語言的語法知識,但不能停留在語法上,可以根據(jù)任務和項目的需要插入介紹一些系統(tǒng)函數(shù),并適時地將所學知識應用到項目和任務當中,讓學生學以致用。
(3)綜合階段。為了讓學生熟練使用語法知識,還需要布置一些較長的程序讓學生閱讀分解,嘗試修改語句和程序結構。這一階段中,我會經(jīng)常提出一些相對復雜的問題,放手讓學生討論,逐步深入理解問題,逐步完善流程圖,然后把流程圖翻譯成標準的C程序,然后對流程圖和程序反復并進行修改、運行和調(diào)試。
這一階段中,要鼓勵學生大膽創(chuàng)新,創(chuàng)造性的運用書上的知識。同時,和學生強調(diào)編程的功夫在編程之外,養(yǎng)成學生良好的編程習慣,為學生以后的發(fā)展打下基礎。
(4)提升階段。我會根據(jù)不同層次的學生提出不同的設計要求,因材施教,盡量使每一個學生都能將所學到的程序設計方法和相關語法綜合應用。同時,告訴學生,要達到能用C語言編寫較大的應用程序,并不是僅在一個學期的學習過程中就能完成的,在以后的實踐中,要繼續(xù)學習。
在C語言的教學中,采用適度靈活的教學方法,理論講授和上機實踐緊密結合,語法與實例緊密結合,可以激發(fā)學生的學習興趣,增強學生的求知欲,降低課程難度,會達到良好的教學效果。當然,具體教學方式、方法的選擇,不同的老師可以根據(jù)實際需要而定。
參考文獻
[1] 范華,秦茂玲,張俊.透視C程序設計語言[J].計算機技術與發(fā)展,2008,18(6):64 -661
[2] 譚浩強.C程序設計[M].第3版1北京:清華大學出版社,2005.
[3] Kernighan B W,Ritchie D M.C程序設計語言[M].第2版.徐寶文,等譯.北京:機械工業(yè)出版社,2005.
[4] Reek KA.POINTERS ONC[M].徐 波,譯.北京:人民郵電出版社,2003.