1. 良好的编程习惯,头文件里面尽量不要放using namespace,避免引入头文件的源码命名冲突;
2. 引入string的推荐方法,最小的using
#include <string>
using std::string;
// 而不是 using namespace std;
3.std::string 区别于C语言中的字符串,末尾并不包含'\0'结束字符
4.如果使用等号初始化一个变量,实际上执行的是拷贝初始化,编译器将等号右侧的数值拷贝到新创建的对象中去。与之相反,如果不使用等号,则执行的是直接初始化。
5. string 从数据流(cin)读取数据的时候,自动会忽略开头的空格,使用空格进行自动切分,如下所示
string s;
cin >> s;
cout << s <<endl;
如果输入的是“ hello world! ”,那么输出是“hello”,如果想要输出所有的,包括其中的空格,你应该使用 std::getline
函数而不是 cin,如下所示
std::getline(std::cin,s);
读取所有的字符串,直到遇到换行符,注意这个换行符并不会在string内。
6.string::size()函数返回值类型为string::size_type(),这是一个与机器无关的通用的无符号整形的标准类型,设计之初就是考虑兼容性。C++11的标准auto,decltype可以自动识别。
不要试图用size_type的数与一个负数做比较,由于size_type默认为无符号的整数,作比较的负数会被强制转换为无符号的整形,也就是取模,会得到很大的整数,得到的结果与预期不符
string s = "123";
auto length = s.size();
int length_thres = -1;
// 理论期望肯定是 length > length_thres为true;
// 实际上,由于强制类型转换,length_thres会被转换为很大的正数,所以下面的判断不成立
if(length > length_thres){
};
7. C++兼容了C的头文件,例如“name.h”,不过为了风格兼容,会对名字进行修正,修正为“cname”,这里的c表示的是C语言标准库的头文件。
8. C++标准并不要求标准库检查下标的合法性,一单是用来一个超出范围的下标,就会产生不可预知的结果。
9. C++风格,用指定数量的字符,初始化某一个变量,一般是如下:
// 类型名 变量名(数量 指定字符)
// 5个s
string s(5,'s')
// 10个1
vector<int> v(10,1)
10. 如下所示
vector<int> v1{10,1}
上面这个代码有两种解读方式,第一种,vector存储10,1;第二种,vector存储10个1。但是,在使用列表初始化的时候,优先尽可能将花括号内的值当成元素初始值来处理。只有在无法执行列表初始化时,才会考虑其他初始化方式。如下所示
// 初始化10个空字符
vector<string> v4{10}
// 初始化10个 "hi"字符串
vector<string> v5{10, "hi"}
// 初始化 10 ,hi
vector<string> v6{"10","hi"}
11. vector 在创建的时候就制定容量大小,有利于性能提升。
12 在使用范围for循环时,不应改变所遍历序列的大小,即以下行为是严禁的
// 这是禁止的
vector<int> v1(5,1);
for(auto i:v1){
v1.push_back(1);
}
修改容器的影响(引用自chatgpt)
当在循环体内向
vector
添加元素时,会影响vector
的容量。如果vector
的容量不足以容纳新添加的元素,整个vector
的内存可能会被重新分配以增加容量。这种重新分配会导致以下问题:
迭代器失效:所有指向
vector
的迭代器、指针和引用在内存重新分配后都将变为无效。范围for
循环底层使用的迭代器也会受此影响,导致迭代器不再指向正确的元素,甚至指向一个已经不存在的内存位置。访问违规:使用无效迭代器继续访问元素可能导致访问违规错误,这是一种典型的未定义行为,可能导致程序崩溃或数据损坏。
13.如果要使用size_type,需首先指定它是由哪种类型定义的。vector对象的类型总是包含着元素的类型,如下所示
vector<int>::size_type //正确的
vector::size_type //错误的
14 vector之间可以使用运算符比较大小,比较方法与字符串类似