• #《Essential C++》读书笔记# 第一章 C++ 编程基础


    前言

        Stanley B.Lippman 先生所著的《C++ Primer》是学习C++的一本非常优秀的教科书,但《C++ Primer》作为一本大部头书,显然不适合所有的初学者。所以Lippman先生又返璞归真地写了这本短小轻薄的《Essentia C++》。这本书以简短的章节篇幅,帮助初学者快速学习C++的语法,了解C++语言特性,理解C++的设计目的和基本原理。笔者阅读的是《Essential C++》中文版,其译者为侯捷老师,他也是《C++ Primer》中文版第三版的译者。

    基础知识

    第一个完整的C++程序:

    #include <iostream>
    #include <string>
    
    using namespace std;
    
    int main()
    {
        string user_name;
        cout << "Please enter your first name:";
        cin >> user_name;
        cout << '
    '
            << "Hello, "
            << user_name
            << "...and goodbye!
    ";
        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() 来表示“删去一个字符”的原因。

    template class 允许我们在“不必指明 data member 类型”的情况下定义class。template class 机制使程序员得以直到使用 template class 时才决定真正的数据类型。程序员可以先插入一个代名,稍后才绑定至实际的数据类型。

    由于反斜线字符以用作转义字符的起头字符,因此连续两个反斜线即表示一个真正的反斜线字符。

    被定义为 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
    ";
            return -1;
        }
        ofstream out_file("2.txt");
        if (!out_file)
        {
            cerr << "opps! unable to open output file
    ";
            return -1;
        }
        string word;
        vector<string> text;
        while (in_file >> word)
            text.push_back(word);
        size_t ix;
        cout << "unsorted text:
    ";
        for (ix = 0;ix < text.size();++ix)
        {
            cout << text[ix] << ' ';
        }
        cout << endl;
        sort(text.begin(), text.end());
        cout << "sorted text:
    ";
        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。

    “取乎其上,得乎其中;取乎其中,得乎其下;取乎其下,则无所得矣。”

  • 相关阅读:
    react中实现滚动到指定位置固定显示导航栏,反之浸入背景
    activeElement解决ios滚动到底部显示内容时,键盘挡住显示内容的问题
    公积金无租房备案提取如何办理?(以成都为例)
    公积金状态封存怎么解封?
    你应该知道的公积金基础知识科普
    react antd表单不用form.create方法怎么设置input 回显值
    简述个人账户向公司账户转账的方法
    js拖拽进入和离开重复触发的问题
    Electron截屏功能
    Electron在mac下快捷键失效的问题及解决
  • 原文地址:https://www.cnblogs.com/zhuifeng17/p/12232318.html
Copyright © 2020-2023  润新知