c++ Primer 第三章:字符串、向量和数组 练习答案记录
练习题导航
- c++ Primer 第三章:字符串、向量和数组 练习答案记录
- 3.1 命名空间的using声明
- 3.2 标准库类型string
- 3.2.1 定义和初试化string对象
- 3.2.2 string对象上的操作
- 3.2.3 处理string对象中的字符
- 练习3.6 编写一段程序,使用范围for语句将字符串内的所有字符用X代替 法一
- 练习3.6 编写一段程序,使用范围for语句将字符串内的所有字符用X代替 法二
- 练习3.6 编写一段程序,使用范围for语句将字符串内的所有字符用X代替 法三
- 练习3.6 编写一段程序,使用范围for语句将字符串内的所有字符用X代替 法四
- 练习3.7 就上一题如果将循环控制变量的类型设为char将发生什么?先估计一下结果,然后实际编程进行验证
- 练习3.8 分别用while循环和传统的for循环重写第一题的程序,你觉得哪种形式更好呢?为什么?
- 练习3.9 下面的程序有何作用?它合法吗?如果不合法,为什么?
- 练习3.10 编写一段程序,读入一个包含标点符号的字符串,将标点符号去除后输出字符串剩余的部分
- 练习3.11 下面的范围for语句合法吗?如果合法,c的类型是什么?
- 3.3 标准库类型vector
- 3.4 迭代器介绍
- 3.5 数组
- 3.6 多维数组
下面练习程序别忘记开头都加上这一语句
#include<iostream>
3.1 命名空间的using声明
练习3.1(1) 使用恰当的using声明重做1.4.1节(第11页)的练习
using std::cin;
using std::cout;
using std::endl;
int main()
{
int i = 0;
int sum = 0, j = 50;
cout << "请输入所要进入的练习:" << endl;
cin >> i;
switch (i) {
case 1:
cout << "练习1.9 编写程序,使用while循环将50到100的整数相加\n" << endl;
while (j<= 100) {
sum += j;
j++;
}
cout << "50到100的整数相加结果:" << sum << endl;
break;
case 2:
cout << "练习1.10 编写程序,使用递减运算符在循环中按递减顺序打印出10到0之间的整数\n" << endl;
for (int a = 10; a >= 0; a--) {
cout << a << " " << endl;
}
break;
case 3:
cout << "练习1.11 提示用户输入两个整数,打印出这两整数所指定的范围内的所有整数\n" << endl;
cout << "输入两个整数,打印出这两整数所指定的范围内的所有整数:" << endl;
cin >> i >> j;
if (i < j) {
for (i; i <= j; i++) {
cout << i << endl;
}
}
else {
if (i == j) {
cout << "所输入两整数相等,无范围" << endl;
}
else {
for (i; i >= j; i--) {
cout << i << endl;
}
}
}
break;
}
}
练习3.1(1) 使用恰当的using声明重做2.6.2节(第67页)的练习
练习2.41 使用你自己的Sales_data类重写1.5.1节(第20页)、1.5.2节(21页)和1.6节(22页)的练习
using std::cin;
using std::cout;
using std::endl;
using std::string;
struct Sales_data {
string book_name; //图书编号
unsigned book_sales = 0; //图书售出数量
double unit_price = 0; //图书销售单价
double book_revenue = 0; //计算销售收入
};
int main()
{
Sales_data data, data1, data2;
int i = 0, sum = 1;
cout << "请输入所需要进入的练习程序中:" << std::endl;
cin >> i;
switch (i) {
case 1:
cout << "练习1.23 编写程序,读取多条销售记录,并统计每个ISBN(每本书)有几条销售记录" << endl;
if (cin >> data1.book_name) {
if (data1.book_name == "over")
break;
cin >> data1.book_sales >> data1.unit_price;
}
while (cin >> data2.book_name) {
if (data2.book_name == "over") //当输入over的时候,跳出循环
break;
cin >> data2.book_sales >> data2.unit_price;
if (data1.book_name == data2.book_name) { //如果两书名字相同
sum++;
}
else {
cout << data1.book_name << "卖出了:" << sum << "本" << endl;
data1.book_name = data2.book_name;
data1.book_sales = data2.book_sales;
data1.unit_price = data2.unit_price;
sum = 1;
}
}
break;
case 2:
cout << "练习1.24 输入表示多个ISBN的多条销售记录来测试上一个程序,每个ISBN的记录应该聚在一起" << endl;
break;
}
}
3.2 标准库类型string
3.2.1 定义和初试化string对象
3.2.2 string对象上的操作
练习3.2 编写一段程序从标准输入中一次读入一整行,然后修改该程序使其一次读入一个词
#include<string>
using namespace std;
int main()
{
string input;
unsigned int i = 0;
cout << "从标准输入中一次读入一整行按1,一次读入一个词按2" << endl;
cin >> i;
switch (i) {
case 1:
cout << "从标准输入中一次读入一整行:" << endl;
cin.ignore(); //忽略一个回车符号,不然下面语句自动判断回车不运行了
getline(cin, input);
cout << input << endl;
break;
case 2:
cout << "一次读入一个词" << endl;
while (cin >> input) {
if (input == "over")
break;
cout << input << endl;
}
break;
}
}
练习3.4 编写一段程序读入两个字符串,比较其是否相等并输出结果。结果不相等,输出较大的那个字符串。改写上述程序,比较输入的两个字符串是否等长,如果不等长,输出长度较大的那个字符串
#include<string>
using namespace std;
int main()
{
string input1,input2;
unsigned i = 0;
cout << "两个字符串,结果不相等,输出较大的那个字符串按1,比较输入的两个字符串是否等长,如果不等长,输出长度较大的那个字符串按2" << endl;
cin >> i;
switch (i) {
case 1:
cout << "比较两个字符串,结果不相等,输出较大的那个字符串" << endl;
cin.ignore(); //忽略一个回车符号,不然下面语句自动判断回车不运行了
getline(cin, input1);
getline(cin, input2);
if (input1 == input2) {
cout << "两字符串相同" << endl;
}
else {
if (input1 > input2) {
cout <<"第一个字符串比较大:" << input1 << endl;
}
else {
cout <<"第二个字符串比较大:" << input2 << endl;
}
}
break;
case 2:
cout << "比较输入的两个字符串是否等长,如果不等长,输出长度较大的那个字符串" << endl;
cin.ignore(); //忽略一个回车符号,不然下面语句自动判断回车不运行了
getline(cin, input1);
getline(cin, input2);
if (input1.size() == input2.size()) {
cout << "两字符串等长" << endl;
}
else {
if (input1.size() > input2.size()) {
cout << "第一个字符串长:" <<input1<< endl;
}
else {
cout << "第二个字符串长:"<<input2 << endl;
}
}
break;
}
}
练习3.5 编写一段程序从标准输入中读入多个字符串并将它们连接在一起,输出链接成的大字符串。然后修改上述程序,用空格把输入的多个字符串分隔开来
#include<string>
using namespace std;
int main()
{
string input,output;
cout << "请输入字符串,如若结束输入则输入over" << endl;
while (getline(cin,input)) {
if (input == "over")
break;
cout << "请继续输入字符串,如若结束输入则输入over" << endl;
output = output + input;
}
cout << "入多个字符串并将它们连接在一起,输出链接成的大字符串:" << output << endl;
}
3.2.3 处理string对象中的字符
练习3.6 编写一段程序,使用范围for语句将字符串内的所有字符用X代替 法一
#include<string>
using namespace std;
int main()
{
string str = "Hello World!";
const char* a = "X"; //这个是n所返回的类型,所以要这样定义
for (auto& n : str) {
n = *a;
}
cout << str << endl;
}
练习3.6 编写一段程序,使用范围for语句将字符串内的所有字符用X代替 法二
#include<string>
using namespace std;
int main()
{
string str = "Hello World!";
const char* a = "X"; //这个是n所返回的类型,所以要这样定义
for (int i = 0; i <= str.size();i++) {
str[i] = *a;
}
cout << str << endl;
}
练习3.6 编写一段程序,使用范围for语句将字符串内的所有字符用X代替 法三
#include<string>
using namespace std;
int main()
{
string str = "Hello World!";
const char* a = "x"; //这个是n所返回的类型,所以要这样定义
for (int i = 0; i <= str.size();i++) {
str[i] = toupper(*a);
}
cout << str << endl;
}
练习3.6 编写一段程序,使用范围for语句将字符串内的所有字符用X代替 法四
#include<string>
using namespace std;
int main()
{
string str = "Hello World!";
for (int i = 0; i <= str.size();i++) {
str[i] = 'X'; //字符字面值
}
cout << str << endl;
}
练习3.7 就上一题如果将循环控制变量的类型设为char将发生什么?先估计一下结果,然后实际编程进行验证
答案是类型不匹配,字符字面值可以匹配,变成char型就会显示无法给const
char*赋char型,所以3.6中我所用的法一到法三都是为了解决这个问题
练习3.8 分别用while循环和传统的for循环重写第一题的程序,你觉得哪种形式更好呢?为什么?
我认为for循环更好,一般情况所声明的变量不会对其他程序产生影响。
#include<string>
using namespace std;
int main()
{
string str = "Hello World!";
string::size_type n = 0;
while (n<=str.size()) {
str[n] = 'X';
n++;
}
cout << str << endl;
}
练习3.9 下面的程序有何作用?它合法吗?如果不合法,为什么?
合法
#include<string>
using namespace std;
int main()
{
string s;
cout << s[0] << endl;
}
练习3.10 编写一段程序,读入一个包含标点符号的字符串,将标点符号去除后输出字符串剩余的部分
#include<string>
using namespace std;
int main()
{
string str,output;
cout << "读入一个包含标点符号的字符串,将标点符号去除后输出字符串剩余的部分" << endl;
getline(cin, str);
for (auto& n : str) {
if (!ispunct(n)) { //如果不是标点符号则输入
output += n;
}
}
cout << "将标点符号去除后输出字符串剩余的部分为:" << output << endl;
}
练习3.11 下面的范围for语句合法吗?如果合法,c的类型是什么?
合法:对const char的引用,但是不能对c进行改变,如果改变就会像下面一样报错
#include<string>
using namespace std;
int main()
{
const string s = "Keep out!";
for (auto& c : s) {
c = 'X'; //错误:“c”: 不能给常量赋值
}
}
3.3 标准库类型vector
3.3.1 定义和初始化vector对象
练习3.12 下列vector对象的定义有不正确的吗?如果有,请指出来。对于正确的,描述其结果;对于不正确的,说明其错误的原因
#include<string>
#include<vector>
using namespace std;
int main()
{
vector<vector<int>>ivec; //合法:该向量元素是vector对象
//vector<string>svec = ivec; //错误:无法从“std::vector<std::vector<int,std::allocator<int>>,std::allocator<std::vector<int,std::allocator<int>>>>”转换为“std::vector<std::string,std::allocator<std::string>>”
vector<string>svec(10, "null"); //合法:创建了包含10元素“null”的svec对象
}
练习3.13 下列的vector对象各包含多少个元素?这些元素的值分别是多少?
#include<string>
#include<vector>
using namespace std;
int main()
{
vector<int> v1; //创建了一个默认初始值的对象v1(包含0元素)
vector<int>v2(10); //创建了包含10个元素的对象v2
vector<int>v3(10, 42);//创建了值为42,包含10个元素的对象v3
vector<int>v4{ 10 }; //创建了包含一个元素,值为10的对象v4
vector<int>v5{ 10,42 };//创建了包含两个元素,值分别为10,42的对象v5
vector<string>v6{ 10 };//创建了包含10个元素的对象v6(空字符串)
vector<string>v7{ 10,"hi" };//创建了包含10个元素,都为“hi”的对象v7
}
3.3.2 向vector对象中添加元素
练习3.14 编写一段程序,用cin读入一组整数并把它们存入一个vector对象
#include<string>
#include<vector>
using namespace std;
int main()
{
vector<int> digit;
int i = 0;
while (cin >> i) {
digit.push_back(i);
}
}
练习3.15 改写上一题程序,不过这次读入的是字符串
#include<string>
#include<vector>
using namespace std;
int main()
{
vector<string> str;
string i;
while (cin >> i) {
str.push_back(i);
}
}
3.3.3 其他vector操作
练习3.16 编写一段程序,把练习3.13中vector对象的容量和具体内容输出出来。检验你之前的回答是否正确,如果不对,回过头重新学习3.3.1节(第87页)直到弄明白错在哪里为止
#include<string>
#include<vector>
using namespace std;
int main()
{
vector<int> v1; //创建了一个默认初始值的对象v1(包含0元素)
vector<int>v2(10); //创建了包含10个元素的对象v2
vector<int>v3(10, 42);//创建了值为42,包含10个元素的对象v3
vector<int>v4{ 10 }; //创建了包含一个元素,值为10的对象v4
vector<int>v5{ 10,42 };//创建了包含两个元素,值分别为10,42的对象v5
vector<string>v6{ 10 };//创建了包含10个元素的对象v6(空字符串)
vector<string>v7{ 10,"hi" };//创建了包含10个元素,都为“hi”的对象v7
cout << "v1输出:" << endl;
for (auto i : v1) {
cout << i << endl;
}
cout << "v2输出:" << endl;
for (auto i : v2) {
cout << i << endl;
}
cout << "v3输出:" << endl;
for (auto i : v3) {
cout << i << endl;
}
cout << "v4输出:" << endl;
for (auto i : v4) {
cout << i << endl;
}
cout << "v5输出:" << endl;
for (auto i : v5) {
cout << i << endl;
}
cout << "v6输出:" << endl;
for (auto i : v6) {
cout << i << endl;
}
cout << "v7输出:" << endl;
for (auto i : v7) {
cout << i << endl;
}
}
练习3.17 从cin读入一组词并把它们存入一个vector对象,然后设法把所有词语都改成大写形式。输出改变后的结果,每个词占一行
#include<string>
#include<vector>
using namespace std;
int main()
{
vector<string> str;
string input;
while (cin >> input) {
if (input == "over")
break;
else
str.push_back(input);
}
for (auto& i : str) { //这里的i是一个字符串,还需要变成单个字符才行
for (auto& j : i) {
j = toupper(j);
}
}
for (auto i : str) {
cout << i << endl;
}
}
练习3.18 下面的程序合法吗?如果不合法,你准备如何修改?
#include<string>
#include<vector>
using namespace std;
int main()
{
vector<int> ivec;
ivec[0] = 42; //错误:这里应该使用ivec.push_back(42);
}
练习3.19 如果想定义一个含有10个元素的vector对象,所有元素的值都是42,请列举出三种不同的实现方法。哪种方法更好呢?为什么?
#include<string>
#include<vector>
using namespace std;
int main()
{
vector<int> i(10, 42); //法一
vector<int> j{ 42,42,42,42,42,42,42,42,42,42 }; //法二
vector<int> k; //法三
for (int i = 0; i < 10; i++) {
k.push_back(42);
}
}
练习3.20 读入一组整数并把它们存入一个vector对象,将每对相邻整数的和输出出来。
改写你的程序,这次要求先输入第一个和最后一个元素的和,接着输出第2个和倒数第二个元素的和,以此类推
#include<string>
#include<vector>
using namespace std;
int main()
{
vector<int> data,output; //output用于存储最后要输出的对象
int i = 0, digit = 0;
cout << "读入一组整数并把它们存入一个vector对象,当输入-1的时候结束存入操作" << endl;
while (cin >> digit) {
if (digit == -1)
break;
data.push_back(digit);
}
int m = data.size();
cout << "按1:将每对相邻整数的和输出出来 按2:先输入第一个和最后一个元素的和,接着输出第2个和倒数第二个元素的和,以此类推" << endl;
cin >> i;
switch (i) {
case 1:
cout << "将每对相邻整数的和输出出来:" << endl;
for (int j = 0; j < data.size()-1; j++) {
output.push_back(data[j] + data[j + 1]);
}
for (int j : output) {
cout << j << endl;
}
break;
case 2:
cout << "先输入第一个和最后一个元素的和,接着输出第2个和倒数第二个元素的和,以此类推:" << endl;
for (int j = 0; j < m; j++) { //小于m的意思是当为奇数输入时候,我们使得奇数中间位自己加自己
output.push_back(data[j] + data[m-1]); //要注意data【】是从0开始计算的,所以要把m减1,不然程序会发生错误,因为根本没有data【m】项
m--;
}
for (int n : output) {
cout << n << endl;
}
break;
}
}
3.4 迭代器介绍
3.4.1 使用迭代器
练习3.21 请使用迭代器重做3.3.3节(第94页)的第一个练习
编写一段程序,吧练习3.13中的vector对象的容量和具体内容输出出来
#include<string>
#include<vector>
using namespace std;
int main()
{
vector<int> v1; //创建了一个默认初始值的对象v1(包含0元素)
vector<int>v2(10); //创建了包含10个元素的对象v2
vector<int>v3(10, 42);//创建了值为42,包含10个元素的对象v3
vector<int>v4{ 10 }; //创建了包含一个元素,值为10的对象v4
vector<int>v5{ 10,42 };//创建了包含两个元素,值分别为10,42的对象v5
vector<string>v6{ 10 };//创建了包含10个元素的对象v6(空字符串)
vector<string>v7{ 10,"hi" };//创建了包含10个元素,都为“hi”的对象v7
for (auto i = v1.cbegin(); i != v1.cend();i++) {
cout << *i << endl;
}
for (auto i = v2.cbegin(); i != v2.cend(); i++) {
cout << *i << endl;
}
for (auto i = v3.cbegin(); i != v3.cend(); i++) {
cout << *i << endl;
}
for (auto i = v4.cbegin(); i != v4.cend(); i++) {
cout << *i << endl;
}
for (auto i = v5.cbegin(); i != v5.cend(); i++) {
cout << *i << endl;
}
for (auto i = v6.cbegin(); i != v6.cend(); i++) {
cout << *i << endl;
}
for (auto i = v7.cbegin(); i != v7.cend(); i++) {
cout << *i << endl;
}
}
练习3.22 修改之前那个输出text第一段程序,首先把text的第一段全都改成大写形式,然后再输出它
#include<string>
#include<vector>
using namespace std;
int main()
{
vector<string> str{ "abcd","","kkkk" };
for (auto t = str.begin(); t != str.end() && !(*t).empty(); t++) {
for (auto& i : *t) {
i = toupper(i);
}
}
for (auto t = str.begin(); t != str.end() && !(*t).empty(); t++) {
for (auto i : *t) {
cout << i << endl;
}
}
}
练习3.23 编写一段程序,创建一个含有10个整数的vector对象,然后使用迭代器将所有元素的值都变成原来的两倍。
输出vector对象的内容,检验程序是否正确
#include<string>
#include<vector>
using namespace std;
int main()
{
vector<int> data;
int digit = 0;
cout << "请输入十位整数" << endl;
for (int i = 0; i < 10; i++) {
cin >> digit;
data.push_back(digit);
}
for (auto i = data.begin(); i != data.end(); i++) {
*i = *i * 2;
}
for (auto i = data.begin(); i != data.end(); i++) {
cout << *i << endl;
}
}
3.4.2 迭代器运算
练习3.24 请使用迭代器重做3.3.3节(第94页)的最后一个练习
读入一组整数并把它们存入一个vector对象,将每队相邻整数的和输出出来。
改写你的程序,这次要求先输出第一个和最后一个元素的和,接着输出第二个和倒数第二个元素的和,以此类推
#include<string>
#include<vector>
using namespace std;
int main()
{
vector<int> data, output;
cout << "读入一组整数(当输入为-1时结束读入):" << endl;
int i = 0;
while(i!=-1){
cin >> i;
if (i != -1) {
data.push_back(i);
}
}
auto begin = data.begin(), end = data.end();
cout << "按1:将每队相邻整数的和输出出来 按2:先输出第一个和最后一个元素的和,接着输出第二个和倒数第二个元素的和,以此类推" << endl;
cin >> i;
switch (i) {
case 1:
cout << "将每队相邻整数的和输出出来:" << endl;
for (auto j = data.begin(); j != data.end()-1; j++) {
output.push_back(*j + *(j + 1));
}
for (auto j = output.begin(); j != output.end(); j++) {
cout << *j << endl;
}
break;
case 2:
cout << "先输出第一个和最后一个元素的和,接着输出第二个和倒数第二个元素的和,以此类推:" << endl;
for (begin; begin < end; begin++) {
output.push_back(*begin + *(end-1));
end--;
}
for (auto j = output.begin(); j != output.end(); j++) {
cout << *j << endl;
}
break;
}
}
练习3.25 3.3.3节(93页)划分分数段的程序是使用下标运算符实现的,请利用迭代器改写该程序并实现完全相同的功能
#include<string>
#include<vector>
using namespace std;
int main()
{
vector<int> scores(11, 0);
unsigned grade;
while (cin >> grade) {
if (grade == -1) {
break;
}
++* (scores.begin() + (grade / 10));
}
for (auto j = scores.begin(); j != scores.end(); j++) {
cout << *j << endl;
}
}
练习3.26 在100页的二分搜索中,为什么用的是min=beg+(end-beg)/2,而非min=(end+beg)/2
这里是因为迭代器和迭代器相加之后,已经超出的end的范围,无意义了
3.5 数组
3.5.1 定义和初始化内置数组
练习3.27 假设text_size是一个无参数的函数,它的返回值是int。请回答下列哪个定义是非法的?为什么?
#include<string>
using namespace std;
int main()
{
unsigned buf_size = 1024;
int ia[buf_size]; //错误:类型不匹配
int ia[4 * 7 - 14];
int ia[txt_size()];
char st[11] = "fundamental"; //错误:算上空字符占了12位,超过维度了
}
练习3.28 下列数组中元素的值是什么?
#include<string>
using namespace std;
string sa[10]; //空字符串
int ia[10]; //0
int main()
{
string sa2[10]; //空字符串
int ia2[10]; //不确定值
}
练习3.29 相比于vector来说,数组有哪些缺点,请列举一些
数组大小确定不变,不能随意向数组中增加元素,虽然因为这个特性对于某些特殊的应用来说程序运行时性能较好,但也相应地损失了一点灵活性
3.5.2 访问数组元素
练习3.30 指出下面代码中的索引错误
下面程序运行将会发生错误,因为for循环超出了ia的维度
#include<string>
using namespace std;
int main()
{
constexpr size_t array_size = 10;
int ia[array_size];
for (size_t ix = 1; ix <= array_size; ++ix) {
ia[ix] = ix;
}
}
练习3.31 编写一段程序,定义一个含有10个int的数组,令每个数组的值就是其下标值
#include<string>
using namespace std;
int main()
{
constexpr int a = 10;
int arr[a];
for (int i = 0; i < 10; i++) {
arr[i] = i;
cout << arr[i] << endl;
}
}
练习3.32 将上一题刚刚创建的数组拷贝给另外一个数组。利用vector重写程序,实现类似的功能
#include<string>
#include<vector>
using namespace std;
int main()
{
constexpr int a = 10;
int arr[a],drr[a];
for (int i = 0; i < 10; i++) {
arr[i] = i;
drr[i] = arr[i]; //拷贝
}
vector<int> crr;
for (int i = 0; i < 10; i++) {
crr.push_back(i);
}
for (int i = 0; i < 10; i++) {
cout << crr[i] << endl;
}
}
练习3.33 对于104页的程序来说,如果不初试化scores将发生什么?
在数组里面,不能确定初始值是多少
3.5.3
练习3.34 假定p1和p2指向同一个数组中的元素,则下面程序的功能是什么?什么情况下该程序是非法的?
p1+=p2-p1 相当于p1=p1+(p2-p1) 这个语句的意思是,让p1所指向的数组地址移动p2减去p1距离的步数
当超出维度的时候该程序就非法了
练习3.35 编写一段程序,利用指针将数组中的元素置为0 法一
#include<string>
#include<vector>
using namespace std;
int main()
{
int arr[10];
int* p = arr;
for (int i = 0; i < 10; i++) {
*(p + i) = 0;
cout << arr[i] << endl;
}
}
练习3.35 编写一段程序,利用指针将数组中的元素置为0 法二
#include<string>
#include<vector>
using namespace std;
int main()
{
int arr[10];
int* a = begin(arr); //这里返回的是一个首地址
int* b = end(arr); //这里返回的是一个尾地址
for (a; a < b; a++) {
*a = 0;
}
for (int i = 0; i < 10; i++) {
cout << arr[i] << endl;
}
}
练习3.36 编写一段程序,比较两个数组是否相等。再写一段程序,比较两个vector对象是否相等
#include<string>
#include<vector>
using namespace std;
int main()
{
int choose = 0, choose1 = 0;;
cout << "按1:比较两个数组是否相等 按2:比较两个vector对象是否相等" << endl;
cin >> choose;
int arr[3] = { 1,2,3 };
int brr[4] = { 1,2,3,4 };
int crr[3] = { 1,2,4 };
int drr[3] = { 1,2,3 };
int digit = 0, digit1 = 0, digit2 = 0; //用来比较两数组长度是否一致
vector<int> a{ 1,2,3 };
vector<int> b{ 1,2,3,4 };
switch (choose) {
case 1:
cout << "按1:比较arr与brr数组 按2:比较arr与crr数组 按3:比较arr与drr数组" << endl;
cin >> choose1;
switch (choose1) {
case 1:
//先比较两数组长度是否一致
cout << "比较arr与brr数组:" << endl;
for (auto i : arr) {
digit1++;
}
for (auto i : brr) {
digit2++;
}
if (digit1 != digit2) {
cout << "两数组不相等" << endl;
}
else {
for (auto i = begin(arr); i != end(arr); i++) { //如果两数组长度相等那么比较每个位置是否相等
if (arr[digit] != brr[digit]) {
cout << "两数组不相等" << endl;
break;
}
digit++;
}
if (digit == digit1) //这里表示上面循环完了都没找到不相等的,所以两数组相等
cout << "两数组相等" << endl;
}
break;
case 2:
//先比较两数组长度是否一致
cout << "比较arr与crr数组:" << endl;
for (auto i : arr) {
digit1++;
}
for (auto i : crr) {
digit2++;
}
if (digit1 != digit2) {
cout << "两数组不相等" << endl;
}
else {
for (auto i = begin(arr); i != end(arr); i++) {
if (arr[digit] != crr[digit]) {
cout << "两数组不相等" << endl;
break;
}
digit++;
}
if (digit == digit1)
cout << "两数组相等" << endl;
}
break;
case 3:
//先比较两数组长度是否一致
cout << "比较arr与drr数组:" << endl;
for (auto i : arr) {
digit1++;
}
for (auto i : drr) {
digit2++;
}
if (digit1 != digit2) {
cout << "两数组不相等" << endl;
}
else {
for (auto i = begin(arr); i != end(arr); i++) {
if (arr[digit] != drr[digit]) {
cout << "两数组不相等" << endl;
break;
}
digit++;
}
if (digit == digit1)
cout << "两数组相等" << endl;
}
break;
}
break;
case 2:
if (a == b) {
cout << "两vector相等" << endl;
}
else {
cout << "两vector不相等" << endl;
}
break;
}
}
比较arr与brr数组是否相等
比较arr与crr数组是否相等
比较arr与drr数组是否相等
比较两vector是否相等
3.5.4 C风格字符串
练习3.37 下面的程序是何含义,程序的输出结果是什么?
#include<string>
#include<vector>
using namespace std;
int main()
{
const char ca[] = { 'h','e','l','l','o'};
const char* cp = ca; //cp指向ca的头指针
while (*cp) {
cout << *cp << endl; //不会停止,会一直循环,应该在ca尾部加个'\0'作为结束符号
++cp;
}
}
练习3.38 在本节中我们提到,将两个指针相加不但是非法的,而且也没有什么意义。请问为什么两个指针相加没什么意义?
试图将两个指针相加,所指向的地址可能是空的,也可以有别的东西,因此是非法的,也没有什么意义
练习3.39 编写一段程序,比较两个string对象。再编写一段程序,比较两个c风格字符串的内容
#include<string>
#include<vector>
using namespace std;
int main()
{
string a = "Hello World!";
string b = "Hello world!";
if (a > b) {
cout << "a比b大" << endl;
}
else {
cout << "a比b小" << endl;
}
const char c[] = "Hello World!";
const char d[] = "Hello world!";
if (strcmp(c, d) > 0) {
cout << "c>d" << endl;
}
else {
cout << "c<d" << endl;
}
}
练习3.40 编写一段程序,定义两个字符数组并用字符串字面值初始化它们接着再定义一个字符数组存放前两个数组连接后的结果。使用strcpy和strcat把前两个数组的内容拷贝到第三个数组中
注意:微软担心使用这些会造成内存异常,所以就改写了同样功能的函数,改写了的函数进行了参数的检测,使用这些新的函数会更安全和便捷。库函数改写例子:mkdir改写为 _mkdir;fopen改写为 fopen_s ;stricmp改写为 stricmp_s ;strcpy改写为strcpy_s; scanf改写为scanf_s
#include<string>
#include<vector>
#include<cstring>
using namespace std;
int main()
{
char str1[] = "hello";
char str2[] = "Hello";
char str3[20];
strcpy_s(str3, str1);
strcat_s(str3, str2);
cout << str3 << endl;
}
3.5.5 与旧代码的接口
练习3.41 编写一段程序,用整型数组初始化一个vector对象
#include<string>
#include<vector>
#include<cstring>
using namespace std;
int main()
{
int a[] = { 1,2 };
vector <int> b(begin(a), end(a));
for (auto n : b) {
cout << n << endl;
}
}
练习3.42 编写一段程序,将含有整数元素的vector对象拷贝给一个整型数组
#include<string>
#include<vector>
#include<cstring>
using namespace std;
int main()
{
vector<int> a = { 1,2,3 };
int b[] = { a[0],a[1],a[2] };
for (int i = 0; i != 3; i++) {
cout << b[i] << endl;
}
}
3.6 多维数组
练习3.43 编写3个不同版本的程序,令其均能输出ia的元素。版本1使用范围for语句管理迭代过程;版本2和版本3都使用普通的for语句;版本2要求用下标运算符,版本3要求用指针;此外,在所有3个版本的程序中都要直接写出数据类型,而不能使用类型别名,auto关键字或decltype关键字
#include<string>
#include<cstring>
#include<vector>
using namespace std;
int main()
{
int i = 0;
int ia[3][4] = { 0,1,2,3,4,5,6,7,8,9,10,11 };
cout << "按1:使用范围for语句管理迭代过程 按2:用下标运算符 按3:用指针" << endl;
cin >> i;
switch (i) {
case 1:
cout << "使用范围for语句管理迭代过程" << endl;
for (int(&i)[4] : ia) { //要使用范围for语句处理多维数组,除了最内层的循环外,其他所有循环的控制变量都应该是引用类型
for (int j : i) {
cout << j << endl;
}
}
break;
case 2:
cout << "用下标运算符" << endl;
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 4; j++) {
cout << ia[i][j] << endl;
}
}
break;
case 3:
cout << "用指针" << endl;
for (int(*p)[4] = ia; p != end(ia); p++) {
for (int* q = *p; q != end(*p); q++) {
cout << *q << endl;
}
}
break;
}
}
练习3.44 改写上一个练习中的程序,使用类型别名来代替循环控制变量的类型
#include<string>
#include<cstring>
#include<vector>
using namespace std;
typedef int int_array[4];
int main()
{
int i = 0;
int ia[3][4] = { 0,1,2,3,4,5,6,7,8,9,10,11 };
cout << "按1:使用范围for语句管理迭代过程 按2:用下标运算符 按3:用指针" << endl;
cin >> i;
switch (i) {
case 1:
cout << "使用范围for语句管理迭代过程" << endl;
for (int_array &i : ia) { //要使用范围for语句处理多维数组,除了最内层的循环外,其他所有循环的控制变量都应该是引用类型
for (int j : i) {
cout << j << endl;
}
}
break;
case 2:
cout << "用下标运算符" << endl;
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 4; j++) {
cout << ia[i][j] << endl;
}
}
break;
case 3:
cout << "用指针" << endl;
for (int_array *p = ia; p != end(ia); p++) {
for (int* q = *p; q != end(*p); q++) {
cout << *q << endl;
}
}
break;
}
}
练习3.45 再一次改写程序,这次使用auto关键字
#include<string>
#include<cstring>
#include<vector>
using namespace std;
int main()
{
int i = 0;
int ia[3][4] = { 0,1,2,3,4,5,6,7,8,9,10,11 };
cout << "按1:使用范围for语句管理迭代过程 按2:用下标运算符 按3:用指针" << endl;
cin >> i;
switch (i) {
case 1:
cout << "使用范围for语句管理迭代过程" << endl;
for (auto &i : ia) { //要使用范围for语句处理多维数组,除了最内层的循环外,其他所有循环的控制变量都应该是引用类型
for (int j : i) {
cout << j << endl;
}
}
break;
case 2:
cout << "用下标运算符" << endl;
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 4; j++) {
cout << ia[i][j] << endl;
}
}
break;
case 3:
cout << "用指针" << endl;
for (auto* p = ia; p != end(ia); p++) {
for (int* q = *p; q != end(*p); q++) {
cout << *q << endl;
}
}
break;
}
}