编译软件为 vs2015。

第一章

练习1.9:

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

#include "stdafx.h"
#include<iostream>int main()
{int sum = 0, val = 50;while (val <= 100) {sum += val;val++;}std::cout << " sum of 50 to 100 is " << sum << std::endl;return 0;
}

练习1.10:

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

#include "stdafx.h"
#include<iostream>int main()
{int i = 10;while (i >= 0) {std::cout << i << std::endl;i--;}return 0;
}

练习1.11:

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

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

#include "stdafx.h"
#include<iostream>int main()
{int i, j;std::cout << "please input two numbers:" << std::endl;std::cin >> i >> j;if (i >= j){while (j <= i) {std::cout << j << std::endl;j++;}}else {while (i <= j) {std::cout << i << std::endl;i++;}}return 0;
}

练习1.13:

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

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

练习1.16:

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

#include "stdafx.h"
#include<iostream>int main()
{int sum = 0, val = 0;std::cout << "please intput numbers:" << std::endl;while (std::cin>>val) sum += val;std::cout << " sum of these numbers is: " << sum << std::endl;return 0;
}

练习1.20:

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

#include "stdafx.h"
#include<iostream>
#include"Sales_item.h"int main()
{Sales_item book;std::cin >> book;std::cout << book << std::endl;return 0;
}

使用输入方法如下:

练习1.21:

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

#include"stdafx.h"
#include<iostream>
#include"Sales_item.h"int main()
{Sales_item book1, book2;std::cin >> book1 >> book2;std::cout << book1 + book2 << std::endl;return 0;
}

练习1.22:

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

#include"stdafx.h"
#include<iostream>
#include"Sales_item.h"int main()
{Sales_item salessum, sales;std::cin >> salessum;while (std::cin >> sales)salessum += sales;std::cout << salessum;return 0;
}

练习1.23:

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

#include"stdafx.h"
#include<iostream>
#include"Sales_item.h"int main() {Sales_item salessum, sales;int cnt = 1;if (std::cin >> salessum){while (std::cin >> sales) {if (sales.isbn() == salessum.isbn())++cnt;else {std::cout << " the note of " << salessum.isbn() << " is " << cnt << std::endl;cnt = 1;salessum = sales;}}std::cout << " the note of " << salessum.isbn() << " is " << cnt << std::endl;//记住打印最后一条记录}return 0;
}
//此程序只能读取多条ISBN号相同连续的记录 类似:xxxxccc,若为:xcxcxcx,则不能处理 

第二章

练习2.3、2.4:

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

#include "stdafx.h"
#include<iostream>int main()
{unsigned u = 10, u2 = 42;std::cout << u2 - u << std::endl;std::cout << u - u2 << std::endl;int i = 10, i2 = 42;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;
}

结果分别对应如下:

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,最后转到新一行。

#include "stdafx.h"
#include<iostream>int main()
{std::cout << "\062\115\n" << std::endl;std::cout << "\062\t\x4d\012" << std::endl;return 0;
}

