C++ Primer Plus 第6版 读书笔记(3) 第3章 处理数据

简介: C++是在 C 语言基础上开发的一种集面向对象编程、泛型编程和过程化编程于一体的编程语言,是C语言的超集。本书是根据2003年的ISO/ANSI C++标准编写的,通过大量短小精悍的程序详细而全面地阐述了 C++的基本概念和技术,并专辟一章介绍了C++11新增的功能。

C++是在 C 语言基础上开发的一种集面向对象编程、泛型编程和过程化编程于一体的编程语言,是C语言的超集。本书是根据2003年的ISO/ANSI C++标准编写的,通过大量短小精悍的程序详细而全面地阐述了 C++的基本概念和技术,并专辟一章介绍了C++11新增的功能。


《C++ Primer Plus(第6版)中文版》分18章,分别介绍了C++程序的运行方式、基本数据类型、复合数据类型、循环和关系表达式、分支语句和逻辑运算符、函数重载和函数模板、内存模型和名称空间、类的设计和使用、多态、虚函数、动态内存分配、继承、代码重用、友元、异常处理技术、string类和标准模板库、输入/输出、C++11新增功能等内容。


《C++ Primer Plus(第6版)中文版》针对C++初学者,从C语言基础知识开始介绍,然后在此基础上详细阐述C++新增的特性,因此不要求读者有C语言方面的背景知识。《C++ Primer Plus(第6版)中文版》可作为高等院校教授C++课程的教材,也可供初学者自学C++时使用。


本章内容包括:

C++变量的命名规则。

C++内置的整型——unsigned long、long、unsigned int、int、unsigned short、

short、char、unsigned char、signed char 和 bool。

C++11 新增的整型:unsigned long long 和 long long。 表示各种整型的系统限制的 climits 文件。

各种整型的数字字面值(常量)。

使用 const 限定符来创建符号常量。

C++内置的浮点类型:float、double 和 long double。

表示各种浮点类型的系统限制的 cfloat 文件。

各种浮点类型的数字字面值。

C++的算术运算符。

自动类型转换。

强制类型转换。


 

   面向对象编程(OOP)的本质是设计并扩展自己的数据类型。设计自己的数据类型就是让类型与数据 匹配。如果正确做到了这一点,将会发现以后使用数据时会容易得多。然而,在创建自己的类型之前,必须了解并理解 C++内置的类型,因为这些类型是创建自己类型的基本组件。

  内置的 C++类型分两组:基本类型和复合类型。本章将介绍基本类型,即整数和浮点数。似乎只有两种类型,但 C++知道,没有任何一种整型和浮点型能够满足所有的编程要求,因此对于这两种数据,它提供了多种变体。第 4 章将介绍在基本类型的基础上创建的复合类型,包括数组、字符串、指针和结构。

   当然,程序还需要一种标识存储的数据的方法,本章将介绍这样一种方法—使用变量;然后介绍如 何在 C++中进行算术运算;最后,介绍 C++如何将值从一种类型转换为另一种类型。


3.1 简单变量


程序必须记录 3 个基本属性:


信息将存储在哪里;

要存储什么值;

存储何种类型的信息

例如:


int braincount;

braincount 5;

 这些语句告诉程序,它正在存储整数,并使用名称 braincount 来表示该整数的值(这里为 5)。实际上, 程序将找到一块能够存储整数的内存,将该内存单元标记为 braincount,并将 5 复制到该内存单元中;然 后,您可在程序中使用 braincount 来访问该内存单元。这些语句没有告诉您,这个值将存储在内存的什位置,但程序确实记录了这种信息。实际上,可以使用&运算符来检索 braincount 的内存地址。下一章介绍另一种标识数据的方法(使用指针)时,将介绍这个运算符。


3.1.1 变量名


必须遵循几种简单的 C++命名规则

在名称中只能使用字母字符、数字和下划线(_)。

名称的第一个字符不能是数字。

区分大写字符与小写字符。

