郭亮 郭海智
摘要:針對(duì)C語(yǔ)言教學(xué)過程中存在的問題并結(jié)合自身教學(xué)實(shí)踐,提出幾點(diǎn)具體建議。包括從類型和變量出發(fā),自教學(xué)初期就加強(qiáng)對(duì)語(yǔ)言中的一些核心問題講解,并在課程教學(xué)前期的語(yǔ)言基礎(chǔ)部分對(duì)此進(jìn)行反復(fù)強(qiáng)調(diào)及緊密聯(lián)系,后期再專注于程序設(shè)計(jì)能力及計(jì)算思維的培養(yǎng)。
關(guān)鍵詞:C語(yǔ)言;類型;指針;函數(shù)
中圖分類號(hào):G642 文獻(xiàn)標(biāo)識(shí)碼:A 文章編號(hào):1009-3044(2016)24-0116-02
Abstract: Aiming at the existing problems in the process of C language teaching, combined with personal teaching practice, giving some suggestions. Starting from the types and variables, the suggestions include strengthen the interpretation of some core elements in C language at the primary stage of teaching, emphasize the interrelation of these elements, later stage focus on training the ability of programming and computational thinking.
Key words: C language; type; porinter; function
C語(yǔ)言高效、靈活且兼具高級(jí)和低級(jí)語(yǔ)言的特點(diǎn),使其應(yīng)用及影響極其廣泛,并早已成為各大高校的第一門程序設(shè)計(jì)課程。該課程信息量大且地位顯著但授課時(shí)間有限,作為重點(diǎn)和難點(diǎn)的指針等概念也提高了學(xué)習(xí)門檻,導(dǎo)致教學(xué)效果普遍不理想,影響了后期多門專業(yè)課程的開展。
1 教學(xué)中的問題
C語(yǔ)言教學(xué)過程中除了需要平衡語(yǔ)言特性和程序設(shè)計(jì)能力培養(yǎng)外,還應(yīng)針對(duì)教學(xué)對(duì)象的特點(diǎn)進(jìn)行內(nèi)容的合理編排,加強(qiáng)各個(gè)知識(shí)點(diǎn)的聯(lián)系,降低學(xué)習(xí)曲線的陡峭程度。當(dāng)前眾多教材及教學(xué)過程在內(nèi)容編排上采用類似自頂向下的教學(xué)方法,簡(jiǎn)述變量、常量等基礎(chǔ)概念后,在控制結(jié)構(gòu)中開始程序設(shè)計(jì)能力的初步培養(yǎng),到數(shù)組、指針及函數(shù)參數(shù)部分轉(zhuǎn)而強(qiáng)化底層概念,最后通過結(jié)構(gòu)體、綜合示例及簡(jiǎn)單數(shù)據(jù)結(jié)構(gòu)等回歸到設(shè)計(jì)[1]。這樣的教學(xué)過程可能會(huì)使部分學(xué)員在對(duì)前期語(yǔ)言基本要素掌握不到位的基礎(chǔ)上產(chǎn)生一些錯(cuò)誤理解,后期再來修正就比較困難。
結(jié)合個(gè)人教學(xué)經(jīng)驗(yàn)及我校的教學(xué)情況,在課程編排上應(yīng)盡早讓學(xué)員理解并熟悉底層概念,盡早引入函數(shù)概念并持續(xù)培養(yǎng)模塊化程序設(shè)計(jì)方法[2]。前期教學(xué)重點(diǎn)講述核心概念及常規(guī)用法,加深學(xué)員對(duì)語(yǔ)言整體的理解,后期重點(diǎn)培養(yǎng)程序設(shè)計(jì)和計(jì)算思維能力①。
2 具體改進(jìn)
2.1 堅(jiān)持清晰第一
任何課程,每次課堂的教學(xué)都應(yīng)遵從清晰第一原則,C語(yǔ)言教學(xué)也不例外。清晰第一的一個(gè)功能是重點(diǎn)突出。對(duì)C教學(xué)而言,講解所用的代碼表述要保證清晰明了,不要過多討論i+++j等問題,避免由于寫法的技巧性和語(yǔ)法的復(fù)雜性加重學(xué)員學(xué)習(xí)負(fù)擔(dān)。有文章列出的一些“有趣C問題”并不能提高大部分初級(jí)學(xué)員的興趣,反而可能會(huì)使其產(chǎn)生挫敗感并導(dǎo)致厭學(xué)心態(tài),這樣的東西在教學(xué)初期應(yīng)該適度引入。清晰第一的另一個(gè)功能是避免了部分的不可移植性問題及潛在的錯(cuò)誤。在C語(yǔ)言中存在表達(dá)式計(jì)算的副作用和順序點(diǎn)問題,對(duì)int i=1;f(i++)+g(i--)沒有約定是進(jìn)行f(1)+g(1)還是f(1)+g(2),利用本原則可以消除由于此類語(yǔ)義表述所埋下的隱患,突出避免編寫依賴特定計(jì)算順序表達(dá)式的重要性。另外,清晰第一還體現(xiàn)在可讀性上,排版、注釋、標(biāo)識(shí)符命名及編程風(fēng)格等方面,需持續(xù)培養(yǎng)學(xué)員良好的編程習(xí)慣,盡力使教學(xué)與實(shí)際開發(fā)保持一致。清晰第一要避免對(duì)晦澀用法的講解和考核但不是簡(jiǎn)單反對(duì)和拋棄慣用的簡(jiǎn)潔描述,課堂上應(yīng)該給出習(xí)慣用法以體現(xiàn)C語(yǔ)言的靈活性。
2.2 強(qiáng)化類型概念
類型體現(xiàn)了抽象,抽象是人認(rèn)識(shí)客觀世界的主要能力。類型作為計(jì)算機(jī)科學(xué)的核心概念在眾多C語(yǔ)言教材中闡述并不多,教學(xué)過程中理應(yīng)讓學(xué)員對(duì)此留下深刻印象。講解中通過整數(shù)的補(bǔ)碼表示,字符型的ASCII編碼等讓學(xué)員明確計(jì)算機(jī)對(duì)不同信息的分類表示。由此引出,類型約定了表示的形式,進(jìn)而限制了存儲(chǔ)空間的大小和取值范圍。初期講解常量時(shí)用printf( )的不同格式描述符驗(yàn)證int和double的編碼不同,結(jié)合sizeof運(yùn)算符驗(yàn)證不同類型的存儲(chǔ)大小,并在介紹位運(yùn)算后深入了解整型的補(bǔ)碼編碼方式。利用求余運(yùn)算符的兩個(gè)操作數(shù)為整數(shù)而非浮點(diǎn)數(shù),驗(yàn)證類型對(duì)操作的限定,引出類型在另一方面又約束了其上的相關(guān)操作。類型概念應(yīng)該在課程教學(xué)的各個(gè)章節(jié)進(jìn)行強(qiáng)化,比如后續(xù)講解指針運(yùn)算只有加減和比較操作時(shí)可再次強(qiáng)調(diào)。同類型之間可直接操作,異類間操作需先統(tǒng)一為同種類型,重視了類型問題也就便于掌握類型轉(zhuǎn)換,減少了轉(zhuǎn)換出錯(cuò)的概率。面向?qū)ο蟮某绦蛘Z(yǔ)言強(qiáng)化了C語(yǔ)言本就具有的這個(gè)核心概念,并發(fā)展到了一個(gè)新高度,C中類型的這兩個(gè)能力與面向?qū)ο蟮睦斫饣疽恢?,掌握好該核心概念也有利于后續(xù)面向?qū)ο蟪绦蛟O(shè)計(jì)語(yǔ)言的學(xué)習(xí)。
2.3 深入理解變量與賦值適度引入指針
C語(yǔ)言兼具高級(jí)語(yǔ)言和低級(jí)語(yǔ)言的特點(diǎn),其實(shí)現(xiàn)與內(nèi)存關(guān)系緊密。變量的功用是保存信息以便后續(xù)使用,信息的類型不同變量類型的選擇也就不同。講解時(shí)無(wú)需簡(jiǎn)單羅列所有變量類型,建議把整型變量單拿出來細(xì)講,這樣學(xué)員理解好了一個(gè),也就方便了后續(xù)其他類型的學(xué)習(xí)。讓學(xué)員理解變量名屏蔽了底層地址信息所帶來的使用方便性,以及掌握利用底層地址信息進(jìn)行間接訪問操作的一致性。對(duì)整型變量int i;通過printf(“%d,%p”,i,&i)引出%p格式描述符和&取地址運(yùn)算符以驗(yàn)證變量的存儲(chǔ)內(nèi)容和存儲(chǔ)起始地址,并指出變量初始化的重要性。進(jìn)一步用printf(“%d,%p,%d”,i,&i,*&i)引出用地址求值的間接訪問運(yùn)算符*,為指針的引入建立基礎(chǔ)。C語(yǔ)言的賦值并非數(shù)學(xué)中的相等比較,示例中用i=1與j=i,強(qiáng)調(diào)i在等號(hào)的左邊表示存儲(chǔ)位置,在等號(hào)的右邊表示存儲(chǔ)內(nèi)容,由此引出左值和右值概念,明確左值是能指代存儲(chǔ)空間的對(duì)象,從而避免i++++此類錯(cuò)誤操作。通過賦值操作符設(shè)問如何保存地址信息從而完整地引出指針類型,用示例強(qiáng)化指針相關(guān)的兩個(gè)重點(diǎn)操作&,*。再次結(jié)合sizeof查看多個(gè)同類型變量的內(nèi)存分布,以引出指針的加減及比較操作,并由不同指針類型間轉(zhuǎn)換引出void *這個(gè)類型轉(zhuǎn)換橋梁,以方便后期數(shù)組、結(jié)構(gòu)體等教學(xué)。至此,完成對(duì)指針涉及的所有基礎(chǔ)知識(shí)講解,后續(xù)課程重點(diǎn)講其應(yīng)用即可。有了這些概念后引出scanf以盡快開啟交互式程序的設(shè)計(jì),提高學(xué)習(xí)興趣。
2.4 盡早引入函數(shù)
個(gè)人認(rèn)為很多教材將函數(shù)放在課程后半部分講是不合理的。為了便于學(xué)員理解到函數(shù)及模塊化的重要性,盡早接觸到結(jié)構(gòu)化程序設(shè)計(jì)思想,建議在賦值語(yǔ)句和表達(dá)式之后就以“命名的語(yǔ)句塊”方式初步引出函數(shù)概論以熟悉基本框架和使用,并在后續(xù)章節(jié)逐步深入。在控制結(jié)構(gòu)中結(jié)合函數(shù)進(jìn)行基本編程能力的培養(yǎng),重視函數(shù)設(shè)計(jì)的通用性[3]。講解函數(shù)時(shí),不必按參數(shù)、返回值等對(duì)函數(shù)進(jìn)行分類,重點(diǎn)應(yīng)該從主調(diào)和被調(diào),從使用和實(shí)現(xiàn)的角度出發(fā),對(duì)比兩者對(duì)函數(shù)的關(guān)注點(diǎn)和關(guān)注內(nèi)容的不同,體現(xiàn)出接口的重要性,并讓學(xué)員在設(shè)計(jì)與調(diào)用時(shí)做到清晰明了。需強(qiáng)調(diào)函數(shù)參數(shù)的值傳遞方式而無(wú)需引入地址傳遞等其他表述以減輕學(xué)習(xí)負(fù)擔(dān)。對(duì)函數(shù)調(diào)用棧狀態(tài)變化的講解要簡(jiǎn)明扼要,以清晰值傳遞的實(shí)現(xiàn)基礎(chǔ),并體會(huì)語(yǔ)句塊內(nèi)局部變量的概念,為后續(xù)變量作用域和存在期講解打下鋪墊。在具有指針的基礎(chǔ)概念上對(duì)比void func1(int a){a++;}和void func2(int *a){(*a)++;},前者用復(fù)印件的類比說明修改不涉及原件,后者用鑰匙的類比說明直接修改原件,以及利用2值交換函數(shù)理解函數(shù)內(nèi)修改函數(shù)外數(shù)據(jù)時(shí)利用指針間接訪問所帶來的便利性。由于程序運(yùn)行時(shí)存儲(chǔ)在內(nèi)存,其中的所有對(duì)象都有地址信息也包括函數(shù),由此引出函數(shù)指針及其基本用法。關(guān)于遞歸的講解涉及的是程序設(shè)計(jì)方法與機(jī)器細(xì)節(jié)相關(guān)不大,重點(diǎn)通過簡(jiǎn)單示例強(qiáng)調(diào)思維方式。對(duì)漢諾塔、二叉樹遍歷等經(jīng)典例子以及數(shù)據(jù)結(jié)構(gòu)與算法基礎(chǔ)內(nèi)容等可在課程的后半部分單設(shè)常用編程技術(shù)章節(jié)專門提高程序設(shè)計(jì)能力。
2.5 清晰數(shù)組概念
由于前述教學(xué)安排,數(shù)組可放到指針及函數(shù)之后講解。對(duì)該概念的引入可以提兩點(diǎn),一是便于大量同類型變量的定義及使用,int a[1000]比a1,a2...a1000方便定義,下標(biāo)操作方便使用;二是內(nèi)存采用連續(xù)地址空間實(shí)現(xiàn)數(shù)組,存儲(chǔ)的空間順序性保證了元素間關(guān)系的順序性,使得數(shù)組成為多種數(shù)據(jù)結(jié)構(gòu)實(shí)現(xiàn)的基礎(chǔ)。強(qiáng)調(diào)數(shù)組名代表整個(gè)數(shù)組對(duì)象從而不具有左值特性,也就無(wú)法進(jìn)行整體賦值和a++等操作。對(duì)數(shù)組名用sizeof(a)計(jì)算整體占用空間,引出sizeof(a)/sizeof(a[0])的習(xí)慣用法。強(qiáng)調(diào)數(shù)組名a的類型類似int *const指針,值為頭元素地址,即a等值于&a[0],可對(duì)其加減以獲得特定指向。結(jié)合int (*p)[1000]=&a;指出a,&a二者值相等但類型不,并在示例中利用a+1,&a[0]+1,&a+1結(jié)合內(nèi)存模型進(jìn)行驗(yàn)證。既然數(shù)組名類似指針,也就引出數(shù)組表示和指針表示的統(tǒng)一性,即a[2]等價(jià)于*(a+2),由加法交換律*(a+2)等價(jià)于*(2+a),也就解釋了2[a]這種奇怪寫法的存在,同理也解釋了1[“abc”]是什么。對(duì)數(shù)組用a[-1],a[-2]示例編譯器不進(jìn)行訪問越界的檢測(cè),體會(huì)不可控越界的危險(xiǎn)性。聯(lián)系到函數(shù)參數(shù)傳遞時(shí),用swap(int a[],int b[])與swap(int *a,int *b)完成2值交換的一致性驗(yàn)證數(shù)組名退化為指針類型,引出參數(shù)傳遞中一維數(shù)組長(zhǎng)度信息的丟失問題,總結(jié)出函數(shù)參數(shù)中應(yīng)該帶入數(shù)組長(zhǎng)度信息func(int a[],int length),并結(jié)合二維及多維數(shù)組再次強(qiáng)調(diào)參數(shù)傳遞忽略最高維的原因。后期涉及結(jié)構(gòu)體講解時(shí),以struct B{ int i[3];}b1,b2;b2=b1;做對(duì)比,突顯出結(jié)構(gòu)體整體賦值的特殊性,并以此討論數(shù)組與結(jié)構(gòu)體在進(jìn)行函數(shù)參數(shù)傳遞的成本問題,以體現(xiàn)指針的優(yōu)勢(shì)。
3 結(jié)語(yǔ)
關(guān)于程序設(shè)計(jì)能力和計(jì)算思維的培養(yǎng)是個(gè)長(zhǎng)期過程,需要在整個(gè)培養(yǎng)體系中利用多門課程和實(shí)踐進(jìn)行貫穿和深入。實(shí)踐證明,當(dāng)前這種教學(xué)編排強(qiáng)化了學(xué)員對(duì)上述重要概念的理解,知識(shí)點(diǎn)間聯(lián)系更緊密,對(duì)事物的前因后果更清晰,在一定程度上減少了學(xué)習(xí)彎路,提高了教學(xué)效果。
參考文獻(xiàn):
[1] 譚浩強(qiáng).C程序設(shè)計(jì)[M].4版.北京:清華大學(xué)出版社,2012.
[2] 裘宗燕.從問題到程序——程序設(shè)計(jì)與C語(yǔ)言引論[M].2版.北京:機(jī)械工業(yè)出版社,2011.
[3] 朱安平.一種C語(yǔ)言函數(shù)教學(xué)的設(shè)計(jì)與實(shí)踐[J].計(jì)算機(jī)工程與科學(xué),2014,36(S1):139-142.