初始化string对象的6种方式
string s1; //默认空串 sting s2(s1); string s2 = s1; string s3("value"); //直接初始化 string s3 = "value"; //拷贝初始化 string s4(n,'c'); //由连续n个字符c组成的串
在读写string对象时,string对象会自动忽略开头的空白(空格、换行符、制表符)直到遇见下一处空白为止
getline函数以换行符为结尾(换行符也被读进来了),然后将所读内容存入string对象中(不存换行符),如果一开始就是个换行符,那么所得结果就是个空串
string line; //读取一整行并输出直至文件末尾 while(getline(cin, line)) cout << line << endl;
如果一条表达式里已经有了size()函数就不要再用int,避免int 与unsigned可能带来的问题
在使用string加法时,必须确保每个加法运算符(+)两侧的运算对象至少有一个为string,字符串字面值与string类型是不同的类型
- 实例化:编译器根据模板创建类或函数的过程
关于列表初始值还是元素数量:
(1)如果是用圆括号(),提供的值是用来构造对象vector的,如果是用花括号{ },则是列表初始值vector<int> v1(10); // v1有10个元素,每个元素值为0 vector<int> v2{10}; // v2有1个元素,该元素值为10 vector<int> v3(10,1); // v3有10个元素,每个元素值为1 vector<int> v3{10,1}; // v3有2个元素,分别为10,1
(2)如果初始化时使用了花括号但是提供的值却不能用来列表初始化,就要考虑用该值来构造对象,下面表达式中只有v5为列表初始化,若花括号中的值无法执行列表初始化,编译器会尝试用其值来构造vector对象
vector<string> v5{"hi"}; // 列表初始化,v5有1个元素 vector<string> v6("hi"); // 错误,不能用字符串来构建对象 vector<string> v7{10}; /* 本来应列表初始化,但传入的值为一个数字, 则编译器会将其构造为有10个默认元素的vector */ vector<int> v3{10,"hi"}; // 同上,相当于 vector<int> v3(10,"hi");
- 所有标准库容器都定义了==和 != ,但大多数没有定义 < 运算符,所以在循环判断条件中,对于迭代器应使用 !=
- 不能在范围for循环中向vector对象添加元素;任何一种可能改变vector容量的操作可能会使迭代器失效
- 两个指向同一容器的迭代器相减得到的值为距离,其类型为difference_type的带符号型整数
默认情况下,类型修饰符从右向左依次绑定 ,所以int *ptr[10]为指针数组
int *(&array)[10] = ptr; //array是数组的引用,该数组含有10个指针
- 在很多用到数组名字的地方,编译器会自动将其替换成一个指向该数组首元素的指针;当使用数组时真正使用的是指向数组首元素的指针;两个指向同一数数组元素的指针相减得到的结果是两指针间的距离,类型为ptrdiff_t
不能用string对象直接初始化指向字符的指针,可以使用 c_str 成员函数进行转换完成该功能
string s; const char *str = s.c_str();
要使用范围for语句处理多维数组,除了最内层循环外,其他所有循环控制变量都应该是引用类型。这是因为在很多使用数组名字的地方,编译器会自动将其替换成一个指向该数组首元素的指针。将外层循环的控制变量声明为引用类型是为了避免数组被自动转成指针。
/* 该程序无法通过编译,因为row不是引用类型,编译器初始化row时会自动 将这些数组形式的元素转化成指向该数组内首元素的指针这样得到的row类型 就是int*,显然内层的循环就不合法了 ,编译器将试图在一个int*内遍历 */ int ia[3][4] = { {0,1,2,3}, {4,5,6,7}, {8,9,10,11} }; for(auto row : ia) for(auto col : row) cout << col << endl;