C++ Primer 第一章习题
1. c++ primer 第一章习题
1.1 练习1.3
#include<iostream>
int main(){
std::cout << "Hello World!\n";
return 0;
}
下图来自:Hello World
注意:别为了方便cout前不写std::而直接用 using namespace std; 把所有symbols都引入,而是写为 std::cout
写完后编译源码形成可执行文件
编译时可以加入一些参数
编译和执行过程展示
1.2 练习1.4
#include<iostream>
int main(){
//初始化两个整数
int n1,n2;
std::cout << "Input two integer:";
//输入两个整数
std::cin >> n1 >> n2;
//两个整数相乘
std::cout << "product of two integer:" << n1*n2 << '\n';
return 0;
}
下图来自:Input & Output (Basics)
注意:别每次输出都用std::endl结尾,每次调用 std::endl 都会刷新输出缓冲区并立即写入输出,这会造成性能退化
注意:
仅对运算符 << 进行一次调用(每次额外的调用都会产生少量开销)
仅当您绝对需要确保某些输出需要立即实现时才使用 std::endl
1.3 练习1.6
1.4 练习1.7
注意:嵌套注释是非法的
1.5 练习1.9
#include<iostream>
int main(){
int i=50,result=0;
while (i<=100)
{
result+=i;
i++;
}
std::cout << "sum of 50 to 100:" << result << std::endl;
return 0;
}
1.6 练习1.10
#include<iostream>
int main(){
int i=10;
while (i>=0)
{
std::cout << i << '\n';
i--;
}
return 0;
}
1.7 练习 1.11
#include<iostream>
int main(){
int a=0,b=0;
std::cout << "please input two integer:";
std::cin >> a >> b;
std::cout << "integer from " << a << " to " << b << ": ";
for (size_t i = a; i <= b; i++)
{
std::cout << i << " ";
}
std::cout << std::endl;
return 0;
}
注意:为避免bugs,当我们在声明变量时要进行初始化
注意:要充分考虑用户输入的各种情况
1.8 练习 1.13
1.4.1节中的练习包括:1.9、1.10、1.11
用for重写练习1.9
#include<iostream>
int main(){
int sum = 0;
for (size_t i = 50; i <= 100; i++)
{
sum += i;
}
std::cout << "The sum of 50 to 100 is " << sum << std::endl;
return 0;
}
什么时候使用size_t?
数组下标、循环计数、指定分配内存大小等等
用for重写练习1.10
#include<iostream>
int main(){
for (size_t i = 10; i >= 0; i--)
{
std::cout << i << '\n';
}
std::cout << std::endl;
return 0;
}
打印出来的不是10到0,而是一堆大整数
原因:当前的代码会导致无限循环,因为 size_t 是无符号整数,当 i 减到 0 时再减 1 会导致它变成一个非常大的正数。
解决:去掉等于0
#include<iostream>
int main(){
for (size_t i = 10; i > 0; i--) //去掉=0
{
std::cout << i << '\n';
}
std::cout << std::endl;
return 0;
}
参考答案:
用for重写练习1.11
#include<iostream>
int main(){
int a=0,b=0;
std::cout<<"Enter two numbers:";
std::cin>>a>>b;
if (a<=b)
{
for (size_t i = a; i <= b; i++)
{
std::cout<<i<<'\n';
}
}
else
{
for (size_t i = b; i <= a; i++)
{
std::cout<<i<<'\n';
}
}
std::cout<<std::endl;
return 0;
}
什么时候使用std::endl?
参考答案:
1.9 练习 1.14
1.10 练习 1.15
1.11 练习 1.16
#include<iostream>
int main(){
int number=0,sum=0;
std::cout<<"Enter numbers (Add new line in the end):"<<std::endl;
while (std::cin>>number) //当输入流成功读取一个整数时,循环继续
{
sum+=number;
}
std::cout<<"the sum of these numbers:"<< sum <<std::endl;
return 0;
}
参考答案:
1.12 练习 1.20
Sales_item.h
/*
#ifndef 和 #endif 是为了防止多次包含相同的头文件。这种技术称为“包含保护”或“头文件保护”。它的目的是避免重复定义和编译错误。
第一次包含:
当头文件第一次被包含时,SALESITEM_H 未定义,因此 #ifndef SALESITEM_H 条件为真,编译器会处理接下来的代码。
#define SALESITEM_H 定义了 SALESITEM_H,以便下次包含该文件时,#ifndef SALESITEM_H 条件为假。
后续包含:
当头文件再次被包含时,SALESITEM_H 已定义,因此 #ifndef SALESITEM_H 条件为假,编译器会跳过 #ifndef 和 #endif 之间的所有代码。
*/
#ifndef SALESITEM_H // 如果 SALESITEM_H 未定义
#define SALESITEM_H // 定义 SALESITEM_H
// 包含输入输出流库
#include <iostream>
// 包含字符串库
#include <string>
// 定义 Sales_item 类
class Sales_item {
// 声明友元函数,允许这些函数访问类的私有成员
friend std::istream& operator>>(std::istream&, Sales_item&);
friend std::ostream& operator<<(std::ostream&, const Sales_item&);
friend bool operator<(const Sales_item&, const Sales_item&);
friend bool operator==(const Sales_item&, const Sales_item&);
public:
// 默认构造函数,用于初始化内置类型的成员
Sales_item() = default;
// 带参数的构造函数,用于初始化 bookNo
Sales_item(const std::string &book): bookNo(book) { }
// 从输入流中读取数据的构造函数
Sales_item(std::istream &is) { is >> *this; }
public:
// 成员函数,重载 += 运算符
Sales_item& operator+=(const Sales_item&);
// 成员函数,返回书籍编号
std::string isbn() const { return bookNo; }
// 成员函数,计算平均价格
double avg_price() const;
private:
// 私有成员变量,书籍编号
std::string bookNo; // 隐式初始化为空字符串
// 私有成员变量,售出数量
unsigned units_sold = 0; // 显式初始化
// 私有成员变量,收入
double revenue = 0.0;
};
// 内联函数,比较两个 Sales_item 对象的 ISBN
inline
bool compareIsbn(const Sales_item &lhs, const Sales_item &rhs)
{ return lhs.isbn() == rhs.isbn(); }
// 非成员函数,重载 + 运算符
Sales_item operator+(const Sales_item&, const Sales_item&);
// 内联函数,重载 == 运算符
inline bool
operator==(const Sales_item &lhs, const Sales_item &rhs)
{
// 比较两个 Sales_item 对象的所有成员变量
return lhs.units_sold == rhs.units_sold &&
lhs.revenue == rhs.revenue &&
lhs.isbn() == rhs.isbn();
}
// 内联函数,重载 != 运算符
inline bool
operator!=(const Sales_item &lhs, const Sales_item &rhs)
{
// 基于 == 运算符定义 != 运算符
return !(lhs == rhs);
}
// 成员函数,重载 += 运算符
// 假设两个对象都引用相同的 ISBN
Sales_item& Sales_item::operator+=(const Sales_item& rhs)
{
// 累加售出数量和收入
units_sold += rhs.units_sold;
revenue += rhs.revenue;
return *this;
}
// 非成员函数,重载 + 运算符
// 假设两个对象都引用相同的 ISBN
Sales_item
operator+(const Sales_item& lhs, const Sales_item& rhs)
{
// 创建一个临时对象 ret,初始化为 lhs
Sales_item ret(lhs);
// 将 rhs 的内容添加到 ret
ret += rhs;
// 返回 ret
return ret;
}
// 非成员函数,重载 >> 运算符
std::istream&
operator>>(std::istream& in, Sales_item& s)
{
// 临时变量,用于存储价格
double price;
// 从输入流中读取书籍编号、售出数量和价格
in >> s.bookNo >> s.units_sold >> price;
// 检查输入是否成功
if (in)
// 计算收入
s.revenue = s.units_sold * price;
else
// 输入失败,将对象重置为默认状态
s = Sales_item();
return in;
}
// 非成员函数,重载 << 运算符
std::ostream&
operator<<(std::ostream& out, const Sales_item& s)
{
// 输出书籍编号、售出数量、收入和平均价格
out << s.isbn() << " " << s.units_sold << " "
<< s.revenue << " " << s.avg_price();
return out;
}
// 成员函数,计算平均价格
double Sales_item::avg_price() const
{
// 如果售出数量不为零,返回平均价格
if (units_sold)
return revenue/units_sold;
else
// 否则返回 0
return 0;
}
#endif // 结束 #ifndef 块
#include<iostream>
#include"Sales_item.h"
/*
book私有成员变量
private:
// 私有成员变量,书籍编号
std::string bookNo; // 隐式初始化为空字符串
// 私有成员变量,售出数量
unsigned units_sold = 0; // 显式初始化
// 私有成员变量,收入
double revenue = 0.0;
重载输入
// 非成员函数,重载 >> 运算符
std::istream&
operator>>(std::istream& in, Sales_item& s)
{
// 临时变量,用于存储价格
double price;
// 从输入流中读取书籍编号、售出数量和价格
in >> s.bookNo >> s.units_sold >> price;
// 检查输入是否成功
if (in)
// 计算收入
s.revenue = s.units_sold * price;
else
// 输入失败,将对象重置为默认状态
s = Sales_item();
return in;
}
重载输出
// 非成员函数,重载 << 运算符
std::ostream&
operator<<(std::ostream& out, const Sales_item& s)
{
// 输出书籍编号、售出数量、收入和平均价格
out << s.isbn() << " " << s.units_sold << " "
<< s.revenue << " " << s.avg_price();
return out;
}
*/
int main(){
//实例化类对象
Sales_item book;
//读取ISBN编号、售出数量和总价
std::cout << "请输入书籍编号、售出数量和总价:" << std::endl;
//读取多本书籍销售记录
while(std::cin >> book)
{
//将每条记录打印到标准输出上
std::cout << "ISBN、售出数量、总价、单价" << '\n' << book << std::endl;
}
return 0;
}
参考答案:
1.13 练习 1.21
#include<iostream>
#include"Sales_item.h"
/*
book私有成员变量
private:
// 私有成员变量,书籍编号
std::string bookNo; // 隐式初始化为空字符串
// 私有成员变量,售出数量
unsigned units_sold = 0; // 显式初始化
// 私有成员变量,收入
double revenue = 0.0;
重载输入
// 非成员函数,重载 >> 运算符
std::istream&
operator>>(std::istream& in, Sales_item& s)
{
// 临时变量,用于存储价格
double price;
// 从输入流中读取书籍编号、售出数量和价格
in >> s.bookNo >> s.units_sold >> price;
// 检查输入是否成功
if (in)
// 计算收入
s.revenue = s.units_sold * price;
else
// 输入失败,将对象重置为默认状态
s = Sales_item();
return in;
}
重载输出
// 非成员函数,重载 << 运算符
std::ostream&
operator<<(std::ostream& out, const Sales_item& s)
{
// 输出书籍编号、售出数量、收入和平均价格
out << s.isbn() << " " << s.units_sold << " "
<< s.revenue << " " << s.avg_price();
return out;
}
重载+
// 非成员函数,重载 + 运算符
// 假设两个对象都引用相同的 ISBN
Sales_item
operator+(const Sales_item& lhs, const Sales_item& rhs)
{
// 创建一个临时对象 ret,初始化为 lhs
Sales_item ret(lhs);
// 将 rhs 的内容添加到 ret
ret += rhs;
// 返回 ret
return ret;
}
*/
int main(){
//实例化类对象
Sales_item book;
Sales_item book2;
//输出提示信息
std::cout << "Please input two books' sales information:" << std::endl;
//读取两本书的销售信息
std::cin >> book >> book2;
//检查两本书是否是同一本
if(book.isbn() == book2.isbn()){
//将每条记录打印到标准输出上
std::cout << "ISBN、售出数量、总价、单价" << std::endl;
//如果是同一本书,输出两本书的销售信息
std::cout << book + book2 << std::endl;
}else{
//如果不是同一本书,输出错误信息
std::cerr << "Data must refer to same ISBN" << std::endl;
return -1;
}
return 0;
}
参考答案:
头文件中提供了比较两本书isbn的函数
// 内联函数,比较两个 Sales_item 对象的 ISBN
inline
bool compareIsbn(const Sales_item &lhs, const Sales_item &rhs)
{ return lhs.isbn() == rhs.isbn(); }
头文件中重载了加号操作符
// 非成员函数,重载 + 运算符
// 假设两个对象都引用相同的 ISBN
Sales_item
operator+(const Sales_item& lhs, const Sales_item& rhs)
{
// 创建一个临时对象 ret,初始化为 lhs
Sales_item ret(lhs);
// 将 rhs 的内容添加到 ret
ret += rhs;
// 返回 ret
return ret;
}
1.14 练习 1.22
#include<iostream>
#include"Sales_item.h"
int main() {
Sales_item total; // 保存当前 ISBN 的总和
std::cout << "Please input the sales record: " << std::endl;
if (std::cin >> total) { // 读取第一条销售记录
Sales_item trans; // 保存每一条销售记录
while (std::cin >> trans) { // 读取剩余的销售记录
if (compareIsbn(total,trans)) { // 检查 ISBN 是否相同
total += trans; // 更新总和,相同书的销售记录合并
} else {
std::cout << "ISBN is different" << std::endl;
}
}
std::cout << "Total for ISBN " << total.isbn() << ": " << total << std::endl; // 输出最后一组 ISBN 的总和
} else {
std::cerr << "No data?!" << std::endl; // 没有输入任何数据
return -1; // 表示失败
}
return 0; // 表示成功
}
参考答案:
1.15 练习 1.23
#include <iostream>
#include "Sales_item.h"
int main() {
Sales_item currentBook, newBook;
int count = 0;
int cnt[100] = {0}; // 假设最多有 100 种不同的 ISBN
// 读取 ISBN、售出数量和价格
std::cout << "请输入书籍信息(Ctrl+D 结束输入):" << std::endl;
if (std::cin >> currentBook) {
cnt[count]++; // 统计第一条记录
while (std::cin >> newBook) {
if (compareIsbn(currentBook, newBook)) { // ISBN 相同
cnt[count]++;
} else { // ISBN 不同
currentBook = newBook; // 更新当前书籍
cnt[++count]++; // 统计新 ISBN 的记录
}
}
} else {
std::cerr << "No data?!" << std::endl;
return -1; // 表示失败
}
// 打印每个 ISBN 的销售记录数量
for (int i = 0; i <= count; i++) {
std::cout << "ISBN " << i + 1 << " has " << cnt[i] << " records." << std::endl;
}
return 0; // 表示成功
}
参考答案:
#include <iostream>
#include "Sales_item.h"
int main() {
Sales_item trans1, trans2;
int num = 1;
std::cout << "输入多条销售记录"<< std::endl;
if (std::cin>>trans1)
{
while (std::cin>>trans2) //读入后续交易记录
{
//检查两条交易记录是否有相同的ISBN
if (compareIsbn(trans1, trans2))
{
num++;
}else{ //ISBN不同
std::cout << "ISBN:" << trans1.isbn() << "有" << num << "条销售记录" << std::endl; //打印相同书籍的销售记录
trans1 = trans2; //将新书籍销售记录赋给trans1
num = 1; //重置num
}
}
std::cout << "ISBN:" << trans1.isbn() << "有" << num << "条销售记录" << std::endl;
}else{ //没有读入数据
std::cerr << "No data?!" << std::endl;
return -1;
}
return 0;
}
每次比较两个书籍的ISBN,如果一样就num加一,再读入一条记录,比较两条记录,如果ISBN不一样,先打印之前的trans1的记录,然后将这条不一样的记录覆盖trans1,用于下一次比较,对应num置1
原文地址:https://blog.csdn.net/weixin_48524215/article/details/142620958
免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!