硬著頭皮啃C Primer 第1章 開始

2021-10-02 15:36:06 字數 3358 閱讀 4583

早已聽說c++primer的大名,可一直沒時間去拜讀。趁這個假期,來拜會一下這本神書。我會將這本書的重點記錄下來,和大家分享。

1.1 編寫乙個簡單的c++程式

乙個函式的定義包括四個部分:返回型別、函式名、乙個括號包圍的形參列表以及函式體。

每個c++程式都必須有乙個或多個函式,其中必須有乙個命名為main。main函式的返回值型別必須為int。

1.2 初識輸入與輸出

c++語言並未定義任何輸入與輸出語句,它包含乙個全面的標準庫來提供io機制。我們通常使用iostream庫來進行輸入與輸出。這個庫包含兩個基礎型別:istream和ostream,分別表示輸入流和輸出流。乙個流就是乙個字串行。這兩個型別對應四個io物件。其中,cin為istream型別的物件,也被稱為標準輸入。cout為ostream型別的物件,也被稱為標準輸出。還有兩個ostream型別的物件,clog和cerr,前者用於輸出一般性資訊,後者用於輸出警告和錯誤資訊。後者也被稱為標準錯誤。

系統通常將程式所執行的視窗和這些物件相關聯,因此,當我們讀取cin,就是從程式正在執行的視窗中讀入資訊;當我們將資料寫入cout等,就是將資訊輸出到視窗。

這裡糾正了我之前沒有正式學過c++時的乙個誤區:我之前用c++,倒不如說是就是用c加上stl,那時我就認為cin和cout是倆指令,類似for啊while等等,用於輸入和輸出,代替scanf和printf的。但是現在才知道,這是倆物件,也就是和int a裡面的a是乙個意思。它能夠實現輸入和輸出,很大程度上是靠它和》、《實現的,而不是我之前簡單的認為就是呼叫乙個指令罷了。

這裡的《叫做輸出運算子,相對應的,>>叫做輸入運算子。既然它們是運算子,那麼就一定有運算物件,這裡規定輸出運算子《的左側必須是乙個ostream型別的值,一般就是cout;右側是我們想要列印的值。這個運算子的功能就是把想要列印的值寫入到ostream中,輸出運算子的計算結果就是其左側計算物件。這句話看起來是廢話,但在理解下面這句**時候很有用:

std::cout<<"enter two numbers:"《我們都寫過許多與之類似的**,但是其原理可能並不很清楚,我就只知道這個輸出幾句輸出幾個變數時很方便,但到底為什麼也沒注意過。

實際上,上面這句**可以加上如下所示的括號:

(std::cout<<"enter two numbers:")《什麼意思呢?就是說,既然《是乙個運算子,那麼自然有運算順序,運算順序就是從左到右,首先計算cout和"enter"這一句,將"enter"寫入cout,結果就是cout,然後再將endl寫入cout。由於「《的計算結果是其左側的計算物件」同時「《的計算順序是從左往右」,因此我們才能夠乙個接乙個的輸出。

這裡的endl我平時都是懶得寫的——不知道它有什麼用,不加也沒見程式出什麼錯,那就不加了。這個玩意叫做操縱符,它的用途是結束當前行,並把裝置關聯的緩衝區的內容重新整理到裝置中。這個東西是確保所有程式的輸出結果都能顯示在螢幕上的:因為輸出的原理是「程式計算輸出結果,放進緩衝區,從緩衝區拿資料寫入輸出流」,那麼就存在這樣一種情況:我緩衝區中的內容沒等全寫入輸出流,程式就崩潰了,那麼輸出就會缺失,這會導致錯誤。加上這個操縱符,只要這一句執行完,就能保證緩衝區的所有內容全被寫入輸出流。緩衝區:我被輸出流榨幹了= =。

再來看這個std::,這是說明cout和endl是定義在名為std的命名空間中。命名空間主要為了防止我們起名出現衝突。就像我喊「蕭炎~」,可能大家一臉懵逼,蕭炎誰啊?我要是喊「鬥破蒼穹::蕭炎」,大家就明白了,我喊的是鬥破蒼穹這個命名空間裡面的蕭炎。這裡的::也是乙個運算子,叫做作用域運算子。

與《類似,>>要求其左側是乙個istream型別的運算物件,接受乙個物件作為其右側的物件。這個運算子的作用是從istream中讀入資料,並儲存在其右側的物件中。它也返回其左側物件作為運算結果。這裡有乙個問題:ostream我們可以自己控制什麼時候向其寫入的結束時刻,istream向物件寫入資料怎麼判斷結束呢?一般用空格,回車什麼的隔斷就行了。比如下面一句:

