C++ primer(5e)第2章习题

2019.04.27第二遍

特别注意的地方

  1. 与其他整型不同,字符型被分成了三种:char、unsigned char、signed char。char是哪种是由编译器决定的。
  2. 当我们赋给带符号类型一个超出它表示范围的值时,结果是未定义的。此时,程序可能继续工作、可能崩溃、也可能产生垃圾数据。
  3. 类型short没有对应的字面值。
  4. 十进制字面值不可能是负值,如有有个带负号的字面值,那么那个负号作用仅仅是对字面值取负值。
  5. 字符串字面值的实际长度要比它的内容多1 。
  6. 对象是指一块能存储数据并具有某种类型的内存空间。
  7. 初始化和赋值是两个完全不同的操作。
  8. 定义于任何函数体之外的变量被初始化为0,定于在函数体内部的内置类型变量将不被初始化。
  9. 用花括号来初始化变量被称为列表初始化,这种初始化有一个重要特点:如果我们使用列表初始化且初始值存在丢失信息的风险,则编译器会报错。
  10. 如果想声明一个变量而非定义它,就在变量名前添加关键字extern,而且不要显式地初始化变量。任何包含了显示初始化的声明即成为定义。
  11. 在函数体内部,如果试图初始化一个由extern关键字标记的变量,将引发错误。
  12. 用户自定义的标识符中不能连续出现两个下划线,也不能以下划线紧连大写字母开头。定义在函数体外的标识符不能以下划线开头。
  13. 右值引用主要用于内置类。引用必须被初始化。引用类型的初始值必须是一个对象。
  14. 指针是对象且无须在定义时赋值。不能定义指向引用的指针。
  15. 使用未经初始化的指针是引发运行时错误的一大原因。
  16. 如果利用一个对象去初始化另外一个对象,则它们是不是const都无关紧要。
  17. auto定义的变量必须有初始值;会忽略掉顶层const。
  18. decltype((variable))的结果永远是引用。

2.1

1.一个int至少和一个short一样大,一个long至少个一个int一样大,一个long long 至少和一个long一样大。
2.带符号类型可以表示正数、负数或0,无符号类型则仅能表示大于等于0的值。
3.一般来说,float类型有7个有效位,double类型有16个有效位。
(float至少有6个有效位,double至少有10个有效位)

2.2

利率:double(floatdouble的计算代价相差不大,对于某些机器,double更快)
本金:long long (不清楚你是不是想买豪宅)
付款:long long (同上)

2.3

unsigned u = 10, u2 = 42;
std::cout << u2 - u << std::endl;     // 32
std::cout << u - u2 << std::endl;     //  2^32 - 32 

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
int main()
{
	unsigned u = 10, u2 = 42;
	int i = 10, i2 = 42;

	std::cout << u2 - u << std::endl;
	std::cout << u - u2 << std::endl;
	std::cout << i2 - i << std::endl;
	std::cout << i - i2 << std::endl;
	std::cout << i - u << std::endl;
	std::cout << u - i << std::endl;
	return 0;
}

运行结果如下
C++ primer(5e)第2章习题_第1张图片

2.5

 (a) 'a', L'a', "a", L"a"   // 
 字符字面值:char ;宽字符型字面值: wchar_t;  字符串字面值 ; 宽字符串字面值  
 (b) 10, 10u, 10L, 10uL, 012, 0xC
 int , unsigned int , long , unsigned long, 八进制,16进制
 (c) 3.14, 3.14f, 3.14L
 double, float, long double
 (d) 10, 10u, 10., 10e-2
 int , unsigned int, 浮点型字面值, 科学计数法

2.6

int month = 9, day = 7;
int month = 09, day = 07;
有区别,上面的day为10进制,下面的day为8进制。

2.7

(a) 只知道/145/012构成转义字符
(b)long double型加科学计数法 31.4
(c) float1024.0
(d) long double3.14

2.8

#include
int main()
{
	std::cout << "2\x4d\n" << std::endl;
	std::cout << "2\t\x4d\n" << std::endl;
	return 0;
}

2.9

(a) 错误。未定义的input_value,改为 int input_value; std::cin >> input_value;
(b) 错误。从doubleint 需要收缩变换
(c) =从右向左结合,wage未定义类型
(d) 可以运行。

2.10

std::string global_str;
int global_int;
int main()
{
	int local_int;
	std::string local_str;
}
定义于任何函数体之外的变量被初始化为0,故global_str = "0", global_int = 0。
定义在函数体内部的内置类型变量不被初始化,故local_int, local_str值未定义。

2.11

(a)定义
(b)声明并定义
(c)声明

2.12

(a)非法
(b)合法 
(c)非法
(d)非法
(e)合法

2.13

100

2.14

合法
输出:100 45
for循环定义的i到结束循环就不能使用了,故i输出为100

2.15

(a)不太好,但是可以。
(b)不合法,引用类型的初始值必须是一个对象
(c)合法
(d)不合法,引用必须被初始化

