#《Essential C++》讀書筆記# 第一章 C++ 編程基礎

前言

    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。

「取乎其上,得乎其中;取乎其中,得乎其下;取乎其下,則無所得矣。」

相關文章
相關標籤/搜索