前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >C++11基础学习系列二

C++11基础学习系列二

作者头像
吕海峰
发布2018-04-03 15:18:57
5960
发布2018-04-03 15:18:57
举报
文章被收录于专栏:Brian

概述

在C++11基础学习系列一中介绍一些c++11一些基础知识。基础学习系列二进一步讲解C++11.

string

string不可思议,在C++中是字符串类库。如何初始化类的对象是由类本身决定的。类可以定义很多种初始化对象的方式。比如:

代码语言:javascript
复制
#include <iostream>
#include <string>

int main() {
	//默认初始化,s1是一个空字符串。
    std::string s1;
	//s2是s1的副本
    std::string s2(s1);
	//等价于s3(s1),拷贝初始化。
    std::string s3 = s1;
	//s4是字面值的副本,直接初始化
    std::string s4("value");
	//s5拷贝初始化
    std::string s5 = "value";
	//s6是一个包含有10c的字符串,直接初始化。
    std::string s6(10,'c');
    return 0;
}

1.使用=在初始化对象,实际上执行的是拷贝初始化,编译器把等号右边对象的初始值拷贝到新创建的对象;如果不使用=,则执行的是直接初始化。 2.当初始值只有一个时,拷贝初始化或直接初始化都可以;当多于一个时一般都是采用的直接初始化。比如(s6)。

string常用函数

1.getline读取一行字符串处理函数,包含输入时的空白符。 2.empty判断字符串是否为空 3.size字符串对象的长度,size返回的是string::size_type,它也是无符号类型的值并且是与机器无关的特性。在c++11标准里面,允许编译器通过auto或者decltype来推断变量的类型。由于是无符号类型,切记与有符号混合使用,会带来一些非确定结果。

代码语言:javascript
复制
#include <iostream>
#include <string>


int main() {
    std::string s1;
    while (getline(std::cin,s1)){
        if(!s1.empty()) {
		    auto len = s1.size();
            std::cout << s1<<" the size is "<<len<< std::endl;
        } else{
            std::cout << "the input string is empty"<<std::endl;
        }
    }
    return 0;
}

string对象操作

两个字符串相加大致分为两种情况,并且差异很大:

  • 两个string对象直接相加。
  • 字面值和string对象相加。

对于第一种情况完全支持,没有什么特别的。第二种情况需要注意一些,C++标准库允许字面值把字符串字面值转化为string对象。字符串和string对象进行相加时,至少保证+两侧运算对象至少有一个是string对象。

代码语言:javascript
复制
#include <iostream>
#include <string>

int main() {
    std::string s1="hello",s2="work";
	//没有问题,先进行(s1+",")得到的是一个string对象,然后新的字符串对象再和s2相加。
    std::string s3 = s1+","+s2;
	//也是没有问题的
    std::string s4 = s3+",";
	//错误,字符串字面值不能直接相加。
    std::string s5 = "hello"+",";
	//先进行(s1+",")得到一个新的string对象,string对象在和"hello相加。"
    std::string s6 = s1+","+"hello";
	//错误,字符串字面值无法进行直接相加
    std::string s7 = "hello"+"world"+s1;
    return 0;
}

C++标准库不仅包含C++语言特有的功能外,也兼容C语言的标准库。C语言的标准库形如name.h,C++将这些文件命名为cname。 在处理字符串操作时,不得不介绍range for,用于遍历的。

代码语言:javascript
复制
#include <iostream>
#include <string>

int main() {
    std::string s1="hello";
    for(auto i : s1){
        std::cout<< i <<std::endl;
    }
    std::cout << s1<<std::endl;
    for(auto &c : s1){
        c = toupper(c);
    }
    std::cout << s1<<std::endl;
    return 0;
}

如果只处理一部分字符或者说通过索引来处理,比如:

代码语言:javascript
复制
#include <iostream>
#include <string>

int main() {
    std::string s1("hello world");
    for (decltype(s1.size()) index = 0;index != s1.size() && !isspace(s1[index]);++index){
        s1[index] = toupper(s1[index]);
    }
    std::cout<<s1<<std::endl;
    return 0;
}

vector

vector是容器的一种类型,用于存放对象的集合。它在数据结构上的表示为单链表,也是C++的类模板。模板可以看做是编译器生成类或者函数编写的一份说明,编译器根据模板创建类或函数的过程(实例化)。vector是模板而非类型。 初始化vector对象有很多种方式: 1.默认初始化 2.拷贝初始化 3.直接初始化 3.列表初始化

