Stanley B.Lippman 先生所著的《C++ Primer》是學習C++的一本很是優秀的教科書,但《C++ Primer》做爲一本大部頭書,顯然不適合全部的初學者。因此Lippman先生又返璞歸真地寫了這本短小輕薄的《Essentia C++》。這本書以簡短的章節篇幅,幫助初學者快速學習C++的語法,瞭解C++語言特性,理解C++的設計目的和基本原理。筆者閱讀的是《Essential C++》中文版,其譯者名爲侯捷,他也是《C++ Primer》中文版第三版的譯者。ios
第一個完整的C++程序:程序員
#include <iostream> #include <string> using namespace std; int main() { string user_name; cout << "Please enter your first name:"; cin >> user_name; cout << '\n' << "Hello, " << user_name << "...and goodbye!\n"; return 0; }
關鍵字(keyword),就是程序語言預先定義的一些具備特殊意義的名稱。算法
函數(function)是一塊獨立的程序代碼序列,可以執行一些運算。它包含四個部分,返回值類型(return type),函數名稱,參數列表(parameter list),以及函數體(function body)。main並不是是程序語言定義的關鍵字,可是,C++編譯系統會假設程序中定義有main()函數。main()函數是程序執行的起點,若是咱們沒有定義,程序將沒法執行。函數
類(class),class機制賦予了咱們「增長程序內之類型抽象化層次」的能力。class機制讓咱們得以將數據類型加入咱們的程序中,並有能力識別它們。面向對象的類層次體系(class hierarchy)定義了整個家族體系的各個相關類型。class的定義通常來講分爲兩部分,分別寫在不一樣的文件中。一個就是所謂的「頭文件(header file)」,用來聲明該class所提供的的各類操做行爲(operation)。另外一個文件,程序代碼文件(program text),則包含了這些行爲的實現內容(implementation)。欲使用class,咱們必須先在程序中包含其頭文件,頭文件可讓程序知道class的定義。工具
命名空間(namespace),是一種將庫名稱封裝起來的方法。經過這種方法,能夠避免和應用程序發生命名衝突獲得問題(所謂命名衝突是指在應用程序內兩個不一樣的實體(entity)具備相同名稱),致使程序沒法區分二者。命名衝突發生時,程序必須等到該命名衝突得到解析(resolve)以後,才得以繼續執行。命名空間像是在衆多名稱的可見圍內豎起一道圍牆。學習
爲了定義對象,咱們必須爲它命名,並賦予它數據類型。對象名稱能夠是任何字母、數字、下畫線的組合,並大小寫敏感。對象名稱不能以數字開頭。固然任何命名不能和程序語言自己關鍵字徹底一致。例如 delete 是語言關鍵字,因此 string class 採用 earse() 而非 delete() 來表示「刪去一個字符」的緣由。ui
template class 容許咱們在「沒必要指明 data member 類型」的狀況下定義class。template class 機制使程序員得以直到使用 template class 時才決定真正的數據類型。程序員能夠先插入一個代名,稍後才綁定至實際的數據類型。this
因爲反斜線字符以用做轉義字符的起頭字符,所以連續兩個反斜線即表示一個真正的反斜線字符。spa
被定義爲 const 的對象,在得到初值以後,沒法在有任何變更。若是你企圖爲 const 對象指定新值,會產生編譯錯誤。設計
對於 OR 邏輯運算符( || ),左側表達式會先被求值,若是其值爲 true,剩下的表達式就不須要再被求值(此所謂短路求值法)。AND 邏輯運算符( && ),最左側表達式會先被求值,其結果若爲 false ,則 AND 運算符的求值結果即爲 false,其他表達式不會再被求值。
一些運算符優先級簡列於下,位置在上者的優先級高於位置在下者,同一行的各類運算符具備相同的優先級,其求值次序取決於它在該表達式中的位置(由左至右)。
邏輯運算符 NOT
算術運算符(*,/,%)
算術運算符(+,-)
關係運算符(<,>,<=,>=)
關係運算符(==,!=)
邏輯運算符 AND
邏輯運算符 OR
賦值運算符 (assignment = )
若是要訪問一個由指針所指的對象,咱們必須對該指針進行提領(dereference,也叫解引用)操做——也就是取得「位於該指針所指內存地址上」的對象。在指針以前使用「*」號,即可以達到這個目的。
咱們可使用 dot 成員選擇運算符(member selection opereation),用來選擇咱們想要的操做。若是要經過指針來選擇操做,必須改用 arrow 成員選擇運算符。若是要使用下標運算符(subscript operator),咱們必須先提領指針,因爲下標運算符的優先級較高,所以指針提領操做的兩旁必須加上小括號。
練習1.5 編寫一個程序,可以詢問用戶的姓名,並讀取用戶所輸入的內容。請確保用戶輸入的名稱長度大於兩個字符。若是用戶的確輸入了有效的名稱,就響應一些信息。請以兩種方式實現:第一種使用C-style字符串,第二種使用string對象。
#include <iostream> #include <string> #include <iomanip> #include <cstring> using namespace std; #define MAX 50 #define MIN 2 int main() { //C-style 字符串 /* const int nm_size = 128; //分配一個固定大小 char user_name[nm_size]; cout << "Please enter your name:"; cin >> setw(nm_size) >> user_name; //保證讀入不超過127個字符,最後一個空間保存null size_t len = strlen(user_name); if (len <= 3) { cout << "Please enter a longer name!" << endl; return 0; } cout << "Hello," << user_name << endl; */ //string對象 string user_name; cout << "Please enter your name:"; cin >> user_name; size_t len = user_name.size(); //獲取的即爲字符串長度,無null if (len <= 2) { cout << "Please enter a longer name!" << endl; return 0; } cout << "Hello," << user_name << endl; return 0; }
練習1.6 編寫一個程序,從標準輸入設備讀取一串整數,並將讀入的整數依次放到 array 和 vector,而後遍歷這兩種容器,求取值總和。將總和及平均值輸出至標準輸出設備。
#include <iostream> #include <vector> using namespace std; #define MAX 10 int main() { /* //存放到vector vector<double> v; double temp=0; double sum = 0; double ave = 0.0; while (cin >> temp) { v.push_back(temp); } for (int i = 0;i < v.size();i++) { sum += v[i]; } ave = sum / v.size(); cout << "Sum=" << sum << endl; cout << "Average=" << ave << endl; */ //存放到array double arr[MAX]; int count = 0; int count2 = 0; double temp; double sum = 0.0; double ave = 0.0; while (count<10 && cin >> temp) { arr[count] = temp; count++; } count2 = count; count--; while (count >= 0) { sum += arr[count]; count--; } ave = sum / count2; cout << "Sum=" << sum << endl; cout << "Average=" << ave << endl; return 0; }
練習1.7 使用你最稱手的編輯工具,輸入兩行(或更多)文字存盤。而後編寫一個程序,打開該文本文件,將其中的每一個字都讀取到一個 vector<string> 對象中。遍歷該 vector,將內容顯示到 cout。而後利用泛型算法 sort(),對全部文字排序。
#include <iostream> #include <fstream> #include <algorithm> #include <string> #include <vector> using namespace std; int main() { ifstream in_file("1.txt"); if (!in_file) { cerr << "opps! unable to open input file\n"; return -1; } ofstream out_file("2.txt"); if (!out_file) { cerr << "opps! unable to open output file\n"; return -1; } string word; vector<string> text; while (in_file >> word) text.push_back(word); size_t ix; cout << "unsorted text:\n"; for (ix = 0;ix < text.size();++ix) { cout << text[ix] << ' '; } cout << endl; sort(text.begin(), text.end()); cout << "sorted text:\n"; for (ix = 0;ix < text.size();++ix) { cout << text[ix] << ' '; out_file << text[ix] << ' '; } cout << endl; out_file << endl; return 0; }
練習1.8 1.4節的 switch 語句讓咱們得以根據用戶答錯的次數提供不一樣的安慰語句。請以 array 儲存四種不一樣的字符串信息,並以用戶答錯的次數做爲 array 的索引值,以此方式來顯示安慰語句。
#include <iostream> #include <stdlib.h> #include <ctime> using namespace std; const char* msg_to_usr(int num_tries); int main() { int count=0; srand(time(0)); int answer = rand() % 3; int myAnswer; char isContinue = 'y'; while (isContinue=='y') { cout << "Please input your answer(0-2): "; cin >> myAnswer; if (myAnswer == answer) { cout << "Congratulations!" << endl; break; } else { count++; cout << msg_to_usr(count) << endl; cout << "Continue? input y or n: "; cin >> isContinue; } } return 0; } const char* msg_to_usr(int num_tries) { const int rsp_cnt = 5; static const char* usr_msgs[rsp_cnt] = { "Go on, make a guess. ", "Oops! Nice guess but not quite it. ", "Hmm. Sorry. Wrong a second time. ", "Ah, this is harder than it looks, no? ", "It must be getting pretty frustrating by now! " }; if (num_tries < 0) { num_tries = 0; } else if (num_tries >= rsp_cnt) num_tries = rsp_cnt - 1; return usr_msgs[num_tries]; }
end。
「取乎其上,得乎其中;取乎其中,得乎其下;取乎其下,則無所得矣。」