目录

cin和getline
- void test()
- {
- string s;
- while (cin >> s)
- {
- cout << s << endl;
- }
- }
-
- 输入:
- abc de
- 输出:
- abc
- de
- void test()
- {
- string s;
- while (getline(cin, s))
- {
- cout << s << endl;
- }
- }
-
- 输入:
- abc de
- 输出:
- abc de
规则:必须保证=两边至少有一个是string


- void test()
- {
-
- string s("abcd");
- for (auto c : s)
- {
- cout << c << " ";
- }
- }
- 输出: a b c d
- 注,如果for (int c : s),那么输出 97 98 99 100,因为是这样的:
- char c = 'a';
- int temp = c;
- cout << temp;
注:向vector添加元素,不能使用 range for!因为:

但是可以用range for来遍历!
遍历vector的时候,依然必须要保证下标的合法的!!
![]()
()和{}
一般来说,圆括号()表示"构造",花括号{}表示初始化值的列表
对于后者,也有例外:

注意,对于用 range for初始化的理解:
- // 第一种情况
- vector<int> v(10);
- for (auto i : v)
- {
- cout << i << " ";
- v[i] = 42;
- }
- for (auto num : v)
- {
- cout << num << " ";
- }
- cout << endl;
- 最后输出:
- 0 0 0 0 0 0 0 0 0 0
- 42 0 0 0 0 0 0 0 0 0
-
- // 另一种情况
- vector<int> v2(10);
- for (auto &i : v2)
- {
- i = 42;
- }
- for (auto num : v2)
- {
- cout << num << " ";
- }
- cout << endl;
-
- 最后输出:
- 42 42 42 42 42 42 42 42 42 42
range for的原理是,每次迭代i都会被初始化为v中下一个元素的值;
第3-7行,因为v每个元素都是0,因此i每次都是0,因此v[i] = 42永远只有第0个元素被赋值为42,其余不变;
第19-22行,因为i是个引用,遍历整个v2,因此每次i = 42都会把每个元素赋值为42;
C在创建vector的时候,顺便指定其容量是最好的;
C++却相反,事先设定大小反而性能可能更差。


- void test()
- {
- vector<int >v;
- v[10] = 10; // 直接崩溃!因为v是空的,无法用下标访问
-
- vector<int >v1(11, 0); // 初始化v1为11个0
- v[10] = 10; // 正确, 因为现在v1有11个元素,因此可以访问
-
- }


技巧:平时其实无须注意迭代器的类型,用auto即可,因此:
- vector<int>::iterator iter = v1.begin(); // 完全不用写前面的那一长串!
- 直接用:
- auto iter = v1.begin();
*iter 解引用,获得迭代器所指元素的引用(*iter).age 解引用,获得迭代器所指对象的age成员iter->age 和上面的等价++/-- iter 移动迭代器因此,用->会方便点,就不需要每次都加*了(->把解引用和成员访问两个操作结合在一起)
注1:C++迭代器可以往回退,但Python里的迭代器是不行的,例如:
- void test()
- {
- vector<int> v1;
- for (int i = 0; i < 10; ++i)
- {
- v1.push_back(i);
- }
-
- vector<int>::iterator iter = v1.begin() + 3;
- cout << *iter << endl; // 输出3
-
- --iter; // 回退
- cout << *iter; // 输出2
- }
注2:C++11没有定义迭代器的加法,因为是没有意义的。而可以用两个迭代器相减,得到迭代器之间的距离。
- void test()
- {
- vector<int>v;
- for (int i = 0; i < 10; ++i)
- {
- v.push_back(i);
- }
-
- auto begin = v.begin();
- auto end = v.end();
- cout << *(begin + end); // 错误
- cout << end - begin; // 输出10, 指的是end到begin之间的距离(元素个数)
- }
注3:不能对end进行增减或解引用,因为end返回的迭代器不实际指示某个元素。
对于C++来说,推荐使用迭代器去遍历容器!


