?

C++語言教學中編碼標準化問題淺析

2008-07-14 10:05陳南京
電腦知識與技術 2008年18期
關鍵詞:高等教育標準

陳南京 萬 瑾

摘要:C++程序良好的可移植性使得C++語言成為程序設計人員的首選工具語言,而保證這一特性必需使用標準化的C++編碼。國內高校尤其是高職院校的教材中,存在著大量非標準化的C++程序,不利于培養具有標準化C++編程風格的學生。本文從C++發展史、教育工作者和教材規范化等多個角度出發,分析了這一問題產生的原因,并提出了相應的解決辦法。

關鍵詞:C++標準;可移植性;高等教育

中圖分類號:TP311文獻標識碼:A文章編號:1009-3044(2008)18-21ppp-0c

1 引言

1983年第一個C++程序投入使用,1994年8月,ANSI/ISO委員會草案登記,這便是業內所稱的早期的C++標準,1998年11月,ISO/IEC:98-14882標準(以下簡稱98標準)被批準,標志著C++代碼的標準化正式誕生[1]。C++語言誕生以來,延續了C語言的重要特征,即C++源程序良好的可移植性。正是這一特性,使得C/C++語言長期以來一直是程序開發人員的首選。

C++語言良好的可移植性是它具有較強生命力的關鍵所在。目前標準委員會正在修訂C++標準,并擬于2009年發布修訂后的09標準??梢灶A見,C++語言作為程序開發的主要工具仍將延續很長的一段時間。然而,國內高等教育尤其是高職教育,在C++語言的教學中卻長期使用了非標準化的編碼方式,這對于學生畢業后從事程序設計,寫出具有良好可移植性的程序是相當不利的。

C++程序編碼的標準化在互聯網的一些論壇里有一些討論,然而關于現行教材或專著里存在的問題,卻鮮有文章進行報道。本文通過討論現有高校教材尤其是高職教材中C++代碼編寫方式與現行C++標準的一些距離,試圖引導高校教材尤其是高職教材中C++程序編碼走向標準化。

2 標準化的目的和意義

標準化之爭是信息時代商業競爭乃至國家之間競爭的必爭之地。歐美的企業一直依賴都很熱衷于標準化之爭,UNIX從誕生到現在的各自為政就是一個很好的例子。而IT領域信息技術的高度集中和相對壟斷也使得國際標準化組織制定的很多標準并沒有被企業所采用,相反地,出現了很多像“Microsoft Windows”、“Internet Explorer”這種“事實上的工業標準”。C++語言從誕生到98標準誕生,花了整整15年的時間,對于發展迅猛的信息技術,這是一個相當漫長的過程。在此期間,國際上一些跨國公司如Microsoft、IBM、Borland(如今的Inprise)相繼開發了自己的C++編譯器,這些公司的編譯器除了包含標準的C++編譯器的內容之外,還加入了自己的一些特性,甚至修改了部分標準。一旦程序設計人員使用了這些非標準的特性,代碼的可移植性將會成為一個大問題。因此,如何教導學生編寫標準化的C++源程序,成為C++語言教學中一個非常重要的問題。

3 C++語言教學中存在的非標準化編碼的主要問題

Microsoft公司曾經因為其在軟件行業得天獨厚的地位,而在MS Visual C++編譯器中采使用了很多非標準化的內容。然而,在MS Visual Studio 2005發布之后,Microsoft公司相關人員特別指出該產品的一個重要變化就是完全符合98標準[2]。對于程序員來說,如果他原先在MS Visual C++中使用了非標準化的代碼,在移植到MS Visual Studio2005這個平臺上時將會花費相當大的精力去修改代碼。即便是微軟這樣一個跨國企業,都不得不向國際標準靠攏,可想而知,標準化對于企業來講是多么重要了。對于程序員,如何編寫標準化的C++代碼,保持C++代碼的良好可移植性則是重中之重。然而,在我國的高校尤其是高職教材中卻存在著甚至是大量存在著非標準化的C++程序,究其原因,筆者認為主要有如下幾個方面:

3.1 C語言的影響