输出结果: (转义字符参照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:

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

std::string global_str;int gobal_int;int main(){int  local_int;std::string local_str;}

变量 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 的值是多少?

int i = 42;
int main()
{int i = 100;int j = i;std::cout << j << std::endl;return 0;
}

输出结果 j = 100;

练习2.14:

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

int main()
{int i = 100, sum = 0;for (int i = 0; i != 10;++i)sum += i;std::cout << i << " " << sum << std::endl;return 0;
}

解答:

程序合法,输出结果为: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:

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

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

 输出如下:

练习2.18:

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

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

 输出结果如下:

练习2.19:

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

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

练习2.20:

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

int i = 42;int *p1 = &i;*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定义的程序语句如下:

#include "stdafx.h"
#include<iostream>int main()
{int i = 0, &r = i;// i 是一个整数,r 是对 i 的引用;auto a = r;// a 是一个整数;const int ci = i, &cr = ci;// ci 是一个整形常量,cr 是对整形常量的引用;auto b = ci;// b 是一个整数,auto 忽略掉了 ci 的顶层 const;auto c = cr;// c 与 b 同,是一个整数auto d = &i;// d 是一个整形指针,指向整数 i;auto e = &ci;// e 是一个指向整形常量 ci 的指针(对常量对象取地址是一种底层 const);auto &g = ci;// g 是一个对整形常量 ci 的应用,与 ci 绑定;std::cout << " a = " << a << "\n" << std::endl;std::cout << " b = " << b << "\n" << std::endl;std::cout << " c = " << c << "\n" << std::endl;std::cout << " d = " << d << "\n" << std::endl;std::cout << " e = " << e << "\n" << std::endl;std::cout << " g = " << g << "\n" << std::endl;//练习2.33:a = 42;b = 42;c = 42;   d = 42;e = 42;g = 42;std::cout << " a = " << a << "\n" << std::endl;std::cout << " b = " << b << "\n" << std::endl;std::cout << " c = " << c << "\n" << std::endl;std::cout << " d = " << d << "\n" << std::endl;std::cout << " e = " << e << "\n" << std::endl;std::cout << " g = " << g << "\n" << std::endl;return 0;
}

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

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

#include "stdafx.h"
#include<iostream>int main()
{int i = 0, &r = i;// i 是一个整数,r 是对 i 的引用;auto a = r;// a 是一个整数;const int ci = i, &cr = ci;// ci 是一个整形常量,cr 是对整形常量的引用;auto b = ci;// b 是一个整数,auto 忽略掉了 ci 的顶层 const;auto c = cr;// c 与 b 同,是一个整数auto d = &i;// d 是一个整形指针,指向整数 i;auto e = &ci;// e 是一个指向整形常量 ci 的指针(对常量对象取地址是一种底层 const);auto &g = ci;// g 是一个对整形常量 ci 的应用,与 ci 绑定;std::cout << " a = " << a << "\n" << std::endl;std::cout << " b = " << b << "\n" << std::endl;std::cout << " c = " << c << "\n" << std::endl;std::cout << " d = " << d << "\n" << std::endl;std::cout << " e = " << e << "\n" << std::endl;std::cout << " g = " << g << "\n" << std::endl;std::cout << "\n" << std::endl;//练习2.33:a = 42;b = 42;c = 42;  //d = 42;//e = 42;//g = 42;*d = 42;//对 d 指向的对象即 i 赋值;e = &a;//此时 e 指向整数 a 的地址;std::cout << " a = " << a << "\n" << std::endl;std::cout << " b = " << b << "\n" << std::endl;std::cout << " c = " << c << "\n" << std::endl;std::cout << " d = " << d << "\n" << std::endl;std::cout << " e = " << e << "\n" << std::endl;std::cout << " g = " << g << "\n" << std::endl;return 0;
}

运行结果如下:

练习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 为整形常量引用;

程序运行如下:

#include "stdafx.h"
#include <iostream>
#include <typeinfo>
using std::cout;
using std::endl;int main()
{const int i = 42;auto j = i;const auto &k = i;auto *p = &i;const auto j2 = i, &k2 = i;cout << "i is " << typeid(i).name() << "\n" << endl;cout << "j is " << typeid(j).name() << "\n" << endl;cout << "k is " << typeid(k).name() << "\n" << endl;cout << "p is " << typeid(p).name() << "\n" << endl;cout << "j2 is " << typeid(j2).name() << "\n" << endl;cout << "k2 is " << typeid(k2).name() << "\n" << endl;return 0;
}

运行结果如下:

练习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;

程序验证如下:

#include "stdafx.h"
#include<iostream>
using std::cout;
using std::endl;int main()
{int a = 3, b = 4;decltype(a) c = a;decltype((b)) d = a;++c;++d;cout << "a =  " << a << " and type is " << typeid(a).name() << "\n" << endl;cout << "b =  " << b << " and type is " << typeid(b).name() << "\n" << endl;cout << "c =  " << c << " and type is " << typeid(c).name() << "\n" << endl;cout << "a =  " << d << " and type is " << typeid(d).name() << "\n" << endl;return 0;
}

结果如图:

练习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 和引用在内。

举例如下:

#include "stdafx.h"
#include<iostream>
using std::cout;
using std::endl;int main()
{int m = 5, &n = m;//auto 与 decltype 指定类型相同时auto a = m;//a 为一个整数decltype(m) b = m;//b 为一个整数cout << "a =  " << a << " and type is " << typeid(a).name() << "\n" << endl;cout << "b =  " << b << " and type is " << typeid(b).name() << "\n" << endl;//auto 与 decltype 指定类型不同时auto i = n;//i 为一个整数decltype(n) t = n;//t 为一个整型引用cout << "i =  " << i << " and type is " << typeid(i).name() << "\n" << endl;cout << "t =  " << t << " and type is " << typeid(t).name() << "\n" << endl;return 0;
}

练习 2.39:

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

解答: 

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

错误提示如下:

练习2.40:

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

解答: 

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

练习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。读取一组书籍销售记录并将结果打印到标准输出上

//用自己定义的 Sales_data 类改写练习1.20。读取一组书籍销售记录并将结果打印到标准输出上
#include "stdafx.h"
#include<iostream>
#include<string>struct Sales_data {std::string bookNo;//书号ISBNunsigned unit_sold = 0;//销售量double revenue = 0.0;//销售额
};int main()
{Sales_data book;double price = 0.0;//销售单价//首先读入书号ISBN、销售量、单价std::cin >> book.bookNo >> book.unit_sold >> price;//计算销售额并打印结果到标准输出上book.revenue = book.unit_sold*price;std::cout << book.bookNo << " total revenue is " << book.revenue << std::endl;return 0;
}

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

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

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

