int main(){ int sum = 0, val = 50; while (val <= 100) { sum += val; val++; } s..._给定指针p 你能知道它是否指向了一个合法对象">
当前位置:   article > 正文

C++ Primer 第五版 课后章节练习答案 第一、二章_给定指针p 你能知道它是否指向了一个合法对象

给定指针p 你能知道它是否指向了一个合法对象

编译软件为 vs2015。

第一章

练习1.9:

编写程序,使用 while 循环将 50 到100 的整数相加。

  1. #include "stdafx.h"
  2. #include<iostream>
  3. int main()
  4. {
  5. int sum = 0, val = 50;
  6. while (val <= 100) {
  7. sum += val;
  8. val++;
  9. }
  10. std::cout << " sum of 50 to 100 is " << sum << std::endl;
  11. return 0;
  12. }

练习1.10:

除了++运算符将运算对象的值增加 1 之外,还有一个递减运算符(--)实现将值减少 1 。编写程序,使用递减运算符在循环中按照递减顺序打印出 10 到 0 之间的整数。

  1. #include "stdafx.h"
  2. #include<iostream>
  3. int main()
  4. {
  5. int i = 10;
  6. while (i >= 0) {
  7. std::cout << i << std::endl;
  8. i--;
  9. }
  10. return 0;
  11. }

练习1.11:

编写程序,提示用户输入两个整数,打印出这两个整数所指定范围内的所有整数。

(此程序可判断输入两个值的大小,并按照递增的顺序打印两个值范围内的所有整数,包括两个值在内。若按照递减的顺序原理相同。)

  1. #include "stdafx.h"
  2. #include<iostream>
  3. int main()
  4. {
  5. int i, j;
  6. std::cout << "please input two numbers:" << std::endl;
  7. std::cin >> i >> j;
  8. if (i >= j)
  9. {
  10. while (j <= i) {
  11. std::cout << j << std::endl;
  12. j++;
  13. }
  14. }
  15. else {
  16. while (i <= j) {
  17. std::cout << i << std::endl;
  18. i++;
  19. }
  20. }
  21. return 0;
  22. }

练习1.13:

用 for 循环重做1.4.1节中的所有练习。

  1. //for循环实现 50 到 100 间整数相加
  2. #include "stdafx.h"
  3. #include<iostream>
  4. int main()
  5. {
  6. int sum = 0;
  7. for (int val = 50; val <= 100; val++)
  8. sum += val;
  9. std::cout << " sum of 50 to 100 is: "<<sum << std::endl;
  10. return 0;
  11. }
  1. //for 循环按递减顺序打印 10 到 0 间整数
  2. #include "stdafx.h"
  3. #include<iostream>
  4. int main()
  5. {
  6. for (int i = 10; i >= 0; i--)
  7. std::cout << i << std::endl;
  8. return 0;
  9. }
  1. //提示用户输入两个数,for 循环打印两个数间的所有整数
  2. #include "stdafx.h"
  3. #include<iostream>
  4. int main()
  5. {
  6. int i, j, max, min;
  7. std::cout << "please input two numbers:" << std::endl;
  8. std::cin >> i >> j;
  9. if (i >= j)
  10. max = i, min = j;
  11. else {
  12. max = j, min = i;
  13. }
  14. for (int val = min; val <= max; val++)
  15. std::cout << val << std::endl;
  16. return 0;
  17. }

练习1.16:

编写程序,从 cin 中读取一组数据,输出其和。

  1. #include "stdafx.h"
  2. #include<iostream>
  3. int main()
  4. {
  5. int sum = 0, val = 0;
  6. std::cout << "please intput numbers:" << std::endl;
  7. while (std::cin>>val)
  8. sum += val;
  9. std::cout << " sum of these numbers is: " << sum << std::endl;
  10. return 0;
  11. }

练习1.20:

在网站 http://www.informit.com/title/0321714113 上,第一章的代码目录中包含了头文件 Sales_item.h将它拷贝到你自己的工作目录中。用它编写一个程序,读取一组书籍销售记录,将每条记录打印到标准输出上。

  1. #include "stdafx.h"
  2. #include<iostream>
  3. #include"Sales_item.h"
  4. int main()
  5. {
  6. Sales_item book;
  7. std::cin >> book;
  8. std::cout << book << std::endl;
  9. return 0;
  10. }

使用输入方法如下:

练习1.21:

编写程序,读取两个 ISBN 相同的 Sales_item 对象,输出它们的和。

  1. #include"stdafx.h"
  2. #include<iostream>
  3. #include"Sales_item.h"
  4. int main()
  5. {
  6. Sales_item book1, book2;
  7. std::cin >> book1 >> book2;
  8. std::cout << book1 + book2 << std::endl;
  9. return 0;
  10. }

练习1.22:

编写程序,读取多个具有相同 ISBN 的销售记录,输出所有记录的和。

  1. #include"stdafx.h"
  2. #include<iostream>
  3. #include"Sales_item.h"
  4. int main()
  5. {
  6. Sales_item salessum, sales;
  7. std::cin >> salessum;
  8. while (std::cin >> sales)
  9. salessum += sales;
  10. std::cout << salessum;
  11. return 0;
  12. }

练习1.23:

编写程序,读取多条销售记录。并统计每个 ISBN (每本书)有几条销售记录。

  1. #include"stdafx.h"
  2. #include<iostream>
  3. #include"Sales_item.h"
  4. int main() {
  5. Sales_item salessum, sales;
  6. int cnt = 1;
  7. if (std::cin >> salessum){
  8. while (std::cin >> sales) {
  9. if (sales.isbn() == salessum.isbn())
  10. ++cnt;
  11. else {
  12. std::cout << " the note of " << salessum.isbn() << " is " << cnt << std::endl;
  13. cnt = 1;
  14. salessum = sales;
  15. }
  16. }
  17. std::cout << " the note of " << salessum.isbn() << " is " << cnt << std::endl;//记住打印最后一条记录
  18. }
  19. return 0;
  20. }
  21. //此程序只能读取多条ISBN号相同连续的记录 类似:xxxxccc,若为:xcxcxcx,则不能处理

第二章

练习2.3、2.4:

读程序写结果。编写程序检查你的估计是否正确,如果不正确,请仔细研读本节直到弄明白问题所在。

  1. #include "stdafx.h"
  2. #include<iostream>
  3. int main()
  4. {
  5. unsigned u = 10, u2 = 42;
  6. std::cout << u2 - u << std::endl;
  7. std::cout << u - u2 << std::endl;
  8. int i = 10, i2 = 42;
  9. std::cout << i2 - i << std::endl;
  10. std::cout << i - i2 << std::endl;
  11. std::cout << i - u << std::endl;
  12. std::cout << u - i << std::endl;
  13. return 0;
  14. }

结果分别对应如下:

32;
4294967264;(32位)
32;
-32;
0;
0;

练习2.5 :

指出下述字面值的数据类型并说明每一组内几种字面值的区别。

(a) 'a', L'a', "a", L"a";

(b) 10, 10u, 10L, 10uL, 012, 0xC;

(c)3.14, 3.14f, 3.14L;

(d)10, 10u, 10., 10e-2;

解答:

(a)字符字面值,宽字符字面值,字符串字面值,宽字符串字面值;

(b)十进制整形字面值,无符号十进制整形字面值,十进制长整型字面值,无符号十进制长整型字面值,八进制整形字面值,十六进制整形字面值;

(c)双精度浮点型字面值,单精度浮点型字面值,扩展精度浮点型字面值;

(d)十进制字面值,无符号十进制字面值,双精度浮点型字面值(注意有小数点),双精度浮点型字面值;

练习2.6:

下面两组定义是否有区别,如果有,请叙述之。

int month = 9, day = 7;

int month = 09, day = 07;

定义有区别,第一种定义数据类型为十进制,第二种为八进制。八进制时,“int month = 09”是无效的定义,9 基于八进制时应该有进位。

练习2.7:

下述字面值表示何种含义?他们各自的数据类型是什么?

(a) “who goes with F\145rgus?\012”;

(b)3.14e1L;

(c)1024f;

(d)3.14L;

解答:

(a)字符串字面值。\145输出为字母 e ,\012表示换行符;

(b)扩展精度浮点型字面值。3.14以 e 为底,10 的 1 次方;

(c)单精度浮点型字面值;

(d)扩展精度浮点型字面值;

练习2.8: 

请利用转义序列编写一段程序,要求先输出 2M,然后转到新一行。修改程序,使其先输出 2,然后输出制表符,在输出 M,最后转到新一行。

  1. #include "stdafx.h"
  2. #include<iostream>
  3. int main()
  4. {
  5. std::cout << "\062\115\n" << std::endl;
  6. std::cout << "\062\t\x4d\012" << std::endl;
  7. return 0;
  8. }

输出结果: (转义字符参照ASCII码) 

练习2.9:  

解释下列定义的含义。对于非法的定义,请说明错在何处并将其改正。

(a)std::cin >> int input_value;

(b)int i = { 3.14 };

(c)double salary = wage = 9999.99;

(d)int i = 3.14;

解释如下:

(a)非法定义。std::cin>>输入符号相当于给变量赋值,初始化不是赋值,因此该变量是未定义的,正确表达为:

          int input_value = 0;

         std::cin>>input_value;

(b)非法定义.。此表达为列表初始化,变量类型为整形,初始化值为浮点数,不匹配,存在初始化数据丢失的风险。正确表达为:

         double i = { 3.14 };

(c)非法定义。wage变量没有被定义,变量定义的形式的是在类型说明符后紧跟多个变量名,并且以逗号隔开,以分号结束。正确表达为:

          double wage;

          double salary = wage = 9999.99;

(d)非法定义。与(b)相同,将浮点数赋予整型变量作为初始化值了。正确表达为:

           double i = 3.14;

练习2.10: 

下列变量的初始值分别是什么?

  1. std::string global_str;
  2. int gobal_int;
  3. int main()
  4. {
  5. int local_int;
  6. std::string local_str;
  7. }

变量 global_str 是定义于函数体之外的,由其类决定的(每个类各自决定其促石化对象的方式,此处为 string 类),非显示的初始化,为一个空串。

变量 global_int 为定义于函数体之外的,其被初始化为 0。

变量 local_ int 为定义于函数体内的内置类型,没有被初始化,其值是未定义的。

变量 local_str 为类的非显示初始化,定义于函数体内,被初始化为一个空串。

练习2.11: 

指出下面的语句是声明还是定义。

(a)extern int ix = 1024;

(b)int iy;

(c)extern int iz;

解答:

(a)定义。(若出现在函数体内部,则会引发错误)

(b)定义。

(c)声明。

练习2.12:

请指出下面的名字哪些是非法的?

(a)int double = 3.14;

(b)int _;

(c)int catch-22;

(d)int 1_or_2;

(e)double Double;

解答:

(a)非法定义。double 为关键字,不能被用作标识符。

(b)正确。(注意,定义在函数体外的标识符不能以下画线开头。)

(c)非法定义。c++中标识符只能包括字母、数字、下画线。

(d)非法定义。标识符必须以字母或下画线开头。

(e)正确。 

 练习2.13:

下面程序中 j 的值是多少?

  1. int i = 42;
  2. int main()
  3. {
  4. int i = 100;
  5. int j = i;
  6. std::cout << j << std::endl;
  7. return 0;
  8. }

 输出结果 j = 100;

练习2.14: 

下面的程序合法吗?如果合法,它将输出什么?

  1. int main()
  2. {
  3. int i = 100, sum = 0;
  4. for (int i = 0; i != 10;++i)
  5. sum += i;
  6. std::cout << i << " " << sum << std::endl;
  7. return 0;
  8. }

解答:

程序合法,输出结果为:100 45 。在 for 语句中定义的 i 值,只能在 for 语句中访问。

练习2.15:

下面哪个定义是不合法的?为什么?

(a)int ival = 1.01;

(b)int &rval1 = 1.01;

(c)int &rval2 = ival;

(d)int &rval3;

解答:

(a)合法的;但赋值为浮点数,会被保存为整数。

(b)不合法,引用不是对象,它只是一个已经存在的对象的另一个名字,不能被定义;

(c)合法;

(d)不合法,

 练习2.16:

考查下面的所有赋值然后回答:哪些赋值是不合法的?为什么?哪些赋值是合法的?它们执行了什么样的操作?

int i = 0,&r1 = i;

double d = 0,&r2 = d;

(a)r2 = 3.14159;

(b)r2 = r1;

(c)i = r2;

(d)r1 = d;

解答:

(a)合法,将3.14159这个值赋予变量 d;

(b)合法,将 r1 指向的对象 i 赋给 r2 指向的对象 d,并且类型会发生转变;

(c)合法,将 r2 指向的对象 d 赋给 i,并且类型会发生转变;

(d)合法,将 d 赋给 r1指向的对象,并且类型会发生转变;

练习2.17:

执行下面的代码将输出什么结果?

  1. #include "stdafx.h"
  2. #include<iostream>
  3. int main()
  4. {
  5. int i, &ri = i;
  6. i = 5, ri = 10;//执行的操作是将 10 赋予 ri 指向的对象 i;
  7. std::cout << i << " " << ri << std::endl;
  8. return 0;
  9. }

 输出如下:

练习2.18: 

编写代码分别更改指针的值以及指针所指对象的值。

  1. #include "stdafx.h"
  2. #include<iostream>
  3. int main()
  4. {
  5. int i = 42, d = 36;//定义两个 int 型变量
  6. int *p = &i;//定义指针 p 指向变量 i 的地址
  7. std::cout << i << " " << d << " " << p << "\n" << std::endl;//输出此时变量 i、d 的值以及指针 p 的值
  8. p = &d;//更改指针使其指向变量 d 的地址,相当于更改了指针的值
  9. *p = 11;//更改指针所指对象的值,此时指针指向的对象是 d
  10. std::cout << i << " " << d << " " << p << "\n" << std::endl;
  11. //输出此时变量 i、d 的值以及指针 p 的值,更改了指针 p 的值以及变量 d 的值
  12. return 0;
  13. }

 输出结果如下:

练习2.19: 

说明指针和引用的主要区别。

指针和引用都能提供对其它对象的间接访问,两者最大的不同在于指针本身是一个对象,允许对指针赋值和拷贝,但引用不是;其次,指针无须在定义时赋初始值,但是引用必须被初始化。 

练习2.20: 

请叙述下面这段代码的作用。

  1. int i = 42;
  2. int *p1 = &i;
  3. *p1 = *p1 * *p1;

 解答:

此段代码将变量 i 平方后在赋值到 i;输出 i 为 1764,等价于 i = i *  i= 42*42;

练习2.21:

请解释下述定义。在这些定义中有非法的吗?如果有,为什么?

int i = 0;

(a)double*   dp = &i;

(b)int *ip = i;

(c)int *p = &i;

解答:

(a)不合法。i 为 int 类型的值,不能用于初始化 double 类型的指针。

(b)不合法。不能把 int 变量直接赋值给指针。

(c)合法。指针指向变量 i 的地址

 练习2.22:

假设 p 是一个 int 型指针,请说明下述代码的含义。

 if (p) // ...

if (*p) // ..

解答:

 if (p) // ... 如果 p 的值为 0,条件值为 false,看 p 是否为空指针;

if (*p) // ..如果 p 指向的对象的值为 0,条件值为 false,看 p 指向的对象值是否为 0;

练习2.23: 

给定指针 p, 你能知道它是否指向了一个合法的对象吗?如果能,叙述判断的思路,如果不能,说明原因。

不能直接判断。例如存在 void* 型指针,无法确定其类型,也无法确定该对其进行哪些操作,需要更多的信息联合判断。 

练习2.24:

下面这段代码中为什么 p 合法而 lp 非法? 

int i = 42; void *p = &i;long *lp = &i;

解答:

因为 void* 是一种特殊的指针类型,其指针的类型不确定,可以指向任意类型对象的地址,但 long* 型是确定的,为长整型,与变量 i 的类型不匹配,因此指针 lp 的定义是非法的。 

练习2.25: 

说明下列变量的类型和值。

(a)int*  ip,i,&r = i;

(b)int i,*ip = 0;

(c)int*  ip,ip2;

解答:

(a)ip 是一个 int 型指针,i 为 int 型变量,r 为一个引用,与 i 绑定在一起;

(b)i 为一个 int 型变量,ip 为一个 int 型指针,值为 0 ,即为空指针; 

(c)ip 为一个 int 型指针,ip2 是一个 int 型变量;

练习2.26: 

下面哪些句子是合法的?如果有不合法的句子,请说明为什么?

(a)const int buf;

(b)int cnt = 0;

(c)const int sz = cnt;

(d)++cnt;++sz;

解答:

 (a)不合法,const 对象必须初始化;

(b)合法;

(c)合法;

(d)不合法,const 对象值不能被改变,++sz 操作改变了 const sz 对象的值;

练习2.27:

下面那些初始化是合法的?请说明原因。

(a)int i = -1,&r = 0;

(b)int *const p2 = &i2;

(c)const int i = -1,&r = 0;

(d)const int *const p3 = &i2;

(e)const int *p1 = &i2;

(f)const int &const r2;

(g)const int i2 = i,&r = i;

解答: 

(a)不合法,引用类型的初始值必须是一个对象;

(b)合法,常量指针 p2 指向 i2 的地址;

(c)i 是一个常量,r 是一个常量引用(与引用不同,引用初始值必须为一个对象);

(d)合法,常量指针 p3 指向 i2 的地址;

(e)合法,p1 为指向常量的指针;

(f)不合法,&const r2 是对常量 r2 的引用,未经初始化,const 对象必须初始化;

(g)合法;

练习2.28: 

说明下面这些定义是什么意思,挑出其中不合法的。

(a)int i,*const cp;

(b)int *p1,*const p2;

(c)const int ic,&r = ic;

(d)const int *const p3;

(e)const int *p; 

 解答:

(a)不合法,cp 为常量指针,必须初始化;

(b)不合法,p2 为常量指针,必须初始化;

(c)不合法,const 对象必须初始化,ic 为 const 对象,没有初始化;

(d)不合法, p3 为指向常量的常量指针,必须初始化;

(e)合法,p 为指向常量的指针;

练习2.29:

假设已有上一个练习中定义的那些变量,则下面的哪些语句是合法的?请说明原因。

(a)i = ic;

(b)p1 = p3;

(c)p1 = &ic;

(d)p3 = &ic;

(e)p2 = p1;

(f)ic = *p3;

解答: 

(a)合法,拷贝常量 ic 的值,并不会改变它;

(b)不合法,p1 为指向普通变量的指针,p3 为常量指针,类型不匹配;

(c)不合法,p1 为指向普通变量的指针,而 ic 为常量,p1 会改变只想对象的值;  

(d)不合法,p3 为指向常量的常量指针,自己本身是一个常量,一旦初始化完成,其值不能再被改变;

(e)不合法,p2 是常量指针,初始化完成后,其值不能再被改变;

(f)不合法,ic 为常量,不能在被赋值;

练习2.30: 

对于下面这些语句,请说明对象被声明成了顶层 const 还是底层 const ?

(a)const int v2 = 0;

(b)int v1 = v2;

(c)int *p1 = &v1,&r1 = v1;

(d)const int *p2 = &v2,*const p3 = &i,&r2 = v2;

解答:

v2 自己本身是一个常量,为顶层 const;

p2 为指向常量的指针,为底层 const;

p3 靠右的 const 是顶层,靠左的 const 是底层;

r2 是对常量的引用,是底层 const;

练习2.31:

假设已有上一个练习中所做的那些声明,则下面的哪些语句是合法的?请说明顶层 const 和 底层 const 在每个例子中有何体现。

(a) r1 = v2;

(b)p1 = p2;

(c)p2 = p1;

(d)p1 = p3; 

(f)p2 = p3;

 解答:

(a) 合法,拷贝 v2 的值并不会改变它;

(b)不合法,p1 是指向普通变量的指针,p2 是指向常量的指针,是底层 const ,p1 与 p2 不匹配;

(c)合法,p2 是底层 const ,允许将非常量变为常量;

(d)不合法,p3 是底层 const ,p1 是指向常量的指针,不匹配;

(e)合法,p2 和 p3 均为底层 const;

练习2.32:

下面的代码是否合法?如果非法,请设法将其修改正确。

int null = 0,*p = null;

解答: 

不合法,不能把 int 变量直接赋值给指针。

修改:int null = 0,*p = &null; 

练习2.33:

利用本节定义的变量,判断下列语句的运行结果。

a = 42;

b = 42;

c = 42;

d = 42;

e = 42;

f = 42;

解答: 

(需要参考书中的定义) 

a = 42;// a 是一个整数,因此可以将 42 赋值给 a;

b = 42;// b 是一个整数,可以将 42 赋值给 b ,auto 会忽略顶层 const 属性,b 不是常量;

c = 42;// c 是一个整数,可以将 42 赋值给 c;

错误;// d 为一个整形指针,正确语句应为 *d = 42;// 指针 d 的值为 42;

错误;// e 为一个指向整形常量的指针,正确语句应为 e = &a;

错误;// g 为一个整形常量引用,与常量 ci 绑定,不能修改;

练习2.34: 

基于上一个练习中的变量和语句编写一段程序,输出赋值前后变量的内容,你刚才的推断正确吗?如果不对,请反复研读本节的示例直到你明白错在何处为止。

解答: 

按照练习2.33定义的程序语句如下:

  1. #include "stdafx.h"
  2. #include<iostream>
  3. int main()
  4. {
  5. int i = 0, &r = i;// i 是一个整数,r 是对 i 的引用;
  6. auto a = r;// a 是一个整数;
  7. const int ci = i, &cr = ci;// ci 是一个整形常量,cr 是对整形常量的引用;
  8. auto b = ci;// b 是一个整数,auto 忽略掉了 ci 的顶层 const;
  9. auto c = cr;// c 与 b 同,是一个整数
  10. auto d = &i;// d 是一个整形指针,指向整数 i;
  11. auto e = &ci;// e 是一个指向整形常量 ci 的指针(对常量对象取地址是一种底层 const);
  12. auto &g = ci;// g 是一个对整形常量 ci 的应用,与 ci 绑定;
  13. std::cout << " a = " << a << "\n" << std::endl;
  14. std::cout << " b = " << b << "\n" << std::endl;
  15. std::cout << " c = " << c << "\n" << std::endl;
  16. std::cout << " d = " << d << "\n" << std::endl;
  17. std::cout << " e = " << e << "\n" << std::endl;
  18. std::cout << " g = " << g << "\n" << std::endl;
  19. //练习2.33:
  20. a = 42;
  21. b = 42;
  22. c = 42;
  23. d = 42;
  24. e = 42;
  25. g = 42;
  26. std::cout << " a = " << a << "\n" << std::endl;
  27. std::cout << " b = " << b << "\n" << std::endl;
  28. std::cout << " c = " << c << "\n" << std::endl;
  29. std::cout << " d = " << d << "\n" << std::endl;
  30. std::cout << " e = " << e << "\n" << std::endl;
  31. std::cout << " g = " << g << "\n" << std::endl;
  32. return 0;
  33. }

下图展示编译软件中显示的错误类型,分别对应 d 、e、g、,由此可知与上一练习中分析的相同; 

下面是修改正确后的语句:

  1. #include "stdafx.h"
  2. #include<iostream>
  3. int main()
  4. {
  5. int i = 0, &r = i;// i 是一个整数,r 是对 i 的引用;
  6. auto a = r;// a 是一个整数;
  7. const int ci = i, &cr = ci;// ci 是一个整形常量,cr 是对整形常量的引用;
  8. auto b = ci;// b 是一个整数,auto 忽略掉了 ci 的顶层 const;
  9. auto c = cr;// c 与 b 同,是一个整数
  10. auto d = &i;// d 是一个整形指针,指向整数 i;
  11. auto e = &ci;// e 是一个指向整形常量 ci 的指针(对常量对象取地址是一种底层 const);
  12. auto &g = ci;// g 是一个对整形常量 ci 的应用,与 ci 绑定;
  13. std::cout << " a = " << a << "\n" << std::endl;
  14. std::cout << " b = " << b << "\n" << std::endl;
  15. std::cout << " c = " << c << "\n" << std::endl;
  16. std::cout << " d = " << d << "\n" << std::endl;
  17. std::cout << " e = " << e << "\n" << std::endl;
  18. std::cout << " g = " << g << "\n" << std::endl;
  19. std::cout << "\n" << std::endl;
  20. //练习2.33:
  21. a = 42;
  22. b = 42;
  23. c = 42;
  24. //d = 42;
  25. //e = 42;
  26. //g = 42;
  27. *d = 42;//对 d 指向的对象即 i 赋值;
  28. e = &a;//此时 e 指向整数 a 的地址;
  29. std::cout << " a = " << a << "\n" << std::endl;
  30. std::cout << " b = " << b << "\n" << std::endl;
  31. std::cout << " c = " << c << "\n" << std::endl;
  32. std::cout << " d = " << d << "\n" << std::endl;
  33. std::cout << " e = " << e << "\n" << std::endl;
  34. std::cout << " g = " << g << "\n" << std::endl;
  35. return 0;
  36. }

运行结果如下:

练习2.35: 

判断下列定义推断出的类型是什么,然后编写程序进行验证。

const int i = 42;

auto j = i;

const auto &k = i;

auto *p = &i;

const auto j2 = i,&k2 = i; 

解答:

i 为常整数;

j 为整数;

k 为整形常量引用;

p 为指向整形常量的指针;

j2 为一个常整数;

k2 为整形常量引用;

程序运行如下:

  1. #include "stdafx.h"
  2. #include <iostream>
  3. #include <typeinfo>
  4. using std::cout;
  5. using std::endl;
  6. int main()
  7. {
  8. const int i = 42;
  9. auto j = i;
  10. const auto &k = i;
  11. auto *p = &i;
  12. const auto j2 = i, &k2 = i;
  13. cout << "i is " << typeid(i).name() << "\n" << endl;
  14. cout << "j is " << typeid(j).name() << "\n" << endl;
  15. cout << "k is " << typeid(k).name() << "\n" << endl;
  16. cout << "p is " << typeid(p).name() << "\n" << endl;
  17. cout << "j2 is " << typeid(j2).name() << "\n" << endl;
  18. cout << "k2 is " << typeid(k2).name() << "\n" << endl;
  19. return 0;
  20. }

运行结果如下: 

 

练习2.36:

关于下面的代码,请指出每一个变量的类型及程序结束时它们各自的值。

int a = 3,b = 4;

decltype(a) c = a;

decltype ((b)) d = a;

++c;

++d;

解答:

a 为一个整数,数值为 4;

b 为一个整数,数值为 4;

c 为一个整数,数值为 4;

d 为一个整形引用,与 a 绑定,数值为 4;

注:此时由于 d 是一个引用且与 a 绑定,所以最后 a 的输出数值已经由 d 改变,所以不再是 3 而是 4;

程序验证如下:

  1. #include "stdafx.h"
  2. #include<iostream>
  3. using std::cout;
  4. using std::endl;
  5. int main()
  6. {
  7. int a = 3, b = 4;
  8. decltype(a) c = a;
  9. decltype((b)) d = a;
  10. ++c;
  11. ++d;
  12. cout << "a = " << a << " and type is " << typeid(a).name() << "\n" << endl;
  13. cout << "b = " << b << " and type is " << typeid(b).name() << "\n" << endl;
  14. cout << "c = " << c << " and type is " << typeid(c).name() << "\n" << endl;
  15. cout << "a = " << d << " and type is " << typeid(d).name() << "\n" << endl;
  16. return 0;
  17. }

结果如图:

练习2.37: 

赋值是会产生引用的一类典型表达式,引用的类型就是左值的类型。也就是说,如果 i 是 int ,则表达式 i = x 的类型是 int&。根据这一特点,请指出下面代码每一个变量的类型和值。

int a = 3,b = 4;

decltype(a) c = a;

decltype(a = b) d = a;

解答: 

a 为整数,值为 3;

b 为整数,值为 4;

c 为整数,值为 3;

d 为整形引用,值为 3; 

练习2.38: 

说明 decltype 指定类型和由 auto 指定类型有何区别。请举出一个例子, decltype 指定的类型和 auto 指定的类型一样;再举出一个例子,decltype 指定的类型和 auto 指定类型不一样。

解答: 

 区别:再返回变量的类型中, auto 一般会忽略掉顶层 const,底层 const 会保留下来 ,而 decltype 返回变量的类型则包括顶层 const 和引用在内。

举例如下:

  1. #include "stdafx.h"
  2. #include<iostream>
  3. using std::cout;
  4. using std::endl;
  5. int main()
  6. {
  7. int m = 5, &n = m;
  8. //auto 与 decltype 指定类型相同时
  9. auto a = m;//a 为一个整数
  10. decltype(m) b = m;//b 为一个整数
  11. cout << "a = " << a << " and type is " << typeid(a).name() << "\n" << endl;
  12. cout << "b = " << b << " and type is " << typeid(b).name() << "\n" << endl;
  13. //auto 与 decltype 指定类型不同时
  14. auto i = n;//i 为一个整数
  15. decltype(n) t = n;//t 为一个整型引用
  16. cout << "i = " << i << " and type is " << typeid(i).name() << "\n" << endl;
  17. cout << "t = " << t << " and type is " << typeid(t).name() << "\n" << endl;
  18. return 0;
  19. }

练习 2.39:

编译下面的程序观察其运行结果,注意,如果忘记写类定义体后面的分号会发生什么情况?记录下相关信息,以后可能会有用。

解答:  

  1. #include "stdafx.h"
  2. struct Foo {/*此处为空*/ }//注意没有分号
  3. int main()
  4. {
  5. return 0;
  6. }

 错误提示如下:

练习2.40:

根据自己的理解写出 Sales_data 类,最好与书中的例子有所区别。

解答: 

  1. struct Sales_data {
  2. std::string bookNo;//定义一个类型为 string 的变量,书号
  3. unsigned unit_sold = 0;//定义一个类型为 unsigned 的变量,销售量
  4. double revenue = 0.0;//定义一个类型为 double 的变量,销售额
  5. double unit_price = 0.0;//定义一个类型为double 的变量,销售单价
  6. //此为举例,可自定义变量
  7. };

 练习2.41:

使用你自己的 Sales_data 类,重写1.5.1节(第20页)、1.5.2节(第21页)和1.6节(第22页)的练习。眼下先把 Sales_data 类的定义和 main 函数放在同一个文件里。

解答: (注:编程过程中由于题目中说明的是输入相同 ISBN 号的数据记录,因此程序中没有写判断 ISBN 号是否相同这一步骤,在测试程序时注意要输入相同的 ISBN 号)

//用自己定义的 Sales_data 类改写练习1.20。读取一组书籍销售记录并将结果打印到标准输出上

  1. //用自己定义的 Sales_data 类改写练习1.20。读取一组书籍销售记录并将结果打印到标准输出上
  2. #include "stdafx.h"
  3. #include<iostream>
  4. #include<string>
  5. struct Sales_data {
  6. std::string bookNo;//书号ISBN
  7. unsigned unit_sold = 0;//销售量
  8. double revenue = 0.0;//销售额
  9. };
  10. int main()
  11. {
  12. Sales_data book;
  13. double price = 0.0;//销售单价
  14. //首先读入书号ISBN、销售量、单价
  15. std::cin >> book.bookNo >> book.unit_sold >> price;
  16. //计算销售额并打印结果到标准输出上
  17. book.revenue = book.unit_sold*price;
  18. std::cout << book.bookNo << " total revenue is " << book.revenue << std::endl;
  19. return 0;
  20. }

 

//用自己定义的 Sales_data 类改写练习1.21。读取 ISBN 号相同的两组书籍并计算这两个项目的“和” 

  1. //用自己定义的 Sales_data 类改写练习1.21。读取 ISBN 号相同的两组书籍并计算这两个项目的“和”
  2. #include"stdafx.h"
  3. #include<iostream>
  4. #include<string>
  5. struct Sales_data {
  6. std::string bookNo;//书号ISBN
  7. unsigned unit_sold = 0;//销售量
  8. double revenue = 0.0;//销售额
  9. };//注意不要忘记加分号
  10. int main()
  11. {
  12. Sales_data book1, book2;//两本 ISBN 号相同的书籍
  13. double price = 0.0, price1 = 0.0, price2 = 0.0;//平均销售单价、book1销售单价、book2销售单价
  14. double total_revenue = 0.0;//总销售额
  15. //首先读入两组 ISBN 号相同的书籍记录book1、book2
  16. std::cin >> book1.bookNo >> book1.unit_sold >> price1 >> book2.bookNo >> book2.unit_sold >> price2;
  17. //计算两个项目的和,包括总销售量、总销售额、平均售价
  18. total_revenue = book1.unit_sold*price1 + book2.unit_sold *price2;
  19. price = total_revenue / (book1.unit_sold + book2.unit_sold);
  20. std::cout << book1.bookNo << " " << book1.unit_sold + book2.unit_sold << " " << total_revenue << " " << price << std::endl;
  21. return 0;
  22. }

 //用自己定义的 Sales_data 类改写练习1.22。读取多个具有相同 ISBN 的销售记录,并输出他们的和:

  1. //用自己定义的 Sales_data 类改写练习1.22。读取多个具有相同 ISBN 的销售记录,并输出他们的和
  2. #include"stdafx.h"
  3. #include<iostream>
  4. #include<string>
  5. struct Sales_data {
  6. std::string bookNo;//书号ISBN
  7. unsigned unit_sold = 0;//销售量
  8. double revenue = 0;//销售额
  9. };
  10. int main()
  11. {
  12. double a_price = 0.0, salessum_price = 0.0, sales_price = 0.0;//平均销售单价
  13. Sales_data salessum, sales;//定义总项目和单项
  14. //首先读入第一个输入的项,并将其初始化为 salessum
  15. std::cin >> salessum.bookNo >> salessum.unit_sold>>salessum_price;
  16. salessum.revenue = salessum.unit_sold*salessum_price;//首先计算出第一项的销售额
  17. while (std::cin >> sales.bookNo >> sales.unit_sold >> sales_price) {
  18. sales.revenue = sales.unit_sold*sales_price;
  19. salessum.unit_sold = salessum.unit_sold + sales.unit_sold;//将第一项作为总项不断与输入项相加,求得总销售量
  20. salessum.revenue = salessum.revenue + sales.revenue;//求得总销售额
  21. a_price = salessum.revenue / salessum.unit_sold;//求出平均销售单价
  22. }
  23. std::cout << salessum.bookNo << " " << salessum.unit_sold << " "
  24. << salessum.revenue << " " << a_price << " " << std::endl << "\n";
  25. return 0;
  26. }

 (此段程序用到 while 循环,当输入结束时,退出 while 循环简单的方式就是输入和以上格式不同的字符即可,这里使用的是N N)

//用自己定义的 Sales_data 类改写练习1.23、1.24。 读取多条销售记录,并统计每个ISBN有几条销售记录,每个 ISBN 应该聚集在一起。

  1. //用自己定义的 Sales_data 类改写练习1.23、1.24。 读取多条销售记录,并统计每个ISBN有几条销售记录,每个 ISBN 应该聚集在一起。
  2. #include"stdafx.h"
  3. #include<iostream>
  4. #include<string>
  5. struct Sales_data {
  6. std::string bookNo;
  7. unsigned unit_sold = 0;
  8. double revenue = 0.0;
  9. };
  10. int main() {
  11. Sales_data salessum, sales;
  12. double price1 = 0.0, price2 = 0.0;
  13. double total_revenue = 0.0;
  14. int cnt = 1; //设置计数器 cnt
  15. if (std::cin >> salessum.bookNo >> salessum.unit_sold >> price1) { //使得第一个输入的组为salessum
  16. salessum.revenue = salessum.unit_sold*price1;
  17. while (std::cin >> sales.bookNo >> sales.unit_sold >> price2) { //如果继续输入则为sales
  18. sales.revenue = sales.unit_sold*price2;
  19. if (sales.bookNo == salessum.bookNo) {
  20. ++cnt;//如果输入的组的书号 ISBN 相同,则计数器加一
  21. salessum.revenue = salessum.revenue + sales.revenue;
  22. }
  23. else {
  24. std::cout << " the note of " << salessum.bookNo << " is " << cnt
  25. << " and the total revenue is " << salessum.revenue << std::endl;
  26. cnt = 1; // 如果输入的某一组 ISBN 与之前不同,则输出此时计数器的值,即为销售记录的条数,并将计数器置为1
  27. salessum = sales;
  28. }
  29. }
  30. std::cout << " the note of " << salessum.bookNo << " is " << cnt
  31. << " and the total revenue is " << salessum.revenue << std::endl;
  32. }// 直到输入结束,输出最后一条 ISBN 的销售记录
  33. return 0;
  34. }
  35. //如题目,ISBN 记录应该连在一起,此程序只能读取多条ISBN号相同连续的记录 类似:xxxxccc,若为:xcxcxcx,则不能处理

 //用自己编写的Sales_data文件改写练习1.25。运行书中的书店程序

  1. //用自己编写的Sales_data文件改写练习1.25。运行书中的书店程序
  2. #include"stdafx.h"
  3. #include<iostream>
  4. #include<string>
  5. struct Sales_data {
  6. std::string bookNo;
  7. unsigned unit_solds = 0;
  8. double revenue = 0.0;
  9. };
  10. int main()
  11. {
  12. Sales_data totals;
  13. double price1 = 0.0, price2 = 0.0;
  14. if (std::cin >> totals.bookNo >> totals.unit_solds >> price1) {
  15. totals.revenue = totals.unit_solds*price1;
  16. Sales_data trans;
  17. while (std::cin >> trans.bookNo >> trans.unit_solds >> price2) {
  18. trans.revenue = trans.unit_solds*price2;
  19. if (totals.bookNo == trans.bookNo) {
  20. totals.unit_solds += trans.unit_solds;
  21. totals.revenue += trans.revenue;
  22. }
  23. else {
  24. std::cout << " The note of " << totals.bookNo << " unit sold is "
  25. << totals.unit_solds << " total revenue is " << totals.revenue << "\n" << std::endl;
  26. totals = trans;
  27. }
  28. }
  29. std::cout << " The note of " << totals.bookNo << " unit sold is "
  30. << totals.unit_solds << " total revenue is " << totals.revenue << "\n" << std::endl;
  31. }
  32. else {
  33. std::cerr << " No data?! " << "\n" << std::endl;
  34. return -1;
  35. }
  36. return 0;
  37. }

 (N N表示结束符)

练习2.42: 

根据你自己的理解重新写一个 Sales_data.h 头文件,并以此为基础,重做 2.6.2 节(第67页)的练习。

解答:Sales_data.h文件如下

  1. #ifndef SALES_DATA_H
  2. #define SALES_DATA_H
  3. #include <iostream>
  4. #include <string>
  5. struct Sales_data {
  6. std::string bookNo;
  7. unsigned unit_sold = 0;
  8. double revenue = 0.0;
  9. double price = 0.0;
  10. void oridata(Sales_data item);//设置原始数据的对应值
  11. void cins();//设置输入函数
  12. void data_revenue();//设置求销售额函数
  13. void sumdata(Sales_data item);//设置项相加函数
  14. double averdata();//设置求平均销售单价函数
  15. void couts();//设置输出函数
  16. };
  17. #endif
  18. void Sales_data::cins() {
  19. std::cin >> bookNo >> unit_sold >> price;
  20. }
  21. void Sales_data::oridata(Sales_data item) {
  22. bookNo = item.bookNo;
  23. unit_sold = item.unit_sold;
  24. revenue = item.revenue;
  25. price = item.price;
  26. }
  27. void Sales_data::data_revenue() {
  28. revenue = unit_sold*price;
  29. }
  30. void Sales_data::sumdata(Sales_data item) {
  31. if (bookNo != item.bookNo)
  32. return;
  33. unit_sold += item.unit_sold;
  34. revenue += item.revenue;
  35. }
  36. double Sales_data::averdata() {
  37. if (unit_sold != 0)
  38. return revenue / unit_sold;
  39. else
  40. std::cout<< "no sales";
  41. }
  42. void Sales_data::couts() {
  43. double aver_revenue = averdata();
  44. std::cout << bookNo << " " << unit_sold << " " << revenue << " " << aver_revenue << "\n";
  45. }

使用方法如下: 

  1. #include "stdafx.h"
  2. #include<iostream>
  3. #include<string>
  4. #include"Sales_data.h"
  5. //1.20读取一组书籍销售记录并将结果打印到标准输出上
  6. int main()
  7. {
  8. Sales_data book;
  9. book.cins();
  10. book.data_revenue();
  11. book.couts();
  12. return 0;
  13. }*/

运行结果如下: 

  1. #include "stdafx.h"
  2. #include<iostream>
  3. #include<string>
  4. #include"Sales_data.h"
  5. //1.21读取 ISBN 号相同的两组书籍并计算这两个项目的“和”
  6. int main()
  7. {
  8. Sales_data book1, book2;
  9. book1.cins();
  10. book2.cins();
  11. book1.data_revenue();
  12. book2.data_revenue();
  13. book2.sumdata(book1);
  14. book2.couts();
  15. return 0;
  16. }

运行结果如下:

  1. #include "stdafx.h"
  2. #include<iostream>
  3. #include<string>
  4. #include"Sales_data.h"
  5. //1.22读取多个具有相同 ISBN 的销售记录,并输出他们的和
  6. int main()
  7. {
  8. Sales_data salessum, sales;
  9. salessum.cins();
  10. salessum.data_revenue();
  11. while (std::cin >> sales.bookNo >> sales.unit_sold >> sales.price) {
  12. sales.data_revenue();
  13. salessum.sumdata(sales);
  14. }
  15. salessum.couts();
  16. return 0;
  17. }

  1. //1.23、1.24 读取多条销售记录,并统计每个ISBN有几条销售记录
  2. #include "stdafx.h"
  3. #include<iostream>
  4. #include<string>
  5. #include"Sales_data.h"
  6. int main() {
  7. Sales_data salessum, sales;
  8. int cnt = 1;
  9. if (std::cin >> salessum.bookNo >> salessum.unit_sold >> salessum.price) {
  10. salessum.data_revenue();
  11. while (std::cin >> sales.bookNo >> sales.unit_sold >> sales.price) {
  12. sales.data_revenue();
  13. if (sales.bookNo == salessum.bookNo) {
  14. salessum.sumdata(sales);
  15. ++cnt;
  16. }
  17. else {
  18. std::cout << "\n";
  19. std::cout << " the sum of " << salessum.bookNo << " is " << " \n";
  20. salessum.couts();
  21. std::cout << " the note of " << salessum.bookNo << " is " << cnt << "\n";
  22. std::cout << "\n";
  23. cnt = 1;
  24. salessum = sales;
  25. }
  26. }
  27. std::cout << "\n";
  28. std::cout << " the sum of " << salessum.bookNo << " is " << "\n";
  29. salessum.couts();
  30. std::cout << " the note of " << salessum.bookNo << " is " << cnt << "\n";
  31. std::cout << "\n";
  32. }
  33. return 0;
  34. }

运行结果如下:

 

 

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/花生_TL007/article/detail/136448
推荐阅读
相关标签
  

闽ICP备14008679号