C++Primer第五版 ——— (ch2)课后习题参考答案
练习 2.1
类型 int、long、long long 和 short 的区别是什么?无符号类型和带符号类型的区别是什么?float 和 double的区别是什么?
C++语言规定一个int至少和一个short一样大,一个long至少和一个int一样大,一个long long至少和一个long一样大。每个的最小尺寸分别为:short,16位;int,16位;long,32位;long long,64位。 除去布尔型和扩展的字符型外,其他整形可以划分为带符号的和无符号的两种。带符号类型可以表示正数、负数或0,无符号类型则仅能表示大于等于0的值。 float最小尺寸为6位有效值,double最小尺寸为10位有效值。
练习 2.2
计算按揭贷款时,对于利率、本金和付款分别应选择何种数据类型?说明你的理由。
都选用double,只需查看是否超过最小单位即可,利率4.5%=0.045,本金和付款金额都是以元为单位,钱的最小金额是分,需要精确到小数点后两位,所以都选用double。
练习 2.3
读程序写结果。
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;
#include <iostream>
using namespace std;
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;
}
练习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;
(a)十进制整形; (b)八进制整形,八进制总没有09。 两组day结果相同,month的八进制错误。
练习2.7
下述字面值表示何种含义?它们各自的数据类型是什么?
( a ) “Who goes with F\145rgus?\012”
( b ) 3.14e1L
( c ) 1024f
( d ) 3.14L
( a ) string; ( b ) long double; ( c ) 非法,整形字面值不可加后缀f; ( d ) long double。
2.8 练习
请利用转义序列编写一段程序,要求先输出 2M,然后转到新一行。修改程序使其先输出 2,然后输出制表符,再输出 M,最后转到新一行。
#include <iostream>
int main()
{
std::cout << 2 << "\115\012";
std::cout << 2 << "\011\115\012";
return 0;
}
练习 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 ) 非法,>>运算符后不能定义; 改为 :
int input_value;
std::cin >> input_value;
( b ) 非法,不能执行强制转换; 改为: int i = 3.14,但仍旧会丢失信息。 ( c ) 非法,同一语句的初始化应该分别进行;wage变量没有被定义,变量定义的形式是在类型说明符后紧跟多个变量名时,以逗号分隔,以分号结束。 改为:
double salary = 9999.99, wage = 9999.99;
( d ) 合法,已强制转换。
练习 2.10
下列变量的初值分别是什么?
std::string global_str;
int global_int;
int main()
{
int local_int;
std::string local_str;
}
三条性质:1、定义在任何函数体外的变量会被初始化为0。 2、定义在函数体内部的变量不会被初始化。 3、类的对象未被初始化,则初值由类决定。
#include <iostream>
#include <string>
std::string global_str;
int global_int;
int main()
{
int local_int;
std::string local_str;
std::cout << global_str << std::endl;
std::cout << global_int << std::endl;
std::cout << local_int << std::endl;
std::cout << local_str << std::endl;
return 0;
}
练习 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 = 1;
( e ) double Double = 3.14;
(a) 非法,double是关键字,不能被用作标识符;
(b)可以;
(c)非法,由数字下划线字母组成,“-”不属于其中;
(d)非法,不能以数字开头;
(e)可以。
练习 2.13
下面程序中 j 的值是多少?
int i = 42;
int main()
{
int i = 100;
int j = i;
}
j = 100
练习 2.14
下面的程序合法吗?如果合法,它将输出什么?
int i = 100, sum = 0;
for (int i = 0; i != 10; ++i)
sum += i;
std::cout << i << " " << sum << std::endl;
100 45
练习 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;
都合法,第一个d的值为3.14159,其他的都会发生类型转换。
练习 2.17
执行下面的代码段将输出什么结果?
int i, &ri = i;
i = 5; ri = 10;
std::cout << i << " " << ri << std::endl;
10 10 为引用ri赋值,是把值赋给了与引用绑定的i
练习 2.18
编写代码分别改变指针的值以及指针所指对象的值。
#include <iostream>
using namespace std;
int main()
{
int a = 0, b = 0;
int* pr = nullptr, * pr0 = nullptr;
a = 10;
pr = &a;
cout << "a = " << a << " pr = " << pr << endl;
*pr = 20;
cout << "a = " << a << " pr = " << pr << endl;
pr0 = &b;
pr = pr0;
cout << "pr = " << pr << " pr0 = " << pr0 << endl;
return 0;
}
练习 2.19
说明指针和引用的主要区别
- 引用在定义时必须
初始化 ,指针没有要求 - 引用在初始化时引用一个实体后,就不能再引用其他实体,而指针可以在任何时候指向任何一个同类型
实体 - 没有NULL引用,但有NULL指针
- 在sizeof中含义不同:引用结果为引用类型的大小,但指针始终是地址空间所占字节个数(32位平台下占
4个字节) - 引用自加即引用的实体增加1,指针自加即指针向后偏移一个类型的大小
- 有多级指针,但是没有多级引用
- 访问实体方式不同,指针需要显式解引用,引用编译器自己处理
- 引用比指针使用起来相对更安全
练习 2.20
请叙述下面这段代码的作用。
int i = 42;
int *p1 = &i;
*p1 = *p1 * *p1;
- 定义一个 int 类型的对象 i ,并赋值为 42;
- 定义一个 int 类型的指针 p1 指向 i;
- 原表达式可看作 *p1 = ( *p1 ) *( *p1 ),即两个指针 p1 作解指针操作,为 42,然后再相乘(42 * 42),最后将结果赋值给指针 p1 所指的对象 i 。
练习 2.21
请解释下述定义。在这些定义中有非法的吗?如果有,为什么?
int i = 0;
( a ) double* dp = &i;
( b ) int *ip = i;
( c ) int *p = &i;
int i = 0; ( a ) 非法,double* 和 int* 类型不同; ( b ) 非法,int* 和 int 类型不同; ( c ) 合法。
练习 2.22
假设 p 是一个 int 型指针,请说明下述代码的含义。
if (p)
if (*p)
1.判断条件是指针 p 是否为空指针; 2.判断条件是指针所指的对象是否为0。
练习 2.23
给定指针 p,你能知道它是否指向了一个合法的对象吗?如果能,叙述判断的思路;如果不能,也请说明原因。
需要更多的消息判断指针是否有效。
练习 2.24
在下面这段代码中为什么 p 合法而 lp 非法?
int i = 42;
void *p = &i;
long *lp = &i;
p 是一个 void* 指针可以表示任何类型的对象;而 pl 是 long 类型与 &i 声明的对象的类型 int 不同。
练习 2.25
说明下列变量的类型和值。
( a ) int *ip, i, &r = i;
( b ) int i, *ip = 0;
( c ) int *ip, ip2;
(a) 指向 int 类型的指针,int 类型,int引用; (b) int 类型,指向 int 类型的空指针; ( c ) 指向 int 类型的指针,int类型。
练习 2.26
下面哪些语句是合法的?如果不合法,请说明为什么?
const int buf;
int cnt = 0;
const int sz = cnt;
++cnt;
++sz;
(a)不合法,const对象一旦创建其值就不能改变,所以const对象必须初始化。
(b)合法。
(c)合法,可以在运行时初始化。
(d)不合法,sz不可以改变。
练习2.27
下面的哪些初始化是合法的?请说明原因。
int i = -1, &r = 0;
int *const p2 = &i2;
const int i = -1, &r = 0;
const int *const p3 = &i2;
const int *p1 = &i2;
const int &const r2;
const int i2 = i, &r = i;
0是常量,&r不是对常量的引用; 合法; 合法; 合法; 合法; 非法,没有初始化; 合法;
练习 2.28
说明下面的这些定义是什么意思,挑出其中不合法的。
int i, *const cp;
int *p1, *const p2;
const int ic, &r = ic;
const int *const p3;
const int *p;
不合法,常量指针 cp 没有初始化; 不合法,常量指针 p2 没有初始化; 不合法,常量 ic 没有初始化; 不合法,指向常量的常量指针 p3 没有初始化; 合法,指向常量的指针可以不初始化。
练习 2.29
假设已有上一个练习中定义的那些变量,则下面的哪些语句是合法的?请说明原因。
i = ic;
p1 = p3;
p1 = ⁣
p3 = ⁣
p2 = p1;
ic = *p3;
合法; 非法,p3 是指向 const int 的指针; 非法,ic 是 const int; 非法,p3 是常量指针,不能再次赋值; 非法,p2 是常量指针,不能再次赋值; 非法,ic 是const int ,不能改变。
github部分代码
https:
|