C++ Primer第五版_第二章习题答案 变量和基本类型
创始人
2025-05-28 18:06:51
0

文章目录

      • 题目概览
        • 2.1 类型区别
        • 2.2 按揭贷款
        • 2.3 读程序,写结果
        • 2.4 无符号整数
        • 2.5 字面值的数据类型
        • 2.6 十进制与八进制
        • 2.7 字面值的含义
        • 2.8 转义序列
        • 2.9 定义的含义
        • 2.10 变量初值
        • 2.11 声明还是定义
        • 2.12 非法命名
        • 2.13 j的值
        • 2.14 程序合法性
        • 2.15 定义的合法性
        • 2.16 赋值的合法性
        • 2.17 代码段输出
        • 2.18 改变指针的值以及指针所指对象的值
        • 2.19 指针和引用的区别
        • 2.20 代码段的作用
        • 2.21 非法的定义
        • 2.22 代码的含义
        • 2.23 给定指针
        • 2.24 合法指针
        • 2.25 变量的类型和值
        • 2.26 变量的类和值,语句合法性
        • 2.27 合法初始化
        • 2.28 不合法的定义
        • 2.29 合法语句
        • 2.30 顶层底层const
        • 2.31 顶层底层const的体现
        • 2.32 代码合法
        • 2.33 定义的变量
        • 2.34 赋值前后变量
        • 2.35类型推断
        • 2.36 变量类型及结束时的值
        • 2.37 变量的类型和值
        • 2.38 decltype和auto
        • 2.39 编译程序观察结果
        • 2.40 Sales_data

题目概览

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

2.1 类型区别

C++ 规定 shortint 至少16位,long 至少32位,long long 至少64位。 带符号类型能够表示正数、负数和 0 ,而无符号类型只能够表示 0 和正整数。

用法:

  • 一般使用 int 做整数运算,short 因为太小在实际中用的少,long 通常和 int 有着相同的大小。如果数据非常大,可以使用 long long
  • 如果你确认数据是非负的,那么就使用 unsigned 无符号类型。
  • 执行浮点运算时用 double ,因为 float 通常精度不够而且双精度浮点数和单精度浮点数的计算代价相差无几。

参考:

  • What are the criteria for choosing between short / int / long data types?
  • Difference between float and double

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

2.2 按揭贷款

使用 doublefloat

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

2.3 读程序,写结果

32
4294967264
32
-32
0
0

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

2.4 无符号整数

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZNLtq0c5-1678889883366)(.\media\2-2.png)]

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

  • (a) ‘a’, L’a’, “a”, L"a"
  • (b) 10, 10u, 10L, 10uL, 012, 0xC
  • © 3.14, 3.14f, 3.14L
  • (d) 10, 10u, 10., 10e-2

2.5 字面值的数据类型

(a)字符字面值,宽字符字面值,字符串字面值,宽字符串字面值;
(b)整形字面值,无符号整形字面值,长整形字面值,无符号长整形字面值,八进制整形字面值,十六进制整形字面值;
(c)浮点型字面值,单精度浮点型字面值,扩展精度浮点型字面值;
(d)整形字面值,无符号整形字面值,浮点型字面值,浮点型字面值。

练习2.6:下面两组定义是否有区别,如果有,请叙述之:

int month = 9, day = 7;
int month = 09, day = 07;

2.6 十进制与八进制

第一行定义的是十进制整型。 第二行定义的是八进制整型,但是 month 变量无效,因为八进制没有 9 。

练习2.7:下述字面值表示何种含义?它们各自的数据类型是什么?

(a) "Who goes with F\145rgus?\012"
(b) 3.14e1L
(c) 1024f
(d) 3.14L

2.7 字面值的含义

(a): Who goes with Fergus?(换行),string 类型
(b): long double
(c): 无效,因为后缀 f 只能用于浮点字面量,而 1024 是整型。
(d): long double

参考:ASCII Table

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

2.8 转义序列

#include int main()
{std::cout << 2 << "\115\012";std::cout << 2 << "\t\115\012";return 0;
}

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

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

2.9 定义的含义

(a): 应该先定义再使用。

int input_value = 0;
std::cin >> input_value;

(b): 用列表初始化内置类型的变量时,如果存在丢失信息的风险,则编译器将报错。

double i = { 3.14 };

©: 在这里 wage 是未定义的,应该在此之前将其定义。

double wage;
double salary = wage = 9999.99;

(d): 不报错,但是小数部分会被截断。

double i = 3.14;

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

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

2.10 变量初值

global_int 是全局变量,所以初值为 0 。

local_int 是局部变量并且没有初始化,它的初值是未定义的。

global_strlocal_str 是 string 类的对象,该对象定义了默认的初始化方式,即初始化为空字符串。

练习2.11:指出下面的语句是声明还是定义:

  • (a) extern int ix = 1024;
  • (b) int iy;
  • © extern int iz;

2.11 声明还是定义

(a): 定义
(b): 定义
©: 声明

