国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

C語言編程常見問題解答之可移植性

2019-11-17 05:41:43
字體:
來源:轉載
供稿:網友
    可移植性并不是指所寫的程序不作修改就可以在任何計算機上運行,而是指當條件有變化時,程序無需作很多修改就可運行。
    你不要把“我不會碰到這種情況”這句話說得太早。直到MS—Windows出現之前,許多MS—DOS程序員還不怎么關心可移植性問題。然后,忽然之間,他們的程序不得不在一個看起來不同的操作系統上運行。當Power PC流行起來后,Mac機的程序員不得不去應付一個新的處理器。任何一個在同版本的UNIX下維護過程序的人所了解的可移植性的知識,恐怕都足以寫成一本書,更別說寫成一章了。
    假設你用基本ALBATR—OS(Anti-lock Braking and Tire Rotation Operating system)的TUCker C來編寫防抱死剎車軟件,這聽起來好象是一個最典型的不可移植軟件。即便如此,可移植性仍然很重要:你可能需要把它從Tucker C的7.55c版本升級到8.O版本,或者從ALBATR—OS的3.o版本升級到3.2a版本,以修改軟件中的某些錯誤;你也可能會出于仿真測試或宣傳的目的,而把它(或其中一部分)移植到MS-Windows或UNIX工作站上;更為可能的是,在它尚未最終完工之前,你會把它從一個程序員手中交到另一個程序員手中。
    可移植性的本意是按照意料之中的方式做事情,其目的不在于簡化編譯程序的工作,而在于使改寫(重寫!)程序的工作變得輕易。假如你就是接過別人的程序的“倒霉蛋”,那么原程序中的每一處出乎意料之外的地方都會花去你的時間,并且將來可能會引起微妙的錯誤。假如你是原程序的編寫者,你應該注重不要使你的程序中出現出乎接手者意料之外的代碼。你應該盡量使程序輕易理解,這樣就不會有人抱怨你的程序難懂了。此外,幾個月以后,下一個“倒霉蛋”
很可能就會是你自己了,而這時你可能已經忘記了當初為什么用這樣復雜的一種方式來寫一個for循環。
    使程序可移植的本質非常簡單:假如做某些事情有一種既簡單又標準的方法,就按這種方法做。
    使程序可移植的第一步就是使用標準庫函數,并且把它們和ANSI/ISO C標準中定義的頭文件放在一起使用,詳見第11章“標準庫函數”。
    第二步是盡可能使所寫的程序適用于所有的編譯程序,而不是僅僅適用于你現在所使用的編譯程序。假如你的手冊提醒你某種功能或某個函數是你的編譯程序或某些編譯程序所特有的。你就應該謹慎地使用它。有許多關于c語言編程的好書中都提出了一些關于如何保持良好的可移植性的建議。非凡地,當你不清楚某個東西是否會起作用時,不要馬上寫一個測試程序來看看你的編譯程序是否會接受它,因為即使這個版本的編譯程序接受它,也不能說明這個程序就有很好的可移植性(C++程序員比c程序員應該更重視這個問題)。此外,小的測試程序很可能會漏掉要測試的性能或問題的某些方面。
    第三步是把不可移植的代碼分離出來。假如你無法確定某段程序是否可移植,你就應該盡快注釋出這一點。假如有一些大的程序段(整個函數或更多)依靠于它們的運行環境或編譯方式,你就應該把其中不可移植的代碼分離到一些獨立的“.c”文件中。假如只在一些小的程序段中存在可移植性問題,你可以使用#ifdef預處理指令。例如,在MS-DOS中文件名的形式為“\tools\readme”,而在UNIX中文件名的形式為“/tools/readme”。假如你的程序需要把這樣的
