《好學的C 第2版》 第9章 一些高階程式設計技術

2022-09-11 18:30:08 字數 3544 閱讀 3503

轉向c++0x和oop之前,需要掌握其他一些技巧。

c++命令列引數:

main函式須這樣定義:

int main(int argc, char* ar**)  //argc計數包括程式名,所以至少是1;ar**[0]就是程式名。這兩個引數可以任意使用,但是是唯讀的,可以隨意顯示或複製它們。程式中可以通過argc判斷輸入引數是否足夠(例如大於1),通過ar**判斷各引數是否合法,合法的話存入其他變數使用;不合法的話提示輸入後,存入其他變數中使用即可。max_path:系統能支援的檔案路徑名的最大長度。

除了#define, const也可用來宣告常量。

c++支援過載(overloading,也稱作復用):重複使用同乙個函式名去處理不同型別的資料,使用時根據入參型別區分。過載函式的每乙個版本都須有其函式宣告和定義。  //it:型別名稱不同但實際型別相同(例如typedef之後結構體的兩種用法)是否算過載?  c及絕大多數非oop語言不支援過載,只能通過函式名區分。為何?(!!!oop樶核心概念之一:資料型別決定著函式或操作符的行為。相關話題是操作符過載:有些操作符(例如+ -)可以根據運算元的型別進行不同的處理,可以為自己的型別編寫操作符函式。如果運算元的型別發生變化,編譯器將生成不同的指令。it:其實加法作用於整數之間跟作用於整數和指標之間,明顯機制不同。)過載還算不上這個核心概念的完美實現,在某些場合,型別資訊可能到了編譯階段也還是不夠完備,這時就需要多型程式設計技術大顯身手了。(後續講)

dowhile(x)

switch(x)

case 1:

break;   //控制權將轉移至switch語句末尾,否則將轉入下乙個case語句

case 2:

default:

多模組:可以使用1個以上的源**模組(.cpp)。

同乙個函式只能放進乙個檔案,不允許分割放入多個檔案。

####重要規則####

1、每個函式的定義只能出現在某乙個原始檔裡(it:編譯器編譯各個模組時檢查是否有重複宣告(?)和定義,其他檔案的static函式定義不會被本檔案編譯檢查到。)  //it: 標頭檔案命名和放置位置有何規則?

2、每個原始檔都必須有某個函式的宣告(原型)才能呼叫該函式。c++編譯器會在原始檔裡為每乙個函式原型尋找與之對應的函式定義,如果找不到,編譯器會假定該函式是在另乙個模組裡定義的。

如果某個函式需要被多個模組共享,最好辦法是把它和其他共享函式的函式宣告都集中放置到乙個檔案裡去,即所謂標頭檔案,然後在每個模組開頭加上一條#include語句。那些宣告就會自動成為每個模組的一部分。

用類似方法共享資料變數:

c/c++中,函式外定義的變數都是全域性變數,可以在隨後定義的任何函式裡使用。變數預設是建立它的模組的「私有財產」。若想共享它們,就需要在每個檔案(或每個標頭檔案)裡加上extern宣告(extern關鍵字是告訴編譯器該變數是在其他檔案中宣告的)(it:意思是從外部匯入的變數)。extern用來說明變數在程式其他地方宣告,有可能(但不必要)是在另乙個模組裡,但這種變數必須保證只在某乙個模組裡被建立了一次。

多模組對大型軟體專案非常有用,有利於碼農分工協作(實現自己模組功能和介面),以及對程式進行按邏輯劃分,以及控制各個模組之間相互通訊的程度。

在c這樣的老語言裡,使用彼此相對獨立的模組是隔離私有符號和公用(共享)符號的唯一手段。(模組中的私有部分對外部不可見,不用擔心其他模組來呼叫私有函式或訪問私有資料)。

這種「公私分明」做法是產生封裝效果的方法之一。(封裝是c++類帶來的好處之一。it:公私分明可以用類來實現,而非像c一樣必須用多模組來實現。)

寫好各個模組原始碼之後,就可將.cpp分別編譯成.o,隨後鏈結c++庫,即可生成.exe。(ide設定好之後可自動完成此過程)

(it:sourceinsight是否可直接編譯?it:應可,但c**是為linux編寫的,若不支援跨平台,那編譯基本通不過(例如檔案路徑格式就不對。怎樣跨平台?))

