本節書摘來自異步社群出版社《c++ 開發從入門到精通》一書中的第2章,第2.4節,作者: 王石磊 , 韓海玲,更多章節内容可以通路雲栖社群“異步社群”公衆号檢視。
1 知識點講解:CD光牒:視訊ppt講解(知識點)第2章輸入輸出基礎.mp4
c++并沒有直接定義進行輸入或輸出(io)的任何語句,而是由标準庫(standard library)提供,io庫為程式員提供了大量的工具。然而對于許多應用來說,包括本書的例子而言,程式設計者隻需要了解一些基本概念和操作。本書中的大多數例子都使用了處理格式化輸入和輸出的iostream庫。iostream庫的基礎是兩種命名為istream和ostream的類型,分别表示輸入流和輸出流。流是指要從某種io裝置上讀入或寫出的字元序列。術語“流”試圖說明字元是随着時間順序生成或消耗的。在本節的内容中,将簡要講解c++實作輸入和輸出的基本知識。
标準庫定義了4個io對象。處理輸入時使用命名為cin(讀作see-in)的istream類型對象。這個對象也叫作标準輸入(standard input)。處理輸出時使用命名為cout(讀作see-out)的ostream類型對象,這個對象也稱為标準輸出(standard output)。标準庫還定義了另外兩個ostream對象,分别命名為cerr和clog(分别讀作“see-err”和“see-log”)。cerr對象又叫作标準錯誤(standard error),通常用來輸出警告和錯誤資訊給程式的使用者。而clog對象用于産生程式執行的一般資訊。
在一般情況下,系統将這些對象與執行程式的視窗聯系起來。這樣,當我們從cin讀入時,資料從執行程式的視窗讀入,當寫到cout、cerr或clog時,輸出寫至同一視窗。運作程式時,大部分作業系統都提供了重定向輸入或輸出流的方法。利用重定向可以将這些流與所選擇的檔案聯系起來。
到目前為止,我們已經明白如何編譯與執行簡單的程式,雖然那個程式什麼也不做。在接下來的内容中,我們先來看一看應該如何實作把兩數相加的處理代碼。我們可以使用io庫來擴充main程式,實作輸出使用者給出的兩個數的和的功能,具體代碼如下。
在上述代碼中,首先在使用者螢幕上顯示提示語“輸入兩個數字:”,輸入後按下Enter鍵,将輸出兩者的和。程式的第一行是一個預處理訓示。
<code>#include <iostream></code>
功能是告訴編譯器要使用iostream庫。尖括号裡的名字是一個頭檔案。當程式使用庫工具時必須包含相關的頭檔案。#include指令必須單獨寫成一行——頭檔案名和#include必須在同一行。通常,#include指令應出現在任何函數的外部。而且習慣上,程式的所有#include訓示都在檔案開頭部分出現。
main函數體中第一條語句執行了一個表達式(expression)。c++中,一個表達式由一個或幾個操作數和通常是一個操作符組成。該語句的表達式使用輸出操作符(<<操作符),在标準輸出上輸出如下提示語。
<code>std::cout << "enter two numbers:" << std::endl;</code>
上述代碼用了兩次輸出操作符,每個輸出操作符執行個體都接受兩個操作數:左操作數必須是ostream對象,右操作數是要輸出的值。操作符将其右操作數寫到作為其左操作數的ostream對象。
在c++中,每個表達式産生一個結果,通常是将運算符作用到其操作數所産生的值。當操作符是輸出操作符時,結果是左操作數的值。也就是說,輸出操作傳回的值是輸出流本身。
既然輸出操作符傳回的是其左操作數,那麼我們就可以将輸出請求連結在一起。輸出提示語的那條語句等價下面的代碼。
<code>(std::cout << "enter two numbers:") << std::endl;</code>
因為(std::cout << "enter two numbers:")傳回其左操作數std::cout,這條語句等價下面的代碼。
endl是一個特殊值,稱為操縱符(manipulator),将它寫入輸出流時,具有輸出換行的效果,并重新整理與裝置相關聯的緩沖區(buffer)。通過重新整理緩沖區,保證使用者立即看到寫入到流中的輸出。
f:paiban電子書41885圖zy.png
注意:程式員經常在調試過程中插入輸出語句,這些語句都應該重新整理輸出流。忘記重新整理輸出流可能會造成輸出停留在緩沖區中,如果程式崩潰,将會導緻程式錯誤推斷崩潰位置。
細心的讀者會注意到這個程式中使用的是std::cout和std::endl,而不是cout和endl。字首std::表明cout和endl是定義在命名空間(namespace)std中的。命名空間使程式員可以避免與庫中定義的名字相同引起的無意沖突。因為标準庫定義的名字定義在命名空間中,是以我們可以按自己的意圖使用相同的名字。
标準庫使用命名空間的副作用是,當我們使用标準庫中的名字時,必須顯式地表達出使用的是命名空間std下的名字。std::cout的寫法使用了作用域操作符(scope operator,::操作符),表示使用的是定義在命名空間std中的cout。
在輸出提示語後,将讀入使用者輸入的資料。先定義兩個名為v1和v2的變量(variable)來儲存輸入。
<code>int v1, v2;</code>
将這些變量定義為int類型,int類型是一種代表整數值的内置類型。這些變量未初始化(uninitialized),表示沒有賦給它們初始值。這些變量在首次使用時會讀入一個值,是以可以沒有初始值。下一條語句讀取輸入如下。
<code>std::cin >> v1 >> v2;</code>
輸入操作符(>>操作符)行為與輸出操作符相似,功能是接受一個istream對象作為其左操作數,接受一個對象作為其右操作數,它從istream操作數讀取資料并儲存到右操作數中。像輸出操作符一樣,輸入操作符傳回其左操作數作為結果。由于輸入操作符傳回其左操作數,我們可以将輸入請求序列合并成單個語句。換句話說,這個輸入操作等價于下面的代碼。
輸入操作的效果是從标準輸入讀取兩個值,将第一個存放在v1中,第二個存放在v2中。
剩下的就是要輸出結果。
上述代碼雖然比輸出提示語的語句長,但是在概念上沒什麼差別,功能是将每個操作數輸出到标準輸出。有趣的是操作數并不都是同一類型的值,有些操作數是字元串字面值。例如下面的代碼。
<code>"the sum of "</code>
其他是不同的int值,如v1和v2以及對算術表達式v1 + v2求值的結果。iostream庫定義了接受全部内置類型的輸入輸出操作符版本。
注意:在寫c++程式時,大部分出現空格符的地方,可用換行符代替。這條規則的一個例外是字元串字面值中的空格符不能用換行符代替。另一個例外是換行符不允許出現在預處理訓示中。