不能将 C++关键字用作名称。

    以两个下划线或下划线和大写字母打头的名称被保留给实现(编译器及其使用的资源)使用。以一个下划线开头的名称被保留给实现,用作全局标识符。

   C++对于名称的长度没有限制,名称中所有的字符都有意义,但有些平台有长度限制。

C++提供了一种灵活的标 准,它确保了最小长度(从 C 语言借鉴而来),如下所示:

short 至少 16 位;

int 至少与 short 一样长;

long 至少 32 位,且至少与 int 一样长;

long long 至少 64 位,且至少与 long 一样长


*位与字节


     计算机内存的基本单元是位(bit)。可以将位看作电子开关,可以开,也可以关。关表示值 0,开表示值 1。8 位的内存块可以设置出 256 种不同的组合,因为每一位都可以有两种设置,所以 8 位的总组合数为 2×2×2×2×2×2×2×2,即 256。因此,8 位单元可以表示 0-255 或者-128 到 127。每增加一位,组合数便加倍。这意味着可以把 16 位单元设置成 65 536 个不同的值,把 32 位单元设置成 4 294 672 296个不同的值,把 64 位单元设置为 18 446 744 073 709 551 616 个不同的值。作为比较,unsigned long 存储不了地球上当前的人数和银河系的星星数,而 long long 能够。

字节(byte)通常指的是 8 位的内存单元。从这个意义上说,字节指的就是描述计算机内存量的度量单位,1KB 等于 1024 字节,1MB 等于 1024KB。然而,C++对字节的定义与此不同。C++字节由至少能够容纳实现的基本字符集的相邻位组成,也就是说,可能取值的数目必须等于或超过字符数目。在美国,基本字符集通常是 ASCII 和 EBCDIC 字符集,它们都可以用 8 位来容纳,所以在使用这两种字符集的系统中,C++字节通常包含 8 位。然而,国际编程可能需要使用更大的字符集,如 Unicode,因此有些实现可能使用16 位甚至 32 位的字节。有些人使用术语八位组(octet)表示 8 位字节。


3.1.4 无符号类型


前面介绍的 4 种整型都有一种不能存储负数值的无符号变体,其优点是可以增大变量能够存储的最大 值。例如,如果 short 表示的范围为−32768 到+32767,则无符号版本的表示范围为 0-65535。当然,仅当数值不会为负时才应使用无符号类型,如人口、粒数等。要创建无符号版本的基本整型,只需使用关键字 unsigned 来修改声明即可

3.png




整型溢出:

4.png




该程序将一个 short 变量(sam)和一个 unsigned short 变量(sue)分别设置为最大的 short 值,在我们的系统上,是 32767。然后,将这些变量的值都加 1。这对于 sue 来说没有什么问题,因为新值仍比无符号整数的最大值小得多;但 sam 的值从 32767 变成了−32768!同样,对于 sam,将其设置为 0 并减去 1,也不会有问题;但对于无符号变量 sue,将其设置为 0 并减去后,它变成了 65535。可以看出,这些整型变量的行为就像里程表。如果超越了限制,其值将为范围另一端的取值(参见图 3.1)。C++确保了无符号类型的这种行为;但 C++并不保证符号整型超越限制(上溢和下溢)时不出错,而这正是当前实现中最为常见的行为。


