C++标准规定的尺寸最小值,编译器被允许赋予这些类型更大的尺寸。
C++Primer第五版习题集的答案如下,已在VS2019中进行了测试。
012是一个八进制数,对应着十进制的10;
0xC是十六进制数,对应着十进制的12;
10e-2是一个浮点数,使用了科学计数法表示,大小为10*10-2=0.1
#include
#include
#include"Sales_item.h"
using namespace std;
int main()
{
cout << "2M\n";
cout << "2\tM\n";
return 0;
}
void*是一种特殊的指针类型,可以存放任意对象的地址。
顶层const:指针本身是一个常量
底层const:指针所指的对象是一个常量
执行对象的拷贝操作的时候,顶层const不受什么影响,拷入和拷出的对象必须具有相同的底层const资格。
auto一般会忽略掉顶层const,同时底层const会被保留。
如果希望得到的auto类型是顶层const,需要明确指出const auto = ……
decltype类型指示符:选择并返回操作数的数据类型。
如果使用的表达式不是一个变量,那么decltype返回表达式结果对应的类型:例如如果表达式是一个解引用操作,则得到引用类型。
赋值是一种会产生引用的类型表达式。
struct Sales_data
{
std::string bookNo;//书籍编号
unsigned units_sold = 0;//销售量
double sellingprice = 0.0;//零售价
double saleprice = 0.0;//实售价
double discount = 0.0;//折扣
double revenue = 0.0;//销售收入
};
#include
#include
using namespace std;
class Sales_data
{
//运算符重载
//友元函数
friend std::istream& operator >> (std::istream&, Sales_data&);
//友元函数
friend std::ostream& operator << (std::ostream&, const Sales_data&);
//友元函数
friend bool operator < (const Sales_data&, const Sales_data&);
//友元函数
friend bool operator == (const Sales_data&, const Sales_data&);
public://三种形式的构造函数
Sales_data() = default;
Sales_data(const std::string& book) :bookNo(book) {}
Sales_data(std::istream& is) { is >> *this; }
public:
Sales_data& operator += (const Sales_data&);
std::string isbn() const { return bookNo; }
private:
std::string bookNo;//书籍编号,隐式初始化为空串
unsigned units_sold = 0;//销售量,显示初始化为0
double sellingprice = 0.0;//原始价格,显式初始化为0.0
double saleprice = 0.0;//实售价格,显式初始化为0.0
double discount = 0.0;//折扣,显式初始化为0.0
};
inline bool compareIsbn(const Sales_data& lhs, const Sales_data& rhs)
{
return lhs.isbn() == rhs.isbn();
}
Sales_data operator + (const Sales_data&, const Sales_data&);
inline bool operator == (const Sales_data& lhs, const Sales_data& rhs)
{
return lhs.units_sold == rhs.units_sold &&
lhs.sellingprice == rhs.sellingprice &&
lhs.saleprice == rhs.saleprice &&
lhs.isbn() == rhs.isbn();
}
inline bool operator != (const Sales_data& lhs, const Sales_data& rhs)
{
return !(lhs == rhs);//基于运算符==给出!=定义
}
Sales_data& Sales_data::operator += (const Sales_data& rhs)
{
units_sold += rhs.units_sold;
saleprice = (rhs.saleprice * rhs.units_sold + saleprice * units_sold) / (rhs.units_sold + units_sold);
if (sellingprice != 0)
{
discount = saleprice / sellingprice;
}
return *this;
}
Sales_data operator + (const Sales_data& lhs, const Sales_data& rhs)
{
Sales_data ret(lhs);//把lhs的内容拷贝到临时变量ret中,便于运算
ret += rhs;
return ret;
}
std::istream& operator>>(std::istream& in, Sales_data& s)
{
in >> s.bookNo >> s.units_sold >> s.sellingprice >> s.saleprice;
if (in && s.sellingprice != 0)
{
s.discount = s.saleprice / s.sellingprice;
}
else {
s = Sales_data();//输入错误,重置输入的数据
}
return in;
}
std::ostream& operator<<(std::ostream& out, const Sales_data& s)
{
out << s.isbn() << " " << s.units_sold << " " << s.sellingprice << " " << s.saleprice << " " << s.discount;
return out;
}
int main()
{
Sales_data book;
std::cout << "请输入销售记录:ISBN 售出本数 原始价格 实售价格 " << std::endl;
while (std::cin >> book) {
std::cout << "ISBN 售出本数 原始价格 实售价格 折扣为:\n" << book << std::endl;
}
Sales_data trans1, trans2;
std::cout << "请输入两条相同ISBN的销售记录:" << std::endl;
std::cin >> trans1 >> trans2;
if (compareIsbn(trans1, trans2))
{
std::cout << "汇总信息:ISBN 售出本数 原始价格 实售价格 折扣为:\n" << trans1 + trans2 << std::endl;
}
else {
std::cout << "两条销售记录的ISBN不同" << std::endl;
}
Sales_data total, trans;
std::cout << "请输入几条ISBN相同的销售记录" << std::endl;
if (std::cin >> total) {
while (std::cin >> total)
{
if (compareIsbn(total, trans))//ISBN相同
total = total + trans;
else {
//ISBN不同
std::cout << "当前书籍ISBN不同" << std::endl;
break;
}
}
std::cout << "有效汇总信息: ISBN 售出本数 原始价格 实售价格 折扣为:\n" << total << std::endl;
}
else
{
std::cout << "没有数据" << std::endl;
return -1;
}
int num = 1;//记录当前书籍的销售记录总数
std::cout << "请输入若干销售记录:" << std::endl;
if (std::cin >> trans1)
{
while (std::cin >> trans2)
{
if (compareIsbn(trans1, trans2))//ISBN相同
num++;
else {
//ISBN不同
std::cout << trans1.isbn() << "共有" << num << "条销售记录" << std::endl;
trans1 = trans2;
num = 1;
}
}
std::cout << total.isbn() << "共有" << num << "条销售记录" << std::endl;
}
else {
std::cout << "没有数据" << std::endl;
return -1;
}
return 0;
}
while (std::cin >> book) {
std::cout << "ISBN 售出本数 原始价格 实售价格 折扣为:\n" << book << std::endl;
}
此处输入一次以后Enter不会退出循环,要求继续输入。然后使用Ctrl+Z虽然退出循环,但是后面所有的输入流都不会再执行。
解决:在后面的while输入循环前,加了个cin.clear();对cin标志位进行复位。即改为如下代码:
while (std::cin >> book) {
std::cout << "ISBN 售出本数 原始价格 实售价格 折扣为:\n" << book << std::endl;
}
std::cin.clear();
参考了以下博客:
C++:关于cin输入ctrl+Z之后不能再用问题的原因
预处理变量无视C++中关于作用域的规则。
#ifndef SALES_DATA_H_INCLUDED
// we're here only if SALESDATA_H has not yet been defined
#define SALES_DATA_H_INCLUDED
// Definition of Sales_item class and related functions goes here
#include
#include
class Sales_data
{
//运算符重载
//友元函数
friend std::istream& operator >> (std::istream&, Sales_data&);
//友元函数
friend std::ostream& operator << (std::ostream&, const Sales_data&);
//友元函数
friend bool operator < (const Sales_data&, const Sales_data&);
//友元函数
friend bool operator == (const Sales_data&, const Sales_data&);
public://三种形式的构造函数
Sales_data() = default;
Sales_data(const std::string& book) :bookNo(book) {}
Sales_data(std::istream& is) { is >> *this; }
public:
Sales_data& operator += (const Sales_data&);
std::string isbn() const { return bookNo; }
private:
std::string bookNo;//书籍编号,隐式初始化为空串
unsigned units_sold = 0;//销售量,显示初始化为0
double sellingprice = 0.0;//原始价格,显式初始化为0.0
double saleprice = 0.0;//实售价格,显式初始化为0.0
double discount = 0.0;//折扣,显式初始化为0.0
};
inline bool compareIsbn(const Sales_data& lhs, const Sales_data& rhs)
{
return lhs.isbn() == rhs.isbn();
}
Sales_data operator + (const Sales_data&, const Sales_data&);
inline bool operator == (const Sales_data& lhs, const Sales_data& rhs)
{
return lhs.units_sold == rhs.units_sold &&
lhs.sellingprice == rhs.sellingprice &&
lhs.saleprice == rhs.saleprice &&
lhs.isbn() == rhs.isbn();
}
inline bool operator != (const Sales_data& lhs, const Sales_data& rhs)
{
return !(lhs == rhs);//基于运算符==给出!=定义
}
Sales_data& Sales_data::operator += (const Sales_data& rhs)
{
units_sold += rhs.units_sold;
saleprice = (rhs.saleprice * rhs.units_sold + saleprice * units_sold) / (rhs.units_sold + units_sold);
if (sellingprice != 0)
{
discount = saleprice / sellingprice;
}
return *this;
}
Sales_data operator + (const Sales_data& lhs, const Sales_data& rhs)
{
Sales_data ret(lhs);//把lhs的内容拷贝到临时变量ret中,便于运算
ret += rhs;
return ret;
}
std::istream& operator>>(std::istream& in, Sales_data& s)
{
in >> s.bookNo >> s.units_sold >> s.sellingprice >> s.saleprice;
if (in && s.sellingprice != 0)
{
s.discount = s.saleprice / s.sellingprice;
}
else {
s = Sales_data();//输入错误,重置输入的数据
}
return in;
}
std::ostream& operator<<(std::ostream& out, const Sales_data& s)
{
out << s.isbn() << " " << s.units_sold << " " << s.sellingprice << " " << s.saleprice << " " << s.discount;
return out;
}
#endif
#include
#include
#include"Sales_data.h"
int main()
{
Sales_data book;
std::cout << "请输入销售记录:ISBN 售出本数 原始价格 实售价格 " << std::endl;
while (std::cin >> book) {
std::cout << "ISBN 售出本数 原始价格 实售价格 折扣为:\n" << book << std::endl;
}
std::cin.clear();
Sales_data trans1, trans2;
std::cout << "请输入两条相同ISBN的销售记录:" << std::endl;
std::cin >> trans1 >> trans2;
if (compareIsbn(trans1, trans2))
{
std::cout << "汇总信息:ISBN 售出本数 原始价格 实售价格 折扣为:\n" << trans1 + trans2 << std::endl;
}
else {
std::cout << "两条销售记录的ISBN不同" << std::endl;
}
Sales_data total, trans;
std::cout << "请输入几条ISBN相同的销售记录" << std::endl;
if (std::cin >> total) {
while (std::cin >> total)
{
if (compareIsbn(total, trans))//ISBN相同
total = total + trans;
else {
//ISBN不同
std::cout << "当前书籍ISBN不同" << std::endl;
break;
}
}
std::cout << "有效汇总信息: ISBN 售出本数 原始价格 实售价格 折扣为:\n" << total << std::endl;
}
else
{
std::cout << "没有数据" << std::endl;
return -1;
}
int num = 1;//记录当前书籍的销售记录总数
std::cout << "请输入若干销售记录:" << std::endl;
if (std::cin >> trans1)
{
while (std::cin >> trans2)
{
if (compareIsbn(trans1, trans2))//ISBN相同
num++;
else {
//ISBN不同
std::cout << trans1.isbn() << "共有" << num << "条销售记录" << std::endl;
trans1 = trans2;
num = 1;
}
}
std::cout << total.isbn() << "共有" << num << "条销售记录" << std::endl;
}
else {
std::cout << "没有数据" << std::endl;
return -1;
}
return 0;
}
#define
指令把一个名字设定为预处理变量。另外两个指令分别检查某个指定的预处理变量是否已经定义,一旦检查结果为真就会一直执行后续操作直到遇到#endif
终止。如果为假,便会忽略#ifdef
或#ifndef
到#endif
之间的部分#ifdef
:如果变量已定义则为真#ifndef
:如果变量未定义则为真