異常處理:

大型程式才最有用。

其實除了語法錯誤和程式邏輯錯誤以外,還可以劃分出第三類錯誤:異常。涵蓋各種執行錯誤(例如0為除數、錯用空指標、記憶體已滿申請不到、算術計算溢位)。

異常處理的關鍵是對非正常情況作出平穩合理的處理,包括輸出日誌資訊用於發現和定位。在大型程式裡返回錯誤碼要層層傳遞向上返回才能到達與使用者互動的層次,這是大型程式裡讓人頭痛的地方。(it:做好錯誤碼的分類分層次就很重要)

try-catch異常處理:

除最古老版本外,c++如今版本都支援使用try-catch-throw關鍵字來處理各種異常。異常處理把程式中的出錯處理集中到了一處,無論**發生錯誤,控制權都能跳到正確的位置。

trythrow exception_object; //例如throw 12;會丟擲乙個int型別的異常。異常可以是任何一種型別

catch(exception_type [arguments]) //異常型別與exception_type相匹配才會進入,[arguments]是可選的

//it:多個catch後帶同一exception_type會怎樣?不匹配會繼續檢查下乙個catch塊,若該異常一直不能**獲,程式將終止執行

許多態別異常是系統丟擲的,它們全都派生自exception類,因而以下**可捕獲所有系統丟擲的異常:

catch (exception &e)

cout<< "raised:"<注意:

ifstream in_file;

in_file.exceptions(ifstream::eofbit | ifstream::failbit | ifstream::badbit);

小結撿漏:

要想訪問命令列引數,就要在宣告main函式時給它增加argc和ar**兩個各個入參(it:只增加乙個可否?)

ar**是乙個字串指標陣列。

過載函式在編譯器件被區分了。(除了函式名字相同,這些函式其實毫不相關,幹的活可以大相徑庭)

只要有乙個以上的函式或全域性資料宣告,都可把程式劃分為多個原始檔,其每乙個都是乙個模組。

乙個函式可以呼叫在另乙個模組中定義的函式,前提是前者所在模組必須引入後者的原型。把所有公用函式原型集中起來放到每個模組開始部分早已是碼農共識。而把原型集中放到標頭檔案裡,是方便措施。(it:如何避免重複宣告?it:之所以**庫搜到那麼多重名函式卻互不干擾,是因為實際編譯時只能看到乙個?)

#include "kissyou.h"

將在整個程式範圍內共享的變數,需要在每乙個相關模組裡對之做出extern宣告,同時,需保證在且僅在某乙個模組裡使用標準變數宣告對此類變數進行定義。(it:若是部分檔案共享,在其中乙個檔案中定義,在其他檔案中用extern匯入(或者在這些檔案公用的標頭檔案中extern匯入)。若是大部分模組都要用,或者保證不會重名,或者暫時不用的模組將來可能要用,那就在被工程各個模組都include的標頭檔案中放入extern宣告。)

it:使用其他模組的函式要引入其原型;使用其他模組定義的變數要在本模組用extern宣告。

《好學的C 第2版》 第8章 檔案 電子儲存

主記憶體 ram,隨機訪問記憶體 當計算機關閉時其資料就丟失。對於cin和cout支援的函式呼叫和操作,c 提供的檔案流也同樣支援。前者需要 include 後者需要 include 流 stream 在寫資料時是目的地,讀資料時就是源頭。開啟badgirl.txt檔案 ofstream fout ...

C 高階程式設計(第9版) 第06章 陣列

好久沒發東西了 一停下來就會變懶。雖然沒完成,也就是它吧 以下正文 本章要點 1 簡單陣列 2 多維陣列 3 鋸齒陣列 4 array類 5 作為引數的陣列 6 列舉 7 元組 8 結構比較 同一型別和不同型別的多個物件 如果需要使用同一型別的多個物件,就可以使用集合 參見第10章 和陣列。c 用特...

C 高階程式設計第11版 附贈第一章

microsoft composition是乙個用來構建元件 part 和容器 container 之間依賴關係 independency 的框架。元件可以被容器使用,而容器無需知道具體實現和細節。容器只需要乙個契約 contract 例如,乙個使用元件的介面。microsoft compositi...