练习2.12:请指出下面的名字中哪些是非法的?

  • (a) int double = 3.14;
  • (b) int _;
  • © int catch-22;
  • (d) int 1_or_2 = 1;
  • (e) double Double = 3.14;

2.12 非法命名

(a)非法,关键词;
(b)合法;
(c)非法;
(d)非法,字母、下划线开头;
(e)合法。

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

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

2.13 j的值

j 的值是 100 ,局部变量 i 覆盖了全局变量 i

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

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

2.14 程序合法性

合法。输出是 100 45

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

  • (a) int ival = 1.01;
  • (b) int &rval1 = 1.01;
  • © int &rval2 = ival;
  • (d) int &rval3;

2.15 定义的合法性

(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;

2.16 赋值的合法性

(a): 合法。给 d 赋值为 3.14159。
(b): 合法。会执行自动转换(int->double)。
©: 合法。会发生小数截取。
(d): 合法。会发生小数截取。

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

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

2.17 代码段输出

10, 10

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

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:说明指针和引用的主要区别

2.19 指针和引用的区别

  1. 引用是另一个对象的别名,而指针本身就是一个对象。
  2. 引用必须初始化,并且一旦定义了引用就无法再绑定到其他对象。而指针无须在定义时赋初值,也可以重新赋值让其指向其他对象。

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

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

2.20 代码段的作用

让指针 pi 指向 i,然后将 i 的值重新赋值为 42 * 42 (1764)。

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

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

2.21 非法的定义

(a): 非法。不能将一个指向 `double` 的指针指向 `int` 。
(b): 非法。不能将 `int` 变量赋给指针。
(c): 合法。

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

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

2.22 代码的含义

if (p) // ... 判断 p 是不是一个空指针, if (*p) // ... 判断 p 所指向的对象的值是不是为 0

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

2.23 给定指针

不能,因为首先要确定这个指针是不是合法的,才能判断它所指向的对象是不是合法的。

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

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

2.24 合法指针

void * 是从 C语言那里继承过来的,可以指向任何类型的对象。而其他指针类型必须要与所指对象严格匹配。

练习2.25:说明下列变量的类型和值。

  • (a) int* ip, i, &r = i;
  • (b) int i, *ip = 0;
  • © int* ip, ip2;

2.25 变量的类型和值

(a): ip 是一个指向 int 的指针, i 是一个 int, r 是 i 的引用。
(b): i 是 int , ip 是一个空指针。
©: ip 是一个指向 int 的指针, ip2 是一个 int。

练习2.26:说明下列变量的类型和值。下面哪些语句是合法的?如果不合法,请说明为什么?

const int buf;
int cnt = 0;
const int sz = cnt;
++cnt; ++sz;

2.26 变量的类和值,语句合法性

(a)不合法,const int必须初始化;
(b)合法;
(c) 合法;
(d)++cnt,合法;++sz,不合法,const int不能改变。

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

2.27 合法初始化

(a)0是常量,&r不是对常量的引用,所以可以改变,这显然是不对的;
(b)如果i2是const int,这是不对的;
(c)合法;
(d)合法;
(e)合法;
(f)不合法,没有初始化;
(g)合法。

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

int i, *const cp;       
int *p1, *const p2;     
const int ic, &r = ic;  
const int *const p3;    
const int *p;         

2.28 不合法的定义

(a)不合法,常量指针未初始化;
(b)不合法,常量指针未初始化;
(c)不合法,常量ic未初始化;
(d)不合法,常量指针未初始化;
(e)合法,指向常量的指针可以不初始化。

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

i = ic;
p1 = p3;
p1 = ⁣
p3 = ⁣
p2 = p1;
ic = *p3;

2.29 合法语句

(a)合法;
(b)非法,p3是指向const int的指针;
(c)非法,ic是const int;
(d)非法,p3是常量指针,不能再次赋值;
(e)非法,p2是常量指针,不能再次赋值;
(f)非法,ic是const int。

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

const int v2 = 0; int v1 = v2;
int *p1 = &v1, &r1 = v1;
const int *p2 = &v2, *const p3 = &i, &r2 = v2;

2.30 顶层底层const

v2 是顶层const,p2 是底层const,p3 既是顶层const又是底层const,r2 是底层const。

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

r1 = v2;
p1 = p2;
p2 = p1;
p1 = p3;
p2 = p3;

2.31 顶层底层const的体现

r1 = v2; // 合法,v2为顶层const
p1 = p2; // 非法,p2为底层const
p2 = p1; // 合法
p1 = p3; // 非法
p2 = p3; // 合法

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

int null = 0, *p = null;

2.32 代码合法

非法,把int变量直接赋给指针是错误的操作,即使int变量的值恰好等于0也不行.

int null = 0, *p = 0;

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

a=42;
b=42;
c=42;
d=42;
e=42;
g=42;

2.33 定义的变量

a=42; // a 是 int
b=42; // b 是一个 int,(ci的顶层const在拷贝时被忽略掉了)
c=42; // c 也是一个int
d=42; // d 是一个 int *,所以语句非法
e=42; // e 是一个 const int *, 所以语句非法
g=42; // g 是一个 const int 的引用,引用都是底层const,所以不能被赋值

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

2.34 赋值前后变量

#include int main()
{int i = 0, &r = i;auto a = r;   // a is an int (r is an alias for i, which has type int)const int ci = i, &cr = ci;auto b = ci; // b is an int (top-level const in ci is dropped)auto c = cr; // c is an int (cr is an alias for ci whose const is top-level)auto d = &i; // d is an int* (& ofan int objectis int*)auto e = &ci; // e is const int*(& of a const object is low-level const)const auto f = ci; // deduced type of ci is int; f has type const intauto &g = ci; // g is a const int& that is bound to cia = 42; b = 42; c = 42; *d = 42; e = &c;return 0;
}

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

const int i = 42;
auto j = i; const auto &k = i; auto *p = &i; 
const auto j2 = i, &k2 = i;

2.35类型推断

j 是 int,k 是 const int的引用,p 是const int *,j2 是const int,k2 是 const int 的引用。

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

int a = 3, b = 4;
decltype(a) c = a;
decltype((b)) d = a;
++c;
++d;

2.36 变量类型及结束时的值

c 是 int 类型,值为 4。d 是 int & 类型,绑定到 a,a 的值为 4 。

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

int a = 3, b = 4;
decltype(a) c = a;
decltype(a = b) d = a;

2.37 变量的类型和值

c 是 int 类型,值为 3。d 是 int& 类型,绑定到 a。

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

2.38 decltype和auto

decltype 处理顶层const和引用的方式与 auto不同,decltype会将顶层const和引用保留起来。

int i = 0, &r = i;
//相同
auto a = i;
decltype(i) b = i;//不同 d 是一个 int&
auto c = r;
decltype(r) d = r;

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

struct Foo { /* 此处为空  */ } // 注意:没有分号
int main()
{return 0;
}

2.39 编译程序观察结果

Error message: [Error] expected ';' after struct definition

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

2.40 Sales_data

struct Sale_data
{std::string bookNo;std::string bookName;unsigned units_sold = 0;double revenue = 0.0;double price = 0.0;//...
}

相关内容

热门资讯

linux入门---制作进度条 了解缓冲区 我们首先来看看下面的操作: 我们首先创建了一个文件并在这个文件里面添加了...
C++ 机房预约系统(六):学... 8、 学生模块 8.1 学生子菜单、登录和注销 实现步骤: 在Student.cpp的...
JAVA多线程知识整理 Java多线程基础 线程的创建和启动 继承Thread类来创建并启动 自定义Thread类的子类&#...
【洛谷 P1090】[NOIP... [NOIP2004 提高组] 合并果子 / [USACO06NOV] Fence Repair G ...
国民技术LPUART介绍 低功耗通用异步接收器(LPUART) 简介 低功耗通用异步收发器...
城乡供水一体化平台-助力乡村振... 城乡供水一体化管理系统建设方案 城乡供水一体化管理系统是运用云计算、大数据等信息化手段࿰...
程序的循环结构和random库...   第三个参数就是步长     引入文件时记得指明字符格式,否则读入不了 ...
中国版ChatGPT在哪些方面... 目录 一、中国巨大的市场需求 二、中国企业加速创新 三、中国的人工智能发展 四、企业愿景的推进 五、...
报名开启 | 共赴一场 Flu... 2023 年 1 月 25 日,Flutter Forward 大会在肯尼亚首都内罗毕...
汇编00-MASM 和 Vis... Qt源码解析 索引 汇编逆向--- MASM 和 Visual Studio入门 前提知识ÿ...
【简陋Web应用3】实现人脸比... 文章目录🍉 前情提要🌷 效果演示🥝 实现过程1. u...
前缀和与对数器与二分法 1. 前缀和 假设有一个数组,我们想大量频繁的去访问L到R这个区间的和,...
windows安装JDK步骤 一、 下载JDK安装包 下载地址:https://www.oracle.com/jav...
分治法实现合并排序(归并排序)... 🎊【数据结构与算法】专题正在持续更新中,各种数据结构的创建原理与运用✨...
在linux上安装配置node... 目录前言1,关于nodejs2,配置环境变量3,总结 前言...
Linux学习之端口、网络协议... 端口:设备与外界通讯交流的出口 网络协议:   网络协议是指计算机通信网...
Linux内核进程管理并发同步... 并发同步并发 是指在某一时间段内能够处理多个任务的能力,而 并行 是指同一时间能够处理...
opencv学习-HOG LO... 目录1. HOG(Histogram of Oriented Gradients,方向梯度直方图)1...
EEG微状态的功能意义 导读大脑的瞬时全局功能状态反映在其电场结构上。聚类分析方法一致地提取了四种头表面脑电场结构ÿ...
【Unity 手写PBR】Bu... 写在前面 前期积累: GAMES101作业7提高-实现微表面模型你需要了解的知识 【技...