文件名分解為獨立的部分,你就需要查找正確的分隔符。假如有這樣一段代碼
    #ifdef unix
    #define FILE_SEP_CHAR'/'
    #endif
    #ifdef  __MSDOS__
    define FILE SEP CHAR'//'
    #endif
    你就可以通過把FILE_SEP_CHAR傳遞給strchr()或strtok()來找出文件名中的路徑部分。盡管這一步還無法找出一個MS-DOS文件的驅動器名,但它已經是一個正確的開頭了。
  最后,找出潛在的可移植性問題的最好方法之一就是請別人來查找!假如可以的話,最好請別人來檢查一下你的程序。他或許知道一些你不知道的東西,或許能發現一些你從未想過的問題(有些名稱中含"lint"的工具和有些編譯程序選項可以幫助你找出一些問題,但你不要指望它們能找出大的問題)。    15.1  編譯程序中的C++擴充功能可以用在C程序中嗎?
    不可以,它們只能用在真正的C++程序中。
    C++中的一些突出性能已被ANSI/ISO C標準委員會所接受,它們不再是“C++擴充功能”,而已經成為C的一部分。例如,函數原型和const要害字就被補充到C中,因為它們確實非常有用。
    有一些C++性能,例如內聯(inline)函數和用const代替#define的方法,有時被稱為“高級C”性能。有些C和C++共用的編譯程序提供了一些這樣的性能,你可以使用它們嗎?
    有些程序員持這樣一種看法:假如要寫C代碼,就只寫C代碼,并且使它能被所有的C編譯程序接受。假如想使用C++性能,那么就轉到C++上。你可以循序漸進,每次用一點新的技巧;也可以一步到位,用大量的內聯函數,異常處理和轉換運算符編寫模塊化的抽象基類。當你跨過這一步之后,你的程序就是現在的C++程序了,并且你不要指望C編譯程序還會接受它。
    筆者的看法是:你的工作是從一個新的C標準開始的,這個標準中包含一些C++性能和一些嶄新的性能。在以后的幾年中,一些編譯程序的開發商會去實現這些新的性能的一部分,但這并不能保證所有的編譯程序都會去實現這些性能,也不能保證下一個C標準會納入這些性能。你應該保持對事態發展的關注,當一項新的性能看上去已經真正流行起來,并且不僅僅出現在你現在所使用的編譯程序中,而是出現在所有你可能用到的編譯程序中時,你就可以考慮使用它了。例如,假如過去有人非要等到1989年才開始使用函數原型,那么這其實就不是一種明智之舉;另一方面,在保證可移植性的前提下,過去也沒有一個開始使用noalias要害字的最佳時機。
    請參見:
    15.2 C++和C有什么區別?    15.2 C++和C有什么區別?
    這個問題要從C程序員和C++程序員兩個角度去分析。
    對C程序員來說,C++是一種古怪的難以把握的語言。大多數C++庫無法通過C編譯程序連接到c程序中(在連接時編譯程序必須創建模型或“虛擬表”,而C編譯程序不提供這種支持)。即使用c++編譯程序來連接程序,c程序仍然無法調用許多C++函數。除非非常小心地編寫c++程序,否則C++程序總會比類似的c程序慢一些,并且大一些。C++編譯程序中的錯誤也比C編譯程序中的多。C++程序更難于從一種編譯程序移植到另一種編譯程序上。最后一點,C++是一種龐大的難以學會的語言,它的定義手冊(1990)超過400頁,而且每年還要加入大量的內容。另一方面,c語言是一種既漂亮又簡煉的語言,并且這幾年來沒有什么改動(當然不可能永遠不會有改動,見14.1)。C編譯程序工作良好,并且越來越好。好的c程序可以很方便地在好的C編譯程序之間移植。雖然在C中做面向對象的設計并不輕易,但也不是非常困難。假如需要的話,你(幾乎)總是可以用c++編譯程序來生成C程序。
    對于C++程序員來說,c是一個好的開端。在C++中你不會重犯在C中犯過的許多錯誤,因為編譯程序不會給你這個機會。C的有些技巧,假如使用稍有不當,就會帶來很大的危險。
    另一方面,c++是一種優秀的語言。只需應用少數原則,稍作一點預先的設計工作,就能寫出安全、高效并且非常輕易理解和維護的C++程序。用有些方法寫C++程序,能使C++程序比類似的C程序更快并且更小。面向對象的設計在C++中非常輕易,但你不一定要按這種方式工作。編譯程序日臻完善,標準也逐漸確立起來。假如需要的話,你隨時可以返回到C中。
    那么,c和C++之間有什么具體的區別呢?C的有些成分在c++中是不答應使用的,例如老式的函數定義。大致來說,C++只是一種增加了一些新性能的C:
    ·新的注釋規則(見15.3);
    ·帶有真正的true和false值的布爾類型,與現有的c或c++程序兼容(你可以把貼在顯示器上的寫著“O=false,1=true”的紙條扔掉了。它仍然有效,但已不是必須的了)。
    ·內聯函數比#define宏定義更加安全,功能也更強,而速度是一樣的。
    ·假如需要的話,可以確保變量的初始化,不再有用的變量會被自動清除。
    ·類型檢查和內存治理的功能更好,更安全,更強大。
    ·封裝(encapsulation)——使新的類型可以和它們的所有操作一起被定義。c++中有一種complex類型,其操作和語法規則與float和double相同,但它不是編譯程序所固有的,而是在C++中實現的,并且所使用的是每一個C++程序員都能使用的那些性能。
    ·訪問權控制(access contr01)——使得只能通過一個新類型所答應的操作來使用該類型。
    ·繼續和模板(inheritance and templates)——兩種編寫程序的輔助方法,提供了函數調用之外的代碼復用方式。
    ·異常處理(exceptions)——使一個函數可以向它的調用者之外的函數報告問題。
    ·一種新的I/O處理方法——比PRintf()更安全并且功能更強,能把格式和要寫入的文件的類型分離開。
    ·一個數據類型豐富的庫——你永遠不需要自己編寫鏈表或二叉樹了(這一點是千真萬確的!)。
 &nb

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 蚌埠市| 贺州市| 怀柔区| 玉门市| 汝南县| 石渠县| 新田县| 航空| 金坛市| 钟山县| 昌乐县| 广饶县| 桦甸市| 东宁县| 花莲市| 皮山县| 郧西县| 定西市| 台南市| 锡林郭勒盟| 七台河市| 巴南区| 涞水县| 安义县| 定南县| 阜城县| 上饶县| 武邑县| 额尔古纳市| 灵宝市| 寿光市| 台东市| 云阳县| 余江县| 旬阳县| 滨州市| 比如县| 新和县| 腾冲县| 石棉县| 文山县|