C++Primer练习[第三章]

//练习 3.1使用恰当的using声明重做1.4.1节(第11页)和2.6.2节(第67页)的练习
//1.4.1节 
//1.9 编写程序,使用while循环将50到100的整数相加
#include <iostream>
using std::cout;
using std::endl;
int main()
{
int i = 50;
int sum = 0;
while (i <= 100)
{
sum = sum + i;
i++;
}
cout << sum << endl;
system("pause");
return 0;

}



//1.10除了++运算符将运算对象的值加1之外,还有一个递减运算符–实现将值减一,编写程序,使用递减运算符在循环中按递减顺序打印出10到0的整数。
#include <iostream>
using std::cout;
using std::endl;
int main()
{
int i = 10;
while (i >= 0)
{
cout << i << endl;
i--;
}
system("pause");
return 0;

}



//1.11 编写程序,提示用户输入两个整数,打印出这两个整数所指定的范围内的所有整数。
#include <iostream>
using std::cout;
using std::endl;
using std::cin;
int main()
{
int v1 = 0, v2 = 0;
cout << "请输入两个整数,用空格分开: " << endl;
cin >> v1 >> v2;
int i = v1;
int max = v2;
if (v1 > v2)
{
i = v2;
max = v1;
}
while (i <= max)
{
cout << i << endl;
i++;
}
system("pause");
return 0;

}



//2.6.2节 
//2.41使用自己的Sales_data 类重写1.5.1节(第20页)、1.5.2节(第21页)和1.6节(第22页)的练习.
//眼下先把Sales_data和main函数放在同一个文件。
//2.41-1 读取一组书籍销售记录,将每条记录打印到标准输出上。
#include <iostream>
#include <string>
using std::string;
using std::cout;
using std::endl;
using std::cin;
struct Sales_data
{
string bookNo; //isbn
unsigned units_sold = 0; //销量
double revenue = 0; //总价
double price = 0.0f; //单价
};
int main()
{
Sales_data book;
while (cin >> book.bookNo >> book.units_sold >> book.price)
{
book.revenue = book.units_sold * book.price;
cout << book.bookNo << " " << book.units_sold << " " << book.revenue << " " << book.price << " " << endl;
}
system("pause");
return 0;

}



//2.41-2 编写程序,读取两个ISBN相同的Sales_item对象,输出它们的和
#include <iostream>
#include <string>
using std::string;
using std::cout;
using std::endl;
using std::cin;
struct Sales_data
{
string bookNo; //isbn
unsigned units_sold = 0; //销量
double revenue = 0; //总价
double price = 0.0f; //单价
};
int main()
{
Sales_data book1, book2;
cout << "请输入两个ISBN相同的销售记录" << endl;
cin >> book1.bookNo >> book1.units_sold >> book1.price;
cin >> book2.bookNo >> book2.units_sold >> book2.price;
while (book1.bookNo != book2.bookNo)
{
cout << "请输入两个ISBN相同的销售记录" << endl;
cin >> book1.bookNo >> book1.units_sold >> book1.price;
cin >> book2.bookNo >> book2.units_sold >> book2.price;
}
book1.revenue = book1.units_sold * book1.price;
book2.revenue = book2.units_sold * book2.price;
cout << "总和:" << book1.bookNo << " " << book1.units_sold + book2.units_sold << " " << book1.revenue + book2.revenue << " " << ((book1.revenue + book2.revenue) / (book1.units_sold + book2.units_sold)) << " " << endl;
system("pause");
return 0;

}



//2.41-3 编写程序,读取多个具有相同ISBN的销售记录,输出所有记录之和
#include <iostream>
#include <string>
using std::string;
using std::cout;
using std::endl;
using std::cin;
using std::cerr;
struct Sales_data
{
string bookNo; //isbn
unsigned units_sold = 0; //销量
double revenue = 0; //总价
double price = 0.0f; //单价
};
 
int main()
{
Sales_data book;
Sales_data sum_book;
cout << "请输入ISBN相同的销售记录" << endl;
if (cin >> book.bookNo >> book.units_sold >> book.price)
{
book.revenue = book.units_sold * book.price;
sum_book.bookNo = book.bookNo;
sum_book.units_sold = book.units_sold;
sum_book.revenue = book.revenue;
sum_book.price = book.price;
cout << "请输入ISBN相同的销售记录" << endl;
while (cin >> book.bookNo >> book.units_sold >> book.price)
{
if (book.bookNo == sum_book.bookNo)
{
book.revenue = book.units_sold * book.price;
sum_book.units_sold += book.units_sold;
sum_book.revenue += book.revenue;
cout << "请输入ISBN相同的销售记录" << endl;
}
else
{
cout << "请输入ISBN相同的销售记录" << endl;
}
}
cout << "总和:" << sum_book.bookNo << " " << sum_book.units_sold << " " << sum_book.revenue << " " << (sum_book.revenue / sum_book.units_sold) << " " << endl;
}
else
{
cerr << "没有数据" << endl;
return -1;
}
system("pause");
return 0;

}



