C++Primer第五版 习题答案 【总目录】:https://blog.csdn.net/Dust_Evc/article/details/114334124
2.1
C++ 规定 `short` 和 `int` 至少16位,`long` 至少32位,`long long` 至少64位。
带符号类型能够表示正数、负数和 0 ,而无符号类型只能够表示 0 和正整数。
用法:
1. 一般使用 `int` 做整数运算,`short` 因为太小在实际中用的少,`long` 通常和 `int` 有着相同的大小。如果数据非常大,可以使用 `long long` 。
2. 如果你确认数据是非负的,那么就使用 `unsigned` 无符号类型。
3. 执行浮点运算时用 `double` ,因为 `float` 通常精度不够而且双精度浮点数和单精度浮点数的计算代价相差无几。
2.2
使用 `double` 或 `float` 。
2.3
unsigned u = 10, u2 = 42;
std::cout << u2 - u << std::endl; //32
std::cout << u - u2 << std::endl; //4294967264
int i = 10, i2 = 42;
std::cout << i2 - i << std::endl; //32
std::cout << i - i2 << std::endl; //-32
std::cout << i - u << std::endl; //0
std::cout << u - i << std::endl; //0
2.4
#include <iostream>
int main()
{
unsigned u = 10, u2 = 42;
std::cout << u2 - u << std::endl; // 32
std::cout << u - u2 << std::endl; // 4294967264
int i = 10, i2 = 42;
std::cout << i2 - i << std::endl; // 32
std::cout << i - i2 << std::endl; // -32
std::cout << i - u << std::endl; // 0
std::cout << u - i << std::endl; // 0
return 0;
}
2.5
(a): 字符字面值,宽字符字面值,字符串字面值,宽字符串字面值
(b): 十进制整型,十进制无符号整型,十进制长整型,八进制整型,十六进制整型
(c): double, float, long double
(d): 十进制整型,十进制无符号整型,double, double
2.6
第一行定义的是十进制整型。
第二行定义的是八进制整型,但是 month 变量无效,因为八进制没有 9 。
2.7
(a): Who goes with Fergus?(换行),string 类型
(b): long double
(c): 无效,因为后缀 f 只能用于浮点字面量,而 1024 是整型。
(d): long double
2.8
int main()
{
std::cout << 2 << "\115\012";
std::cout << 2 << "\t\115\012";
return 0;
}
2.9
(a): 应该先定义再使用。
int input_value = 0;
std::cin >> input_value;
(b): 用列表初始化内置类型的变量时,如果存在丢失信息的风险,则编译器将报错。
double i = { 3.14 };
(c): 在这里 wage 是未定义的,应该在此之前将其定义。
double wage;
double salary = wage = 9999.99;
(d): 不报错,但是小数部分会被截断。
double i = 3.14;
2.10
`global_str` 和 `global_int` 是全局变量,所以初值分别为空字符串和 0 。
`local_int` 是局部变量并且没有初始化,它的初值是未定义的。
`local_str` 是 string 类的对象,它的值由类确定,为空字符串。
2.11
(a): 定义
(b): 定义
(c): 声明
2.12
`(a)`, `(c)`, `(d)` 非法。
2.13
`j` 的值是 `100` ,局部变量 `i` 覆盖了全局变量 `i` 。
2.14
合法。输出是 ` 100 45 ` 。
2.15
`(b)` 和 `(d)` 不合法,`(b)` 引用必须绑定在对象上,`(d)` 引用必须初始化。
2.16
(a): 合法。给 d 赋值为 3.14159。
(b): 合法。会执行自动转换(int->double)。
(c): 合法。会发生小数截取。
(d): 合法。会发生小数截取。
2.17
10, 10
2.18
int a = 0, b = 1;
int *p1 = &a, *p2 = p1;
// change the value of a pointer.
p1 = &b;
// change the value to which the pointer points
*p2 = b;
2.19
1. 引用是另一个对象的别名,而指针本身就是一个对象。
2. 引用必须初始化,并且一旦定义了引用就无法再绑定到其他对象。而指针无须在定义时赋初值,也可以重新赋值让其指向其他对象。
2.20
让指针 `pi` 指向 `i`,然后将 `i` 的值重新赋值为 42 * 42 (1764)。
2.21
(a): 非法。不能将一个指向 `double` 的指针指向 `int` 。
(b): 非法。不能将 `int` 变量赋给指针。
(c): 合法。
2.22
`if (p) // ...` 判断 p 是不是一个空指针,
`if (*p) // ...` 判断 p 所指向的对象的值是不是为 0
2.23
不能,因为首先要确定这个指针是不是合法的,才能判断它所指向的对象是不是合法的。
2.24
`void *` 是从 C语言那里继承过来的,可以指向任何类型的对象。而其他指针类型必须要与所指对象严格匹配。
2.25
(a): ip 是一个指向 int 的指针, i 是一个 int, r 是 i 的引用。
(b): i 是 int , ip 是一个空指针。
(c): ip 是一个指向 int 的指针, ip2 是一个 int。
2.26
const int buf; // 不合法, const 对象必须初始化
int cnt = 0; // 合法
const int sz = cnt; // 合法
++cnt; ++sz; // 不合法, const 对象不能被改变
2.27
int i = -1, &r = 0; // 不合法, r 必须引用一个对象
int *const p2 = &i2; // 合法
const int i = -1, &r = 0; // 合法
const int *const p3 = &i2; // 合法
const int *p1 = &i2; // 合法
const int &const r2; // 不合法, r2 是引用,引用没有顶层 const
const int i2 = i, &r = i; // 合法
2.28
int i, *const cp; // 不合法, const 指针必须初始化
int *p1, *const p2; // 不合法, const 指针必须初始化
const int ic, &r = ic; // 不合法, const int 必须初始化
const int *const p3; // 不合法, const 指针必须初始化
const int *p; // 合法. 一个指针,指向 const int
2.29
i = ic; // 合法, 常量赋值给普通变量
p1 = p3; // 不合法, p3 是const指针不能赋值给普通指针
p1 = ⁣ // 不合法, 普通指针不能指向常量
p3 = ⁣ // 合法, p3 是常量指针且指向常量
p2 = p1; // 合法, 可以将普通指针赋值给常量指针
ic = *p3; // 合法, 对 p3 取值后是一个 int 然后赋值给 ic
2.30
const int v2 = 0; int v1 = v2;
int *p1 = &v1, &r1 = v1;
const int *p2 = &v2, *const p3 = &i, &r2 = v2;
2.31
r1 = v2; // 合法, 顶层const在拷贝时不受影响
p1 = p2; // 不合法, p2 是底层const,如果要拷贝必须要求 p1 也是底层const
p2 = p1; // 合法, int* 可以转换成const int*
p1 = p3; // 不合法, p3 是一个底层const,p1 不是
p2 = p3; // 合法, p2 和 p3 都是底层const,拷贝时忽略掉顶层const
2.32
合法。指针可以初始化为 0 表示为空指针。
2.33
a=42; // a 是 int
b=42; // b 是一个 int,(ci的顶层const在拷贝时被忽略掉了)
c=42; // c 也是一个int
d=42; // d 是一个 int *,所以语句非法
e=42; // e 是一个 const int *, 所以语句非法
g=42; // g 是一个 const int 的引用,引用都是底层const,所以不能被赋值
2.34
#include <iostream>
int main()
{
int i = 0, &r = i;
auto a = r; // a是一个整数(r是i的别名,而i是以一个整数)
const int ci = i, &cr = ci;
auto b = ci; // b是一个整数(ci的顶层const特性被忽略掉了)
auto c = cr; // c是一个整数(cr是ci的别名,ci本身是一个顶层const)
auto d = &i; // d是一个整型指针(整数的地址就是指向整数的指针)
auto e = &ci; // e是一个指向整数常量的指针(对常量对象去地址是一种底层const)
const auto f = ci; // ci的推演类型是int,f是const int
auto &g = ci; // g是一个整型常量引用,绑定到ci
std::cout << a << std::endl;
std::cout << b << std::endl;
std::cout << c << std::endl;
std::cout << d << std::endl;
std::cout << e << std::endl;
std::cout << f << std::endl;
std::cout << g << std::endl;
std::cout << "--------------" << std::endl;
a = 42; b = 42; c = 42; //d = 42; e = 42; g = 42;
std::cout << a << std::endl;
std::cout << b << std::endl;
std::cout << c << std::endl;
std::cout << d << std::endl;
std::cout << e << std::endl;
std::cout << f << std::endl;
std::cout << g << std::endl;
return 0;
}
2.35
j 是 int,k 是 const int的引用,p 是const int *,j2 是const int,k2 是 const int 的引用。
2.36
c 是 int 类型,值为 4。d 是 int & 类型,绑定到 a,a 的值为 4 。
2.37
c 是 int 类型,值为 3。d 是 int& 类型,绑定到 a。
2.38
decltype 处理顶层const和引用的方式与 auto不同,decltype会将顶层const和引用保留起来。
int i = 0, &r = i;
//相同
auto a = i;
decltype(i) b = i;
//不同 d 是一个 int&
auto c = r;
decltype(r) d = r;
2.39
提示应输入分号。
2.40
struct Sale_data
{
std::string bookNo;
std::string bookName;
unsigned units_sold = 0;
double revenue = 0.0;
double price = 0.0;
//...
}
2.41
1.5.1
#include <iostream>
#include <string>
struct Sale_data
{
std::string bookNo;
unsigned units_sold = 0;
double revenue = 0.0;
};
int main()
{
Sale_data book;
double price;
std::cin >> book.bookNo >> book.units_sold >> price;
book.revenue = book.units_sold * price;
std::cout << book.bookNo << " " << book.units_sold << " " << book.revenue << " " << price;
return 0;
}
1.5.2
#include <iostream>
#include <string>
struct Sale_data
{
std::string bookNo;
unsigned units_sold = 0;
double revenue = 0.0;
};
int main()
{
Sale_data book1, book2;
double price1, price2;
std::cin >> book1.bookNo >> book1.units_sold >> price1;
std::cin >> book2.bookNo >> book2.units_sold >> price2;
book1.revenue = book1.units_sold * price1;
book2.revenue = book2.units_sold * price2;
if (book1.bookNo == book2.bookNo)
{
unsigned totalCnt = book1.units_sold + book2.units_sold;
double totalRevenue = book1.revenue + book2.revenue;
std::cout << book1.bookNo << " " << totalCnt << " " << totalRevenue << " ";
if (totalCnt != 0)
std::cout << totalRevenue / totalCnt << std::endl;
else
std::cout << "(no sales)" << std::endl;
return 0;
}
else
{
std::cerr << "Data must refer to same ISBN" << std::endl;
return -1; // indicate failure
}
}
1.6
#include <iostream>
#include <string>
struct Sale_data
{
std::string bookNo;
unsigned units_sold = 0;
double revenue = 0.0;
};
int main()
{
Sale_data total;
double totalPrice;
if (std::cin >> total.bookNo >> total.units_sold >> totalPrice)
{
total.revenue = total.units_sold * totalPrice;
Sale_data trans;
double transPrice;
while (std::cin >> trans.bookNo >> trans.units_sold >> transPrice)
{
trans.revenue = trans.units_sold * transPrice;
if (total.bookNo == trans.bookNo)
{
total.units_sold += trans.units_sold;
total.revenue += trans.revenue;
}
else
{
std::cout << total.bookNo << " " << total.units_sold << " " << total.revenue << " ";
if (total.units_sold != 0)
std::cout << total.revenue / total.units_sold << std::endl;
else
std::cout << "(no sales)" << std::endl;
total.bookNo = trans.bookNo;
total.units_sold = trans.units_sold;
total.revenue = trans.revenue;
}
}
std::cout << total.bookNo << " " << total.units_sold << " " << total.revenue << " ";
if (total.units_sold != 0)
std::cout << total.revenue / total.units_sold << std::endl;
else
std::cout << "(no sales)" << std::endl;
return 0;
}
else
{
std::cerr << "No data?!" << std::endl;
return -1; // indicate failure
}
}
2.42
Sale_data.h
struct Sale_data
{
std::string bookNo;
std::string bookName;
unsigned units_sold = 0;
double revenue = 0.0;
double price = 0.0;
}
1.5.1
#include <iostream>
#include "Sale_data.h"
int main()
{
Sales_data book;
double price;
std::cin >> book.bookNo >> book.units_sold >> price;
book.CalcRevenue(price);
book.Print();
return 0;
}
1.5.2
#include <iostream>
#include "Sale_data.h"
int main()
{
Sales_data book1, book2;
double price1, price2;
std::cin >> book1.bookNo >> book1.units_sold >> price1;
std::cin >> book2.bookNo >> book2.units_sold >> price2;
book1.CalcRevenue(price1);
book2.CalcRevenue(price2);
if (book1.bookNo == book2.bookNo)
{
book1.AddData(book2);
book1.Print();
return 0;
}
else
{
std::cerr << "Data must refer to same ISBN" << std::endl;
return -1;
}
}
1.6
#include <iostream>
#include "Sale_data.h"
int main()
{
Sales_data total;
double totalPrice;
if (std::cin >> total.bookNo >> total.units_sold >> totalPrice)
{
total.CalcRevenue(totalPrice);
Sales_data trans;
double transPrice;
while (std::cin >> trans.bookNo >> trans.units_sold >> transPrice)
{
trans.CalcRevenue(transPrice);
if (total.bookNo == trans.bookNo)
{
total.AddData(trans);
}
else
{
total.Print();
total.SetData(trans);
}
}
total.Print();
return 0;
}
else
{
std::cerr << "No data?!" << std::endl;
return -1;
}
}