//用自己定义的 Sales_data 类改写练习1.22。读取多个具有相同 ISBN 的销售记录,并输出他们的和
#include"stdafx.h"
#include<iostream>
#include<string>struct Sales_data {std::string bookNo;//书号ISBNunsigned unit_sold = 0;//销售量double revenue = 0;//销售额
};int main()
{double a_price = 0.0, salessum_price = 0.0, sales_price = 0.0;//平均销售单价Sales_data salessum, sales;//定义总项目和单项//首先读入第一个输入的项,并将其初始化为 salessumstd::cin >> salessum.bookNo >> salessum.unit_sold>>salessum_price;salessum.revenue = salessum.unit_sold*salessum_price;//首先计算出第一项的销售额while (std::cin >> sales.bookNo >> sales.unit_sold >> sales_price) {sales.revenue = sales.unit_sold*sales_price;salessum.unit_sold = salessum.unit_sold + sales.unit_sold;//将第一项作为总项不断与输入项相加,求得总销售量salessum.revenue = salessum.revenue + sales.revenue;//求得总销售额a_price = salessum.revenue / salessum.unit_sold;//求出平均销售单价}std::cout << salessum.bookNo << " " << salessum.unit_sold << " " << salessum.revenue << " " << a_price << " " << std::endl << "\n";return 0;
}

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

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

//用自己定义的 Sales_data 类改写练习1.23、1.24。 读取多条销售记录,并统计每个ISBN有几条销售记录,每个 ISBN 应该聚集在一起。
#include"stdafx.h"
#include<iostream>
#include<string>struct Sales_data {std::string bookNo;unsigned unit_sold = 0;double revenue = 0.0;
};int main() {Sales_data salessum, sales;double price1 = 0.0, price2 = 0.0;double total_revenue = 0.0;int cnt = 1; //设置计数器 cntif (std::cin >> salessum.bookNo >> salessum.unit_sold >> price1) { //使得第一个输入的组为salessumsalessum.revenue = salessum.unit_sold*price1;while (std::cin >> sales.bookNo >> sales.unit_sold >> price2) { //如果继续输入则为salessales.revenue = sales.unit_sold*price2;if (sales.bookNo == salessum.bookNo) {++cnt;//如果输入的组的书号 ISBN 相同,则计数器加一salessum.revenue = salessum.revenue + sales.revenue;}else {std::cout << " the note of " << salessum.bookNo << " is " << cnt << " and the total revenue is " << salessum.revenue << std::endl;cnt = 1; // 如果输入的某一组 ISBN 与之前不同,则输出此时计数器的值,即为销售记录的条数,并将计数器置为1salessum = sales;}}std::cout << " the note of " << salessum.bookNo << " is " << cnt << " and the total revenue is " << salessum.revenue << std::endl;}// 直到输入结束,输出最后一条 ISBN 的销售记录return 0;
}
//如题目,ISBN 记录应该连在一起,此程序只能读取多条ISBN号相同连续的记录 类似:xxxxccc,若为:xcxcxcx,则不能处理 

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

//用自己编写的Sales_data文件改写练习1.25。运行书中的书店程序
#include"stdafx.h"
#include<iostream>
#include<string>struct Sales_data {std::string bookNo;unsigned unit_solds = 0;double revenue = 0.0;
};int main()
{Sales_data totals;double price1 = 0.0, price2 = 0.0;if (std::cin >> totals.bookNo >> totals.unit_solds >> price1) {totals.revenue = totals.unit_solds*price1;Sales_data trans;while (std::cin >> trans.bookNo >> trans.unit_solds >> price2) {trans.revenue = trans.unit_solds*price2;if (totals.bookNo == trans.bookNo) {totals.unit_solds += trans.unit_solds;totals.revenue += trans.revenue;}else {std::cout << " The note of " << totals.bookNo << " unit sold is " << totals.unit_solds << " total revenue is " << totals.revenue << "\n" << std::endl;totals = trans;}}std::cout << " The note of " << totals.bookNo << " unit sold is " << totals.unit_solds << " total revenue is " << totals.revenue << "\n" << std::endl;}else {std::cerr << " No data?! " << "\n" << std::endl;return -1;}return 0;
}

 (N N表示结束符)