//2.41-4 编写程序,读取多条销售记录,并统计每个ISBN(每本书)有几条销售记录
#include <iostream>
#include <string>
using std::string;
using std::cout;
using std::endl;
using std::cin;
using std::cerr;
struct Sales_data
{
string bookNo; //isbn
unsigned units_sold = 0; //销量
double revenue = 0; //总价
double price = 0.0f; //单价
};
int main()
{
Sales_data book, currbook;
int count = 0;
cout << "请输入销售记录" << endl;
if (cin >> book.bookNo >> book.units_sold >> book.price)
{
book.revenue = book.units_sold * book.price;
currbook.bookNo = book.bookNo;
currbook.units_sold = book.units_sold;
currbook.revenue = book.revenue;
currbook.price = book.price;
count = 1;
cout << "请输入销售记录" << endl;
while (cin >> book.bookNo >> book.units_sold >> book.price)
{
if (currbook.bookNo == book.bookNo)
{
count++;
}
else
{
cout << currbook.bookNo << "有" << count << "条记录" << endl;
book.revenue = book.units_sold * book.price;
currbook.bookNo = book.bookNo;
currbook.units_sold = book.units_sold;
currbook.revenue = book.revenue;
currbook.price = book.price;
count = 1;
}
cout << "请输入销售记录" << endl;
}
cout << currbook.bookNo << "有" << count << "条记录" << endl;
}
else
{
cerr << "没有数据" << endl;
return -1;
}
system("pause");
return 0;

}



//2.41-5 编译并运行书店程序
#include <iostream>
#include <string>
using std::string;
using std::cout;
using std::endl;
using std::cin;
using std::cerr;
struct Sales_data
{
string bookNo; //isbn
unsigned units_sold = 0; //销量
double revenue = 0; //总价
double price = 0.0f; //单价
};
 
int main()
{
//保持下一条交易记录的变量
Sales_data total;
//读入第一条交易记录,并确保有数据可以处理
if (cin >> total.bookNo >> total.units_sold >> total.price)
{
total.revenue = total.units_sold * total.price;
//保持和的变量
Sales_data trans;
//读入并处理剩余交易记录
while (cin >> trans.bookNo >> trans.units_sold >> trans.price)
{
trans.revenue = trans.units_sold * trans.price;
//如果我们仍在处理相同的书
if (total.bookNo == trans.bookNo)
{
//更新总销售量
total.revenue += trans.revenue;
total.units_sold += trans.units_sold;
}
else
{
//打印前一本书的结果
cout << total.bookNo << " " << total.units_sold << " " << total.revenue << " " << (total.revenue / total.units_sold) << " " << endl;
//total现在表示下一本书的销售额
trans.revenue = trans.units_sold * trans.price;
total.bookNo = trans.bookNo;
total.units_sold = trans.units_sold;
total.revenue = trans.revenue;
total.price = trans.price;
}
}
//打印最后一本书的结果
cout << total.bookNo << " " << total.units_sold << " " << total.revenue << " " << (total.revenue / total.units_sold) << " " << endl;
}
else
{
//没有输入!警告读者
cerr << "No Data?!" << endl;
//表示失败
return -1;
}
system("pause");
return 0;
}



//练习 3.2 编写一段程序从标准输入中读入一整行,然后修改程序使其一次读入一个词。
#include <iostream>
#include <string>
using std::string;
using std::cin;
using std::cout;
using std::endl;
int main()
{
string line_str;
cout << "请输入一行字(这次会直接读入这行):" << endl;
getline(cin, line_str);
cout << line_str << endl;
cout << "请输入一行字(这次会一次读入一个词):" << endl;
string word_str;
while (cin >> word_str)
{
cout << word_str << endl;
}
system("pause");
return 0;
}



//练习 3.3 请说明string类的输入运算符和getline函数分别如何处理空白字符的.
//答:string类的输入运算符会自动忽略开头的空白(即空格符、换行符、制表符等)并从第一个真正的字符开始读起,直到遇到下一处空白为止。
//getline函数从给定的输入流中读入内容,直到遇到换行符为止(换行符也被读进来了),然后把所读的内容存入到string对象中去(不存换行符).


