C++ Primer ch3笔记
ch3
1,标准库类型string
头文件:
#include <string>
定义和初始化string对象:
string str = "fuck"; string str2(10,'f');
直接初始化和拷贝初始化:
使用等号初始化一个变量,实际上执行的是拷贝初始化。
如果不使用等号,则执行的是直接初始化。
string的操作:
s.empty(); // 返回字符串s是否为空 s.size(); // 返回s中字符的个数 getline(is,s); // 从is中读取一行赋给s,返回is
用getline读取一整行:
string s; getline(cin, s); cout << s << endl; /*消除空格,一行一行地读入。*/
加法操作:
加法运算符两侧的运算对象至少有一个是string:
string s0 = "fuck" + "you"; // 错误:两个运算对象都不是string string s1 = "you"; string s2 = "fuck " + s1 + "!"; // 正确:每个加法运算符都有一个运算对象是string
string::size_type类型:
s.size()的返回值是string::size_type类型。
由于size函数返回的是一个无符号整形数,因此切记,如果在表达式中混用了带符号数和无符号数将可能产生意想不到的结果。
例如,假设n是一个具有负值的int类型数,则表达式s.szie()<n的判断结果几乎肯定是true。这是因为负值n会自动转换一个比较大的无符号值。
cctype头文件中的函数:
1 isalnum() // 返回是否为字母或数字 2 isalpha() // 返回是否为字母 3 iscntrl() // 返回是否为控制字符 4 isdigit() // 返回是否为整数 5 isgraph() // 返回是否为“不是空格但可打印” 6 usage: 7 string s; 8 getline(cin, s); 9 for (string::size_type i = 0; i < s.size(); i++) { 10 if (isgraph(s[i])) 11 cout << s[i]; 12 } 13 islower() // 返回是否是小写字母 14 isupper() // 返回是否是大写字母 15 isprint() // 返回是否可以打印 16 isspace() // 返回是否是空白 17 isxdigit() // 返回是否是十六进制数字 18 tolower()/toupper() // 如果大写输出小写/如果小写输出大写
处理每个字符:
string s = "fuck you"; for (auto c : s) { cout << c << endl; }
使用for语句改变字符串中的字符:
string s = "I wanna fuck you!"; for (auto &c : s) // c是一个引用,用此方法来改变字符串中的值 c = toupper(c); cout << s << endl; // 输出"I WANNA FUCK YOU!"
2,标准库类型vector
vector表示对象的集合,常被称为容器(container)
定义和初始化vector对象:
vector<string> v1{"fuck", "shit", "asshole"}; vector<int> v2(10, -1); // 10个int类型的元素,每个都被初始化为-1 /*如果用的是圆括号,可以说提供的值是用来构造vector对象*/ /*如果是花括号,可以表述成我们想列表初始化*/ vector<int> v3(10); // 10个元素,每个都初始化为0 vector<int> v4{ 10 }; // 1个元素,该元素值是10 vector<int> v5(10, 1); // 10个元素,每个都初始化为1 vector<int> v6{ 10,1 }; // 2个元素,一个为10,一个为1
往vector尾端添加项:
/*vector成员函数push_back():把一个值当成vector对象的尾元素push到vector对象的尾端*/ vector<int> v; for (int i = 0; i < 100; i++) { v.push_back(i); } string words; vector<string> text; while (cin >> words) { text.push_back(words); }
访问vector对象中的元素或改变它:
vector<int> v; for (int i = 1; i <= 99; i++) { v.push_back(i); } for (auto &i : v) { i *= i; } for (auto i : v) { cout << i << " "; }
vector的size()成员函数,返回值还是size_type:
/*要使用size_type,需首先指定它是由哪种类型定义的*/ vector<int>::size_type; vector::size_type; // 错误
3,迭代器(iterator)
使用迭代器:
auto b = v.begin(); auto e = v.end();// 该迭代器指示的是容器的一个本不存在的“尾后”元素 // 如果容器为空,则begin和end返回的都是尾后迭代器
迭代器的运算符:
*iter; // 解引用iter iter->mem; // 解引用iter并获取该元素的名为mem的成员,等价于(*item).mem
迭代器的使用示例(类似于指针):
/* 将一个字符串每个单词的第一位变成大写 */
string s; getline(cin, s);
s[0] = toupper(s[0]); for (auto it = s.begin(); it != s.end(); it++) { if (isspace(*it)) *(it + 1) = toupper(*(it + 1)); } cout << s << endl;
使用迭代器实现二分搜索:
vector<int> v; int n; cin >> n; while (n--) { int temp; cin >> temp; v.push_back(temp); } int target; cin >> target; auto left = v.begin(), right = v.end(), mid = v.begin() + (right - left) / 2; while (mid != right && *mid != target) { if (target < *mid) right = mid; else left = mid + 1; mid = left + (right - left) / 2; } cout << mid - v.begin() + 1 << endl;