练习2.42:

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

解答:Sales_data.h文件如下

#ifndef SALES_DATA_H
#define SALES_DATA_H#include <iostream>
#include <string>struct Sales_data {std::string bookNo;unsigned unit_sold = 0;double revenue = 0.0;double price = 0.0;void oridata(Sales_data item);//设置原始数据的对应值void cins();//设置输入函数void data_revenue();//设置求销售额函数void sumdata(Sales_data item);//设置项相加函数double averdata();//设置求平均销售单价函数void couts();//设置输出函数
};
#endifvoid Sales_data::cins() {std::cin >> bookNo >> unit_sold >> price;
}void Sales_data::oridata(Sales_data item) {bookNo = item.bookNo;unit_sold = item.unit_sold;revenue = item.revenue;price = item.price;
}void Sales_data::data_revenue() {revenue = unit_sold*price;
}void Sales_data::sumdata(Sales_data item) {if (bookNo != item.bookNo)return;unit_sold += item.unit_sold;revenue += item.revenue;
}double Sales_data::averdata() {if (unit_sold != 0)return revenue / unit_sold;elsestd::cout<< "no sales";
}void Sales_data::couts() {double aver_revenue = averdata();std::cout << bookNo << " " << unit_sold << " " << revenue << " " << aver_revenue << "\n";
}

使用方法如下: 

#include "stdafx.h"
#include<iostream>
#include<string>
#include"Sales_data.h"//1.20读取一组书籍销售记录并将结果打印到标准输出上
int main()
{Sales_data book;book.cins();book.data_revenue();book.couts();return 0;
}*/

运行结果如下:

#include "stdafx.h"
#include<iostream>
#include<string>
#include"Sales_data.h"//1.21读取 ISBN 号相同的两组书籍并计算这两个项目的“和”
int main()
{Sales_data book1, book2;book1.cins();book2.cins();book1.data_revenue();book2.data_revenue();book2.sumdata(book1);book2.couts();return 0;
}

运行结果如下:

#include "stdafx.h"
#include<iostream>
#include<string>
#include"Sales_data.h"//1.22读取多个具有相同 ISBN 的销售记录,并输出他们的和
int main()
{Sales_data salessum, sales;salessum.cins();salessum.data_revenue();while (std::cin >> sales.bookNo >> sales.unit_sold >> sales.price) {sales.data_revenue();salessum.sumdata(sales);}salessum.couts();return 0;
}

//1.23、1.24 读取多条销售记录,并统计每个ISBN有几条销售记录
#include "stdafx.h"
#include<iostream>
#include<string>
#include"Sales_data.h"int main() {Sales_data salessum, sales;int cnt = 1;if (std::cin >> salessum.bookNo >> salessum.unit_sold >> salessum.price) {salessum.data_revenue();while (std::cin >> sales.bookNo >> sales.unit_sold >> sales.price) {sales.data_revenue();if (sales.bookNo == salessum.bookNo) {salessum.sumdata(sales);++cnt;}else {std::cout << "\n";std::cout << " the sum of " << salessum.bookNo << " is " << " \n";salessum.couts();std::cout << " the note of " << salessum.bookNo << " is " << cnt << "\n";std::cout << "\n";cnt = 1;salessum = sales;}}std::cout << "\n";std::cout << " the sum of " << salessum.bookNo << " is " << "\n";salessum.couts();std::cout << " the note of " << salessum.bookNo << " is " << cnt << "\n";std::cout << "\n";}return 0;
}

运行结果如下:

