前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【笔记】《C++Primer》—— 第3章

【笔记】《C++Primer》—— 第3章

作者头像
ZifengHuang
发布2020-07-29 15:55:31
8990
发布2020-07-29 15:55:31
举报
文章被收录于专栏:未竟东方白未竟东方白

第三章是讲字符串,向量和数组等容器及其遍历。其中字符串和向量都是C++的STL的类,用好的话会比结尾的数组方便很多。C11的很多特性都让原本难以编写的C++变得方便许多,我越来越喜欢C++了。这篇同样会稍长一些,这次试了很多代码。

3.1

  1. 命名空间之前都只是简单的使用using namespace spacename;的方式来使用,但是实际上可以使用using namespace::name;的格式来单独引入几个想要的命名空间声明。这样子虽然每个名称都要独立声明,但是用起来更加自由。下图是后面的代码可能会用到的名称。
  1. 一个小编程规范,不要在头文件中使用using,因为头文件会被拷贝到引用的文件中,可能导致这个using与其他名称冲突。
  2. 用等于号初始化的对象叫拷贝初始化,用括号初始化的叫直接初始化,很多时候直接初始化更加好用。两者都会产生一个新的对象。
  3. C++风格的头文件是没有.h的,有些C的头文件被移植到了C++中(指代码风格,内容没有改变),也会失去其.h并在文件名前加上c以示区别。例如:ctype.h->cctype

3.2

  1. C++标准库中有个很实用的类:string,在string头文件中,这是C++设计用来替代C风格的字符串char*的。
  2. 用了很多次了也比较熟悉,没怎么注意过的点有:(1)可以用大于号小于号来比较,是按照字典排序比较的,a>A。(2)string对象从标准输入中读入时,会自动忽略头尾的空白符。(3)使用getline可以读到有空白符的字符串,以换行符结尾,每次读一行,但是这个换行符会被舍去。(4)直接构造的string也不会忽略空白。(5)string的构造函数的参数可以是(num,char),从而得到重复了num次的char字符串。
  1. empty()可以返回一个string是否为空,size()返回字符的数量。其中需要注意size返回的其实是size_type格式的,是一个机器无关的足以放下任何string的无符号整形数,所以不要轻易使用int来替代。
  2. 两个string可以使用+或者append()函数进行连接,要注意+号两边至少有一个需要是string,要小心和char*混淆。
  3. append()的效率要比+稍好一些,不过它们的效率都很高。不用执意用char*来代替string,它们的效率差距远没有那么大,而string却能带来很多很多便利。
  4. 前面提到的cctype可以非常方便地处理字符,下面是一个简单的字符串识别及处理。
  1. 这里可以看到我遍历字符串使用的是一种比较特殊的for,这是C11增加的range-for,括号中冒号前的是从后面的序列中得到的一个对象,这种写法在很多现代语言中都被支持了。这么写会自动进行遍历,得到的对象同样可以使用引用来修改原对象的值,配合auto这个新特性用好的话可以让代码简便非常多。
  2. string一样可以使用下标运算符来索引内容,接收的参数其实也是size_type,所以最好使用无符号数来索引。
  3. string前面说到效率与char*接近,因为string也是连续内存,一样支持随机访问。

3.3

  1. 字符串有string来替代,相似的,C++创造了vector(向量)来替代C风格的数组。这个替代相对来说没有那么必要,但是还是很有用。vector的特点是可以非常方便地在结尾增加长度,且同样有效率很高的遍历方法,可以理解为变长数组(内部也是连续内存,不是链表实现),可以作为任何需要有序列的对象的容器使用。
  2. vector的内容必须是对象,不可以是引用这种没有实体的东西。
  3. vector自然也可以是另一个嵌套的vector,也就是可以做到类似多维数组的效果。
  4. 类似于string,也可以用(num,val)来初始化多个重复元素构成的向量。
  5. 对标数组,vector有极其类似与数组的操作,初始化等操作也十分相近,也是同样当初始化指定的内容数量不够时其他内容会进行默认初始化。
  6. 和数组有一点理念上的不同:vector并不需要提前决定大小,vector提供了往末尾增加元素的push_back()函数,效率非常高,相比之下初始指定大小只有在选择初始化为同一个值时才有优势。(也就是不要初始化大小后再用循环来逐个赋值,而是要选择不断的push_back)。
  7. vector自然也有类似于string的各种操作,不表。
  8. 和matlab中的矩阵不同,vector不能给不存在的元素赋值,这会导致错误而不是扩大vector。
  9. 相类似的,为了防止越界建议使用range-for遍历。