//练习 3.4 编写一段程序读入两个字符串,比较其是否相等并输出结果。如果不相等,输出较大的那个字符串。
//改写上述程序,比较两个字符串是否等长,如果不等长,输出长度较大的那个字符串.
#include <iostream>
#include <string>
using std::string;
using std::cin;
using std::cout;
using std::endl;
int main()
{
string str1, str2;
cout << "请输入两个字符串,用回车分割" << endl;
getline(cin, str1);
getline(cin, str2);
//是否相等
if (str1 == str2)
{
cout << "str1:" << str1 << "== str2:" << str2 << endl;
}
else
{
if (str1 > str2)
{
cout << "较大的为str1:" << str1 << endl;
}
else
{
cout << "较大的为str2:" << str2 << endl;
}
}
//是否等长
if (str1.size() == str2.size())
{
cout << "str1.size():" << str1.size() << "== str2.size():" << str2.size() << endl;
}
else
{
if (str1.size() > str2.size())
{
cout << "较长的为str1:" << str1 << endl;
}
else
{
cout << "较长的为str2:" << str2 << endl;
}
}
system("pause");
return 0;
}


//练习 3.5 编写一段程序从标准输入中读入多个字符串并将他们连接在一起,输出连接成的大字符串。
//然后修改上述程序,用空格把输入的多个字符串分隔开来。
#include <iostream>
#include <string>
using std::string;
using std::cin;
using std::cout;
using std::endl;
int main()
{
cout << "请输入内容:" << endl;
string all_str1, all_str2, word_str;
while (cin >> word_str)
{
all_str1 += word_str;
all_str2 = all_str2 + word_str + " ";
}
cout << "大字符串:" << all_str1 << endl;
cout << "用空格分开:" << all_str2 << endl;


system("pause");
return 0;
}


//练习3.6:编写一段程序,使用范围for语句将字符串内的所有字符用X代替
#include <iostream>
#include <string>
using std::cout;
using std::string;
using std::endl;
int main()
{
string str("zhe shi yi duan zifuchuang");
cout << "字符串内容:" << str << endl;
for (auto &c : str)
{
c = 'X';
}
cout << "替换后内容:" << str << endl;
system("pause");
return 0;
}


//练习3.7 就上一题完成的程序而言,如果将循环控制变量的类型设为char将发生什么?
//先估算一下结果,然后实际编程进行验证。
//答:字符串内容将不被改变,输出的字符串内容还是原来的内容。
#include <iostream>
#include <string>
using std::cout;
using std::string;
using std::endl;
int main()
{
string str("zhe shi yi duan zifuchuang");
cout << "字符串内容:" << str << endl;
for (char c : str)
{
c = 'X';
}
cout << "替换后内容:" << str << endl;
system("pause");
return 0;
}


//练习 3.8 分别用while循环和传统for循环重写第一题的程序,你觉得那种形式更好呢?为什么?
//三者相比,范围for循环更好,因为更简洁。其次为传统for循环。
//while循环
#include <iostream>
#include <string>
using std::cout;
using std::string;
using std::endl;
int main()
{
cout << "while循环:" << endl;
string str("zhe shi yi duan zifuchuang");
cout << "字符串内容:" << str << endl;
decltype(str.size()) str_size = str.size();
decltype(str.size()) str_i = 0;
while(str_i < str_size)
{
str[str_i] = 'X'; 
++str_i;
}
cout << "替换后内容:" << str << endl;
system("pause");
return 0;

}



//传统for循环
#include <iostream>
#include <string>
using std::cout;
using std::string;
using std::endl;
int main()
{
cout << "传统for循环:" << endl;
string str("zhe shi yi duan zifuchuang");
cout << "字符串内容:" << str << endl;
decltype(str.size()) str_size = str.size();
for(decltype(str.size()) str_i = 0; str_i < str_size; ++str_i)
{
str[str_i] = 'X';
}
cout << "替换后内容:" << str << endl;
system("pause");
return 0;
}


//练习3.9 下面程序有何作用?它合法吗?如果不合法,为什么?
//string s;
//cout << s[0] << endl;
//答:此程序预期作用应该是要输出字符串s的第一个字符。但是它是不合法的。因为字符串s是个空字符串,s[0]的结果是未定义的,会引发不可预知的结果。


//练习3.10 编写一段程序,读入一个包含标点符号的字符串,将标点符号去除后输出字符串剩余的部分。
#include <iostream>
#include <string>
using std::string;
using std::cin;
using std::cout;
using std::endl;
int main()
{
string str;
cout << "请输入一个包含标点符号的字符串" << endl;
getline(cin, str);
for (auto c : str)
{
if (!ispunct(c))
{
cout << c;
}
}
cout << endl;
system("pause");
return 0;
}