3.1.7 C++如何确定常量的类型


  程序的声明将特定的整型变量的类型告诉了 C++编译器,但编译器是如何知道常量的类型呢?假设在程序中使用常量表示一个数字:程序将把 1492 存储为 int、long 还是其他整型呢?答案是,除非有理由存储为其他类型(如使用了特殊的后缀来表示特定的类型,或者值太大,不能存储为 int),否则 C++将整型常量存储为 int类型。

 首先来看看后缀。后缀是放在数字常量后面的字母,用于表示类型。整数后面的 l 或 L 后缀表示该整 数为 long 常量,u 或 U 后缀表示 unsigned int 常量,ul(可以采用任何一种顺序,大写小写均可)表示 unsigned long 常量(由于小写 l 看上去像 1,因此应使用大写 L 作后缀)。例如,在 int 为 16 位、long 为 32 位的系统上,数字 22022 被存储为 int,占 16 位,数字 22022L 被存储为 long,占 32 位。同样,22022LU 和 22022UL都被存储为 unsigned long。C++11 提供了用于表示类型 long long 的后缀 ll 和 LL,还提供了用于表示类型 unsigned long long 的后缀 ull、Ull、uLL 和 ULL。

   接下来考察长度。在 C++中,对十进制整数采用的规则,与十六进制和八进制稍微有些不同。对于不带后缀的十进制整数,将使用下面几种类型中能够存储该数的最小类型来表示:int、long 或 long long。

  在 int 为 16 位、long 为 32 位的计算机系统上,20000 被表示为 int 类型,40000 被表示为 long 类型,3000000000 被表示为 long long 类型。对于不带后缀的十六进制或八进制整数,将使用下面几种类型中能够存储该数的最小类型来表示:int、unsigned int long、unsigned long、long long 或 unsigned long long。在将 40000 表示为 long 的计算机系统中,十六进制数 0x9C40(40000)将被表示为 unsigned int。这是因为十六进制常用来表示内存地址,而内存地址是没有符号的,因此,usigned int 比 long 更适合用来表示 16 位的地址。

5.png


3.3.1 书写浮点数


C++有两种书写浮点数的方式。

第一种是使用常用的标准小数点表示法:

即使小数部分为 0(如 8.0),小数点也将确保该数字以浮点格式(而不是整数格式)表示。(C++标准允许实现表示不同的区域;例如,提供了使用欧洲方法的机制,即将逗号而不是句点用作小数点。然而,这些选项控制的是数字在输入和输出中的外观,而不是数字在代码中的外观。)

第二种表示浮点值的方法叫做 E 表示法,其外观是像这样的:3.45E6,这指的是 3.45 与 1000000 相乘的结果;E6 指的是 10 的 6 次方,即 1 后面 6 个 0。因此,3.45E6 表示的是 3450000,6 被称为指数,3.45 被称为尾数。下面是一些例子

6.png

    E 表示法确保数字以浮点格式存储,即使没有小数点。注意,既可以使用 E 也可以使用 e,指数可以是正数也可以是负数。(参见图 3.3。)然而,数字中不能有空格,因此 7.2 E6 是非法的。

指数为负数意味着除以 10 的乘方,而不是乘以 10 的乘方。因此,8.33E~4 表示 8.33/104 ,即 0.000833。 同样,电子质量 9.11e~31 kg表示 0.000000000000000000000000000000911 kg。可以按照自己喜欢的方式表示数字(911 在美国是报警电话,而电话信息通过电子传输,这是巧合还是科学阴谋呢?读者可以自己作出评判)。注意,−8.33E4 指的是−83300。前面的符号用于数值,而指数的符号用于缩放。

记住:d.dddE+n 指的是将小数点向右移 n 位,而 d.dddE~n 指的是将小数点向左移 n 位。之所以称为“浮点”,就是因为小数点可移动。

7.png


3.5 总结


   C++的基本类型分为两组:一组由存储为整数的值组成,另一组由存储为浮点格式的值组成。整型之间通过存储值时使用的内存量及有无符号来区分。整型从最小到最大依次是:bool、char、signed char、unsigned char、short、unsigned short、int、unsigned int、long、unsigned long 以及 C++11 新增的 long long和 unsigned long long。还有一种 wchar_t 类型,它在这个序列中的位置取决于实现。C++11 新增了类型 char16_t 和 char32_t,它们的宽度足以分别存储 16 和 32 位的字符编码。C++确保了 char 足够大,能够存储系统基本字符集中的任何成员,而 wchar_t 则可以存储系统扩展字符集中的任意成员,short 至少为 16位,而 int 至少与 short 一样长,long 至少为 32 位,且至少和 int 一样长。确切的长度取决于实现。字符通过其数值编码来表示。I/O 系统决定了编码是被解释为字符还是数字。浮点类型可以表示小数值以及比整型能够表示的值大得多的值。3 种浮点类型分别是 float、double 和long double。C++确保 float 不比 double 长,而 double 不比 long double 长。通常,float 使用 32 位内存,double 使用 64 位,long double 使用 80 到 128 位。通过提供各种长度不同、有符号或无符号的类型,C++使程序员能够根据特定的数据要求选择合适的 类型。