- void test()
- {
- vector<int> v1;
- for (int i = 0; i < 10; ++i)
- {
- v1.push_back(i);
- }
-
- vector<int>::const_iterator citer = v1.begin() + 4;
- *citer = 2; // 错误,因为是const,不可以修改
- cout << *citer;
-
- // 或者用C++11的新函数 cbegin cend
- for (auto citer = v1.cbegin(); citer != v1.cend(); ++citer)
- {
- ...
- }
- }
任何一种可能改变vector容量的操作,例如push_back,都会使vector对象的迭代器失效!
![]()
关于int等基本数据类型和string型的初始化区别
- void test()
- {
- int a[10];
- int b[10] = {};
- cout << a[2]; // 输出错乱!因为函数内不会默认初始化int型数组
- cout << b[2]; // 输出0, 因为上面{}表面已经初始化为全0了
-
- string s[10];
- cout << s[2]; // 输出空串, 因为string特性, 不论函数内还是外, 都会默认初始化为空串!
- }
-
- int c[10]; // 函数外定义, 那么默认初始化全0
-
- int main()
- {
- test();
- cout << c[3]; // 输出0
- return 0;
- }
推荐使用range for这个遍历方法!


对于auto:

对于decltype:该是什么就是什么,不会发生隐式转换

- void test()
- {
- int a[10] = {};
- for (int i = 0; i < 10; ++i)
- {
- a[i] = i;
- }
- int* begin = a; // 指针也是迭代器
- int* end = &a[10]; // 尾后指针
-
- for (; begin != end; ++begin) // 迭代
- {
- cout << *begin << " ";
- }
- }
注意,第9行,a[10]的索引只到9,但作为尾后指针,可以取到最后一个元素的下一个元素,因此索引是10;这个不存在的元素唯一的作用就是提供地址用于初始化end。
但是!这样很容易出错,因为C++11引入了标准库函数begin()和end()
begin和end
注:上面不能用begin和end来作为变量名称,不然会报错:
int *begin = begin(ia); int *end= end(ia); --> 错误
练习3-2
- #include
- #define _CRT_SECURE_NO_DEPRECATE
- using namespace std;
- #include
-
- void test()
- {
- // 一次读入一行
- string s;
- //while (getline(cin, s))
- //{
- // cout << s;
- //}
-
- // 一次读入一个词
- string s1;
- while (cin >> s1)
- {
- cout << s1;
- }
-
- }
-
-
- int main()
- {
- test();
- return 0;
- }
练习3-4
- #include
- #define _CRT_SECURE_NO_DEPRECATE
- using namespace std;
- #include
-
- void test()
- {
- cout << "比大小:" << endl;
- string s1, s2;
- cin >> s1 >> s2;
- if (s1 == s2)
- {
- cout << s1;
- }
- else
- {
- string s3 = (s1 > s2) ? s1 : s2;
- cout << s3 << endl;
- }
-
- cout << "是否等长:" << endl;
- cin >> s1 >> s2;
- if (s1.size() == s2.size())
- {
- cout << s1;
- }
- else
- {
- string s4 = (s1.size() > s2.size()) ? s1 : s2;
- cout << s4 << endl;
- }
-
-
- }
-
-
- int main()
- {
- test();
- return 0;
- }
练习3-5
- #include
- #define _CRT_SECURE_NO_DEPRECATE
- using namespace std;
- #include
-
- void test()
- {
- string s1, s2;
- while (cin >> s1)
- {
- if (s1 == "EOF")
- {
- break;
- }
- s2 += s1;
-
- }
- cout << s2 << endl;
-
- }
-
-
- int main()
- {
- test();
- return 0;
- }
练习3-6
- #include
- #define _CRT_SECURE_NO_DEPRECATE
- using namespace std;
- #include
-
- void test()
- {
- string s;
- getline(cin, s); // 注,空格也是字符,也会被X替代
- for (auto &ch : s)
- {
- ch = 'X';
- }
- cout << s;
-
- }
-
-
- int main()
- {
- test();
- return 0;
- }
练习3-7
- #include
- #define _CRT_SECURE_NO_DEPRECATE
- using namespace std;
- #include
-
- void test()
- {
- string s;
- getline(cin, s); // 注,空格也是字符,也会被X替代
- for (char& ch : s)
- {
- ch = 'X';
- }
- cout << s;
-
- }
-
-
- int main()
- {
- test();
- return 0;
- }
练习3-8
- #include
- #define _CRT_SECURE_NO_DEPRECATE
- using namespace std;
- #include
-
- void test()
- {
- string s;
- getline(cin, s);
-
- decltype(s.size()) index = 0;
- while (true)
- {
- if (index == s.size())
- {
- break;
- }
- char& r = s[index];
- r = 'X';
-
- ++index;
- }
-
- cout << s;
-
- }
-
- void test1()
- {
- string s;
- getline(cin, s);
-
- for (decltype(s.size()) index = 0; index != s.size(); ++index)
- {
- char& r = s[index];
- r = 'X';
- }
-
- cout << s;
-
- }
-
- /// 上面的写复杂了,忘记了还可以下标访问
-
- void test2()
- {
- string s;
- getline(cin, s);
- for (decltype(s.size()) index = 0; index != s.size(); ++index)
- {
- s[index] = 'X';
- }
-
- cout << s;
- }
-
-
- int main()
- {
- test2();
- return 0;
- }
练习3-10
- #include
- #define _CRT_SECURE_NO_DEPRECATE
- using namespace std;
- #include
-
- void test()
- {
- string s1, s2;
- getline(cin, s1);
-
- for (auto c : s1)
- {
- if (ispunct(c))
- {
- continue;
- }
- s2 += c;
- }
-
- cout << s2;
-
- }
-
-
- int main()
- {
- test();
- return 0;
- }
练习3-14
- #include
- #define _CRT_SECURE_NO_DEPRECATE
- using namespace std;
- #include
- #include
-
- void test()
- {
- vector<int> v;
-
- int num = 0;
- while (cin >> num)
- {
- v.push_back(num);
- }
-
- //for (vector
::iterator begin = v.begin(); begin != v.end(); ++begin) - //{
- // cout << *begin << " ";
- //}
- for (auto num : v)
- {
- cout << num << " ";
- }
-
- }
-
-
- int main()
- {
- test();
- return 0;
- }
练习3-15
- #include
- #define _CRT_SECURE_NO_DEPRECATE
- using namespace std;
- #include
- #include
-
- void test()
- {
- vector
v; - string s;
- while (cin >> s)
- {
- if (s == "EOF")
- {
- break;
- }
- v.push_back(s);
- }
-
- for (auto c : v)
- {
- cout << c << " ";
- }
-
- }
-
-
- int main()
- {
- test();
- return 0;
- }
练习3-17
- #include
- #define _CRT_SECURE_NO_DEPRECATE
- using namespace std;
- #include
- #include
-
- void test()
- {
- vector
v; - string s1, s2;
- while (cin >> s1)
- {
- if (s1 == "EOF")
- {
- break;
- }
-
- for (auto& c : s1)
- {
- c = toupper(c);
- }
-
- v.push_back(s1);
- }
-
-
- for (auto str : v)
- {
- cout << str << endl;
- }
-
-
- }
-
-
- int main()
- {
- test();
- return 0;
- }
练习3-19
- #include
- #define _CRT_SECURE_NO_DEPRECATE
- using namespace std;
- #include
- #include
-
- void test()
- {
- // 方法一
- vector<int> v(10, 42);
- for (auto i : v)
- {
- cout << i << " ";
- }
- cout << endl;
-
- // 方法二
- vector<int> v1;
- for (int i = 0; i < 10; ++i)
- {
- v1.push_back(42);
- }
-
- for (auto i : v)
- {
- cout << i << " ";
- }
- cout << endl;
-
- // 方法三 --> 我没想到
- vector<int> v2(10);
- for (auto &i : v2)
- {
- i = 42;
- }
-
- cout << endl;
- for (auto i : v2)
- {
- cout << i << " ";
- }
- cout << endl;
-
- }
-
-
- int main()
- {
- test();
- return 0;
- }
练习3-23
- #include
- #define _CRT_SECURE_NO_DEPRECATE
- using namespace std;
- #include
- #include
-
- void test()
- {
- vector<int>v;
- for (int i = 0; i < 10; ++i)
- {
- v.push_back(i);
- }
-
- for (auto begin = v.begin(); begin != v.end(); ++begin)
- {
- *begin *= 2;
- }
-
- for (auto begin = v.begin(); begin != v.end(); ++begin)
- {
- cout << *begin << " ";
- }
- }
-
-
- int main()
- {
- test();
- return 0;
- }
练习3-24
- #include
- #define _CRT_SECURE_NO_DEPRECATE
- using namespace std;
- #include
- #include
-
- void test()
- {
- vector<int>v;
- for (int i = 0; i < 10; ++i)
- {
- v.push_back(i);
- }
-
- for (auto begin = v.begin(); begin != v.end(); ++begin)
- {
- cout << *begin << " ";
- }
-
- cout << endl;
-
- // 相邻两数之和
- for (auto begin = v.begin(); begin != v.end()-1; ++begin)
- {
- cout << *begin+*(begin+1) << " ";
- }
-
- cout << endl;
-
- // 首位元素之和
- //int tag = 1;
- //for (auto begin = v.begin(); begin != v.end(); ++begin)
- //{
- // if (tag == v.size() / 2)
- // {
- // break;
- // }
- // cout << *(begin) + *(v.size()-tag-1)
-
- //}
-
- }
-
-
- int main()
- {
- test();
- return 0;
- }
练习3-25
- #include
- #define _CRT_SECURE_NO_DEPRECATE
- using namespace std;
- #include
- #include
-
- void test()
- {
- vector<int> v(4);
- int score;
- auto begin = v.begin();
- while (cin >> score)
- {
- if (score <= 30)
- {
- ++* (begin + score / 10);
- }
- }
-
- for (auto begin = v.begin(); begin != v.end(); ++begin)
- {
- cout << *begin << " ";
- }
-
-
- }
-
- int main()
- {
- test();
- return 0;
- }
-
练习3-31
- #include
- #define _CRT_SECURE_NO_DEPRECATE
- using namespace std;
- #include
- #include
-
- void test()
- {
- int a[10] = {};
- int tag = 0;
-
- for (auto& i : a)
- {
- i = tag;
- ++tag;
- }
-
- for (auto& i : a)
- {
- cout << i << " ";
- }
- }
-
-
- int main()
- {
- test();
- return 0;
- }
练习3-32
- #include
- #define _CRT_SECURE_NO_DEPRECATE
- using namespace std;
- #include
- #include
-
- void test()
- {
- int a[10] = {};
- int tag = 0;
-
- // 拷贝给另一个数组
- for (auto& i : a)
- {
- i = tag;
- ++tag;
- }
-
- int b[10] = {};
- tag = 0;
- for (auto i : a)
- {
- b[tag] = i;
- ++tag;
- }
-
- // 用vector重新实现
- vector<int>v;
- for (auto& i : a)
- {
- v.push_back(i);
- }
-
- // 打印输出
- for (auto& i : v)
- {
- cout << i << " ";
- }
- }
-
-
- int main()
- {
- test();
- return 0;
- }
练习3-36
- #include
- #define _CRT_SECURE_NO_DEPRECATE
- using namespace std;
- #include
- #include
-
- void test()
- {
- // 比较数组元素是否相等
- int a[] = { 1,2,3,4,5,6 };
- int b[] = { 1,2,3,4,5,6 };
-
- int numA = 0;
- int numB = 0;
- for (auto i : a)
- {
- ++numA;
- }
- for (auto i : b)
- {
- ++numB;
- }
-
- if (numA != numB)
- {
- cout << "不相等";
- }
- else
- {
- for (int i = 0; i < numA; ++i)
- {
- if (a[i] != b[i])
- {
- cout << "不相等";
- }
- }
- cout << "相等";
- }
-
- }
-
-
- int main()
- {
- test();
- return 0;
- }
练习3-39
- #include
- #define _CRT_SECURE_NO_DEPRECATE
- using namespace std;
- #include
- #include
-
- void test()
- {
- string s1("wind1");
- string s2("wind1");
-
- if (s1.size() != s2.size())
- {
- cout << "不相等";
- }
- else
- {
- int tag = 0;
- for (int i = 0; i < s1.size(); ++i)
- {
- if (s1[i] != s2[i])
- {
- cout << "不相等";
- tag = 0;
- break;
- }
- tag = 1;
-
- }
- if (tag)
- {
- cout << "相等";
- }
-
-
- }
-
- cout << endl;
-
- // 方法二
- if (s1 == s2)
- {
- cout << "相等";
- }
- else
- {
- cout << "不相等";
- }
- }
-
-
- int main()
- {
- test();
- return 0;
- }
练习3-40和3-41
- #include
- #define _CRT_SECURE_NO_DEPRECATE
- using namespace std;
- #include
- #include
-
- void test()
- {
- // 整形数组初始化vector对象
- const int size = 10;
- int a[size] = { 1,2,3,4 };
- vector<int>v(begin(a), end(a));
-
- for (auto i : v)
- {
- cout << i << endl;
- }
- cout << endl;
-
- // vector对象拷贝给整型数组
- int b[size];
- auto it = cbegin(a);
- for (auto& val : b)
- {
- val = *it;
- ++it;
- }
-
- for (auto i : b)
- {
- cout << i << endl;
- }
-
- }
-
-
-
- int main()
- {
- test();
-
- return 0;
- }
-