在C++11基础学习系列一中介绍一些c++11一些基础知识。基础学习系列二进一步讲解C++11.
string不可思议,在C++中是字符串类库。如何初始化类的对象是由类本身决定的。类可以定义很多种初始化对象的方式。比如:
#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)。
1.getline读取一行字符串处理函数,包含输入时的空白符。 2.empty判断字符串是否为空 3.size字符串对象的长度,size返回的是string::size_type,它也是无符号类型的值并且是与机器无关的特性。在c++11标准里面,允许编译器通过auto或者decltype来推断变量的类型。由于是无符号类型,切记与有符号混合使用,会带来一些非确定结果。
#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;
}
两个字符串相加大致分为两种情况,并且差异很大:
对于第一种情况完全支持,没有什么特别的。第二种情况需要注意一些,C++标准库允许字面值把字符串字面值转化为string对象。字符串和string对象进行相加时,至少保证+两侧运算对象至少有一个是string对象。
#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,用于遍历的。
#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;
}
如果只处理一部分字符或者说通过索引来处理,比如:
#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是容器的一种类型,用于存放对象的集合。它在数据结构上的表示为单链表,也是C++的类模板。模板可以看做是编译器生成类或者函数编写的一份说明,编译器根据模板创建类或函数的过程(实例化)。vector是模板而非类型。 初始化vector对象有很多种方式: 1.默认初始化 2.拷贝初始化 3.直接初始化 3.列表初始化
我们以此来看一下:
#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,比如:
#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初始化重点:
#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。
#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都指向同一个位置。
#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;
}
常用的操作:
在C++11版本中增加了两个迭代器类型分别为cbein和cend返回的const_iterator.,而begin和end返回的iterator类型。最主要的区别是:begin和end返回的是即可读又可写的元素类型,而cbegin和cend返回的是只读的元素类型,cbegin和cend是非常有用的,它可以避免你修改元素的风险。
#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》