C++数组和指针实用经验

本文深入探讨了C++中指针与数组的概念及其差异,解析了指针的定义与初始化、数组与指针之间的等价性和差异性、数组指针与指针数组的区别等内容,并提供了预防野指针和合理使用空指针的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

文章内容均抄自    刘光《C++程序员不可不知的101条实用经验

1.理解指针的本质
数组和指针的区别在于数组的长度是固定的,只能存取某一种元素,一旦创建就不允许添加其他的元素。而指针可以像索引一样指向数组的每个元素。
C++规定:存放地址的变量称为指针变量,变量的地址称为变量的指针。在32位系统中指针的宽度为32位(即4个字节)。
小心陷阱:
(1)一个指针变量定义了就要确保初始化,以防指针悬空或变成野指针
(2)如果一个指针变量被delete后,确保其被赋值为NULL,防止指针变量变为野指针
(3)如果一个函数的形参可以接受所有类型的指针,将此形参类型声明为void*型,如memcpy函数
(4)禁止使用void*指针操纵其所指向的对象,因为void*操作对象时无法确定对象的类型
(5)指针不运算“指针 + 指针”的算术操作,不能对void*进行算术操作,因为无法指定到底移动几个字节

2.论数组和指针的等价性
什么时候指针和数组等价:
①表达式中数组名被编译器当做一个指向该数组首元素的指针
②下标总是与指针的偏移量相同
③在函数形式参数声明中,数组名被编译器当做指向数组首元素的指针
请谨记:
(1)作为函数形参时,指针和数组等价,数组会退化为一个指向数组首元素的指针
(2)数组名被编译器当做一个指向该数组首元素的指针,而且是const指针
(3)无论采用a[i]或*(a+i)的形式访问,编译器在编译时均会改写成*(a+i)指针形式访问

3.再论数组和指针的差异性
指针和数组的差异包括两个方面,第一个是两者含义上的区别,第二个是计算容量的差别
(1)数组对应着一块内存区域,而指针是指向一块内存区域,其地址和容量在生命期里不会改变,只有数组的内容可以改变。而指针指向的区域大小可以随时改变,而且指针指向常量时它的内容是不可以改变的。
(2)使用sizeof而已计算数组的字节数,但不能计算出指针所指内存的字节数,对指针做sizeof运算的结果始终是4
请谨记:
(1)数组标识一块区域,数组名称不占用内存;指针指向一块区域,指针会分配内存
(2)使用数组定义变量,声明此数组共其他地方使用时,一定要保持声明和定义一致,不能把数组声明为指针。

4.充满疑惑的数组指针和指针数组
数组指针为指向数组的指针,即是指向数组首元素地址的指针。如 int (*p)[5];
指针数组为可存放指针的数组,数组的每个元素均为指针,如 int *p[5];
int(*p)[5]表示一个指向二维数组的指针变量,该二维数组的列数必须为5。而指针数组int*p[5]表示一个指针数组,它的5个元素均为指针变量
请谨记:
(1)在数组指针中,声明的维数表示指针数组的元素数,而不是指针本身的元素数
(2)指针数组的每个元素均为指针,指向的数据类型为声明时的类型,声明时元素数既是指针数组的元素数
(3)数组指针可用于二维数组元素的操作,只要数组指针声明时的元素数和二维数组第二维元素数一样,二维数组名可直接赋值给数组指针

5.禁止以多态的形式处理数组
小心陷阱:
(1)在使用数组时,一定要保证保存的元素和使用的元素是相同类型的对象,否则会产生不可预期的结果
(2)数组作为函数的形参传给函数,在函数内部数组退化为指针,对此数组名进行的任何操作都会转化为对指针的操作
(3)通过基类指针删除一个由子类构成的数组,其结果未定义

6.防微杜渐,拒绝野指针
野指针不是NULL指针,而是指向“垃圾”内存的指针,在某些环境下使用野指针,程序可以正常运行,但并不表明程序是正确的
野指针的产生过程:
(1)指针变量未初始化。
(2)指针所指向的对象已经不存在了,编程人员误以为指针还是一个合法的指针
(3)指针操作超出变量的作用范围
预防野指针:
(1)声明指针时切记初始化
(2)指针释放后要置为NULL
(3)如果指针作为函数的输入参数时,在引用参数前首先对指针进行参数检查
(4)尽量使用引用替代指针

7.臭名昭著的空指针到底是什么
空指针不是任何变量的指针,同样空指针也不是野指针,每种指针都有一个空指针,而且每种变量的空指针也都不是此种变量的地址
请谨记:
(1)空指针不一定就是0,但必须是指向不能被变量分配到的地址,而NULL肯定是0
(2)赋值为空指针的变量,可确保变量不指向任何对象或函数。合理地使用空指针可有效避免内存泄漏,提高程序的执行效率

8.多维数组和指针
小心陷阱:多维数组作为形参时,第一维的长度其实并不重要,因为在计算下标值时用不到它,但第二维及以后各维必须声明,且各维的声明长度必须和实参传值时数组对应的各维长度保持一致,否则会导致不可预知的行为
请谨记:
(1)多维数组名和多重指针在任何时候都不等价。在C++中多维数组就是一维数组,知识数组中的每个元素又是一个数组。多重指针指的是指向另一个指针的指针
(2)多维数组的数组名的类型是数组指针,而不是多重指针

9.引用和指针的差异
小心陷阱:
(1)声明一个引用不是定义一个新的变量。仅表示该引用名是目标变量名的一个别名。它本身不是一种类型,因此不占用存储单元
(2)对引用求地址和对目标变量求地址是等价的
指针和引用的相同点:指针和引用都是地址的概念,指针只想一块内存,它所存储的内容是地址,而引用是某块地址的别名。两者都可通过间接方式实现数据操作(指针使用*和->,引用使用.),都可实现继承类的动态绑定。
指针和引用的不同点:指针是一个实体,而引用是一个别名,不占用存储空间。引用只能在定义时初始化,且初始化后不可以更改,指针可以任意时候初始化并再次赋值。引用不能用const和volatile关键字修饰,而指针可以。













评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值