Chapter3 处理数据

Chapter3 处理数据

面向对象编程(object oriented programming, OOP)的本质是设计并扩展自己的数据类型,设计自己的数据类型就是让类型与数据匹配。

3.1 简单变量

为把信息存储在计算机中,程序必须记录三个基本属性:

  • 信息将存储在哪里;
  • 要存储什么值;
  • 存储何种类型的信息;

3.1.1 变量名

C++命名规则:

  • 在名称中只能使用字母字符、数字和下划线。
  • 名称的第一个字符不能是数字。
  • 区分大写字符和小写字符。
  • 不能将C++关键字用作名称。
  • 以两个下划线或下划线和大写字母打头的名称都被保留给实现(编译器及其使用的资源)使用。以一个下划线开头的名称被保留给实现,用作全局标识符。
  • C++对名称的长度没有限制,名称中所有的字符都有意义(某些平台可能会有长度限制)

3.1.2 整型

如果将无限大的整数看作很大,则不可能用有限的计算机内存来表示所有的整数,因此,语言只能表示所有整数的一个子集。不同C++整型使用不同的内存量来存储整数,使用的内存量越大,可以表示的整数值范围也越大。术语宽度(width)用于描述存储整数时使用的内存量,使用的内存越多,则越宽。

3.1.3 整型short、int、long和long long

C++的short、int、long和long long类型通过使用不同数目的位来存储值,最多能表示4种不同的整数宽度。C++提供了一种灵活的标准,它确保了最小长度:

  • short至少16位;
  • int至少与short一样长;
  • long至少32位,且至少与int一样长;
  • long long 至少64位,且至少与long一样长

对类型名使用sizeof运算符时,应该将名称放在括号中,但对变量名使用该运算符时,括号时可选的。

头文件climits(老式实现中位limits.h)中包含了关于整型限制的信息。具体来说,它定义了表示各种限制的符号名称。

3.2 const限定符

创建常量的通用格式如下:const type name = value;应在声明中对常量进行初始化,如果在声明常量时没有提供值,则该常量的值将是不确定的,且无法修改。

3.3 浮点数

使用浮点类型可以表示带小数部分的数字。计算机将这样的值分成两部分存储,一部分表示值(基准值),另一部分用于对值进行放大或缩小(缩放因子)。(d.dddE+n指的是将小数点向右移动n位,而d.dddE-n指的是将小数点向左移动n位,之所以称为“浮点数”,就是因为小数点可移动)

image-20201011101439767

与整数相比,浮点数有两大优点。首先,它们可以表示整数之间的值,其次,由于有缩放因子,它们可以表示的范围大得多。另一方面,浮点运算的速度通常比整数运算慢,且精度将降低。

3.4 C++算数运算符

运算符 操作
+ 对操作数执行加法运算
- 从第一个数中减去第二个数
* 将操作数相乘
/ 用第一个数除以第二个数,如果两个操作数都是整数,则结果位商的整数部分,小数部分被舍弃
% 生成第一个数除以第二个数后的余数(两个操作数必须都是整型,该运算符用于浮点数将导致编译错误,如果其中一个是负数,则结果的符号满足如下规则:$(a/b)*b+a%b=a$)

算数运算符遵循通常的代数优先级,先乘除,后加减。当两个运算符的优先级相同时,C++将看操作数的结合性(associativity)是从做到右,还是从右到左。

除法运算符的行为取决于操作数的类型。如果两个操作数都是整数,则C++将执行整数除法,这意味着结果的小数部分将被丢弃,使得最后的结果是一个整数。如果其中有一个(或两个)操作数是浮点值,则保留结果的小数部分。

image-20201011103356575

C++允许将一种类型的值赋给另一种类型的变量,这样做时,值将被转换为接收变量的类型。将一个值赋给取值范围更大的类型通常不会导致什么问题,然而进行窄转换可能会出现一些问题。

潜在的数值转换问题
转换 潜在问题
将较大的浮点类型转换为较小的浮点类型 精度(有效数位)降低,原来的值可能超出目标类型的取值范围,在这种情况下,结果将是不确定的
将浮点类型转换位整型 小数部分丢失,原来的值可能超出目标类型的取值范围,在这种情况下,结果将是不确定的
将较大的整数转换为较小的整数 原来的值可能超出目标类型的取值范围,通常只复制右边的字节
**列表初始化**:C++将使用大括号的初始化称为列表初始化(List-initialization),因为这种初始化常用于给复杂的数据类型提供值列表。列表初始化不允许缩窄(narrowing),及变量的类型可能无法表示赋给它的值。

C++允许通过强制类型转换显式地进行类型转换,强制类型转换不会修改变量本身,而是创建一个新的、指定类型的值,可以在表达式中使用这个值。

C++11新增了一个工具,让编译器能够根据初始值的类型推断变量的类型,为此重新定义了auto的含义,在初始化声明中,如果使用关键字auto,而不指定变量的类型,编译器将把变量的类型设置成与初始值相同。