数据程序是程序的基础:告诉我们数据的意义以及在数据上的操作。
1. 基本内置类型
1.1 算术类型
分类:
- 整型(包括字符型和布尔型)
- 浮点型
1.2 类型转换
bool b = 42;//b为真
int i = b;//i = 1
1.3 字面值常量(literal)
一望而知。每个字面值常量对应一种数据类型。字面值常量的形式和值决定了它的数据类型。
1.3.1 整型和浮点行字面值
整型字面值:
十进制 | 八进制 | 十六进制 |
---|---|---|
20 | 024 | 0x14 |
浮点型字面值:
3.121212 0e0 .001
1.3.2 转义序列
不可直接使用的两类字符:
- 不可打印的字符,如退格还有其他的控制字符
- 转义序列,以反斜杠开始,比如
换行符 | 横向制表符 |
---|---|
\n | \t |
1.3.3 指定字面值的类型
通过添加前缀, 后缀,可以改变整型,浮点型和字符型字面值的默认类型。
L’a’ //宽字符型字面值
u8"hi!" //utf-8字符串字面值
1E-3F //单精度浮点型字面值
34ULL //无符号整型字面值,unsigned long long
1.3.4 布尔字面值和指针字面值
- 布尔字面值: ture , false
- 指针字面值: nullptr;
2. 变量(variable)
变量提供了一个具体名字的、可供程序操作的存储空间。(还是可以把它看成盒子,往里面放东西)
每个变量都有其数据类型,数据类型决定了变量所占内存空间的大小和布局方式,还有该空间能存储的值的范围。
“变量”和“对象”可互换使用。
对象(object):
指:一块能存储数据并具有类型的内存空间,与变量的定义类似
2.1 变量的定义
基本形式: 类型说明符 + 一个或多个变量名
int sum = 0, value;
Sales_item item;//item的类型是Sales_item
2.1.1 初始值
初始化和赋值是两个不一样是操作:
初始化:创建变量时赋予其一个初始值
赋值:把对对象当前的值擦除,而已一个新值代替。
2.1.2 列表初始化
用花括号来初始化变量
int units_sold = { 0 };
如果使用列表初始化且初始值存在丢失信息的风险,编译器会报错
long double ld = 3.121231231;
int a{ld}, b = {ld};//错误 long double 值初始化Iint变量时可能丢失数据
int c(ld),d = ld;//正确
2.1.3 默认初始化
如果内置类型的变量没有被显示初始化,它的值由定义的位置决定。
- 定义于任何函数体之外的变量被初始化为0
- 定义于函数体内部的内置类型变量将不被初始化,其值是未定义的,如果拷贝或其他形式访问此值将会发生错误
- 每个类各自决定其初始化对象的方式。绝大数的类都支持无须显示初始化而定义对象,这样的类提供了一个合适的默认值。
2.2 变量声明和定义的关系
声明(declaration):使得名字为程序所知,一个文件如果想使用别处定义的名字则必须对那个名字进行声明。
变量声明规定了变量的类型和名字。
定义(definition):创建与名字相关联的实体。
定义需要申请存储空间。
想要声明一个变量而不需要定义它,则需要添加关键字extern
extern int i;//声明i 而非定义i
int j;//声明并且定义j
任何包含显示初始化的声明都为定义。
extern double pi = 3.1416;//是定义
Note : 变量能且只能定义一次,但可以被多次声明
2.3 标识符(identifier)
由字母、数字、下划线组成,必须以字面或者下划线开头
2.3.1 变量命名规范
- 要体现实际含义
- 变量名小写
- 用户自定义的类名一般以大写字母开头,如Sales_item
- 如果标识符由多个字母组成,单词间有明显区分,如 student_loan或studentLoan
2.4 名字的作用域
作用域(scope) 花括号里面的部分
3. 复合类型
复合类型(compound type): 指基于其他类型定义的类型。指针和引用
3.1 引用
引用(reference) 为对象起了另外一个名字,引用类型引用另一种类型。
int ival = 1023;
int &refVal = ival;//refVal指向ival,是ival 的另外一个名字
int &refVal2;//错误;引用必须初始化
3.1.1 引用即别名
引用并非对象,它只是为一个已经存在的对象的起的另外一个名字
3.1.2 引用的定义
引用的类型要与之绑定的对象严格匹配。
引用只能绑在对象上,不能与字面值或者表达式绑定在一起。
int &refVal = 10;//错误,引用类型的初始值必须是一个对象
double dval = 3.14;
int &*refVal = dval;//错误,此处引用类型的初始值必须是int类型的
3.2 指针
指针(pointer)是 “指向” (point to)另外一个类型的复合类型。
指针本身就是一个对象,允许对指针进行拷贝和赋值,而且在指针的周期内可以指向几个不同的对象。
指针无须在定义时赋初值。
3.2.1 获取对象的地址
指针用来存放某个对象的地址,要想获取该地址,需要使用取地址符(&)。
int ival = 42;
int *p = &ival;//p存放变量ival的地址,或者说p是指向变量ival的指针
指针的类型必须和它所指的对象严格配对:
double dval;
double *pd = &dval;//正确,初始值是指向doube型对象的地址
double *pd2 = pd;//正确,初始值是指向double 对象的指针
int *pi = pd; //错误,指针pi 的类型和pd的类型不匹配
pi = &dval;//错误,试图把double型对象的地址赋给int型指针
3.2.2 指针值
指针的值(即地址)应属于下列4钟状态之一
- 指向一个对象
- 指向紧邻对象所占空间的下一个位置
- 空指针,指针没有指向任何一个对象
- 无效指针
3.2.3 利用指针访问对象
如果指针指向了一个对象,则可以用解引用符来访问对象:
int ival = 63;
int *p = &ival;//p存放着ival的地址,p是指向变量ival的指针
cout << *p;//由 * 得到指针p 所指的对象,输出63
3.2.4 空指针
空指针不指向任何对象。
3.2.5 赋值和指针
引用本身并不是一个对象。一旦定义看引用就无法绑定另外的对象。
赋值改变的永远是等号左边的对象。
给指针赋值就是令它存放一个新的地址,从而指向一个新的对象
3.2.6 void* 指针
void*是一个特殊的指针类型,可用于存放任意对象的地址。
3.3 理解复合类型的声明
3.3.1指向指针的指针
** 表示指向指针的指针
int **ppi = π
3.3.2指向指针的引用
int i = 21;
int *p;
int *&r = p;//r是对指针 p 的引用
4 const 限定符
值不能改变的变量
const 对象必须初始化
`const int k;//错误,k未初始化
4.1 const 的引用
4.2 指针和const
4.3 顶层const
顶层const(top-level const) 表示指针本身是常量
底层const(low-level const)表示指针所指的对象是个常量
4.4 constexpr和常量表达式
5. 处理类型
5.1 类型别名
类型别名的定义:
- 传统方法,使用关键字typedef:
typedef double wages;
typedef wages base, *p;
wages hourly, monthly;//等价于 double hourly, monthly
- 别名声明:把等号左侧的名字规定成等号右边名字的别名
using SI = Sales_item;
SI item;//等价与 Sales_item item;