第9章 指针和内存分配
9.1 Variable addresses(变量的地址)
在C++程序中使用的每个变量和对象,都存储在内存中特定的存储单元中。
不同的计算机和操作系统为变量分配的内存地址是不同的。
每个存储单元都有唯 一的地址 使用取地址运算符&获取变量的地址,地址都用16 进制数表示。
9.2 Pointer variables(指针变量)
指针变量是存放另一变量地址的变量。
其中 type 代表数据类型 (例如 char, int, float, double和so on)
variable_name代表有效的变量名。 空格中的指针定义是不相关的。
可以从变量名开始按照从后向前的顺序来读指针定义,并将* 读成“是一个指针”。 i
nt*int_ptr读做“int_ptr是一个指向整型变量的指针”
float* float_ptr读做“float_ptr 是一个指向浮点型变量的指针”
两个变量PTR1及PTR2用于存储其他两个变量var1和var2的地址。
9.3 The dereference operator * (解引用运算符*)
解引用运算符“*”用于访问指针变量所指向的存储单元的内容。
*ptr 为指针变量ptr 所指向的存储单元中的内容。
第9行的* 用来定义一个指向整型变量的指针ptr。
第13行的*用来访问指针变量ptr 所指向的存储单元中的内容。
第13行利用解引用运算符*显示指针变量ptr 所指向的存储单元中的内容,称为指针变量ptr的解引用。
*ptr 与var 的值是相同的。
9.4 Using const with pointers(使用const 修饰指针变量)
定义指针变量时,指针变量本身、指针变量所指向的数据都可以声明为常量。
究竟是谁被声明为常量,由变量定义中的const的位置来决定。
9.5 Pointers and one-dimensional arrays (指针和一维数组)
数组名代表数组的首地址。
这个数组的元素是: a[0], a[1], a[2], a[3], a[4]
a为数组名,也是数组的首地址,a 等价于&a[0] →可以使用解引用运算符*来访问数组元素的值。
a + 1 代表数组的第二个元素地址 a + 2 代表数组的第三个元素地址 ….
虽然数组名是指向数组第一个元素的指针,但是由于它是一个常量指针,因此它的值是不能改变的。
可以int* p = a;通过改变p来改变数组中的元素
通过将指针变量加上或减去一个常量,可以使它指向不同的存储单元。 并非所有的算术运算符都可以应用于指针。 两个指针相乘是非法的,因为相乘的结果可能不是一个有效的内存地址。
9.6 Pointers and multi-dimensional arrays (指针和多维数组)
9.7 Pointers to structures(指向结构体的指针)
9.8 Pointers to class objects (指向类对象的指针)
可以用指向运算符->来代替成员选择运算符,适用于访问类对象的公有成员
9.9 Pointers as function arguments(指针变量作为函数实参)
使用引用变量比使用指针变量更简单
必须使用取地址运算符“&”将变量的地址传递给函数
在函数体内部,必须使用解引用运算符“*”来访问每个数据值 很多库函数都是用指针变量作为形参。
库函数 ctime(), 将系统秒级的时间转换成包括日期和时间在内的字符串。
9.10 Dynamic memory allocation(动态内存分配)
为解决定义数组时必须在程序执行前指定数组元素的个数的问题
C++ 允许在程序执行过程中动态地分配内存:通过使用内存分配运算符new 来实现
9.10.1 Allocating memory dynamically for an array
动态内存分配运算符new 可以为任何类型的数组分配一个连续的存储空间,
无论该数组类型是内置数据类型还是用户自定义的结构体或类。
pointer 是指向分配的内存 data_type 是数组的数据类型 size 是数组中元素的个数
当为一个类对象数组动态分配内存时,这个类必须有自己的默认构造函数来初始化类对象数组的元素。
第15行使用new 来分配所需元素的确切数字,可以使用指针或下标方式访问新分配内存的数组元素。
可以使用delete 运算符释放已分配的内存。
当为一个数组释放先前动态分配的内存时,必须用方括号[ ]。
如果不加方括号,那么释放的仅是数组的第一个元素的内存。
9.10.2 Initialization with new
当为一个类对象的数组动态分配内存时,会自动调用类的默认构造函数对数组元素进行初始化。
为内置数据类型的数组动态分配内存时无需对其初始化。
易错警示
1.定义两个或两个以上的指针变量时,每个指针变量前都要加*,如int *p1,*p2;
2.与其他变量相同,指针变量不能自动初始化。在使用指针变量前,必须先对其赋初值。
3.new 运算符使用( )是初始化一个数据类型的单个实例,使用[ ]则是为数组分配动态内存。
4.如果一个对象是使用不带[ ]的new运算符创建的,那么必须使用delete释放为其分配的内存。
如果一个对象是使用new[ ]创建的,那么必须使用delete[ ]释放为其分配的内存。
5.不要使用一个已用delete 释放了内存块的指针变量。
6.对于一块已被动态分配的内存,如果不再有指针变量指向它,那么将发生内存泄露。