C++Primer第五版 第二章练习

来源:互联网 发布:指针数组初始化为null 编辑:程序博客网 时间:2024/05/11 00:35

2.1.1节练习


练习2.1: 类型int ,long ,long long 和 short的区别是什么?无符号类型和带符号类型的区别是什么?float和double的区别是什么?

练习2.2:计算按揭贷款时,对于利率、本金和付款分别应选择何种数据类型?说明你的理由。

答:

2.1

int 是整形 ,最小尺寸16位。
long 是长整形,32位;
long long 也是长整型 最小尺寸为64位;
short为短整形,表示最小尺寸为8位。


无符号类型,举例来说,比如8位二进制存储单元,无符号类型表示的数为[0,-255],而有符号类型表示为[-128,-127],有符号类型的最高位表示正负,剩余位表示为数值。


float 和 double 都是浮点型,float表示单精度浮点数,6位有效数字; double为双浮点数,10位有效数字。

2.2:

  1. 利率应该选择double型,银行利率通常如3.5%,化成小数形式为0.035,因此选用double型比较好;
  2. 本金通常是一个具体的整数,如3500,4000等,因此使用int型基本满足要求;
  3. 而付款等于本金加本金乘以利率,为了保证精度,付款应当也选用double型。

2.1.2节练习


练习2.3:读程序写结果

usinged u = 10, u2 = 42;std::cout << u2-u << std::endl;std::cout << u –u2 <<std::endl;int i = 10, i2 = 42std::cout << i2 – i <<std::endl;std::cout << I –i2 <<std::endl;std::cout << I – u <<std::endl;std::cout << u – I << std::endl;

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

练习2.3
(1)正确,输出32.
(2)正确,输出的为取模后的值
(3)正确,输出32
(4)正确,输出-32
(5)正确,输出0
(6)正确,输出0

练习2.4

/*  *2017-9-3 练习2.3-2.4 */  #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;       system("pause");    return 0;  }

2.1.3节练习


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

练习2.6
下面两组定义是否有区别,如果有,请叙述之?
Int month = 9, day = 7;
Int month = 09, day = 07;

练习 2.7
下面字面值表示何种含义?它们各自的数据类型是什么?
(a) “Who goes with F\145rgus?\012”
(b) 3.14e1L (c)1024f (d)3.14L

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

:


练习 2.5

(a): 字符a ; 宽字符a; 字符串a相当于:两个字符a和\0;宽字符串a。
(b): 10;无符号数10;长整形10;无符号长整型10;八进制还是10;16进制代表13。
(c): 3.14;浮点数3.140000;长整型3.140000000 。
(d): 10,无符号数10,float型的10,0.1。

练习2.6

第一行: 9,7;
第二行:09错误的,八进制最大为7 ,就是7.

练习2.7

注:a. \145 ‘e’, \012 换行
(a) Who goes with Fe rgus?\n\0
(b)long double型3.14e1
(c)float型的1024
(d)long double型的3.14

练习2.8

#include <iostream>  using namespace std;//M 对应的是\115//制表符是\tint main()  {      cout << "2\115\012"<< endl; //输出2M 换行       cout << "2\t\115\12" << endl;//输出2 制表符 M换行       system("pause");    return 0;   }   

2.2.1节练习(变量定义)


练习2.9

(a) std::cin >> int input_value;
(b) int i = { 3.14 };
(c) double salary = wage = 9999.99;
(d) int i = 3.14;

练习2.10
下列变量的初值分别是什么?

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


练习2.9

(a)错误;input_value未被定义;
(b)警告;when you compile the code without the argument “-std=c++11”, you will get the warning below: warning: implicit conversion from ‘double’ to ‘int’ changes value from 3.14 to 3. —when you compile the code using “-std=c+11”, you will get a error below: error: type ‘double’ cannot be narrowed to ‘int’ in initializer list —conclusion: Obviously, list initialization becomes strict in c++11.

double i = { 3.14 };
(c) 错误;wage未定义;
(d)正确,但精度丢失,最终结果为3.

练习2.10

std::string global_str; //空串 int global_int ;  //0 定义为函数体外为0int main(){Int local_int;//没有被初值化,内置类型函数内部不被初始化,显示为随机值std::string local_str;//空串}

2.2.2节练习(变量声明与定义的关系)


练习2.11
指出下面的语句是声明还是定义:
a) extern int ix = 1024;
(b) int iy;
(c) extern int iz;


练习2.11:

(a) extern int ix =1024; //定义
(b) int iy; //声明并定义iy
(c) extern int iz; //仅声明iz

2.2.3节练习(标识符)


练习2.12:请指出下面的名字中哪些是非法的?
(a) int double = 3.14;
(b) int _;
(c) int catch-22;
(d) int 1_or_2 = 1;
(e) double Double = 3.14;

(a) int double = 3.14 //错误,关键字double不能做变量名
(b) int _;//错误,标识符必须由字母,数字和下划线组成,但必须以字母或者下划线开头,函数体外的标识符也不能以下划线开头 //有不同答案
(c) int catch-22; //错误,不能有连字符
(d) int 1_or_2 = 1;//错误,不能以数字开头
(e) double Double = 3.14;//正确

2.2.4节练习(名字的作用域)


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

int i = 42;int main(){    int i = 100;    int j = i;}

练习 2.14: 下面程序合法吗?如果合法?它将输出什么?

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


练习2.13
输出为100;
练习2.14
45; (1+2+3…+9)//for循环中I 是局部变量 出了循环就没用了

2.3.1节练习(引用)


练习2.15: 下面的那个定义是不合法的?为什么?

