第三章 处理数据
面向对象编程的本质是设计并扩展自己的数据类型。设计自己的数据类型就是让类型与数据匹配。
C++也有自己的内置类型:基本类型 和 复合类型
3.1 简单变量
1)变量名及基本类型
必须遵守的几种简单的C++命名规则:
- 在名称中只能使用字母字符、数字和下划线
- 名称的第一个字符不能是数字
- 大小写敏感
- 不能将C++关键字用作名称
- 以两个下划线或下划线和大写字母开头的名称被保留给实现使用。以一个下划线开头的名称被保留给实现,用作全局标识符。
- C++对于名称的长度没有限制,名称中所有的字符都有意义。
很多程序员可能会在变量名中加入其他信息,即描述变量类型或内容的前缀。eg,可以将整形变量myWeight命名为nMyWeight,其中n用来表示整数值,也可叫做inMyWeight,这样更精确。常以这种方法使用的其他前缀有:str或sz、b、p和c
- 整形
不同C++整形使用不同的内存量来存储整数。使用的内存量越大,可以表示的整数值范围也就越大
C++的基本整形(按宽度递增的顺序排列):char 、short、int 、long;
其中每种版本都有符号版和无符号版
- short、int和long
C++提供了一种灵活的标准,它确保了最小长度,如下:
- short至少16位
- int至少与short一样长
- long至少32位,且至少与int一样长
位与字节
计算机内存的基本单元是位(bit)。
字节(byte)通常是指8位的内存单元。
- 使用C++工具检查类型的长度
#include<iostream>
#include<climits>
int main(){
using namespace std;
int n_int = INT_MAX;
short n_short = SHRT_MAX;
long n_long = LONG_MAX;
cout << "int is " << sizeof(int) << " bytes." << endl;
cout << "short is " << sizeof(short) << " bytes." << endl;
cout << "long is " << sizeof(long) << " bytes." << endl;
cout << "Maximum values:" << endl;
cout << "int:" << n_int << endl;
cout << "short:" << n_short << endl;
cout << "long:" << n_long << endl;
cout << "Minimum int value = " << INT_MIN << endl;
cout << "Bits per Byte = " << CHAR_BIT << endl;
return 0;
}
//不同平台的数据数据可能不同
以上程序的主要编程特性:
- 操作符sizeof 指出在8位字节的操作系统中,int的长度为4个字节
- 头文件climits定义了符号常量,如INT_MAX等
符号常量——预处理器方式
#define INT_MAX 32767
在C++编译过程中,首先将源代码传递给预处理器。在这里#define
和#include
一样,也是一个预处理编译指令。该编译指令告诉预处理器:在程序中查找INT_MAX
,并将所有的INT_MAX
都替换为32767。修改后的程序将在完成这些替换后被编译。
#define
是C遗留下来的指令,C++本身有一种更好的创建符号常量的方式,使用关键字const
但是,在有些头文件,尤其是那些被设计成可用于C和C++中的头文件,必须使用#define
- 初始化 初始化将赋值与声明合并在一起 ,如:
int n_int = INT_MAX
⚠️注意:如果不对函数内部定义的变量进行初始化,该变量的值将是不确定的。这意味着该变量的值将是它被创建之前,该内存单元保存的值。因此,在声明的变量的同时初始化,可避免忘记给他赋值。
- 无符号类型
仅当数值不会为负时,才使用无符号类型,只需要在对应类型前加上关键字unsigned
超越long
C99添加了两种新的类型,long long和unsigned long long
,两种类型都至少是64位,且至少同long和unsigned long一样宽
- 选择整数类型
- int被设置为对目标计算机而言最为自然的长度,即指计算机处理起来效率最高的长度
- 如果变量值不可能为负,则使用无符号类型
- 如果知道变量可能表示的整数值大于16位整数的最大可能值,则使用long,即使系统上int为32位,也应该这么做。因为,当程序移植到16位的系统中时,程序就不会突然无法正常工作。
- 仅当有大型整型数组时,才有必要使用short
- 如果只需要一个字节,可使用char
- C++如何确定常量的类型
cout << "Year = " << 2023 << endl;
/*
除非有理由存储位其他类型(如使用了特殊的后缀来表示特定的类型,或者值太大,不能存储为int)
否则,C++将整形常量存储为int类型
*/
- 成员函数
cout.put()
char c = 'M';
cout << c; //打印ASCII码
cout.put(c);//打印字符
Unicode 和 ISO 10646
ASCII是Unicode的子集
- wchar_t
当程序需要处理的字符集可能无法用一个8位的字节表示时,有两种处理方式:
如果大型字符集是实现的基本字符集,则编译器厂商可以将char定义为一个16位的字节或更长的字节
实现一种可以同时支持小型基本字符集和较大的扩展字符集。8位char可以表示基本字符集,另一种wchar_t可以表示扩展字符集
cin和cout将输入输出看作char流,因此不使用处理wchar_t类型。但iostream头文件的最新版本提供了作用相似的工具——wcin和wcout
-
bool类型
3.2 const限定符
常量被初始化后,编译器将不允许再次修改该常量的值;
通用做法是将常量全部大写
3.3 浮点数
1)浮点类型
C++有三种浮点类型:float、double和long double;以它们可表示的有效数位和允许的指数最小范围来描述。
有效位:是指数字中有意义的位
C++ 对于有效位数的要求是:float至少32位、double至少48位且不少于float、long double至少和double一样多
通常,float为32位,double为64位,long double为80、96或128位
另外,这三种类型的指数范围至少是-37到37
- cout.setf()
cout.setf(ios_base::fixed,ios_base::floatfield);
// 使程序显示到小数点后6位小数
// 一般的cout会删除结尾的0
//标准C++在默认情况下总共显示6位
- 浮点常量
可以使用后缀表明类型,float则为f或F后缀;long double则为l或L后缀
2)浮点数的优缺点
优点:
- 可以表示整数之间的值
- 由于有缩放因子,可表示的范围大得多
缺点:
浮点运算速度比整数慢得多且精度降低
3.4 C++操作运算符
- / %
操作符优先级:遵循先乘除后加减
除法分支:取决于操作数的类型,若其中有一个操作数为浮点值,则结果为浮点数
3.5 类型转换
1)表达式中的转换
- 自动转换 或整形提升
short chickens = 20;
short ducks = 35;
short fowl = chickens + ducks;
//为执行第3行语句,C++取得chickens与ducks的值,并将他们转换为int。然后,程序将结果转为short类型
同样,wchar_t被提升为下列类型中第一个宽度足够存储wchar_t取值范围的类型:int、unsigned int、long或unsigned long
- 较小类型转换为较大的类型
2)强制类型转换
显示的进行类型转换
(long) thorn;
long (thorn);
//强制类型转换不会修改thorn变量本身的值,而是创建一个新的、指定类型的值,可以在表达式中使用这个值
C++ 中引入了4个强制类型转换操作符:
- static_cast(thorn)
- reinterpret_cast
- const_cast
- dynamic_cast