C++使用运算符来提供对数字类型的算术运算:加、减、乘、除和求模。当两个运算符对同一个操作数进行操作时,C++的优先级和结合性规则可以确定先执行哪种操作。 对变量赋值、在运算中使用不同类型、使用强制类型转换时,C++将把值从一种类型转换为另一种类型。很多类型转换都是“安全的”,即可以在不损失和改变数据的情况下完成转换。例如,可以把 int 值转换为 long 值,而不会出现任何问题。对于其他一些转换,如将浮点类型转换为整型,则需要更加小心。开始,读者可能觉得大量的 C++基本类型有些多余,尤其是考虑到各种转换规则时。但是很可能最终将发现,某些时候,只有一种类型是需要的,此时您将感谢 C++提供了这种类型。


3.6 复习题


1.为什么 C++有多种整型?

2.声明与下述描述相符的变量。

a.short 整数,值为 80

b.unsigned int 整数,值为 42110

c.值为 3000000000 的整数

3.C++提供了什么措施来防止超出整型的范围?

4.33L 与 33 之间有什么区别?

5.下面两条 C++语句是否等价?

6.如何使用 C++来找出编码 88 表示的字符?指出至少两种方法。

7.将 long 值赋给 float 变量会导致舍入误差,将 long 值赋给 double 变量呢?将 long long 值赋给 double 变量呢?

8.下列 C++表达式的结果分别是多少?

9.假设 x1 和 x2 是两个 double 变量,您要将它们作为整数相加,再将结果赋给一个整型变量。请编写一条完成这项任务的 C++语句。如果要将它们作为 double 值相加并转换为 int 呢?

10.下面每条语句声明的变量都是什么类型?

8.png9.png10.png




3.7 编程练习


1.编写一个小程序,要求用户使用一个整数指出自己的身高(单位为英寸),然后将身高转换为英尺和英寸。该程序使用下划线字符来指示输入位置。另外,使用一个 const 符号常量来表示转换因子。

2.编写一个小程序,要求以几英尺几英寸的方式输入其身高,并以磅为单位输入其体重。(使用 3 个变量来存储这些信息。)该程序报告其 BMI(Body Mass Index,体重指数)。为了计算 BMI,该程序以英寸 的方式指出用户的身高(1 英尺为 12 英寸),并将以英寸为单位的身高转换为以米为单位的身高(1 英寸 =0.0254 米)。然后,将以磅为单位的体重转换为以千克为单位的体重(1 千克=2.2 磅)。最后,计算相应的BMI—体重(千克)除以身高(米)的平方。用符号常量表示各种转换因子。

3.编写一个程序,要求用户以度、分、秒的方式输入一个纬度,然后以度为单位显示该纬度。1 度为 60 分,1 分等于 60 秒,请以符号常量的方式表示这些值。对于每个输入值,应使用一个独立的变量存储它。

下面是该程序运行时的情况:

4.编写一个程序,要求用户以整数方式输入秒数(使用 long 或 long long 变量存储),然后以天、小时、分钟和秒的方式显示这段时间。使用符号常量来表示每天有多少小时、每小时有多少分钟以及每分钟 有多少秒。该程序的输出应与下面类似:

5.编写一个程序,要求用户输入全球当前的人口和美国当前的人口(或其他国家的人口)。将这些信息存储在 long long 变量中,并让程序显示美国(或其他国家)的人口占全球人口的百分比。该程序的输出应与下面类似:

