2.1
- int、long、long long和short区别主要是在所占比特数上有所区别,int 和long通常占32bit,long long占 64bit,short占16bit。
- 无符号类型只能表示0和正数,有符号类型可以表示负数、0、正数;
- float和double主要差别在精度和所占比特数上。float一般32bit,有7个有效位;double一般64bit,有16个有效位
2.2
都应该最好选择double类型,因为利率、本金和付款都是可能有小数出现。
2.5
(a)
‘a’ char;
L’a’ wchar_t;
“a” char数组 ;
L"a" wchar_t数组
(b)10 int类型;
10u 类型为unisgned int(可缩写为unsigned);
10L 为long类型字面值;
10uL unsigned long
012 为8进制int字面值;
0xC 是十六进制int字面值
(c)3.14 double
3.14f float;
3.14L 为long double 字面值
(d)10 int
10u 为unsigned int类型字面值,
10.
double;
10e-2 double
2.6
数值前带0表示八进制,9不是8进制中的数字,所以int month = 09; 会发生编译错误
2.7
(a) Who goes with Fergus? 换行 ,类型:char数组
(b)3.14e1L 为31.4 类型long double
(c)1024.0f 结果为1024.0 类型float
(d)3.14L 结果为3.14 类型为long double
2.8
std::cout << "\x32\115\n"; // \x30 代表数字0
std::cout << "\x32\t\115\n";
2.9
(a)不能对定义语句进行运算操作,修改为:
int input_value;
std::cin >> input_value;
(b)列表初始化对于收缩转换无法自动进行,必须换成用括号或者等号进行初始化:
int i = 3.14;
int i(3.14);
©编译器提示wage为未定义标识符,需要改为
(d)编译器提示从“double”到“int”可能丢失数据
2.10
- global_str 默认初值为 空字符串
- global_int 默认初值为 0
- local_int 默认初值 未定义
- local_str 默认初值 空字符串
2.19
- 指针可以改变指向的对象,引用不可以改变绑定的对象
- 指针是一个对象,可以定义指针的指针;引用本身不是一个对象,不可以定义引用的引用
- 因为引用不是对象,没有实际地址,故不能定义指向引用的指针。
- 指针有空指针,或者不指向对象,引用不可以
- 指针可以不指定指向的对象,引用不可以。
2.25
int *ip, i, &r = i; //ip类型为 int * ;i类型为int类型,r为int变量的引用
//如果定义在全局作用域,ip为00000000,i为0,r为0
//如果定义在局部作用域,ip为未定义,i为未定义数,r为未定义
int i, *ip = 0; //i类型为int类型,ip类型为int *类型
//如果定义在【局部】作用域,i为未定义,ip为0
//定义在【全局】作用域,i为0,ip为0
int *ip, ip2; //ip为int*类型,ip2为int类型
//如果在全局作用域定义,ip为00000000,ip2为0
//如果在局部作用域定义,ip和ip2未定义
2.26
int i = -1, & r = 0; //非法,非常量引用初始化也只能用一个非常量对象
int *const p2 = &i2; //p2是一个常量,存放int * 变量,若i2是一个int变量
const int i = -1, &r = 0; //正确,对const的引用可以绑定字面值(常量)
const int *const p3 = &i2; //正确,不论i2是否为常量,指向常量对象的常量指针都可以指向i2
const int *p1 = &i2; //正确,p1是一个指针,指向const int 类型对象,无论i2是不是const类型,都可以让p1指向i2,p1的值可以改变,但是p1指向的对象的内容不可以改变
const int &const r2; //错误,一个指向常量对象的常量指针必须初始化
const int i2 = i, &r = i; //正确,对const的引用可以绑定一个不管是不是const的int对象,因为都会将其存储到一个临时值中,并让该常量引用绑定到临时值上
2.28
int i, *const cp; //错误,定义个int对象和一个常量(该常量存放int * 对象),常量cp和整型变量必须初始化
int *p1, *const p2; //错误,定义一个指向int对象的指针和一个常量(存放int * 对象),必须都要初始化
const int ic, &r = ic; //正确,定义一个整型常量ic(在全局有默认值),和一个对const的引用绑定到ic上。
const int *const p3; //错误,p3是一个指向常量对象的常量指针必须初始化
const int *p; //p是一个指向const int类型对象的指针,指针值可以修改,但是指针指向的对象不可以更改
2.29
i = ic;//正确,用一个const int对象的值拷贝给int对象合法
p1 = p3; //错误,p1是普通的指针,而p3是指向常量对象的指针,指针的值和指向对象都不可以更改,如果将p3赋值给p1,则表明可以通过*p1来修改p3指向的对象,矛盾。
p1 = ⁣ //错误,非常量指针不可以指向一个常量对象。
p3 = ⁣ //错误,指向常量对象的常量指针不能改变。
p2 = p1; //错误,常量p2不可以改变其值,p2是一个常量(存放指向int对象的指针)
ic = *p3;//错误,ic是一个常量不可以修改值。
2.30
const int v2 = 0; //v2是顶层const,即v2本身的值不可以修改
int v1 = v2; //v1不为顶层以及底层const,只是用const的拷贝来给v1赋值
int *p1 = &v1, &r1 = v1; //指针p1 和引用 r1都不是顶层或底层const
const int *p2 = &v2, *const p3 = &i, &r2 = v2;
//p2为底层const,即p2为指针,指向的对象为常量;p3 即为顶层也为底层const;r2 为底层const
2.33
a = 42; // ok
b = 42; // ok
c = 42; // ok
d = 42; //错误,不能用int类型值给int *类型赋值
e = 42; //错误,42是int类型值,e是const int *类型
g = 42; // 错误,不能给int常量引用【赋值】
2.34
const int i = 42; //int常量
auto j = i; //int变量
const auto& k = i; //int常量的引用
auto* p = &i; //int const *,即指向const int对象的指针(auto 后的*可不加)
const auto j2 = i, & k2 = i; // int常量,int常量的引用
2.36
int a = 3, b = 4;
decltype(a) c = a; //c为int
decltype((b)) d = a; //d为int &
++c;
++d;
//abcd均为4
2.37
int a = 3, b = 4;
decltype(a) c = a; //c为int,3
decltype(a = b) d = a;//d为int &,3
2.38
auto是根据初始化类型来判断,decltype是根据一个额外的表达式来判断
//auto和decltype相同的情况
int a = 5;
decltype (a) b = 6;
auto c = a;
c = 6;
//不同的情况1
const int x = 3;
decltype(x) y = 4;
auto z = x;
y = 5;//错误,y推导出的是const int,不可以赋值
z = 5;
//2
int i = 0, & j = i;
auto l = j; //l是int类型,因为实际上是用j绑定的对象来给l赋值
decltype(j) k = i; //k为int类型的引用
2.42
Sales_data.h
#ifndef SALES_DATA_H // # ifndef .... #endif作用是头文件保护,防止重复包含头文件带来的问题
#define SALES_DATA_H
#include<string>
struct Sales_data {
std::string ISBN;
double totalPrice;
int amount;
};
#endif
main.h
#include<iostream>
#include<string>
#include "Sales_data.h"
void p20()
{
Sales_data book;
double price;
while (std::cin >> book.ISBN >> book.amount >> price)
{
book.totalPrice = price * book.amount;
std::cout << book.ISBN << ' ' << book.amount << ' ' << book.totalPrice;
if (book.amount > 0)
std::cout << ' ' << book.totalPrice / book.amount << std::endl;
else
std::cout << ' ' << "No Sales!" << std::endl;
}
}
void p21()
{
Sales_data book1, book2;
double price = 0.0;
std::cin >> book1.ISBN >> book1.amount >> price;
book1.totalPrice = price * book1.amount;
std::cin >> book2.ISBN >> book2.amount >> price;
book2.totalPrice = price * book2.amount;
//只用两条记录的ISBN号相同才进行相加
if (book1.ISBN == book2.ISBN)
{
//总销售量
book1.amount += book2.amount;
//总销售价格
book1.totalPrice += book2.totalPrice;
std::cout << book1.ISBN << ' ' << book1.amount << ' ' << book1.totalPrice << ' ';
if (book1.amount > 0)
std::cout << book1.totalPrice / book1.amount << std::endl;
else
std::cout << "No Sales!" << std::endl;
//return 0 表示成功
}
else
{
std::cerr << "Data must refer to the same ISBN"
<< std::endl;
// return -1;表示失败
}
}
void p22()
{
Sales_data book1, book2;//book1存放结果,book2用于存放输入
double price = 0.0;
if (!(std::cin >> book1.ISBN >> book1.amount >> price))
return;
book1.totalPrice = book1.amount * price;
while (std::cin >> book2.ISBN >> book2.amount >> price)
{
if (book1.ISBN != book2.ISBN)
{
std::cerr << "Data must refer to the same ISBN!" << std::endl;
return;
}
book2.totalPrice = book2.amount * price;
book1.amount += book2.amount;
book1.totalPrice += book2.totalPrice;
}
std::cout << book1.ISBN << ' ' << book1.amount
<< ' ' << book1.totalPrice << ' ';
if (book1.amount > 0)
{
std::cout << book1.totalPrice / book1.amount << std::endl;
}
else
std::cout << "No Sales!" << std::endl;
}
void p23()
{
Sales_data book1, book2;
double price = 0.0;
int num = 0;
//如果第一次输入的销售记录都错误,那么直接退出
if (!(std::cin >> book1.ISBN >> book1.amount >> price))
return;
num++;
book1.totalPrice = book1.amount * price;
while (std::cin >> book2.ISBN >> book2.amount >> price)
{
book2.totalPrice = book2.amount * price;
if (book1.ISBN == book2.ISBN)
{
book1.amount += book2.amount;
book1.totalPrice += book2.totalPrice;
num++; //记录数递增1
}
else //输入新的书的记录需要把前一本书的销售记录打印出来
{
std::cout << book1.ISBN << ' ' << book1.amount
<< ' ' << book1.totalPrice << ' ';
if (book1.amount > 0)
std::cout << book1.totalPrice / book1.amount << std::endl;
else
std::cout << "No Sales!" << std::endl;
std::cout << "num = " << num << std::endl;
num = 1;
book1 = book2;
}
}
std::cout << book1.ISBN << ' ' << book1.amount
<< ' ' << book1.totalPrice << ' ';
if (book1.amount > 0)
std::cout << book1.totalPrice / book1.amount << std::endl;
else
std::cout << "No Sales!" << std::endl;
std::cout << "num = " << num << std::endl;
}
void p25()
{
Sales_data total;//保存下一条交易记录的变量
double price = 0.0;
//读入第一条交易记录,并确保有数据可以处理
if (std::cin >> total.ISBN >> total.amount >> price)
{
total.totalPrice = price * total.amount;
Sales_data trans; //保存和的变量(存放输入)
//读入并处理剩余交易记录
while (std::cin >> trans.ISBN >> trans.amount >> price)
{
trans.totalPrice = price * trans.amount;
if (total.ISBN == trans.ISBN)
{
total.amount += trans.amount;
total.totalPrice += trans.totalPrice;
}
else//输入了一本新书的数据,需要把前一本书的数据打印出来
{
std::cout << total.ISBN << ' ' << total.amount << ' '
<< total.totalPrice << ' ';
if (total.amount > 0)
std::cout << total.totalPrice / total.amount << std::endl;
else
std::cout << "No Sales!" << std::endl;
total = trans;
}
}
//输出最后一次的记录
std::cout << total.ISBN << ' ' << total.amount << ' '
<< total.totalPrice << ' ';
if (total.amount > 0)
std::cout << total.totalPrice / total.amount << std::endl;
else
std::cout << "No Sales" << std::endl;
}
else
{
//没有输入!警告读者
std::cerr << "No Data?!" << std::endl;
//return -1;
}
}
int main()
{
//p20();
//p21();
//p22();
p23();
//p25();
return 0;
}