《C++PrimerPlus》阅读笔记 + 源码实践
目錄
- 說明
- 前言
- 第一章:開始
- 1.1編寫一個簡單的C++程序
- 1.2初識輸入輸出
- 1.3注釋簡介
- 1.4控制流
- 1.5類
- 文件重定向
- 1.6書店程序
說明
| C++PrimerPlus系列博客是對于書中的知識點進行總結和簡短提煉。 |
| 建議讀者參考C++博客同時閱讀,內容互補。 |
前言
C++本身在不斷成熟,語言本身和程序社區的關注點:機器效率——>編程效率。
新標準的目標:
語言更統一,更易教學。
標準庫更安全簡單、安全、使用更高效。
編寫高效率的抽象和庫變得更簡單。
C++語言的組成:
低級語言:大部分繼承自C語言。
現代高級語言:自定義類型以及組織大規模程序和系統。(面向對象設計)
標準庫:利用高級特性提供有用的數據結構和算法。(STL)
注意:在實際編碼的過程中,更多的去考慮使用標準庫。
標準庫的優勢:
更加容易實現。
更加容易理解。
出錯更少。
標準庫能滿足大多數開發應用場景。
標準庫提供的數據結構和算法效率更高。
第一章:開始
學習一門新的程序設計語言的最好方法就是練習編寫程序。
只有不斷編碼的的過程中才會驗證自己有沒有掌握,才能發現自己的問題并解決問題從而更快的提高。
1.1編寫一個簡單的C++程序
每個C++程序都包含一個或者多個函數,其中一個必須命名為main。
操作系統通過調用main來運行C++程序。
一個函數的定義包括四個部分:
返回類型
函數名
一個括號包圍的形參列表。
函數體。(以左花括號開始,以右花括號結束的語句塊)
雖然main函數在某種程度上比較特殊,但是其定義與其他函數一樣,也是上面4個部分。
當return語句包括一個值時,此返回值的類型必須與函數的返回類型相容。
大多數系統中:main函數返回值被用來指示狀態:
返回值0:表明成功。
返回值非0:含義由系統定義,通常用來指出錯誤類型。
類型決定數據元素的內容,也決定這類數據可以進行的計算。
思考:補碼的設計思路和規范,char類型一個字節8位可以表示2^8= 256個數字,那么為什么表示的是[-128,127]呢?
原因就是內存中去表示char類型數的時候不僅僅只是保存數據,而且還要考慮數據保存之后的計算。
關于補碼的設計規則我在C語言博客中已經詳細說明,內存模型和計算機編碼規則將持續在我們整個計算機的學習之中。所以建議讀者進行跳轉閱讀:
→點擊此處跳轉到計算機編碼規則和補碼的設計博客
1.2初識輸入輸出
Iostream庫中包含兩個基本類型:
Istream:輸入流,從IO設備讀出。
ostream:輸出流,寫入IO設備。
流:字符序列。
標準庫定義了4個IO對象:
cin:istream類型對象:標準輸入,用來從標準輸入讀取數據。
cout:ostream類型對象:標準輸出,用于將數據寫入標準輸出。標準輸出(standard output)輸出流,通常與程序執行所在窗口相關聯。
cerr:ostream類型對象:標準錯誤。(輸出警告和錯誤消息)關聯到標準錯誤,,通常寫入到與標準輸出相同的設備。默認情況下,寫到cerr的數據是不緩沖的。cerr通常用于輸出錯誤信息或其他不屬于程序正常邏輯的輸出內容。
clog:ostream類型對象:輸出程序運行時的一般性信息,關聯到標準錯誤。默認情況下,寫到clog的數據是被緩沖的。clog通常用于報告程序的執行信息,存入一個日志文件中。
一個使用IO庫的程序:
#include <iostream> using namespace std;int main(int argc, char *argv[]) {cout << "Enter two numbers:" << endl;int v1 = 0;int v2 = 0;cin >> v1 >> v2;cout << "The sum of " << v1 << " and " << v2 << " is " << v1 + v2 << endl;cout << "hello world" << endl;cout << "The sum of " << v1 << " and " << v2 << " is " << v1 * v2 << endl;return 0; }運行結果:
一般將一個程序的所有#include指令都放在源文件的開始位置。
輸出運算符<<:
左側運算對象:必須是一個ostream對象。
右側運算對象:要打印的值。
運算結果:將給定的值寫到給定的ostream對象中。
上面代碼中出現的endl:
操縱符。
效果:結束當前行,將與設備關聯的緩沖區中的內容刷新到設備中。
刷新緩沖區:程序所產生的輸出都真正寫入輸出流中,而不是停留在內存緩沖區等待寫入。
注意:
調試程序的時候添加打印語句,應該保證語句”一直”刷新緩沖區。
否則如果程序崩潰,輸出可能停留在緩沖區沒有刷新從而導致程序崩潰位置錯誤推斷。
命名空間:
避免不經意的名字定義沖突。
避免使用庫中相同名字而導致沖突。
標準庫定義的所有名字都在命名空間std中。
初始化變量:創建一個變量的同時為它賦一個值。
未初始化的變量:未賦予初值的變量。
類類型的變量如果未指定初值,則按類定義指定的方式進行初始化。
定義在函數內部的內置類型變量默認是不初始化的,除非有顯式的初始化語句。
試圖使用一個未初始化變量的值是錯誤的。未初始化變量是bug的常見成因。
1.3注釋簡介
注釋的作用:
幫助讀者理解程序。
概述算法。
確定變量的用途。
解釋難懂的代碼段。
編譯器會忽略注釋,因此注釋對程序的行為或性能不會有任何影響。
錯誤的注釋比完全沒有注釋更糟糕,因為它會誤導讀者。所以在修改代碼的時候,同時要更新注釋。
→點擊此處跳轉到注釋的種類和詳細說明博客
注釋代碼:
#include <iostream> using namespace std; /* *簡單主函數 *讀取兩個數,求它們的和 */ int main(int argc, char *argv[]) {cout << "Enter two numbers:" << endl;//提示用戶輸入兩個數int v1 = 0;//保存我們讀入的輸入數據變量int v2 = 0;//保存我們讀入的輸入數據變量cin >> v1 >> v2;//讀取輸入數據cout << "The sum of " << v1 << " and " << v2 << " is " << v1 + v2 << endl;cout << "hello world" << endl;cout << "The sum of " << v1 << " and " << v2 << " is " << v1 * v2 << endl;return 0; }運行結果:
1.4控制流
→點擊此處跳轉到程序設計流程——循環詳細說明博客
while循環:
#include <iostream> using namespace std;int main(int argc, char *argv[]) {int sum = 0;int val = 1;while (val <= 10)//只要val的值小于10,while循環就會持續執行{sum += val;//將sum+val的值賦值給sum++val;//將val+1}cout << "Sum of 1 to 10 inclusive is " << sum << endl;return 0; }運行結果:
for循環:
#include <iostream> using namespace std;int main(int argc, char *argv[]) {int sum = 0;//從1加到10for (int val = 0; val <= 10; ++val){sum += val;//等價于sum = sum + val}cout << "Sum of 1 to 10 inclusive is " << sum << endl;return 0; }運行結果:
讀取數量不定的輸入數據:
#include <iostream> using namespace std;int main(int argc, char *argv[]) {int sum = 0;int val = 0;//讀取數據直到遇到文件尾,計算所有讀入的值的和while (cin>>val){sum += val;//等價于sum = sum + val}cout << "Sum is " << sum << endl;return 0; }運行結果:
如果使用istream對象作為條件,就是檢測流的狀態:
條件為真:流是有效的,流未遇到錯誤,檢測成功。
條件為假:遇到文件結束符(end of file)或者遇到無效輸入時。對象狀態編程無效為假。
從鍵盤輸入文件結束符:
Windows: Ctrl+Z(按住Ctrl鍵的同時按Z鍵),然后按Enter或Return鍵。
UNIX/Mac OS X: Ctrl+D。
編譯器能夠檢查出來程序的錯誤:
語法錯誤。
類型錯誤。
聲明錯誤。
C++程序中的每個名字都要先聲明后使用。
兩種常見的聲明錯誤是:
對來自標準庫的名字忘記使用std::。
標識符名字拼寫錯誤:。
關于編碼風格的思考:
當你要選擇一種格式風格時,思考一下它會對程序的可讀性和易理解性有什么影響,而一旦選擇了一種風格,就要堅持使用。
1.5類
在C++中,我們通過定義一個類(class)來定義自己的數據結構。
類機制是C++最重要的特性之一。
一個類定義了一個類型,以及與其關聯的一組操作。
類的作者決定了類類型對象上可以使用的所有操作。
為了使用一個類,我們不必關心它是如何實現的,只需知道類對象可以執行什么操作。
對于不屬于標準庫的頭文件,則用雙引號(" ")包圍。
文件重定向
在默認情況下我們的輸入流是鍵盤設備,輸出流是顯示器設備。
我們可以通過文件重定向來修改輸入流的源文件和輸出到的文件。
例如:
我們上面使用過的代碼:輸入流是鍵盤設備,輸出流是顯示器。
運行結果:
接下來我們演示重定向輸入輸出文件。
如果使用文件重定向,我們可以選擇某一個文件的內容作為程序的輸入,選擇某一個文件作為保存程序的輸出結果。
在VS2013中操作如下:項目→屬性→配置屬性→調試→命令參數,輸出以下參數。
在源代碼所文件中創建input.txt文件和out.txt文件:
在input文件中輸入22 33:
<input.txt>表示項目工程根目錄下,有一個input.txt的文本文件,就是程序的輸入。
<out.txt>表示項目工程根目錄下,有一個out.txt的文本文件,把程序的輸入保存到這個文件里面。
再次運行程序,不用輸入數據,也不用輸出,程序就結束了。
這時候,再去看看out.txt文件:
網站http://www.informit.com/title/0321714113上,第1章的代碼目錄中包含了頭文件Sales_item.h。將它拷貝到你自己的工作目錄中,編寫下面代碼。
成員函數的使用&Sales_ite對象的加法:
#include <iostream> #include "Sales_item.h" using namespace std;int main(int argc, char *argv[]) {Sales_item item1;Sales_item item2;cin >> item1 >> item2;//首先檢查item1 和 item2 是否表示相同的書if (item1.isbn() == item2.isbn()){cout << item1 + item2 << endl;return 0;//表示成功}else{cerr << "Data must refer to same ISBN" << endl;return -1;//表示失敗}return 0; }運行結果:
類的組成:
數據成員。
函數成員(方法)。
我們通常以一個類對象的名義來調用成員函數:
cin.size();使用點運算符(.)來表達我們需要調用“名為cin的對象的size函數成員”。
點運算符只能用于類類型的對象:
左側運算對象必須是一個類類型的對象。
右側運算對象必須是該類型的一個成員名。
運算結果為右側運算對象指定的成員。
1.6書店程序
#include <iostream> #include "Sales_item.h"using namespace std;int main(int argc, char *argv[]) {Sales_item total;//保存下一條交易記錄的變量//記錄第一條交易記錄并且確保有數據可以處理if (cin >> total){Sales_item trans;//保存和的變量//讀入并處理剩余交易記錄while (cin>>trans){if (total.isbn() == trans.isbn()){total += trans;//更新銷售額}else{//打印前一本書的結果cout << total << endl;total = trans;//total表示下一本書的銷售額}}cout << total << endl;//打印最后一本書的結果}else{//沒有輸入,警告讀者cerr << "No data?!" << endl;return -1;//表示失敗}return 0; }緩沖區說明:
一個存儲區域,用于保存數據。
IO設施通常將輸入(或輸出)數據保存在一個緩沖區中,讀寫緩沖區的動作與程序中的動作是無關的。我們可以顯式地刷新輸出緩沖,以便強制將緩沖區中的數據寫入輸出設備。默認情況下,讀cin會刷新cout;程序非正常終止時也會刷新cout。
總結
以上是生活随笔為你收集整理的《C++PrimerPlus》阅读笔记 + 源码实践的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: C++文件流:myfstream,fst
- 下一篇: 什么是STL