6.编写一个程序,要求用户输入驱车里程(英里)和使用汽油量(加仑),然后指出汽车耗油量为一 加仑的里程。如果愿意,也可以让程序要求用户以公里为单位输入距离,并以升为单位输入汽油量,然后 指出欧洲风格的结果—即每 100 公里的耗油量(升)。

7.编写一个程序,要求用户按欧洲风格输入汽车的耗油量(每 100 公里消耗的汽油量(升)),然后将其转换为美国风格的耗油量—每加仑多少英里。注意,除了使用不同的单位计量外,美国方法(距离/燃料)与欧洲方法(燃料/距离)相反。100 公里等于 62.14 英里,1 加仑等于 3.875 升。因此,19mpg 大约 合 12.4l/100km,l27mpg 大约合 8.71/100km。

目录
相关文章
|
3月前
|
存储 C++
【C++】C++ 基于QT实现散列表学生管理系统(源码+数据+课程论文)【独一无二】
【C++】C++ 基于QT实现散列表学生管理系统(源码+数据+课程论文)【独一无二】
【C++】C++ 基于QT实现散列表学生管理系统(源码+数据+课程论文)【独一无二】
|
3月前
|
存储 算法 C++
C++ STL应用宝典:高效处理数据的艺术与实战技巧大揭秘!
【8月更文挑战第22天】C++ STL(标准模板库)是一组高效的数据结构与算法集合,极大提升编程效率与代码可读性。它包括容器、迭代器、算法等组件。例如,统计文本中单词频率可用`std::map`和`std::ifstream`实现;对数据排序及找极值则可通过`std::vector`结合`std::sort`、`std::min/max_element`完成;而快速查找字符串则适合使用`std::set`配合其内置的`find`方法。这些示例展示了STL的强大功能,有助于编写简洁高效的代码。
45 2
|
3月前
|
编译器 C++
virtual类的使用方法问题之C++类中的非静态数据成员是进行内存对齐的如何解决
virtual类的使用方法问题之C++类中的非静态数据成员是进行内存对齐的如何解决
|
3月前
|
存储 数据挖掘 C语言
【C/C++】C/C++车辆交通违章管理系统(源码+数据文件)【独一无二】
【C/C++】C/C++车辆交通违章管理系统(源码+数据文件)【独一无二】
|
3月前
|
存储 安全 数据处理
【C++】C++ 超市会员卡管理系统(面向对象)(源码+数据)【独一无二】
【C++】C++ 超市会员卡管理系统(面向对象)(源码+数据)【独一无二】
|
4月前
|
存储 C++ 容器
开发与运维数组问题之C++标准库中提供数据容器作为数组的替代如何解决
开发与运维数组问题之C++标准库中提供数据容器作为数组的替代如何解决
53 5
|
4月前
|
设计模式 监控 Go
开发与运维C++问题之C++部分原有的数据发送能力如何解决
开发与运维C++问题之C++部分原有的数据发送能力如何解决
26 1
|
4月前
|
存储 数据格式 运维
开发与运维C++问题之更改数据模型为通用数据结构如何解决
开发与运维C++问题之更改数据模型为通用数据结构如何解决
27 1
|
3月前
|
存储 算法 C++
【C/C++】C/C++ KTV点歌系统设计与实现(源码+数据+报告)【独一无二】
【C/C++】C/C++ KTV点歌系统设计与实现(源码+数据+报告)【独一无二】
|
4月前
|
安全 算法 编译器
C++一分钟之-内存模型与数据竞争
【7月更文挑战第10天】了解C++11内存模型对多线程编程至关重要。它定义了线程间同步规则,包括顺序一致性、原子操作和内存屏障。数据竞争可能导致不确定行为,如脏读和丢失更新。可通过互斥量、原子操作和无锁编程避免竞争。示例展示了`std::mutex`和`std::atomic`的使用。掌握内存模型规则,有效防止数据竞争,确保多线程安全和性能。
57 0