(a) int ival = 1.01;
(b)int&rvall = 1.01;
(c) int &rval12 = ival;
(d): int &rval13;

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

练习2.17: 执行下面的代码段将输出什么结果?

    int i, &ri = i;     i= 5;     ri= 10;     std::cout<< i << " " << ri << std::endl;


练习2.15:
(a)合法,但赋值后精度丢失,变成1
(b)不合法,引用需要与一个变量绑定,不能直接赋值
(c)合法
(d)不合法,没有初始化,引用必须要和一个对象绑定

练习2.16:
(a)合法,r2与d绑定,相当于将d的值修改为3.14159
(b)合法,r1是int 型,r2 是double型,相当于将i的值赋给d,精度不丢失
(c)不合法,double型d赋值给int型I 报错,精度丢失
(d)不合法,高精度赋值给低精度的值,不合法

练习2.17:
由于ri和i绑定,因此对ri赋值相当于对i赋值,第一次i赋值为5,第二次ri赋值为10,相当于将i重新赋值,因此输出结果为10 10

2.3.2节练习(指针)


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

练习2.19:说明指针和引用的主要区别。

练习 2.20: 请叙述下面这段代码的作用。

    int i = 42;    int*p1 = &i;    *p1= *p1 * *p1;

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

int i = 0;(a)double *dp = &i;            (b)int *ip = i;                         (c)int *p = &i;

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

if(p) //.. if(*p) //… 

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

练习2.24: 在下面这段代码中为什么p合法而lp非法/

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

答:


练习2.18:

int a = 0, b = 1;int *p1 = &a, *p2 = p1;// change the value of a pointer.p1 = &b;// change the value to which the pointer points*p2 = b;

练习2.19:说明指针和引用的主要区别。

定义:
指针是“指向”任何其他类型的对象。
引用是对象的“另一个名称”。
关键的区别
1. 引用是已经存在的对象的另一个名称。指针本身就是一个对象。
2. 初始化后,引用仍然绑定到它的初始对象。无法重新绑定引用来引用不同的对象。一个指针可以被分配和复制。
3. 引用总是获取引用最初被绑定的对象。一个指针可以在它的生命周期中指向几个不同的对象。
4. 必须初始化引用。指针在定义的时候不需要初始化。

练习 2.20: 请叙述下面这段代码的作用。

    int i = 42;    int*p1 = &i;    *p1= *p1 * *p1;

*p1是间接访问i的,p1中存放的是i的地址,因此实际是通过指针p1间接修改了i的值,是i的值变成了42×42.

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

int i = 0;(a)double *dp = &i;            (b)int *ip = i;                         (c)int *p = &i;

(a)非法,前后类型不一致 (b)非法,指针存放是一个对象的地址,而非对象本身 (c)合法

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

if(p) //.. if(*p) //… 

if(p) //.. //如果p存放的地址不为空,即p存放的地址存在,条件为真,向下执行
if(*p) //… //如果,p指向的int型对象的值不等于0,条件为真,向下执行。

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

不能判断指针p是否指向了一个合法的对象,因为如果指针p没有被初始化,p存放的是一个随机的地址,这是一件极其危险的事情,再者,如果p没有被合法的初始化,恶意存放了一个地址,也是危险的。所以,需要程序员自己清楚指针是否被合法使用。

练习2.24: 在下面这段代码中为什么p合法而lp非法/

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

void*是一种特殊的指针类型,可以用于存放任意对象的地址。第三个两者类型不一,当然报错,和赋值不一样,指针要求两边类型严格一致(有特例,47页说其他章节会介绍)

2.3.3节练习(理解复合类型的声明)


练习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型的空指针,存放地址为空;
(c)ip存放的是地址,指向一个int型对象,值不确定;ip2是一个int型对象,值不确定。

2.4节练习(const限定符和extern const)


练习2.26:下面那些句子是合法的?如果有不合法的句子,请说明为什么?

(a)const int buf;        (b)int cnt = 0;        (c)const int sz = cnt;   (d)++cnt; ++sz;               

答:


(a)不合法,const对象必须初始化;
(b)合法,cnt是int型,初始化为0;
(c)合法,sz的值需要看cnt;
(d)如果根据(c)项来看,不合法,sz不能自增;

2.4.2节练习(const的引用,指针与const)


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

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

(a) int i ,*const cp;      (b) int *p1 ,*const p2; (c) const int rc, &rc =ic;   (d) const int *const p3; (e) const int *p; 

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

ai = ic;      (b) p1 = p3; (c) p1 = &ic;    (d) p3 = ⁣&ic; (e) p2 = p1;     (f) ic =* p3; 

答:


练习2.27:

(a)非法,int &r = 0。错误 ;
(b)合法 p2是一个常量指针,一直存放i2的地址,不能变动,但能间接改动i2的值
(c)合法
(d)合法 p3是一个常量指针,一直存放i2的地址,且不能通过修改p3来修改i2的值
(e)合法,p1存放i2的地址,不能通过修改p1来改变i2的值,但p1本身存放的地址是不是可以变化?
(f) 非法 引用本身不是一个对象
(g)合法

练习2.28:

(a) 不合法,没有初始化
(b) 不合法,没有初始化
(c) 不合法,前一半没有初始化,后一半类型不对应
(d) 不合法 没有初始化
(e) 不合法 没有初始化

练习2.29:

(a)用const int 赋值 可以
(b)p1是int指针 p3是const int 指针 无法从“const int const”转换为“int ”
(c) 无法从“const int const ”转换为“int ”
(d)如果这句是初始化 可以!!已经初始化过,不行
(e)因为p1指向的对象可能发生变化 ,不合法
(f)ic不能被赋值

原创粉丝点击