//练习3.11 下面的范围for语句合法吗?如果合法,c的类型是什么?
//const string s = "Keep out!";
//for(auto &c:s) {/*...*/}
//合法。c的类型是const char &


//3.12:下列vector对象的定义有不正确的吗?如果有,请指出来。对于正确的,描述其执行结果;对于不正确的,说明其错误的原因。
//(a)vector<vector<int>> ivec;
//(b)vector<string> svec = ivec;
//(c)vector<string> svec(10, "null");
//答:(a)正确,定义了一个名为ivec的vector对象,ivec的元素是vector<int>对象,ivec当前不含任何元素
//(b)不正确,要执行拷贝操作的两个vector对象的类型必须相同。svec的元素是string对象,不是vector<int>
//(c)正确,定义了一个名为svec的vector对象,svec的元素是string对象,svec有10个元素,每个的值都是"null"


//3.13:下列的vector对象各包含多少个元素?这些元素的值分别是多少?
//(a)vector<int> v1; (b)vector<int> v2(10);
//(c)vector<int> v3(10, 42); (d)vector<int> v4{10};
//(e)vector<int> v5{10, 42}; (f)vector<string> v6{10};
//(g)vector<string> v7(10, "hi");
//答:(a)v1包含0个元素。
//(b)v2包含10个元素,每个元素的值都是0
//(c)v3包含10个元素,每个元素的值都是42
//(d)v4包含1个元素,值为10
//(e)v5包含2个元素,值分别为10,42
//(f)v6包含10个元素,每个元素的值都是空字符串
//(g)v7包含10个元素,每个元素的值都是"hi"


//练习3.14:编写一段程序,用cin输入一组整数并把它们存入一个vector对象。
#include <iostream>
#include <vector>
using std::vector;
using std::cin;

int main()
{
vector<int> ivec;
int temp = 0;
while (cin >> temp)
{
ivec.push_back(temp);
}

system("pause");
return 0;
}


//练习3.15:改写上题的程序,不过这次读入的是字符串。
#include <iostream>
#include <vector>
#include <string>
using std::string;
using std::vector;
using std::cin;
int main()
{
vector<string> svec;
string temp;
while (cin >> temp)
{
svec.push_back(temp);
}

system("pause");
return 0;
}

//练习3.16:编写一段程序,把练习3.13中vector对象的容量和具体内容输出出来。检验你之前的回答是否正确,如果不对,回过头重新学习3.3.1节(第87页)直到弄明白错在何处为止。
///////////////////////////////////////////////////////////////////////////
//3.13:下列的vector对象各包含多少个元素?这些元素的值分别是多少?
//(a)vector<int> v1; (b)vector<int> v2(10);
//(c)vector<int> v3(10, 42); (d)vector<int> v4{10};
//(e)vector<int> v5{10, 42}; (f)vector<string> v6{10};
//(g)vector<string> v7(10, "hi");
///////////////////////////////////////////////////////////////////////////
#include <iostream>
#include <string>
#include <vector>
using std::string;
using std::vector;
using std::cout;
using std::endl;
int main()
{
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");

vector<vector<int>> ivec{v1, v2, v3, v4, v5};
vector<vector<string>> svec{ v6, v7 };

unsigned v_index = 1;
unsigned index = 0;

for (auto v : ivec)
{
index = 0;
cout << "v" << v_index << "的值为: " << endl;
for (auto i : v)
{
cout << "v" << v_index << "[" << index << "]:" << i << endl;
++index;
}
++v_index;
}

for (auto v : svec)
{
index = 0;
cout << "v" << v_index << "的值为: " << endl;
for (auto i : v)
{
cout << "v" << v_index << "[" << index << "]:" << i << endl;
++index;
}
++v_index;
}

system("pause");
return 0;
}


//练习3.17:从cin读入一组词并把它们存入一个vector对象,然后设法把所有词都改写为大写形式。输出改变后的结果,每个词占一行。
#include <iostream>
#include <string>
#include <vector>
using std::string;
using std::vector;
using std::cin;
using std::cout;
using std::endl;
int main()
{
vector<string> svec;
string word;
cout << "请输入一组词:" << endl;
while (cin >> word)
{
for (auto &c : word)
{
c = toupper(c);
}
svec.push_back(word);
}
cout << "改变后的结果:" << endl;
for (auto s : svec)
{
cout << s << endl;
}

system("pause");
return 0;
}


//练习3.18:下面的程序合法吗?如果不合法,你准备如何修改?
//vector<int> ivec;
//ivec[0] = 42;
//答:不合法。因为ivec是个空vector<int>对象,ivec[0]的结果是未定义的,会引发不可预知的结果。
//修改为:
//vector<int> ivec;
//ivec.push_back(42);


