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