std::cin>>v1>>v2;

就可以看做首先將cin的用空格隔開的第一部分寫入v1,然後返回cin的剩餘部分,再寫入v2。

1.3 注釋簡介

c++中有兩種注釋:單行注釋和界定符對注釋。單行注釋以雙斜線//開始,以換行符結束。這種注釋可以包含任意文字,包括額外的雙斜線。

界定符對指的是/* 和 */,這種注釋可以包含多行,以 /*開始,以*/結束,可以包含除了*/以外的所有文字。當這類注釋跨過多行時,約定俗成的,在每一行的開頭加上乙個*。下面來看練習1.8:

#include int main()

{ std::cout << "/*";

std::cout<<"*\";

std::cout《在這四句中,只有第一句和第四句能正常執行,輸出「/*」,剩下三句都拉了跨。第二句,由於「\」是轉義字元,因此它將後面的右引號進行了轉義,這樣就沒有右引號和之前的左引號匹配了,會報錯「缺少右引號」。第三句中,出現了完整的界定符對,中間夾著左引號,那麼不看注釋,剩下的就是

std::cout<<"*/;

同樣是缺少右引號。第四句最後會輸出「/*」,這裡需要仔細來看:

首先,開始的一對界定符將乙個引號注釋掉,然後,後面的一對界定符將後面的引號注釋掉,即

std::cout<<"/*";
那麼剩下的就是一對引號包裹著的/*了。這裡我的錯誤在於,以為這裡的第二個「/*」對應最後的「*/」,實際上,與最後的*/對應的是離它最近的左邊的/*,也就是說,上面那句話還不夠嚴密,應該這樣說「界定符對的注釋,以/*開始,可以包含除了/*和*/以外的所有文字,如果出現第二個/*,那麼第乙個/*就無效了。」

1.4 控制流

這一節中只有乙個地方需要注意,就是我們想要實現讀取數量不定的輸入資料,其實這在pat中已經遇到過若干次,在這裡使用更加c++的風格來解決這一問題。**如下:

int value=0;

while(std::cin>>value)

...

這裡使用的判斷條件為cin>>value的執行結果,我們在之前說過,這一表示式的執行結果就是cin本身,也就是說,while就是檢查cin。怎麼檢查呢?

當我們使用乙個istream物件作為判斷條件時,其效果就是檢測流的狀態,如果流是有效的,也就是說流未遇到錯誤,那麼就檢測成功。如果遇到檔案結束符(eof)或者輸入與寫入物件不符,那麼就檢測失敗。在windows中,輸入eof是ctrl+z,然後enter,在linux中則是ctrl+d。

1.5 類簡介

你看它自己也說了簡介,那麼這裡就沒什麼太多有用的東西,也是僅有幾點要注意:首先就是使用include時,後面用尖括號<>還是雙引號"",規定屬於標準庫的標頭檔案使用尖括號,不屬於標準庫的標頭檔案使用雙引號。其次是我們可以使用檔案重定向來代替視窗的輸入和輸出,簡而言之就是從視窗輸入改為從檔案讀入,在視窗顯示改為寫入到檔案。最後就是一件好玩的事:呼叫函式時,函式名後面的()也是運算子,稱為呼叫運算子,它裡面放的是實參。

《c primer》筆記 第1章 開始

main的返回值被用來指示狀態。返回值0表明成功,非0的返回值的含義由系統定義,通常用來指出錯誤型別.寫乙個簡單的測試程式 include int main g g oprogl progl cc o progl是編譯器引數,指定了可執行檔案的檔名。cl從vs2013 開發人員命令提示啟動 cl e...

《c primer》筆記 第1章 開始

main的返回值被用來指示狀態。返回值0表明成功,非0的返回值的含義由系統定義,通常用來指出錯誤型別.寫乙個簡單的測試程式 include int main g g oprogl progl cc o progl是編譯器引數,指定了可執行檔案的檔名。cl從vs2013 開發人員命令提示啟動 cl e...

c primer 學習筆記 1 第1 5章

1.輸入輸出 流 隨著時間的推移,字元是順序生成或消耗的 std cout hello world endl 運算子接受兩個運算物件,左側必須是ostream,右側是要列印的值,計算結果返回ostream物件中。上述使用兩次 運算子,第一次運算結果成了第二次的左側物件。note 在寫過載 運算子是要...