C++ Primer 第五版 课后章节练习答案 第一、二章相关推荐

  1. 《计算机网络》学习笔记----第七版课后习题参考答案 第四章

    1.网络层向上提供的服务有哪两种?是比较其优缺点.网络层向运输层提供 "面向连接"虚电路(Virtual Circuit)服务或"无连接"数据报服务前者预约了双 ...

  2. 《计算机网络》学习笔记----第七版课后习题参考答案 第三章

    3-01  数据链路(即逻辑链路)与链路(即物理链路)有何区别? "电路接通了"与"数据链路接通了"的区别何在? 答:数据链路与链路的区别在于数据链路出链路外, ...

  3. 《计算机网络》学习笔记----第七版课后习题参考答案 第六章

    6-01  因特网的域名结构是怎么样的?它与目前的电话网的号码结构有何异同之处?答:(1)域名的结构由标号序列组成,各标号之间用点隔开: - . 三级域名 . 二级域名 . 顶级域名 各标号分别代表不 ...

  4. C++Primer第五版——习题答案+详解(完整版)

     C++Primer第五版--习题答案详解 新手入门必看的书.知识是一个系统化并且相互关联的体系,零散的东西每天收获如果不形成自己的体系的话,那将是毫无意义的,所以我觉得有必要将这本书先啃一遍,消化其 ...

  5. C++Primer第五版——习题答案详解

     C++Primer第五版--习题答案详解 新手入门必看的书.知识是一个系统化并且相互关联的体系,零散的东西每天收获如果不形成自己的体系的话,那将是毫无意义的,所以我觉得有必要将这本书先啃一遍,消化其 ...

  6. C++ primer 第五版习题答案, Stanley B. Lippman( 斯坦利 李普曼)(持续更新中)

    最新重新看c++ primer 5 第五版本,看到网上很多人在找答案,而这本书是2013年9月份的样子出来的,网上肯定是没有标准答案的,而很多人冒天下之大不韪用c plus plus的答案来来骗取分数 ...

  7. 什么是现代通用计算机的轴型,大学计算机基础(版)各章节习题+答案.doc

    大学计算机基础(版)各章节习题答案 第一章 计算机与信息社会基础知识 一.选择题 1._____________是现代通用计算机的雏形. A. 宾州大学于1946年2月研制成功的ENIAC B.查尔斯 ...

  8. C++ Primer 第五版 第6章——函数阅读笔记及习题答案(完整,附C++代码)

    C++Primer(第五版)第6章函数的阅读笔记及课后习题答案总结,课后习题答案是自己学习写出来的,如果有误,欢迎指正 还不完整,后续会更新添加 阅读笔记 C++ Primer 第五版 第6章 6.1 ...

  9. 《C++Primer 第五版》——第八章 IO 库

    <C++Primer 第五版>--第八章 IO 库 8.1 IO 类 IO 类型间的关系 8.1.1 IO 对象无拷贝或赋值 8.1.2 条件状态 查询流的状态 管理条件状态 8.1.3 ...

最新文章

  1. SDN:软件定义网络
  2. java中List深拷贝的简单实例
  3. 数据在HDFS和HBASE之间互相传递的过程
  4. 新浪微博客户端(53)-记录用户最近点击表情
  5. [python爬虫] 爬取图片无法打开或已损坏的简单探讨
  6. 017 包扫描器和标记注解
  7. C++智能指针(二)模拟实现三种智能指针
  8. 十八般武艺玩转GaussDB(DWS)性能调优:总体调优策略
  9. c/c++入门教程 - 3 职工管理系统 完整代码
  10. mysql_config缺失_安装 mysqlclient 报 mysql_config not found
  11. an argument for principle #1:thoreau's new economics 36-38
  12. 阵列信号处理 窄带信号与包络
  13. mac pro M1(ARM)安装:VMWare Fusion及linux(centos7/ubuntu)(一)
  14. 那些想上天的亿万富翁,开启了新的“太空竞赛”
  15. Vista系统Administrator帐户的激活与禁用
  16. 线上编程学院codecademy
  17. abp ddd mysql_初识ABP vNext(1):开篇计划基础知识
  18. 【Unity】AvProVideo 实现当前视频播放完毕自动加载下一视频
  19. .net mvc ef 视图未定义主键问题
  20. 小米盒子 改装 无线打印服务器,终于找到了“小米盒子增强版”不定期断网的bug了,2.4G模块bug!...

热门文章

  1. 一家公司的PHP实习生笔试题
  2. 3.网络爬虫的组成结构(一个爬虫框架)
  3. C++基础入门(上):命名空间、输入输出、缺省参数
  4. 图像验证码识别(三)——基本流程讨论
  5. java 文件io 实验_java I/O流实验小结
  6. 零代码实现EDI标准报文转换
  7. [C++]Effective C++笔记
  8. 怎么ping 1433端口
  9. SylixOS ArmV7m 支持
  10. vb中imp是什么意思_VB中Implements的作用