字符串、向量和数组
using
通过using namespace::name;的方式来直接使用命名空间的名称。如cin就是using std::cin;
头文件不应该包含using,避免在引用头文件时对程序的内容进行误判。
string
string定义在std命名空间中。
拷贝初始化:初始化中包含=。
直接初始化:初始化中不包含=。
getline(is,var)
size()返回的类型是string::size_type。且返回值是一个无符号整数。
当进行相加时,加号左右必须有一个为string类型(不是字符串字面值,字面值与string不是同一种类型)(从左到右)。
使用for-range来遍历序列。
for( auto i:序列)来遍历序列,如python中for item in list。
使用auto &i来用引用来改变序列中的值。
当使用&&时,若第一个条件为假,就不再继续判断下去。
vector
模板通过提供的信息来实例化。
引用不是对象,不能作为模板的元素。
在c++11中,无需再写成。
可以通过=或者()来对vector进行复制赋值。vec2(vec1)
对vector进行列表初始化vector<…> name{ele1,ele2,…}
vec(个数,ele(可省略)),当省略时会默认初始化。
()与{}的初始化方式是不同的,当且仅当提供的参数不能用来初始化,会考虑其他初始化的方式。
当且仅当其中的所有元素相同时,初始化的效率优于建立一个空的vector。
范围for语句体内不应改变其所遍历序列的大小。
vector.size()返回的类型是vector
当vector中的元素可比较时,vector之间也是可比较的。
确保下标合法的一种有效手段就是尽可能使用范围for语句。
迭代器
begin()返回指向第一个元素的迭代器
end()返回指向最后一个元素后面一个位置的迭代器(尾后迭代器)
当容器为空,begin()返回的也是尾后迭代器。
由于很多的标准库都不支持<或者下标,因此最好多用≠与迭代器。
当获取begin()或end()时,若是vector元素为常量,则返回常量迭代器,若不是,则普通迭代器。
可以通过cbegin()和cend()来固定获取常量迭代器。
(t).num和t→num*是完全一致的,没有区别。
两个迭代器相减所得的类型是difference_type,是带符号整数。
数组
数组在定义时的大小必须为常量表达式。
不能使用auto来推断。
*p[10] 一个存放指针的数组
&p[10] 不存在
*(p)[10] 一个指向数组的指针
(&p)[10] 一个对数组的引用
数组从内向外看类型。
数组的下标最好使用size_t类型(一种足够大的类型),被定义在cstddef。
**={}与={0}**等价。
当使用auto来推断一个以数组来赋值的数组时,会判断出一个指针,指向首元素。
而decltype就没有这个问题。
虽然对于尾后迭代器不能解引用,但我们仍然可以去获取它的地址。
为了防止误获取地址,可以使用begin(arr)和end(arr)两个标准库函数来获取头与尾后指针。
但这两个指针相减的类型是ptrdiff_t类型,是带符号整数。
当以数组中的某个元素的地址作为指针时,也可以将它当做数组来使用,只不过下标就是从当前位置作加减了。
C风格字符串
以***’\0’***(空字符)作为结尾的字符串。
C风格字符串的函数必须传入C风格字符串。
将string转为C风格字符串,str.c_str(),返回值为一个常量字符指针。
但在使用后最好重新拷贝一份结果。
可以用数组来初始化vector,vec(头指针,尾后指针),可以只是数组的一部分。
多维数组
因为引用也可以引用数组,因此多维数组也可以通过range for来遍历,用auto来写对数组引用的类型。但是除了最内层的循环以外,所有的循环都应该是引用,不然会将其判断为指针而非数组。
虽然可以把多维数组看做一个很长的换行的数组,但是,当我们说它的声明符的时候,是一个指向数组的高维指针,而非指向首元素的一级指针,虽然它们的地址完全相同。当对于这个声明符+1的时候,它并非指向第二个元素,而是指向第二行数组。
当使用begin()或end()时,获取的得到的也并非是指向变量的指针,而是指向数组的指针。