cppPrimer第二章习题

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 = &ic; //错误,非常量指针不可以指向一个常量对象。

p3 = &ic; //错误,指向常量对象的常量指针不能改变。

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;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值