//练习3.19:如果定义一个含有10个元素的vector对象,所有元素的值都是42,请列举出三种不同实现的方法。哪种方法更好呢?为什么?
//答:
//1.vector<int> ivec(10,42);
//2.vector<int> ivec{42,42,42,42,42,42,42,42,42,42};
//3.vector<int> ivec;for(decltype(ivec.size()) i = 0;i < 10;++i){ivec.push_back(42);}
//vector<int> ivec(10,42);比较好,更为简洁。


//练习3.20:读入一组整数并把它们存入一个vector对象,将每对相邻整数的和输出出来。
//改写你的程序,这次要求先输出第1个和最后1个元素的和,接着输出第2个和倒数第2个元素的和,以此类推。
#include <iostream>
#include <vector>
using std::vector;
using std::cin;
using std::cout;
using std::endl;
int main()
{
vector<int> ivec;
int temp = 0;
cout << "请输入一组整数" << endl;
while (cin >> temp)
{
ivec.push_back(temp);
}
decltype(ivec.size()) index = 0;
auto max_index = ivec.size() - 1;

cout << "输出每对相邻整数的和:" << endl;
for (auto i : ivec)
{
if (index < max_index)
{
cout << i + ivec[index + 1] << " ";
}
++index;
}
cout << endl;

cout << "先输出第1个和最后1个元素的和,接着输出第2个和倒数第2个元素的和,以此类推:" << endl;
index = 0;
//如果是单数个的,则在中间那个数的时候也进行计算。
for (auto i : ivec)
{
if (index <= max_index)
{
cout << i + ivec[max_index] << " ";
}
++index;
if (max_index > 0)
{
--max_index;
}
}
cout << endl;

system("pause");
return 0;
}


//练习3.21:请使用迭代器重做3.3.3节(第94页)的第一个练习。
//练习3.16:编写一段程序,把练习3.13中vector对象的容量和具体内容输出出来。检验你之前的回答是否正确,如果不对,回过头重新学习3.3.1节(第87页)直到弄明白错在何处为止。
///////////////////////////////////////////////////////////////////////////
//3.13:下列的vector对象各包含多少个元素?这些元素的值分别是多少?
//(a)vector<int> v1; (b)vector<int> v2(10);
//(c)vector<int> v3(10, 42); (d)vector<int> v4{10};
//(e)vector<int> v5{10, 42}; (f)vector<string> v6{10};
//(g)vector<string> v7(10, "hi");
///////////////////////////////////////////////////////////////////////////
#include <iostream>
#include <string>
#include <vector>
using std::string;
using std::vector;
using std::cout;
using std::endl;
int main()
{
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");

vector<vector<int>> ivec{v1, v2, v3, v4, v5};
vector<vector<string>> svec{ v6, v7 };

unsigned v_index = 1;
unsigned index = 0;

for (auto v_it = ivec.cbegin(); v_it != ivec.cend(); ++v_it)
{
index = 0;
cout << "v" << v_index << "的值为: " << endl;
for (auto it = v_it->cbegin(); it != v_it->cend(); ++it)
{
cout << "v" << v_index << "[" << index << "]:" << (*it) << endl;
++index;
}
++v_index;
}

for (auto v_it = svec.cbegin(); v_it != svec.cend(); ++v_it)
{
index = 0;
cout << "v" << v_index << "的值为: " << endl;
for (auto it = v_it->cbegin(); it != v_it->cend(); ++it)
{
cout << "v" << v_index << "[" << index << "]:" << (*it) << endl;
++index;
}
++v_index;
}

system("pause");
return 0;
}


//练习3.22:修改之前那个输出text第一段的程序,首先把text的第一段都改写成大写形式,然后再输出它。
#include <iostream>
#include <string>
#include <vector>
using std::string;
using std::vector;
using std::cout;
using std::cin;
using std::endl;
int main()
{
cout << "请输入text的内容:" << endl;
string word;
vector<string> text;
while (getline(cin, word))
{
text.push_back(word);
}

cout << "首先把text的第一段都改写成大写形式,然后再输出它:" << endl;
for (auto it = text.begin(); it != text.end()&&!it->empty(); ++it)
{
for (auto &c : (*it))
{
c = toupper(c);
}
cout << (*it) << endl;
}
system("pause");
return 0;
}