3.4

  1. 说了两个最常用的容器,C++又给了一个用来替代指针的类:迭代器(iterator)。迭代器用起来比java的迭代器要更顺手,因为其操作思路是和C的指针一致的,但是又要比指针安全方便很多。
  2. 首先迭代器的类型比较复杂,一般是容器名<元素类型>::iterator,还有常量迭代器,表示内容是只读的,类型是容器名<元素类型>::const_iterator。由于写起来比较麻烦,大多数时候使用auto来表示会更舒服。
  3. 获得一个容器的迭代器可以使用支持的容器自带的函数begin()和end(),想要得到常量迭代器的话就使用cbegin()和cend()。其中end得到的是指向容器最后一个元素还要后面的空元素的迭代器,一般用于循环中判断遍历结束。
  4. 迭代器的使用方法很简单,几乎是指针一样。星号* 解引用符得到内容,箭头运算符也可以用,累加递减符,加号减号,迭代器之间的做差等等都是支持的。
  5. 要谨记,千万不要在使用迭代器的时候改变容器的结构(增减元素),这会使迭代器失效。
  6. 迭代器做差得到的返回值是迭代器的距离,类型difference_type,是个有符号数。

3.5

  1. 最后还是要说到最原始的数组和指针,其实没什么好讲的,突出一点就是C++有封装好的类可以用,所以不是很必要了。
  2. 数组的索引类型是size_t,也是无符号数。
  3. 复杂的数组和指针式最好的阅读方式是从内向外阅读。
  4. 当使用数组来给auto推断时,得到的类型是指针,这也是很自然的233
  5. C11为了方便数组和指针的使用,引入了std::begin(),std::end()函数,可以给数组使用并返回类似上面迭代器的指针。
  6. 两个指针相减得到地址差的类型是ptrdiff_t的类型,也是有符号的。可以对指针进行地址的加减来移动指针。
  7. 指针的各种运算也是允许给void空指针使用的。
  8. 指针可以使用下标符来取值,做法类似于数组下标。有一点平时不怎么用到的是下标是可以为负数的,于是可以取到指针前面的数据。这点和vector,string之类的不一样。
  9. 对于C风格的字符串char*,可以通过引用cstring(也就是C++版本的string.h)来简单处理。常用的函数是strlen()求长度,strcmp()进行比较,strcat进行拼接,strcpy进行复制。这些函数都要仔细计算好赋值的数组的长度,不然引发严重错误。
  10. string类作为char*的对接,也提供了转换的接口:c_str()函数可以把string转得一个const char*,而char*也可以用于初始化string。要注意c_str()得到的char*实际上是string里的指针,所以不允许修改。
  11. vector作为数组的对接也有接口,当vector的构造函数参数可以是数组的头尾指针,vector会依此来赋值。

3.6

  1. 多维数组也就是数组的数组。
  2. 可以使用多层的花括号来初始化,未初始化的元素遵循之前的规律。
  3. 配合C11的auto和range-for可以使得对多维数组的遍历变得异常方便。要注意的是用auto遍历时要对数组使用引用来避免数组自动转为指针。
  4. 使用类型别名来给多维数组起别名也可以简化代码防止出现层层嵌套的解引用符*。
  5. 如果遇到了复杂的多维数组,最好的阅读方式还是从内向外阅读。
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-04-17,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 未竟东方白 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
容器服务
腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档