zoukankan      html  css  js  c++  java
  • 《C++Primer》复习——with C++11 [1]

    1.头文件中不应包含using声明,因为头文件的内容会拷贝到所有引用到他的文件中去,如果头文件里有谋个using声明,那么每个使用了该头文件的文件就会有这个声明,由于不经意间包含了一些名字,反而可能产生始料未及的名字冲突。

    2.string对象的拷贝初始化和直接初始化。string str1 = "Hello";是拷贝初始化,编译器吧等号右侧的初始值拷贝到新创建的对象中去。使用getline读取一行, getline(cin, line),函数从给定的输入流中读取内容,知道遇到换行符为止,但是换行符并没有被读入line中去。   

    1 string line;
    2 while (getline(cin, line)) 
    3     cout << line << endl; 

    getline的empty和size操作,empty操作返回string对象是否为空,返回一个对应的布尔值,size返回string对象的长度,即string对象中字符的个数。

    1 while (getline(cin, line))//如果串不空则输出
    2     if (!line.empty())
    3         cout << line << endl;
    4 while (getline(cin, line))//输出字符数量大于30的串
    5     if (line.size > 30)
    6         cout << line << endl;

    string对象的size_type类型是一个无符号整形,用于表示返回自防护大小的类型,允许通过auto来推断他的类型

    auto len = line.size(); //len的类型就是size_type,不过使用的auto自动确定了类型而不需要事先了解size返回类型

    同时string对象也顶一了比较的操作符 != , == , > , <, <= , >= 。string对象也允许对象间的相加,string1+string2。处理字符串中的每个字符,判断特定的字符,用函数库cctype定义了一组表尊库函数处理这些。例如

    1 isalunm(c)//是字母或数字为真
    2 isalpha(c)//是字母为真
    3 iscntrl(c)//是控制字符为真
    4 isdigit(c)//是数字为真
    5 isgraph(c)  // 不是空格但可以打印
    6 islower(c)  //是小写?
    7 isprint(c)    //是否是可打印的字符
    8 tolower(c)    //如果大写字母,转换小写,否则输出
    9 toupper(c)    //如果小写字母,转换成对应的大写,否则原本输出

    使用基于范围的for语句,用范围for把string对象中的字符每行一个输出。

    1 string str("some stringA");
    2 for (auto c : str)            //对于str中的每一个字符
    3     cout << c << endl;    //输出当前字符    

    如下代码使用范围for语句和ispunct函数来统计string对象中标点符号的个数。

    1 string s("hello world!!");
    2 decltype(s.size()) punct_cnt = 0;
    3 for (auto c : s)
    4     if (ispunct(c))
    5         ++punct_cot;
    6 cout << punct_cnt << "puncts in: " << s << endl;

    string对象支持[]下标访问,想要编写一个吧0到15之间的数字转换成对应的十六进制形式,初始化一个字符串令其存放16个十六进制数字。

    1 const string hexdigits = "0123456789ABCDEF";
    2 string result;
    3 string::size_type n;
    4 while (cin >> n)
    5     if (n < hexdigits.size())
    6         result += hexdigits[n];
    7 cout << "Your hex number is:" << result << endl;

    3.vector是一个类模板,vecotr表示对象的集合,其中所有的对象类型一致。因为引用不是对象,所以不包含存在引用的vector,其他大多数非引用类型和类类型都可以构成vector对象,vector的初始化方法如下:

    1 vector<T> v1;              //
    2 vector<T> v2 = v1;         //拷贝初始化
    3 vector<T> v2(v1);          //默认初始化
    4 vector<T> v3(n, val);      //v3含有n个val初始值
    5 vector<T> v4(n);           //v4包含了n个重复执行了初始化的对象
    6 vector<T> v5= {a, b, c, ...};//v5包含了初始值个数的原色
    7 vector<T> v5 {a, b, c, ...};//等价于上面
    vector<string> v1{"hello", "world", "!!!"};//列表初始化
    vector<string> v2("hello", "world", "!!!");//错误

    vector对象的添加元素,首先创建一个空对象,然后用push_back方法相其中添加元素。

    1 vector<int> v2;                 //空vector对象
    2 for (int i = 0; i != 100; ++i)  
    3     v2.push_back(i);        //一次把整数值放在v2的尾端
    1 string word;            
    2 vector<string> text;    //空对象
    3 while (cin >> word)     
    4     text.push_back(word);   //把word添加到text后面

    通常的情况下都是先定义一个空的vector对象,然后在使用的时候添加值,而不开始时候直接复制,vector对象支持高效率的添加元素。vector的操作很多与string的操作类似或者相同,如empty、size、[]、!= == > < <= >= 等。可以使用范围for语句处理vector对象的所有元素

    1     vector<int> v{1,2,3,4,5,6,7,8,9};
    2     for (auto &i : v)
    3         i *= i;
    4     for (auto i: v)
    5         cout << i << " ";
    6     cout << endl;
    1 vector<unsigned> scores(11, 0);
    2 unsigned grade;
    3 while (cin >> grade)
    4 {
    5     if (grade <= 100)
    6         ++scores[grade/10];  //很好的体现了C++代码的简洁性
    7 }

    使用下表的时候确认了他的合法性,属于0 到 scores.size() - 1的才是有效的范围。切记不可使用下标的形式添加元素,例如有100个元素,我们使用 v[100]来添加第101个元素,这是错误的,如果要添加元素,应该使用push_back方法。

    4.迭代器是一个对象,它同指针一样,可以通过它来访问容器中的元素,也可以指向其他元素。获取迭代器不是通过取地址符,而是通过容器对象的一些方法返回之,比如begin、end分别返回了指向第一个元素和最后一个元素的下一个为止的迭代器,下一个位置的迭代器意味着并不是指向最后一个位置,这个位置的迭代器没有实际意义,仅仅作为一个标记。如果容器为空,则begin和end返回的是同一个迭代器,都是韦后迭代器。通过 ==  、!=符号来比较迭代器是否相同。

    1 string s("some string");
    2 if (s.begin() != s.end())
    3 {
    4     auto it = s.begin();
    5     *it = toupper(*it);
    6 }

    通过++运算符我们将迭代器从原来的元素移动到下一个元素,因为end返回的迭代器并不实际指向谋个元素,所以不能对它进行递增或者递减以及解引用的操作。

    1 for (auto it = s.begin(); it != s.end() && !isspace(*it); ++it)
    2     *it = toupper(*it);

    如果对象是敞亮,begin和end返回的迭代器类型是 const_iterator,如果不是敞亮,返回的是iterator类型。为了专门的带const_iterator类型,C++11引入了两个函数分别是cbegin和cend泳衣返回const_iterator类型的迭代器。书上特别的声明了:凡是使用了迭代器的循环体,都不要想迭代器所属的容器添加元素。迭代器相关的操作也有 >/</!=/==之类。下面是使用迭代器写的二分搜索。

    1 auto beg = text.begin(), end = text.end();
    2 auto mid = text.begin() + (end - beg)/ 2;
    3 while (mid != end && *mid != sought){
    4     if (sought < *mid)
    5         end = mid;
    6     else
    7         beg = mid + 1;
    8     mid = beg + (end - beg) / 2;
    9 }

    对于数组,使用迭代器的函数begin和end也可以获取指向数组首元素和为元素下以位置的指针。

    5.try语句块和异常处理。throw表达式引发一个异常,throw表达式包含关键字和紧随其后的一个表达式,其中表达式的类型就是抛出的异常类型,throw表达式后面通常紧跟一个分好,从而构成一条表达式语句。

     1 #include <iostream>
     2 #include <stdexcept>
     3 using namespace std;
     4 void fun(int a, int b)
     5 {
     6     if (a == b)
     7         throw runtime_error("A == B");
     8     else
     9         throw runtime_error("A != B");
    10 }
    11 int main()
    12 {
    13     int x = 1, y = 1;
    14     try{
    15         fun(x, y);
    16     }catch(runtime_error err){
    17         cout << err.what();
    18     }
    19     return 0;
    20 }

    这段代码很明白的演示了throw、try、catch的用法,runtime_error在标准函数库头文件stdexcept中定义。当异常抛出时候,首先搜索抛出该异常的函数,如果没有找到匹配的catch字语句,种植该函数,病在调用该函数中继续寻找,如果还是没有找到匹配的catch语句,这个新的函数也将被种植,继续搜索调用它的函数,以此类推,沿着程序的执行路径逐层回退,知道找到适当的类型catch语句为止。如果最终没有找到catch,程序转到名为terminate的标准库函数,该函数的行为与系统有关,一般情况下,执行该函数将导致程序非正常退出。

    栈展开过程沿着乔涛函数的调用莲不断查找,知道找到了与异常匹配的catch为止,或者没有找到而退出。栈展开过程时,局部对象被销毁,栈展开过程中如果退出了谋个块,编译器将负责确保在这个块中创建的对象能被正确的销毁,如果谋个局部对象是类类型,那么会调用析构函数。如果异常发生在构造函数中,则当前的对象可能只构造了一部分,有的成员已经初始化了,而另外一些成员没有初始化,也保证对象能够正常的销毁。如果析构函数也要抛出异常,那么就在析构函数自身内部try、catch和throw,不能留给别人处理,要在析构函数内部处理完成。更多继承类型的异常在复习了继承以后再来讲述。

  • 相关阅读:
    go语言从零学起(三) -- chat实现的思考
    go语言从零学起(二)--list循环删除元素(转载)
    go语言从零学起(一) -- 文档教程篇
    Spring框架事务支持模型的优势
    Thymeleaf
    社保到底是多交好,还是少交好?
    使用静态工厂方法而不是构造器
    EJB、RMI、XMLRPC、Hessian、Thrift 、Protobuf
    MySQL存储过程
    MySQL常用功能语句分类总结
  • 原文地址:https://www.cnblogs.com/changme/p/4035107.html
Copyright © 2011-2022 走看看