這也是最重要的一點。我國高校早期從事C++語言的教學和傳播者主要是從C語言的使用者轉移過來,C++語言的向下兼容性(即兼容C語言書寫的源程序)使得這批教師能夠較快的勝任C++語言的教學工作。不可否認,他們對中國高等教育的C++語言的教學和普及做出了不可磨滅的貢獻。然而,C++語言所倡導的面向對象程序設計方法和C語言的面向過程程序設計方法還是存在著很大區別的,尤其是面向對象要求對數據進行封裝保護的機制在C語言中是不存在的。而我們的第一批C++語言的傳播者以及教材的編著者,卻把C語言的風格和編程習慣帶到了C++語言的教學中來,并且一直延續至今。例如:在C語言中主函數main是可以沒有返回值的,即返回值類型可以是void,而在C++標準中,明確要求主函數main必須返回int類型。再例如,C語言中人們習慣使用字符數組或字符指針來保存字符串如char name[30], char *str等,而在C++中,提倡使用string對象來替代字符數組的變量。在我所使用的“十一五”國家級規范教材[3]中,從頭到尾使用的都是字符數組和字符指針,而沒有一處使用string對象,這明顯違背了C++面向對象程序設計方法的精神。

有人問及C++語言的創始人也是C++標準的制定者之一Bjarne Stroustrup博士,有沒有想過刪除一些C++語言的特性。Bjarne Stroustrup博士說:從語言設計的角度講,我最不喜歡的部分是與C兼容的那個子集[4]。然而,出于對現實世界里工作的程序員的考慮,保留與C兼容的子集是有必要的,但這并不意味著我們要寫出C風格的C++程序。

3.2 大量非標準化編譯器的影響

C語言和C++語言都是在UNIX平臺下誕生的,在UNIX平臺下使用的都是標準的編譯器G++。而國內由于種種原因,UNIX平臺一直未能進入主流的應用,大多數的企事業單位包括高校使用的都是MS Windows平臺,高校教育又過分的偏愛了MS Visual C++這一典型的非標準C++編譯器,即便是計算機等級考試這一全國性的考試,在C/C++的編程環境上也是選擇了MS Visual C++。MS Visual C++編譯器包含了很多與C++標準有出入的功能。這在某種程度上助長了C++的教學者編寫出大量的非標準化代碼。例如大家所熟悉的eof()函數,該函數根據當前指針是否指向文件結束部分而相應的返回true和false兩個值,即當我們從一個文本文件讀取數據時,如果指針指向文件的尾部則返回true,如果指針還未指向文件的尾部則返回false。MS Visual C++的編譯器和基于標準C++的編譯器如Dev-C++編譯器對這個函數的處理卻有很大的不同[5]。標準編譯器在第一次讀取文件的最后一個數據后仍然返回false,只有在試圖繼續讀取數據時發現已經到了文件的結尾才返回true,而MS Visual C++編譯器則在我們讀取到文件的最后一個數據之后就返回true了。這樣,針對不同的編譯器,下面的這一段代碼就有了不同的結果:

void totalFile(char *fName, float &total)

{

fstream rawData;

float itemPrice;

total = (float) 0.0;

rawData.open( fName, ios::in);

while(!rawData.eof())

{

rawData >> itemPrice;

total += itemPrice;

}

rawData.close();

}

假設我們的文本文件包含兩個數據,如下:

6.00

1.25

如果我們使用MS Visual C++編譯器,則最后得到的total值是7.25,而當我們用標準C++編譯器如Dev-C++編譯器,得到的結果則是8.5。對于MS Visual C++編譯器而言,在讀取1.25之后就認為文件已經結束,并且令eof()函數返回true值,while循環結束;而對于Dev-C++編譯器,讀取1.25后并沒有認為文件已經到達尾部,因此,eof()返回的是false,循環繼續執行,在試圖繼續讀取數據時才知道文件已經結束,但此時的循環體多執行了一次,所以如果不作判斷而直接使用上面的代碼,則最后一個數據將會兩次被加到total上。因此,要得到準確的結果7.25,標準C++的代碼應該是這樣的:

void totalFile(char *fName, float &total)

{

fstream rawData;

float itemPrice;

total = (float) 0.0;

rawData.open( fName, ios::in);

while(!rawData.eof())

{

rawData >> itemPrice;

if(!rawData.eof())/*這邊增加一個判斷,

以避免讀取的最后一個數據被運算兩次 */

total += itemPrice;

}

rawData.close();

}

從上面的例子我們可以看出,基于非標準C++的編譯器和標準C++的編譯器在一些地方會有很大的出入,這種情況下,如果毫不知情的將非標準的C++代碼移植到標準C++的編譯器中進行編譯,無疑將會得到意想不到的結果??梢?,只有編寫出標準的C++代碼,才能滿足程序的可移植性這一重要特點。

3.3 國內部分教育者對國際標準的漠視

