3.1
加入using namespace std、或者使用using std::cin, using std::cout, using std::cerr
3.2
int main()
{
//getline接受两个参数:输入流和string对象,每次读入一整行
string s;
while (getline(cin, s))
{
cout << s << endl;
}
//使用cin读取遇到空格停止
string s1;
while (cin >> s1)
{
cout << s1 << endl;
}
}
3.3
在执行读取操作时string类的输入运算符会自动忽略开头的空白后开始读取,并在遇到下一个空白字符时停止,
getline函数从给定的输入流中读取字符直到遇到换行符\n为止(换行符也读取进来),然后把所读的内容存入到string对象中去(存的过程不包含换行符)。因此,string对象遇到换行符停止,且得到的string对象不包含换行符,在换行符出现前的空白字符均正常读取。
3.4
判断字符串大小:
string s, s1;
cin >> s >> s1;
if (s1 >= s)
cout << s1;
else
cout << s;
判断字符串等长:
string s, s1;
cin >> s >> s1;
if (s1.size() == s.size())
cout << "the length of two strings is equal.";
else if (s1.size() >= s.size())
cout << s1;
else
cout << s;
3.5
连接成大字符串:
string s, s1;
while (cin >> s) {
s1 += s;
}
cout << s1;
用空格分割:
string s, s1;
while (cin >> s) {
s1 += s + ' ';
}
cout << s1;
3.6
string s;
while (cin >> s) {
for (auto &c : s) //传引用!保证可以修改字符串中的值,而不是拷贝出来赋值
c = 'X';
}
cout << s << endl;
3.7
没有变化,字符串的每一位中存放的为字符(char)类型
3.8
while循环:
string s;
cin >> s;
int len = s.size();
while (((--len) >= 0)) {
s[len] = 'X';
}
cout << s << endl;
for循环:
string s;
cin >> s;
int len = s.size();
for (int i = 0; i != len; ++i)
s[i] = 'X';
cout << s << endl;
for循环可读性好些
3.9
不合法,s为空字符串,使用下标访问空string会引发不可预知的错误。
3.10
string s, s1;
cin >> s;
for (auto c : s) {
if (!(ispunct(c)))
s1 += c;
}
cout << s1 <<endl;
3.11
合法,c的类型为char,因为auto会忽略顶层const。
3.12
(a) 正确,创建一个vector,该vector的元素是int型的vector对象
(b) 错误,ivec和svec对象类型不同,svec的元素是string对象,ivec的元素是int型的vector对象
(c) 正确,创建一个vector,svec的元素是string对象,并对其初始化,svec含有10个元素,每个的值都是"null"
3.13
(a) v1是一个空vector,不含任何元素;
(b) v2是一个含有10个元素的vector,每个元素的值被默认初始化为0
(c) v3是一个含有10个元素的vector,每个元素的值为42
(d) v4是一个含有1个元素的vector,该元素值为10
(e) v5是一个含有2个元素的vector,元素值分别为10,42
(f) v6是一个含有10个元素的vector,v6的元素是string对象,值为null
(g) v7是一个含有10个元素的vector,v6的元素是string对象,每个元素的值为"hi"
tips:v7的花括号中提供的元素值不能作为元素的初始值,在确认无法执行列表初始化后,编译器会尝试用默认值初始化vector对象。
(g) vector<string> v7{10,"hi"}; -> 无法列表初始化,等价于 <=> vector<string> v7(10,"hi");
3.14
int n;
vector<int> ivec;
while (cin >> n) {
ivec.push_back(n);
}
3.15
string s;3.
vector<string> svec;
while (cin >> s) {
svec.push_back(s);
}
3.16
vector<int> v1;
vector<int> v2(10);
vector<int> v3(10, 42);
vector<int> v4{ 10 };
vector<int> v5{ 10,42 };
vector<string> v6{ 10 };
vector<string> v7{ 10,"hi" };
cout << "v1" << endl;
for (auto c : v1)
cout << c << endl;
cout << "v2" << endl;
for (auto c : v2)
cout << c << endl;
cout << "v3" << endl;
for (auto c : v3)
cout << c << endl;
cout << "v4" << endl;
for (auto c : v4)
cout << c << endl;
cout << "v5" << endl;
for (auto c : v5)
cout << c << endl;
cout << "v6" << endl;
for (auto c : v6)
cout << c << endl;
cout << "v7" << endl;
for (auto c : v7)
cout << c << endl;
3.17
string s;
vector<string> svec;
while (cin >> s) {
for (auto &c : s) { //注意传引用
c = toupper(c); //将改为大写的char赋值给原char
}
svec.push_back(s);
}
for (int i = 0; i != svec.size(); ++i)
cout << svec[i] << endl;
3.18
不合法,因为ivec为空vector,vector的下标只能用于访问已存在的元素,且不能使用下标形式添加元素,只能使用push_back添加
改为:
vector<int> ivec;
ivec.push_back(42);
3.19
vector<int> ivec(10,42);
vector<int> ivec{42,42,42,42,42,42,42,42,42,42};
vector<int> ivec;
for(int i = 0; i < 10; ++i)
ivec.push_back(42);
使用圆括号形式初始化固定大小且元素值相同的vector最方便。
3.20
//输出相邻整数
int n;
vector<int> ivec;
while (cin >> n) {
ivec.push_back(n);
}
for (int i = 1; i != ivec.size(); ++i)
cout << ivec[i - 1] + ivec[i] << " ";
//输出首尾元素和
int n;
vector<int> ivec;
while (cin >> n) {
ivec.push_back(n);
}
int len = ivec.size();
for (int i = 0; i != (len / 2) + 1; ++i)
cout << ivec[i] + ivec[len - i - 1] << " ";//下标千万不要越界
3.21
// 使用!=进行for循环的判断,在标准库提供的所有容器均有效,
// 养成使用迭代器和!=的习惯,就不用太在意用的到底是哪种容器类型
vector<int> v1;
vector<int> v2(10);
vector<int> v3(10, 42);
vector<int> v4{ 10 };
vector<int> v5{ 10,42 };
vector<string> v6{ 10 };
vector<string> v7{ 10,"hi" };
cout << "v1" << endl;
for (auto it = v1.begin(); it != v1.end(); ++it)
cout << *it << endl;
cout << "v2" << endl;
for (auto it = v2.begin(); it != v2.end(); ++it)
cout << *it << endl;
cout << "v3" << endl;
for (auto it = v3.begin(); it != v3.end(); ++it)
cout << *it << endl;
cout << "v4" << endl;
for (auto it = v4.begin(); it != v4.end(); ++it)
cout << *it << endl;
cout << "v5" << endl;
for (auto it = v5.begin(); it != v5.end(); ++it)
cout << *it << endl;
cout << "v6" << endl;
for (auto it = v6.begin(); it != v6.end(); ++it)
cout << *it << endl;
cout << "v7" << endl;
for (auto it = v7.begin(); it != v7.end(); ++it)
cout << *it << endl;
3.22
vector<string> text;
string str;
while (cin >> str) {
text.push_back(str);
}
for (auto it = text.begin(); it != text.end() && !it->empty(); ++it) {
for (auto &c : *it)
c = toupper(c);
cout << *it << endl;
}
3.23
vector<int> ivec;
int n;
int num = 10;
while (cin >> n && num)
{
ivec.push_back(n);
num--;
}
for (auto it = ivec.begin(); it != ivec.end(); ++it) {
*it *= 2;
cout << *it << " ";
}
3.24
// 输出相邻整数和
vector<int> ivec;
int n;
while(cin>>n)
ivec.push_back(n);
for (auto it = ivec.begin() + 1; it != ivec.end(); ++it) {
cout << *it + *(it-1) << " ";
}
// 输出首尾相加和
// 学会尾部迭代器的使用
vector<int> ivec;
int n;
while(cin>>n)
ivec.push_back(n);
auto beg = ivec.begin();
auto end = ivec.end() - 1;
for (; beg <= end; ++beg, --end) {
cout << *beg + *end << " ";
}
3.25
vector<int> ivec(11);
int n;
while (cin >> n) {
n /= 10;
++ivec[n];
}
for (auto it = ivec.begin(); it != ivec.end(); ++it )
cout << *it << " ";
3.26
迭代器不支持两个迭代器相加的运算,但支持迭代器加上一个整数的运算
(end - beg) / 2 两个迭代器相减返回difference_type,是带符号整型数,可以与迭代器相加。
3.27
(a) 非法,buf_size为非常量表达式
(b) 合法
(c) 若text_size()为常量表达式(constexpr)时,在编译时确定具体指并替换,则正确;否则错误
(d) 非法,溢出,字符数组利用字符串字面值进行初始化时'\0'会包含
3.28
sa和ia位于定义于任何函数体之外,sa为空字符串;ia数组内每个值均初始化为0。
sa2和ia2在函数体内部,srting类规定没有指定初值则声称一个空串;ia2不被初始化,其中的值未定义。
综上,sa和sa2初始化为空串;ia数组内每个值均为0,ia2中值未定义。
3.29
数组没有vector灵活,数组的大小确定不变,不能随意向数组内增加元素。
3.30
int ia[10]中存放ia[0]~ia[9]的值,for循环中访问了ia[10],导致下标越界。
3.31
int a[10];
for(int i = 0; i < 10; ++i)
a[i] = i;
3.32
//数组不允许直接拷贝
int b[10];
for(int i = 0; i < 10; ++i)
b[i] = a[i];
vector<int> vi;
for (int i = 0; i < 10; ++i)
vi.push_back(a[i])
3.33
不初始化scores的话,其内部的值是未定义的,无法实现利用下标统计人数段的功能。
3.34
两个指针相减的结果是它们之间的距离,p2 - p1为类型为ptrdiff_t,值为0的数。p1加上这个数指针不变。
上面程序的功能是p1经过运算后指向p2所指向的元素
3.35
int a[10];
for (int i = 0; i < 10; ++i)
a[i] = i;
int *beg = &a[0];
int *end = &a[10];
for (auto it = beg; it != end; ++it) {
*it = 0;
cout << *it << " ";
}
3.36
//判断数组是否相等
int arr1[]{ 0,1,2,3,4 };
int arr2[]{ 0,1,2,3,6 };
auto *beg1 = begin(arr1);
auto *last1 = end(arr1);
auto *beg2 = begin(arr2);
auto *last2 = end(arr2);
auto n1 = *last1 - *beg1;
auto n2 = *last2 - *beg2;
decltype(n1) acount = 0;
if (n1 == n2) {
for (; beg1 != last1, beg2 != last2; ++beg1, ++beg2); {
if (beg1 != beg2) {
cout << "The two array have same size, but they are not equal." << endl;
}
if (beg1 == beg2) {
++acount;
}
}
if (acount == n1)
cout << "The two array are equal." << endl;
}
else
cout << "The two array are not equal." << endl;
//判断vector是否相等
vector<int> v1{ 0,1,2,3,4 };
vector<int> v2{ 0,1,2,4,3 };
int vcount = 0;
if (v1.size() == v2.size()) {
for (auto i = 0; i != v1.size(); ++i) {
if (v1[i] != v2[i]) {
cout << "The two vector have same size, but they are not equal." << endl; break;
}
else
++vcount;
}
if (vcount == v1.size())
cout << "The two vector are equal." << endl;
}
else
cout << "The two vector are not equal." << endl;
3.37
const char ca[] = {'h', 'e', 'l', 'l', 'o'};
const char *cp = ca;
while(*cp){
cout << *cp <<endl;
++cp;
}
程序输出会打印一些非法字符,ca为一个c风格的字符串,必须以'\0'结束,
正确写法为const char ca[] = {'h', 'e', 'l', 'l', 'o', '\0'};
这样会依次输出字符串每一位(除\0结束符),即输出 h e l l o
3.38
指针表示地址值,两个地址相加没有实际意义
3.39
//比较两个string对象
string s1 = "abcde";
string s2 = "abded";
if (s1 > s2)
cout << "s1 is bigger than s2." << endl;
else if (s1 < s2)
cout << "s1 is smaller than s2." << endl;
else
cout << "s1 and s2 are equal." << endl;
//比较两个C风格字符串
const char ca1[] = "abcde";
const char ca2[] = "abced";
if (strcmp(ca1, ca2) > 0)
cout << "ca1 is bigger than ca2." << endl;
else if (strcmp(ca1, ca2) < 0)
cout << "ca1 is smaller than ca2." << endl;
else
cout << "ca1 and ca2 are equal." << endl;
3.40
//注意要给出被操作数组的具体大小
char ca1[100] = "abcde";
const char ca2[] = "feagr";
char ca3[100] = "";
strcat_s(ca1, ca2);
strcpy_s(ca3, ca1);
cout << ca3 << endl;
3.41
int arr[]{1, 2, 3, 4, 5};
vector<int> vi(begin(arr), end(arr));
3.42
//使用begin和end函数得到数组首指针和尾后指针
vector<int> vi{ 1,2,3,4,5 };
int arr[5];
int *beg = begin(arr);
int *last = end(arr);
for (auto i : vi) {
*beg = i;
++beg;
}
3.43
int ia[3][4]{ {0,1,2,3},
{4,5,6,7},
{8,9,10,11} };
//version 1
for (int (&row)[4] : ia) {
for (int col : row) {
cout << col << " ";
}
cout << endl;
}
//version 2
for (int i = 0; i != 3; ++i) {
for (int j = 0; j != 4; ++j) {
cout << ia[i][j] << " ";
}
cout << endl;
}
//version 3
for (int (*p)[4] = ia; p != ia + 3; ++p) {
for (int *q = *p; q != *p + 4; ++q) {
cout << *q << " ";
}
cout << endl;
}
3.44
int ia[3][4]{ {0,1,2,3},
{4,5,6,7},
{8,9,10,11} };
//version 1
using elem1_1 = int[4];
using elem1_2 = int;
for (elem1_1 &row : ia) {
for (elem1_2 col : row) {
cout << col << " ";
}
cout << endl;
}
//version 2
using elem2 = int;
for (elem2 i = 0; i != 3; ++i) {
for (elem2 j = 0; j != 4; ++j) {
cout << ia[i][j] << " ";
}
cout << endl;
}
//version 3
using elem3_1 = int(*)[4];
using elem3_2 = int*;
for (elem3_1 p = ia; p != ia + 3; ++p) {
for (elem3_2 q = *p; q != *p + 4; ++q) {
cout << *q << " ";
}
cout << endl;
}
3.45
int ia[3][4]{ {0,1,2,3},
{4,5,6,7},
{8,9,10,11} };
//version 1 最外层循环必须是引用,因为不加引用 auto会推断成int*指针
型
for (auto &row : ia) {
for (auto col : row) {
cout << col << " ";
}
cout << endl;
}
//version 2
for (auto i = 0; i != 3; ++i) {
for (auto j = 0; j != 4; ++j) {
cout << ia[i][j] << " ";
}
cout << endl;
}
//version 3
for (auto p = ia; p != ia + 3; ++p) {
for (auto q = *p; q != *p + 4; ++q) {
cout << *q << " ";
}
cout << endl;
}