《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改变所指示的元素。
  • 箭头运算符->等价于解引用*和成员访问.
  • 使用了迭代器的循环体不能向所属容器(即对象)添加元素,会导致迭代器失效。

迭代器运算

vectorstring支持的额外运算:

  • 迭代器与数字运算:跳过多个元素;
  • 迭代器 - 迭代器:两者的距离,类型为size_t
  • 迭代器关系运算:比较位置(即下标)。

数组

定义和初始化内置数组

  • 数组定义中的数组大小要能在编译时确定(constexpr、在定义语句前已赋确切值的变量、常量)。
  • 字符数组在使用字符串字面值初始化时会多存一位空字符\0,如char[5] st = "12345";是错误的。
  • 数组不允许直接拷贝和赋值。

访问数组元素

  • 数组下标类型size_t

指针和数组

  • 数组会在编译时转换为指针,指向首元素;数组作为auto变量初始值时也会返回指针类型;但使用decltype时正常返回数组类型。
  • 指针也有迭代器的运算,相减类型为ptrdiff_t;也有函数begin end,用法为p = begin(arr)

C风格字符串

  • 传入strlenstrcmp等函数的参数为指针,当它指向不以空字符为结尾的数组时会出现错误(一直顺着内存找空字符)。
  • strlen函数不计空字符。
  • string可以在使用字符串字面值的位置,可以用以空字符为结尾的字符数组代替(加法中只限其中一目,因为数组不可相加)。
  • 使用c_str()来使用string对象给C风格字符串初始化,但由于数组等于指针,所以这之后该string对象不能改变(或者拷贝一份用于初始化)。
  • 不可以用数组直接给数组初始化,但是可以给vector对象初始化vector<T> ivec(begin(arr), end(arr));,参数为首尾地址,也可以截取其中的一段。

多维数组

  • 多维数组就是数组的数组。
  • 嵌套范围for循环时,外层循环的元素应为引用,来避免数组被编译为指针无法遍历。
  • 使用autodecltype关键字来避免混乱的指针数组定义,也可使用类型别名。

练习代码

#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;
}
posted @ 2020-11-21 11:03  1Shen  阅读(102)  评论(0)    收藏  举报