國內程序設計語言如C++語言的傳播者(以高校教師為主)甚少關注國際標準,很多老師甚至于不知道自己寫出來的程序是否符合國際標準,通常情況下只是簡單的將寫出來的程序在某一特定編譯器下編譯測試通過就草草了事,導致C++語言教學的教材和各類專著充斥著大量的非標準代碼。國際標準委員會為了讓C++語言更好的實現面向對象程序設計的封裝,在頒布的98標準中對原先提交的標準進行了一些修訂,同時為了使得原有的程序不至于全部都要進行修改,保留了對原有標準的兼容性。而國內的高校教材中卻很少對這些標準進行深入的研究。例如頭文件包含

#include

這樣的寫法,在98標準中已經被廢棄了,而改為使用不含.h的標準寫法。

#include

原因之一是隨著時間的推移,還能夠繼續支持.h的頭文件包含的編譯器將會越來越少,其次,標準寫法在多個方面顯示出了它的優越性,如對異常的捕獲和處理、與其它C++標準類對象在接口方面的結合更緊密以及對本地化更好地支持,更為重要的一點是,iostream所定義的組件被聲明為命名空間std的成員,而iostream.h定義的組件則被聲明為全局的,不利于實現面向對象的封裝性。然而,國內教材中卻大量使用了前一種被廢棄的寫法。

3.4 國內教材出版業的規范化有待完善。

由于眾所周知的原因,國內高校教師出版教材很多時候是迫于壓力不得不做的事情,而出版業的過分商業化在一定程度上助長了這種風氣,導致國內出版的教材良莠不齊。盡管近些年在引進國外的優秀圖書方面出版界作了很大的努力,但是對于教材審查和出版的相對放松在廣大學生中形成的不好的編程習慣是很難一下子扭轉過來的,特別是高職院校的教材主要是以高職院校的教師自己編寫的為主。Bjarne Stroustrup博士在談到如何選擇學習C++語言的書籍時說到:務必注意該書是不是從一開始就講授標準C++,并且矢志不渝地使用標準庫機制[4]。例如,從輸入中讀取一個字符串應該是這樣的:

string s; /*標準C++程序的風格*/

cin>>s;

而不是這樣的:

char s[MAX]; /*標準C程序的風格*/

scanf("%s",s);

可惜,在國內很多C++語言教材中都采用了后者,完全符合C++標準的高校教材是少之又少。

4 問題的解決

造成C++語言教材和專著中大量存在著非標準化代碼的原因是多方面的,因此,要解決這個問題,我認為,應該從以下幾個方面入手:

1) 選擇標準化的C++編譯器。標準化的C++編譯器在編譯非標準的C++代碼時會給出警告信息,編譯人員可以根據警告信息修改自己的代碼,使之符合標準C++程序的編碼風格;

2) 提高教材或專著出版者尤其是高校教師自身的素質。標準C++編譯器不是萬能的,例如上面所提到的eof()函數存在的問題,是編譯器沒有辦法檢查出來的。作為知識的傳播者,高校教師應該努力學習本行業的相關標準,寫出符合國際標準的代碼,使之具有良好的可移植性;

3) 提倡教材編寫與標準化相接軌,規范教材的編寫和嚴格教材的出版。出版社應該組織權威的專家對準備出版的教材進行嚴格的審查,對不符合國際標準的寫法予以糾正。這點在本科和研究生的教材出版中作的相對較好,而在剛起步而又發展迅猛的高職教材中問題較多。

參考文獻:

[1] Juan Soulie. History of C++. [2008-1-18]. http://www.cplusplus.com/info/history.html.

[2] Bradley L. Jones. Breaking Changes in Visual C++ 2005. http://www.developer.com/net/cplus/article.php/3493706.

[3] 吳紹根,陳建潮,張嬋 著. C++面向對象程序設計[M]. 清華大學出版社,2007.

[4] Bjarne Stroustrup. Bjarne Stroustrup's FAQ. http://www.research.att.com/~bs/bs_faq.html. [2008-2-5].

[5] Laurence Boxer. Porting Code between Language Implementations. http://purple.niagara.edu/boxer/essays/prog/porting.htm.

收稿日期:2008-04-18

作者簡介:陳南京(1977-),碩士研究生,現就職于廈門華廈職業學院工科部,擔任計算機教研室主任。

猜你喜歡
高等教育標準
2022 年3 月實施的工程建設標準
忠誠的標準
美還是丑?
你可能還在被不靠譜的對比度標準忽悠
大數據對高等教育發展的推動研究
基于Flash+XML技術的護理技能虛擬教學平臺設計與實現
中國高等教育供給側改革研究:起源、核心、內涵、路徑
高等教育教學中的重與輕分析
一家之言:新標準將解決快遞業“成長中的煩惱”
2015年9月新到標準清單
91香蕉高清国产线观看免费-97夜夜澡人人爽人人喊a-99久久久无码国产精品9-国产亚洲日韩欧美综合