《C++ Primer》笔记(03)
笔记
第 3 章 字符串、向量和数组
命名空间的using声明
头文件一般不使用using,避免引入头文件后产生的重名等。
string类型
定义和初始化string对象
- 使用等号的是拷贝初始化,否则是直接初始化。
string对象上的操作
- 使用IO操作符读
string对象不读入空白,使用getline读整行。 empty判断是否为空;size返回长度,其类型为string::size_type而非int,使用size操作的表达式中尽量不使用int。string对象的大小比较:有成对相异字符则结果为首对相异字符的大小比(字典顺序);无成对相异字符但长度不同,则长的大。- 字符串相加=拼接,字面值(如
"HELLO"和"WORLD")可以与string对象相加,但字面值不能和字面值相加(考虑左结合后,加号两侧必须有一个是string对象)。
处理string对象中的字符
- cctype头文件中定义了一组函数处理字符。
- 范围for语句:
for(变量: 对象),可以遍历对象中的值;想要改变值则要将循环变量定义为引用。 - 使用下标访问、修改
string对象中的值前要判断位置上是否有值。 &&运算符仅在左值为真才会检查右值,故使用下标的条件判断尽量不放在左边(避免越界)。- 将下标类型定为
string::size_type,同时保证下标比size()小即可保证其合法性。
vector类型
- 引用不是对象,故不存在包含引用的
vector。
定义和初始化vector对象
- 圆括号
()构造对象,花括号{}列表初始化;当花括号内的值不能用于列表初始化时(如类型不符),等价于圆括号:vector<string> v1 = {10, "hi"}``v1被构造为有10个值为"hi"的元素的vector对象。
向vector对象中添加元素
- 当
vector对象的元素值不同时,定义对象不要设置大小(有别于数组)。 - 不能使用范围for循环添加元素(范围for循环不应改变遍历序列的大小)。
其他vector操作
基本和string相同。
- 不能通过下标添加元素(空
vector不包含元素)。
迭代器
使用迭代器
和指针有很多相通。
- 使用
begin``end``cbegin``cend指向头个元素/最后一个元素的下一个元素,当对象为空时头尾指向同一个。 - 类似于指针,
*iter返回所指元素的引用,使用前判断是否为空;++iter和--iter改变所指示的元素。 - 箭头运算符
->等价于解引用*和成员访问.。 - 使用了迭代器的循环体不能向所属容器(即对象)添加元素,会导致迭代器失效。
迭代器运算
vector和string支持的额外运算:
- 迭代器与数字运算:跳过多个元素;
- 迭代器 - 迭代器:两者的距离,类型为
size_t; - 迭代器关系运算:比较位置(即下标)。
数组
定义和初始化内置数组
- 数组定义中的数组大小要能在编译时确定(
constexpr、在定义语句前已赋确切值的变量、常量)。 - 字符数组在使用字符串字面值初始化时会多存一位空字符
\0,如char[5] st = "12345";是错误的。 - 数组不允许直接拷贝和赋值。
访问数组元素
- 数组下标类型
size_t
指针和数组
- 数组会在编译时转换为指针,指向首元素;数组作为
auto变量初始值时也会返回指针类型;但使用decltype时正常返回数组类型。 - 指针也有迭代器的运算,相减类型为
ptrdiff_t;也有函数beginend,用法为p = begin(arr)。
C风格字符串
- 传入
strlen、strcmp等函数的参数为指针,当它指向不以空字符为结尾的数组时会出现错误(一直顺着内存找空字符)。 strlen函数不计空字符。string可以在使用字符串字面值的位置,可以用以空字符为结尾的字符数组代替(加法中只限其中一目,因为数组不可相加)。- 使用
c_str()来使用string对象给C风格字符串初始化,但由于数组等于指针,所以这之后该string对象不能改变(或者拷贝一份用于初始化)。 - 不可以用数组直接给数组初始化,但是可以给
vector对象初始化vector<T> ivec(begin(arr), end(arr));,参数为首尾地址,也可以截取其中的一段。
多维数组
- 多维数组就是数组的数组。
- 嵌套范围for循环时,外层循环的元素应为引用,来避免数组被编译为指针无法遍历。
- 使用
auto和decltype关键字来避免混乱的指针数组定义,也可使用类型别名。
练习代码
#include <iostream>
#include <string>
#include <cctype>
#include <vector>
using namespace std;
int main()
{
/* 3.2-3.4
string a, b;
getline(cin, a);
getline(cin, b);
string retVal;
// 大小
if (a == b) {
retVal = "Equal.";
}
else {
retVal = (a > b) ? a : b;
}
// 长度
if (a.size() == b.size()) {
retVal = "Equal.";
}
else {
retVal = (a.size() > b.size()) ? a : b;
}
cout << retVal << endl;
*/
/* 3.5
string line,retVal;
getline(cin, line);
retVal = line;
while (getline(cin, line)) {
retVal += " " + line;
}
cout << retVal << endl;
*/
/* 3.6-3.8
string line;
getline(cin, line);
// range
for (char& x : line) {
x = 'X';
}
// while
decltype(line.size()) index = 0;
if (!line.empty()) {
while (index < line.size()) {
line[index] = 'X';
++index;
}
}
// for
decltype(line.size()) index = 0;
for (; index < line.size(); ++index) {
line[index] = 'X';
}
cout << line << endl;
*/
/* 3.9
string s;
cout << s[0] << ";" << endl;
*/
/* 3.10
string line;
getline(cin, line);
string retVal;
for (auto& c : line) {
if (!ispunct(c)) {
retVal += c;
}
}
cout << retVal << endl;
*/
/* 3.14-3.15
vector<string> v1;
string a;
while (cin >> a) {
v1.push_back(a);
}
for (auto v : v1) {
cout << v << " ";
}
cout << endl;
*/
/* 3.16, 3.21
vector<int> v1;// 空
vector<int> v2(10);// 10个0
vector<int> v3(10, 42);// 10个42
vector<int> v4{ 10 };// 1个10
vector<int> v5{ 10,42 };// 2个,10、42
vector<string> v6{ 10 };// 10个空字符
vector<string> v7{ 10,"hi" };// 10个"hi"
unsigned count = 0;
for (auto v : v3) {
cout << v << ";";
++count;
}
cout << count << endl;
count = 0;
if (v3.empty()) {
cout << "Empty";
}
else {
for (auto it = v3.cbegin(); it != v3.cend(); ++it) {
cout << *it << ";";
++count;
}
}
cout << count << endl;
*/
/* 3.17
vector<string> v1;
string words;
while (cin >> words) {
for (auto& c : words) {
c = toupper(c);
}
v1.push_back(words);
}
for (auto v : v1) {
cout << v << endl;
}
*/
/* 3.19
vector<int> v1(10, 42);
vector<int> v2{ 42,42,42,42,42,42,42,42,42,42 };
vector<int> v3(10);
for (auto& v : v3) {
v = 42;
}
vector<int> v4;
for (int i = 1; i <= 10; ++i) {
v4.push_back(42);
}
*/
/* 3.20
int a;
vector<int> v1;
while (cin >> a) {
v1.push_back(a);
}
decltype(v1.size()) i;
for (i = 1; i < v1.size(); ++i) {
cout << v1[i - 1] + v1[i] << ";";
}
cout << endl;
decltype(v1.size()) count;
count = (v1.size() % 2 == 0) ? (v1.size() / 2) : (v1.size() / 2 + 1);
for (i = 0; i < count; ++i) {
if (i != v1.size() - 1 - i) {
cout << v1[i] + v1[v1.size() - 1 - i] << ";";
}
else {
cout << v1[i] << "*;";
}
}
cout << endl;
*/
/* 3.22
vector<string> text;
string words;
while (cin >> words) {
for (auto it = words.begin(); it != words.end(); ++it) {
*it = toupper(*it);
}
text.push_back(words);
}
for (auto it = text.cbegin(); it != text.cend() && !it->empty(); ++it) {
cout << *it << endl;
}
*/
/* 3.23
vector<int> v1{ 1,2,3,4,5,6,7,8,9,0 };
for (auto it = v1.begin(); it != v1.end(); ++it) {
(*it) *= 2;
cout << *it << ";";
}
cout << v1.cbegin() - v1.cend() << endl;
*/
/* 3.24
int num;
vector<int> v1;
while (cin >> num) {
v1.push_back(num);
}
if (v1.empty()) {
cout << "Empty" << endl;
}
else {
auto it1 = v1.cbegin();
auto it2 = it1 + 1;
for (; it2 != v1.cend(); ++it2) {
cout << (*it1) + (*it2) << ";";
it1 = it2;
}
cout << endl;
auto it3 = v1.cbegin();
auto it4 = v1.cend() - 1;
for (; it3 <= it4; ++it3) {
if (it3 == it4) {
cout << *it3 << "*;";
}
else {
cout << (*it3) + (*it4) << ";";
--it4;
}
}
cout << endl;
}
*/
/* 3.25
vector<unsigned> scores(11, 0);
unsigned grade;
auto it = scores.begin();
while (cin >> grade) {
if (grade <= 100) {
++(*(it + grade / 10));
}
}
for (auto v : scores) {
cout << v << ";";
}
cout << endl;
*/
/* 3,27
int ia[4 * 5 - 1];
unsigned buf_size = 1024;
int ib[buf_size];
char st[10] = "1234567890";
*/
/*
int arr[10]{ 1,2,3,4,5,6,7,8,9,0 };
int* p[10];// 数组p,存放int*
int(*pp)[10] = &arr;// 指针pp,指向arr,等于 int* pp = arr 等于 int* pp = &arr[0]
cout << pp << endl;
cout << (*pp)[0] << endl;
int(&r)[10] = arr;// 引用r,引用arr
cout << r << endl;
cout << r[0] << endl;
int* (&r2)[10] = p;// 引用r2,引用p;p为大小为10,存放int*的数组
*/
/* 3.31-3.32
int arr[10];
for (int i = 0; i < 10; ++i) {
arr[i] = i;
}
int arr2[10];
for (int i = 0; i < 10; i++) {
arr2[i] = arr[i];
}
vector<int> v1;
for (int i = 0; i < 10; i++) {
v1.push_back(i);
}
vector<int> v2;
v2 = v1;
for (auto v : v2) {
cout << v << " ";
}
*/
/* 3.35
int a[10]{ 1,2,3,4,5,6,7,8,9,10 };
int* pb = begin(a);
int* pe = end(a);
for (; pb != pe; ++pb) {
*pb = 0;
}
for (auto v : a) {
cout << v << " ";
}
*/
/* 3.36
int a[10]{ 1,2,3,4,5,6,7,8,9,10 };
int b[9]{ 1,2,3,4,5,6,7,8,9 };
int* pa = begin(a);
int* pb = begin(b);
for (; pa != end(a) && pb != end(b);) {
if (*pa != *pb) {
cout << "No." << endl;
break;
}
++pa;
++pb;
}
if (pa == end(a) && pb == end(b)) {
cout << "Yes." << endl;
}
else {
cout << "No." << endl;
}
vector<int> c{ 1,2,3,4,5,6,7,8,9,0 };
vector<int> d{ 1,2,3,4,5,6,7,8,9,0 };
auto it1 = c.cbegin();
auto it2 = d.cbegin();
for (; it1 != c.cend() && it2 != d.cend();) {
if (*it1 != *it2) {
cout << "No." << endl;
break;
}
++it1;
++it2;
}
if (it1 == c.cend() && it2 == d.cend()) {
cout << "Yes." << endl;
}
else {
cout << "No." << endl;
}
*/
/* 3.37
const char c[] = { 'h','e','l','l','o' };
const char* cp = c;
while (*cp) {
cout << *cp << endl;
++cp;
}
*/
/*
string s{ "hello" };
const char* str = s.c_str();
cout << *str << " " << *(str + 1) << " " << endl;
s = "Hi";
cout << *str << " " << *(str + 1) << " " << endl;
*/
/* 3.41-3.42
int arr[10]{ 0,1,2,3,4,5,6,7,8,9 };
vector<int> ivec(begin(arr), end(arr));
for (auto v : ivec) {
cout << v << " ";
}
cout << endl;
int arr2[10];
int* p = arr2;
for (auto v : ivec) {
*p = v;
++p;
}
for (p = arr2; p != end(arr2); ++p) {
cout << *p << " ";
}
cout << endl;
*/
return 0;
}
浙公网安备 33010602011771号