我们以此来看一下:

代码语言:javascript
复制
#include <iostream>
#include <vector>


int main() {
	//默认初始化,int默认为0
    std::vector<int> test1;
	//直接初始化
    std::vector<int> test2(test1);
	//拷贝初始化
	std::vector<int> test6 = test1;
	//列表初始化
    std::vector<int> test3={1,2,3,4};
	//通过列表里面的元素值,对vector进行列表初始化。
    std::vector<int> test4{2, 3, 4, 5};
    return 0;
}

指定元素数量来初始化vector,比如:

代码语言:javascript
复制
#include <iostream>
#include <vector>
#include <string>

int main() {
	//10个整数元素,每个元素初始化为-1.
    std::vector<int> test(10,-1);
	//10个整数元素,每个元素初始化为0.
    std::vector<int> test1(10);
	//10个字符串元素,每个元素初始化为"hiahi"
    std::vector<std::string> test2(10, "hiahi");
    return 0;
}

vector初始化重点:

  • 如果使用的(),是通过提供的元素数量和值/默认初始值来构造vector。比如:std::vector test(10,-1);std::vector test1(10)。
  • 如果使用的{},可以理解为是通过{}里的值进而通过列表初始化来构造vector对象。比如:std::vector test4{2, 3, 4, 5}。初始化过程会尽可能地把{}里面的值当成是元素初始值的列表来处理。,只是如果无法执行列表初始化时,就会考虑其它的方式进行初始化。
代码语言:javascript
复制
#include <iostream>
#include <vector>
#include <string>

int main() {
	//10个字符串对象,每个元素初始化为hihi.
    std::vector<std::string> test(10,"hihi");
	//只有一个hihi元素初始化vector。
    std::vector<std::string> test1{"hihi"};
	//错误的,无法直接通过字面值常量初始化。
    std::vector<std::string> test2("hihi");
	//10个值为hihi的vector
    std::vector<std::string> test3{10,"hihi"};
	//10个为空的字符串的vector
    std::vector<std::string> test4{10};
    return 0;
}

vector增加元素采用尾部增加,这样的追加元素才是最高效的。值得注意的是不要在for范围里面或者循环里面改变vector的size。

代码语言:javascript
复制

#include <iostream>
#include <vector>
#include <string>

int main() {
    std::vector<std::string> test{"test1","test2","test3"};
    test.push_back("test4");
    for(auto i : test){
        std::cout << i << std::endl;
    }
    return 0;
}
#输出为
test1
test2
test3
test4

迭代器

所有标准的容器类型都可以使用迭代器(string不是容器,但是string支持很多与容器相似的操作包括迭代器。) 迭代器不像指针使用取地址符号,而是采用begin和end方法。begin指向了第一个元素位置,end指向了尾元素的下一个位置,该位置并不存在只是一个标记。如果容器为空,那么begin和end都指向同一个位置。

代码语言:javascript
复制

#include <iostream>
#include <vector>
#include <string>

int main() {
    std::vector<std::string> test{"test1","test2","test3"};
    for(auto start = test.begin();start!=test.end();++start){
        std::cout << *start << std::endl;
    }
    return 0;
}

常用的操作:

  • *iter 返回迭代器iter的引用
  • iter->mem 解引用iter并获取名为mem的成员,等价于(*iter).mem
  • ++iter 指向下一个元素
  • —iter 指向上一个元素
  • iter1==iter2,两个迭代器是否指向同一个元素。

在C++11版本中增加了两个迭代器类型分别为cbein和cend返回的const_iterator.,而begin和end返回的iterator类型。最主要的区别是:begin和end返回的是即可读又可写的元素类型,而cbegin和cend返回的是只读的元素类型,cbegin和cend是非常有用的,它可以避免你修改元素的风险。

代码语言:javascript
复制

#include <iostream>
#include <vector>
#include <string>

int main() {
 const std::vector<std::string> test1{"test1","test2","test3"};
    for(auto start = test1.cbegin();start!=test1.cend() && !start->empty();++start){
        std::cout << *start << std::endl;
    }
	# 获得元素个数
	auto start = test1.cbegin(),end=test1.cend();
	# 值得注意
    std::cout << end-start << std::endl;
    return 0;
}

参考书籍

《C++ Primer》

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2017-05-23,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

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

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

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