4.8.1 指针算数
-
指针算数
a. 正数变量加1,其值增加1
b. 指针变量加1,增加的量等于它指向的类型的字节数,如:
i. 指向double的指针加1,数值增加8(若系统对double使用8字节存储)
ii. 指向short的指针加1,指针值将加2(若系统对double使用2字节存储) -
数组表达式
arrayname[i]
等价于*(arrayname + i)
-
可以修改指针的值,但数组名是常量,不可以修改
pointername = pointername + 1; //valid arrayname = arrayname + 1; // not allowed
-
sizeof运算符
a. 数组:对数组应用sizeof运算符得到的是数组的长度
b. 指针:对指针应用sizeof运算符得到的是指针的长度,即使指针指向的是一个数组 -
数组的地址
short tell[10]; cout << tell << endl; //数组第一个元素的地址,两字节内存块的地址 cout << &tell << endl; //整个数组的地址,20字节内存块的存储 //tell+1 将地址值加2 //&tell+1 将地址值加20
4.8.2 指针小结
-
声明指针:
typeName * pointerName
-
指针赋值:
a. &运算符,获得被命名内存的地址
b. new运算符,返回未命名的内存地址double * pn; double * pa; double bubble = 3.2; pn = &bubble; pa = new double[30];
-
*运算符对指针解除引用,获得指针指向的值
决不要对未初始化为适当地址的指针解除引用
-
数组名
在多数情况下,将数组名视为数组的第一个元素的地址
ps:sizeof运算符用于数组名时,将返回整个数组的长度 -
指针算数
-
数组的静态联编和动态联编
a. 静态:使用数组声明来创建数组
b. 动态:new运算符(注意delete[])
4.8.3 指针和字符串
- 在cout和多数c++表达式中,char数组名,char指针以及用引号括起来的字符串常量都被解释为字符串第一个字符的地址
- 应使用strcpy()或strncpy(),而不是赋值运算符来将字符串赋给数组
- 使用c++ string类型更为简单:不用担心字符串会导致数组越界,也可以使用赋值运算符
4.8.4 new创建动态结构
- 使用new运算符动态创建结构,在程序运行时为结构分配所需的内存;
- new创建结构由两步组成:创建结构+访问其成员,如:
a.inflatable * ps = new inflatable;
b. 访问成员:箭头成员运算符(->)或(*指向结构的指针).成员
4.8.5 自动存储、静态存储和动态存储
-
自动存储
a. 函数内部定义的常规变量使用自动存储空间,称为自动变量。(函数调用时自动产生,函数结束时消亡)。
b. 自动变量存储在栈中(后进先出) -
静态存储
a. 整个程序执行期间都存在的存储方式
b. 使变量称为静态的两种方式:
i. 在函数外定义
ii. 使用关键字static -
动态存储
a. new和delete运算符管理了一个内存池,被称为自由存储空间或堆;
b. 数据的声明周期不完全受程序或函数的生存时间控制;
c. 在栈中自动添加和删除机制使占用的内存总是连续的,但new和delete可能导致占用的自由存储空间不连续 -
内存泄漏
如果new之后没有delete,即使包含指针的内存由于作用域规则和生命周期的云隐被释放,在自由存储空间上动态分配的变量或结构体也将继续存在。这会无法访问自由存储空间的结构,导致内存泄漏。