C++单元学习小结之指针(续),存储空间的分配策略,new和delete运算符,const限定词 结构体(续),枚举
C++单元学习小结
指针(续):
内存地址(可进行查找内存地址进行间接访问):
程序运行时,代码和需要的数据都被存储在内存中
内存是有序的字节序列,每个字节都有唯一的地址,使用该地址可以确定字节的位置,用以存储和获取数据
直接访问(查找变量名)和间接访问(查找变量所在地址):
通过变量的名字直接访问为程序中定义的变量分配的内存单元,存取变量的值
使用变量的内存地址找到存放数据的单元,间接访问其中的内容
指针存放指定类型对象的地址,要获取对象的地址,使用取地址运算符“&”
双重指针:
例:
int ival = 1024;
int *pi = &ival;
int **ppi = π //ppi是指针的指针,存放pi的地址
这就代表指针与两个储存单元有关,一个是自己的储存单元,另一个是所指对象的储存单元
指针不能保存非地址值,也不能被赋值或初始化为不同类型的地址值(参考解指针*)
空指针:
指针值为0时是一个空指针,即不指向任何对象的指针。
表示空指针的3种方法:
0
nullptr(C++11)
预处理常量NULL(包含在头文件中)
例:
int *p1 = nullptr;
int *p2 = 0;
int *p3 = NULL; (一定要加头文件<cstdlib>)
// 生成空指针的3种方法
//不能写成下面的样子:
int zero = 0;
int p4 = zero;
//这只是表示p4指向变量值为0的地址,并不能代表这是空指针(空指针与所指对象值为0是两个不同概念,空指针不指向任何对象)
指针的运算(仅适用于同种类型指针之间,不能用于指针与其他非该类型的指针,更不能用于与其他类型的数据进行运算):
同类型的指针可以进行相等(==)或不相等(!=)的比较操作,比较的结果是布尔类型
指针可以进行加或减整数值的算术运算(两指针相加结果仍是一个指针,两指针相减是一个整型常量)
自增、自减运算适用于指向数组元素的指针
通用指针void*:
可以持有任何类型的地址值,即通用指针
相关的值是个地址,但是该地址保存的对象类型不知道
不能操纵void指针指向的对象,只能传送该地址值或者和其他地址值进行比较
不允许void指针到其他类型指针的直接赋值
存储空间的分配策略:
存储空间可以分为静态存储和动态存储:
静态(编译时)分配空间:
编译器在处理程序源代码时分配内存;
效率高,灵活性差,运行前就要知道程序需要的内存大小和类型。
动态(运行时)分配空间:
程序运行时调用运行时刻库函数来分配内存;
占用程序运行时间,更灵活。
静态和动态内存分配在语法上的主要区别:
静态对象是有名字的变量,可以直接对其进行操作;动态对象没有名字,要通过指针间接地对它进行操作。
静态对象的空间分配与释放由编译器自动处理,动态对象的空间分配与释放必须由程序员显式地管理。
程序使用动态内存的原因:
程序不知道自己需要使用多少对象
程序不知道所需对象的准确类型
程序需要在多个对象间共享数据
动态内存管理方法:
C++通过new和delete运算符进行动态存储空间的管理
new和delete运算符:
现在在这里添加图片笔记进行介绍(笔记字体有些难看。 。 。):
const限定词
结构体(续)
结构体的成员不能单独使用,必须由结构体类型的变量通过成员选择符“.”来选择,或由结构体类型的指针通过“->”运算符选择。
结构体变量的成员在内存中按声明的顺序依次存放。
理论上,结构体变量在内存中的大小是其所有成员的大小之和。
实际上,编译器为了提高访问效率,大都使用了边界对齐技术,也称为补白。
枚举:
枚举类型定义了一组命名的整数常量,以提高代码的可读性。
定义格式可参考如下类型:
enum TrafficLight { red, green, yellow };
enum 表示为枚举定义符,TrafficLight是一个枚举类型,可以用来定义枚举变量,变量的值只能是枚举成员。
TrafficLight stop = red;
同时可以指定枚举成员的值。
编译器会给未指定值的枚举成员赋予相邻的值下一整数值。
例:
enum ShapeType
{circle=10, square=20, rectangle};
//rectangle成员的值是21
当所有成员都未赋值时,系统默认该值从零开始记起。
例:
enum {False, True};
//定义了两个常量False和True,值分别是0和1
枚举类型在使用时有以下几点:
枚举类型在必要时,如参与算术运算时,会被自动提升为算术类型。
能表示枚举成员值的范围。
枚举的成员名字是不可打印的,输出的是它所表示的整数值。
不能使用枚举成员进行迭代。
C++不支持枚举成员之间的前后移动(递增或递减)。