2.16

(a)给d赋值为3.14159
(b)可以,不太好。把int类型的i的值赋给double类型d 
(c)不合法,
(d)不合法,r1的初始值必须为int型对象

2.17

10 10

2.18

#include
int main()
{
	int i = 12;
	int *p = &i;
	// 修改指针的值
	std::cout << p << std::endl;
	p++;
	std::cout << p << std::endl;
	/* 修改指针所指对象的值
	std::cout << *p << std::endl;
	(*p)++;
	std::cout << *p << std::endl;
	*/
	return 0;
}

2.19

指针:允许赋值和拷贝;在生命周期内可以指向不同对象;不需要在定义时赋初值。
引用: 不能定义引用的引用;定义引用时程序是把引用和它的初始值绑定在一起,不是拷贝;引用必须被初始化。

2.20

把i乘以2

2.21

(a)非法,试图把int型对象的地址赋给double型指针
(b)非法,不能把int变量直接赋给指针
(c)合法,把i的地址赋给指针ip

2.22

if(p) // ...         如果指针不为空,则进行下面的语句
if(*p) //...      如果指针指向的值不为空,则进行下面的语句

2.23

先用*p将指针所指对象的值输出,如果报错,则说明指针指向无效的对象,然后用if(p == NULL)进行判断。

2.24

void*指针可用于存放任意对象的地址;而lp指针为long型,不能存在int类型的对象的地址。

2.25

(a)ip为int型指针,i为int型变量,r为对int型变量i的引用
(b)i为int型变量,ip为所指对象的值为0int型指针
(c)ip为int型指针,ip2为int型变量

2.26

(a)不合法,const对象必须初始化
(b)合法
(c)合法
(d)++sz不合法   const对象不能改变值

2.27

(a)不合法,不能为非常量引用绑定字面值
(b)合法
(c)合法
(d)合法
(e)合法
(f)不合法,引用必须初始化
(g)不合法,这样可通过修改r的值来修改i2的值

2.28

(a)i为int类型的变量,cp为int类型的常量指针
(b)p1为int类型指针,p2为int类型常量指针
(c)ic为int类型常量,r为整形常量引用
(d)p3为指向int类型常量的常量指针
(e)p为指向int类型常量的指针

2.29

(a)不合法,不能把常量赋给变量
(b)不合法,同上
(c)不合法,同上
(d)合法
(e)合法
(f)不合法,左边应是变量,不能为常量

2.30

const int v2 = 0;  // 顶层const
int v1 = v2;      // 不合法
int *p1 = &v1, &r1 = v1;   //  没有
const int *p2 = &v2, *const p3 = &i, &r2 = v2; // p2为底层const
   //p3靠右的为顶层const,靠左的为底层const

2.31

r1 = v2;    // 不合法
p1 = p2;    // 不合法
p2 = p1;    // 合法
p1 = p3;    // 不合法
p2 = p3;   // 不合法

2.32

不合法
int null = 0, *p = &null;

2.33

a = 42;    // 合法
b = 42;    // 合法
c = 42;    // 合法
d = 42;    // 不合法
e = 42;   // 不合法
g = 42;   // 不合法

2.34

C++ primer(5e)第2章习题_第2张图片
17、18、19行出现问题,说明我上一个习题推断正确

2.35

const int i = 42;
auto j = i; const auto &k = i; auto *p = &i;
const auto j2 = i, &k2 = i;1)j是一个整数(i的顶层const特性被忽略掉了)
(2)k是一个整形常量引用
(3)p是一个指向int类型指针的指针
(4)j2是一个int类型的常量,k2是常量引用

程序如下:

#include
int main()
{
	const int i = 42;
	auto j = i;
	const auto &k = i;
	auto *p = &i;
	const auto j2 = i, &k2 = i;
	std::cout << j << " " << k << " " << p << " "
		<< j2 << " " << k2 << std::endl;
	return 0;
}

2.36

int a = 3, b = 4;     
decltype(a) c = a;   
decltype ((b)) d = a;  
++c;      // c为int类型,值为4
++d;     // d为int&, 值为4

2.37

int a = 3, b = 4;
decltype(a) c = a;  // c为int类型,值为3
decltype(a = b) d = a;   // d为int&,值为4

2.38

区别:
decltype:如果decltype使用的表达式是一个变量,则decltype返回该变量的类型(包括顶层const和引用在内)
auto:auto一般会忽略顶层const

例子:
一样:int a = 3; decltype (a) b = a;   auto b = a;
不一样:const int a = 3; decltype(a) b = a;  auto b = a;

2.39

C++ primer(5e)第2章习题_第3张图片

2.40

struct Sales_data
{
	std::string bookNo;
	unsigned units_sold = 0;
	double revenue = 0.0;
};
// 书上把想的写出来了,“最好”两字说明可以和书上一样~

你可能感兴趣的:(C++)