//练习3.23:编写一段程序,创建一个含有10个整数的vector对象,然后使用迭代器,将所有元素的值都变成原来的两倍。输出vector对象的内容,检验程序是否正确。
#include <iostream>
#include <vector>
using std::vector;
using std::cout;
using std::endl;
int main()
{
vector<int> vec{ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
for (auto it = vec.begin(); it != vec.end(); ++it)
{
(*it) *= 2;
cout << (*it) << " ";
}
cout << endl;

system("pause");
return 0;
}


//练习3.24:请使用迭代器重做3.3.3节(第94页)的最后一个练习。
//练习3.20:读入一组整数并把它们存入一个vector对象,将每对相邻整数的和输出出来。
//改写你的程序,这次要求先输出第1个和最后1个元素的和,接着输出第2个和倒数第2个元素的和,以此类推。
#include <iostream>
#include <vector>
using std::vector;
using std::cin;
using std::cout;
using std::endl;
int main()
{
vector<int> ivec;
int temp = 0;
cout << "请输入一组整数" << endl;
while (cin >> temp)
{
ivec.push_back(temp);
}

cout << "输出每对相邻整数的和:" << endl;
for(auto it = ivec.cbegin(); it != ivec.cend(); ++it)
{
if ((it+1) != ivec.cend())
{
cout << (*it) + (*(it + 1)) << " ";
}
}
cout << endl;

cout << "先输出第1个和最后1个元素的和,接着输出第2个和倒数第2个元素的和,以此类推:" << endl;
//如果是单数个的,则在中间那个数的时候也进行计算。
auto beg_it = ivec.cbegin();
auto end_it = ivec.cend() - 1;
for (; beg_it <= end_it; ++beg_it, --end_it)
{
cout << (*beg_it) + (*end_it) << " ";
}
cout << endl;

system("pause");
return 0;
}


//练习3.25:3.3.3节(第93页)划分分数段的程序是使用下标运算符实现的,请利用迭代器改写程序并实现完全相同的功能。
#include <iostream>
#include <vector>
using std::vector;
using std::cin;
using std::cout;
using std::endl;
int main()
{
vector<unsigned> scores(11,0);
unsigned grade;
while (cin >> grade)
{
if (grade <= 100)
{
auto it = scores.begin() + (grade / 10);
++(*it);
}
}

for (auto it = scores.cbegin(); it != scores.cend(); ++it)
{
cout << (*it) << " ";
}
cout << endl;

system("pause");
return 0;
}


//练习3.26: 在100页的二分搜索程序中,为什么用的是mid = beg + (end - beg) / 2, 而非mid = (beg + end) / 2;?
//答:因为beg + (end - beg) / 2的含义是计算end和beg的距离/2算出中间值距离beg多少个元素。beg + 距离的元素个数算出中间迭代器。 


//练习 3.27:假设txt_size是一个无参数的函数,它的返回值是int。请回答下列哪个定义是非法的?为什么?
//unsigned buf_size = 1024;
//(a)int ia[buf_size]; (b)int ia[4 * 7 - 14];
//(c)int a[txt_size()]; (d)char st[11] = "fundamental";
//答:(a)非法。buf_size不是常量表达式。
//(b)合法。定义了ia为含有14个整数的数组。
//(c)非法。因为txt_size的返回值是int,不是常量。
//(d)非法。字符串字面值的结尾处还有一个空字符,当前定义的仅可存放字面值的内容,没有空间可存放空字符。


//练习 3.28:下列数组中元素的值是什么?
//string sa[10];
//int ia[10];
//int main() {
// string sa2[10];
// int ia2[10];
//}
//答:数组sa含有10个string类型元素,值都为空字符串。
//数组ia含有10个int类型元素,值都为0。
//数组sa2含有10个string类型元素,值都为空字符串。
//数组ia2含有10个int类型元素,值都为未定义。


//练习3.29:相比于vector来说,数组有哪些缺点,请列举一些。
//答:数组的大小确定不变,不能随意向数组中增加元素,灵活性差。


//练习3.30:指出下面代码中的索引错误。
//constexpr size_t array_size = 10;
//int ia[array_size];
//for (size_t ix = 1; ix <= array_size; ++ix)
// ia[ix] = ix;
//答:数组的下标应从0开始而且小于数组的大小。在此for循环中,ix从1~10,当下标等于10(即等于数组的大小)时会导致数组下标越界。


//练习3.31:编写一段程序,定义一个含有10个int的数组,令每个元素的值就是其下标的值。
#include <iostream>
using std::cout;
using std::endl;
int main()
{
int ia[10] = {};
for (size_t i = 0; i < 10; ++i)
{
ia[i] = i;
}
for (auto i : ia)
{
cout << i << " ";
}
cout << endl;
system("pause");
return 0;
}


//练习3.32:将上一题刚刚创建的数组拷贝给另外一个数组。利用vector重写程序,实现类似的功能。
#include <iostream>
#include <vector>
using std::vector;
using std::cout;
using std::endl;
int main()
{
int ia[10] = {};
int ia2[10];
//拷贝
for (size_t i = 0; i < 10; ++i)
{
ia2[i] = ia[i];
}

//vectro重写
vector<int> vec(10,0);
for (decltype(vec.size()) i = 0; i < vec.size(); ++i)
{
vec[i] = i;
}
for (auto i : vec)
{
cout << i << " ";
}
cout << endl;
system("pause");
return 0;
}


//练习3.33:对于104页的程序来说,如果不初始化scores将发生什么?
//答:不默认初始化,则数组元素的值是未定义的,计算分数段数量将会不正确。


//练习3.34:假定p1和p2指向同一个数组中的元素,则下面程序的功能是什么?什么情况下该程序是非法的。
//p1 += p2 – p1;
//答:功能是将p1指向p2现在指向的元素。因为p2-p1算出p2和p1之间间隔的距离,p1+这个距离就是p2的地址。将这个地址赋值给p1,就是让p1指向p2当前所指向的元素。
//当p1是常量时,该程序是非法的。


//练习3.35:编写一段程序,利用指针将数组中的元素置为0.
#include <iostream>
using std::cout;
using std::endl;
int main()
{
int a[10];
int *p = a;
for (size_t i = 0; i < 10; ++i)
{
*(p + i) = 0;
}
for (auto i : a)
{
cout << i << " ";
}
cout << endl;
system("pause");
return 0;
}


//练习3.36: 编写一段程序,比较两个数组是否相等。再写一段程序,比较vector对象是否相等。
#include <iostream>
#include <vector>

using std::begin;
using std::end;
using std::vector;
using std::cout;
using std::endl;
int main()
{
//比较数组
int a[10], b[10];
auto beg_a = begin(a);
auto beg_b = begin(b);
auto end_a = end(a);
auto end_b = end(b);
bool is_ab = true;
if (end_a - beg_a != end_b - beg_b)
{
is_ab = false;
}
else
{
for (auto i_a = beg_a, i_b = beg_b; i_a != end_a && i_b != end_b; ++i_a, ++i_b)
{
if ((*i_a) != (*i_b))
is_ab = false;
}
}

if (is_ab)
{
cout << "a == b" << endl;
}
else
{
cout << "a != b" << endl;
}

//比较vector
vector<int> va;
vector<int> vb;
if (va == vb)
{
cout << "va == vb" << endl;
}
else
{
cout << "va != vb" << endl;
}
system("pause");
return 0;
}


//练习3.37下面的程序是何含义,程序输出的结果是什么?
//const char ca[] = { ‘h’,’e’,’l’,’l’,’o’ };
//const char *cp = ca;
//while (*cp) {
// cout << *cp << endl;
// ++cp;
//}
//答:先定义一个字符常量数组ca,数组长度为6.
//定义一个指向字符常量的指针cp,cp值为ca这个数组的首地址。
//循环输出ca数组中的内容,直到遇到\0
//输出结果为不确定的,取决于什么时候遇到\0,前几个字符是hello直到遇到\0。


//练习3.38 在本节中我们提到,将两个指针相加不但非法,而且也没有什么意义。请问为什么两个指针相加没什么意义?
//答:因为两个指针相加得到的地址是一个无效指针,所以是无意义的。


//练习3.39 编写一段程序,比较两个string对象。再编写一段程序,比较两个C风格字符串的内容.
#include <iostream>
#include <string>
#include <cstring>
using std::string;
using std::cout;
using std::endl;
int main()
{
//比较string
string str1("hel lp"), str2("hel lo");
if (str1 == str2)
{
cout << "str1 == str2" << endl;
}
else if (str1 < str2)
{
cout << "str1 < str2" << endl;
}
else
{
cout << "str1 > str2" << endl;
}
 //比较C风格字符串
const char *ca1 = "hel lo",*ca2 = "hel lp";
if (strcmp(ca1,ca2) == 0)
{
cout << "ca1 == ca2" << endl;
}
else if (strcmp(ca1, ca2) < 0)
{
cout << "ca1 < ca2" << endl;
}
else
{
cout << "ca1 > ca2" << endl;
}

system("pause");
return 0;
}


//练习3.40 编写一段程序,定义两个字符数组并用字符串字面值初始化它们;接着在定义一个字符数组存放前两个数组连接后的结果。使用strcpy和strcat把前那两个数组的内容拷贝到第三个数组中。
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <cstring>
using std::cout;
using std::endl;
int main()
{
const char *ca1 = "hel lo",*ca2 = "hel lp";
char ca3[64];
strcpy(ca3, ca1);
strcat(ca3, ca2);
cout << ca3 << endl;

system("pause");
return 0;
}


//练习 3.41 编写一段程序,用整型数组初始化一个vector对象。
#include <iostream>
#include <vector>
using std::vector;
using std::cout;
using std::endl;
using std::begin;
using std::end;
int main()
{
int ia[]{1,2,3,4,5,6,7,8,9,10};
vector<int> vec(begin(ia), end(ia));
for (auto i : vec)
{
cout << i << " ";
}
cout << endl;
system("pause");
return 0;
}


//3.42:编写一段程序,将含有整数元素的vector对象拷贝给一个整型数组。
#include <iostream>
#include <vector>
using std::vector;
using std::cout;
using std::endl;

int main()
{
int ia[10];
vector<int> vec{ 1,2,3,4,5,6,7,8,9,10 };
for (size_t i = 0; i < 10; ++i)
{
ia[i] = vec[i];
cout << ia[i] << " ";
}
cout << endl;
system("pause");
return 0;
}


//3.43:编写3个不同版本的程序,令其均能输出ia的元素。
//版本1使用范围for语句管理迭代过程;
//版本2和版本3都使用普通的for语句,其中版本2要求用下标运算符,版本3要求用指针。
//此外,在所有3个版本的程序中都要直接写出数据类型,而不能使用类型别名、auto关键字或decltype关键字。
#include <iostream>
using std::cout;
using std::endl;

int main()
{
constexpr size_t rowCnt = 3, colCnt = 4;
int ia[rowCnt][colCnt]{ 1,2,3,4,5,6,7,8,9,10,11,12 };
//版本1
cout << "范围for语句:" << endl;
for (int (&row)[colCnt]: ia)
{
for (int i : row)
{
cout << i << " ";
}
}
cout << endl;

//版本2
cout << "普通的for语句,用下标运算符:" << endl;

for (size_t i = 0; i != rowCnt; ++i)
{
for (size_t j = 0; j != colCnt; ++j)
{
cout << ia[i][j] << " ";
}
}
cout << endl;

//版本3
cout << "普通的for语句,用指针:" << endl;

for (int (*p)[colCnt] = ia; p != ia + rowCnt; ++p)
{
for (int *q = *p; q != (*p)+ colCnt;++q)
{
cout << *q << " ";
}
}
cout << endl;
system("pause");
return 0;
}


//3.44:改写上一个练习中的程序,使用类型别名来代替循环控制变量的类型。
#include <iostream>
using std::cout;
using std::endl;
constexpr size_t rowCnt = 3, colCnt = 4;
using int_array = int[colCnt];
int main()
{
int ia[rowCnt][colCnt]{ 1,2,3,4,5,6,7,8,9,10,11,12 };
//版本1
cout << "范围for语句:" << endl;
for (int_array &row : ia)
{
for (int i : row)
{
cout << i << " ";
}
}
cout << endl;

//版本2
cout << "普通的for语句,用下标运算符:" << endl;

for (size_t i = 0; i != rowCnt; ++i)
{
for (size_t j = 0; j != colCnt; ++j)
{
cout << ia[i][j] << " ";
}
}
cout << endl;

//版本3
cout << "普通的for语句,用指针:" << endl;

for (int_array *p = ia; p != ia + rowCnt; ++p)
{
for (int *q = *p; q != (*p) + colCnt; ++q)
{
cout << *q << " ";
}
}
cout << endl;
system("pause");
return 0;
}


//3.45:再一次改写程序,这次使用auto关键字。
#include <iostream>
using std::cout;
using std::endl;
constexpr size_t rowCnt = 3, colCnt = 4;

int main()
{
int ia[rowCnt][colCnt]{ 1,2,3,4,5,6,7,8,9,10,11,12 };
//版本1
cout << "范围for语句:" << endl;
for (auto &row : ia)
{
for (auto i : row)
{
cout << i << " ";
}
}
cout << endl;

//版本2
cout << "普通的for语句,用下标运算符:" << endl;

for (auto i = 0; i != rowCnt; ++i)
{
for (auto j = 0; j != colCnt; ++j)
{
cout << ia[i][j] << " ";
}
}
cout << endl;

//版本3
cout << "普通的for语句,用指针:" << endl;

for (auto p = ia; p != ia + rowCnt; ++p)
{
for (auto q = *p; q != (*p) + colCnt; ++q)
{
cout << *q << " ";
}
}
cout << endl;
system("pause");
return 0;

}


猜你喜欢

转载自blog.csdn.net/sukeychen/article/details/80340876