[C++ primer] 第三章习题答案
3.1
使用using namespace std;即可
3.2
一次读入一行:使用getline
#include <iostream>
#include <string>
using namespace std;
int main()
{
string line;
while (getline(cin, line))
{
cout << line << endl;
}
}
一次读入一个词:使用cin
#include <iostream>
#include <string>
using namespace std;
int main()
{
string word;
while (cin >> word)
{
cout << word << endl;
}
}
3.3
使用string类的输入运算符时,string对象会自动忽略开头的空白(空格符、换行符、制表符等)并从第一个真正的字符开始读起,直到遇到下一个空白为止。
使用getline函数时,函数从给定的输入流中读入内容,直到遇到换行符为止(换行符也读进来了),然后将所读内容存入到string对象中去(不存换行符)
3.4
//没有判断相等的情况,默认str1和str2不等长,不相等
#include <iostream>
#include <string>
using namespace std;
int main()
{
string str1, str2;
cin >> str1 >> str2;
if(str1 != str2)
{
cout << (str1 > str2 ? str1 : str2) << endl;
}
cout << (str1.size() > str2.size() ? str1.size() : str2.size()) << endl;
}
3.5
#include <iostream>
#include <string>
using namespace std;
int main()
{
string str;
string res1 = "";
string res2 = "";
while (getline(cin, str))
{
res1 += str;
res2 += str + " ";
cout << "res1 = " << res1 << endl;
cout << "res2 = " << res2 << endl;
}
}
3.6
#include <iostream>
#include <string>
using namespace std;
int main()
{
string str;
cin >> str;
for (char &i : str)
{
i = 'X';
}
cout << str << endl;
}
3.8
已知循环次数,用for循环更加简洁
3.9
不合法,string类型的下标必须大于等于0而小于等于.size()
使用超出此范围的下标将引发不可预知的结果,使用下标访问空string也会引发不可预知的结果
3.10
#include <iostream>
#include <string>
#include <cctype>
using namespace std;
int main()
{
string str;
string res = "";
cin >> str;
for (char i : str)
{
if (!ispunct(i))
{
res += i;
}
}
cout << res << endl;
}
3.11
不合法,设置一个auto类型的引用时,初始值中的顶层const依旧保留,c的类型为const string&。 因此,如果, 在for循环中要改变c的值,则语句不合法。
3.12
(a)正确
(b)不正确,类型不一致
(c)正确
3.13
(a)空vector
(b)十个元素,均为0
(c)十个元素,均为42
(d)一个元素,10
(e)两个元素, 10, 42
(f)十个默认初始化的元素
(g)十个元素,均为hi
3.16
#include <iostream>
#include <string>
#include <cctype>
#include <vector>
using namespace std;
int main()
{
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的元素
vector<int>::iterator iter;
for (iter = v3.begin(); iter != v3.end(); iter++)
{
cout << *iter << endl;
}
}
3.17
c = toupper(c);
3.18
不合法,ivec为空,不包含任何元素,不能通过下标去访问元素。应改为 ivec.push_back(42);
3.19
vector<int> temp1(10, 42);
vector<int> temp2(temp1);
vector<int> temp3 = temp1;
vector<int> temp4 = {42, 42, 42, 42, 42, 42, 42, 42, 42, 42}
3.24
#include <iostream>
#include <string>
#include <cctype>
#include <vector>
using namespace std;
int main()
{
vector<int> text;
for (int i = 0; i < 10; i++)
{
text.push_back(i);
}
vector<int>::iterator iter;
for (iter = text.begin(); iter != text.end() - 1; iter++)
{
cout << *iter + *(iter + 1) << endl;
}
vector<int>::iterator iter2;
for (iter = text.begin(), iter2 = text.end(); iter != iter2; iter++)
{
iter2--;
cout << *iter + *iter2 << endl;
}
}
3.26
因为end指向最后一个元素的下一个位置。
3.27
(a)非法,buf_size不是常量
(b)合法
(c)非法,函数返回值不是常量
(d)非法,没有空间可以存储空字符
以下解释来自:https://blog.csdn.net/misayaaaaa/article/details/53349998
理解复杂数组的声明(难点)
不可以将数组的内容拷贝给其他数组当作初始值,也不能用数组为其他数组赋值。
int a[3] = {0,1,3};
int a1[] = a; //错误
a2 = a; //错误
复杂数组声明的理解
int *a[10]; //a数组含有10个指针整形
int &a[10]; //错误,不存在引用的数组
int (*a)[10]; //a是一个指针,指向一个含有10个整数的数组
int (&a)[10]; //a是一个引用,引用一个含有10个整数的数组
int *(&a)[10]; // a是数组的引用,数组含有十个指针
理解方法:从数组的名字开始,由内向外顺序读取,先左后右,左边为类型。
3.28
string不是内置的数据类型,int是内置的数据类型
sa为空数组
ia中有10个0
sa2为空数组
ia2中有10个整数,由于在函数体内,内容未知
3.29
长度不可变,一旦确定长度,不可以再更改长度
3.30
下标应该是0-array_size - 1
3.31
#include <iostream>
#include <string>
#include <cctype>
#include <vector>
using namespace std;
int main()
{
int a[10] = { 0,1,2,3,4,5,6,7,8,9 };
int b[10];
for (int i = 0; i < 10; i++)
{
b[i] = a[i];
cout << b[i] << endl;
}
vector<int> c;
for (int i = 0; i < 10; i++)
{
c.push_back(i);
}
vector<int> d = c;
}
3.33
不初始化scores,则其中内容未知,可能为空,也可能有别的数据。(因为scores在函数体内)
3.34
p1 = p2 ,因为p1和p2指向同一地址,所以p1地址不变。
当p1和p2指向不同的数组,则语句非法。
3.35
#include <iostream>
#include <string>
#include <cctype>
#include <vector>
using namespace std;
int main()
{
int a[10] = { 0,1,2,3,4,5,6,7,8,9 };
int *p = a;
for (int i = 0; i < 10; i++)
{
//*p++ = 0;
p[i] = 0;//两种表示方法都可以,p[i] = *(p + i)
cout << a[i] << endl;
}
}
3.36
比较数组相等,先比较数组的大小(sizeof(A)),再比较数组的每个元素。
比较vector相等,可以直接比较
3.37
C风格字符串以空字符结束。则传入此类函数的指针必须指向以空字符作为结束的数组。
将ca的每个元素都输出出来。但由于s初始化时,并未加‘\0’,因此其长度未知,while循环会一直继续知道遇见’\0’。输出“hello+未知字符”。
3.38
两个指针相加,相当于两个地址值相加.因此毫无意义
3.39
C++风格的字符串比较是字符串本身的比较
C风格的字符串比较是字符串首地址的比较
#include <iostream>
#include <string>
#include <cctype>
#include <vector>
using namespace std;
int main()
{
string str1 = "hello world";
string str2 = "hello world";
if (str1 == str2) {
cout << str1 << " is equal with " << str2 << endl;
}
else {
cout << str1 << " is not equal with " << str2 << endl;
}
char s1[] = { 'c', '+', '+', '\0' };
char s2[] = { 'c', '+', '+', '\0' };
int result = strcmp(s1, s2);
if (0 == result) {
cout << "s1 is equal with s2!" << endl;
}
else {
cout << "s1 is not equal with s2!" << endl;
}
}
3.40
#include <iostream>
#include <string>
#include <cctype>
#include <vector>
using namespace std;
int main()
{
char str1[20] = "hello world";
char str2[20] = "hello world";
char str3[50];
strcpy(str3, str1);
strcat(str3, " ");
strcpy(str3, str2);
}
3.41
#include <iostream>
#include <string>
#include <cctype>
#include <vector>
using namespace std;
int main()
{
int a[10] = { 0,1,2,3,4,5,6,7,8,9 };
//vector<int> temp(begin(a), end(a));
vector<int> temp(a, a + 10);
for (int i = 0; i < temp.size(); i++)
{
cout << temp[i] << endl;
}
}
3.42
逐个拷贝
3.43
#include <iostream>
#include <string>
#include <cctype>
#include <vector>
using namespace std;
int main()
{
int ia[3][4] = {
{0, 1, 2, 3},
{4, 5, 6, 7},
{8, 9, 10, 11}
};
//version1
for (int (&row)[4] : ia)
{
for (int col : row)
{
cout << col << endl;
}
}
//version2
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 4; j++)
{
cout << ia[i][j] << endl;
}
}
//version3
for (int (*p)[4] = ia; p != ia + 3; p++)
{
for (int *q = *p; q != *p + 4; q++)
{
cout << *q << endl;
}
}
}