C++实用经验(三)


声明:以下内容总结自《C++程序员不可不知的101条实用经验》

理解指针的本质

  1. C++标准规定:存放地址的变量称为指针变量,变量的地址称为变量的指针
  2. 指针的两个属性:(1)指针变量值的范围在[0, 2^n-1],n是机器地址线的数量,即指针变量占用n个bit; (2)指针的类型表示其所指向的变量的类型,作用一是只是编译在解引用时从内存读取几个字节以及指针指向下一个元素内存跳变几个字节,作用二是指示编译在进行指针类型转换是如何进行类型检查和匹配
  3. 指针变量定义必须初始化,delete后必须赋值nullptr,防止其成为野指针
  4. 如果一个函数的形参可接收所有类型的指针,请将此函数的形参声明为void*
  5. 指针的算数操作:(1)指针+/-整数,实现指针在数组上的移动 (2)指针-指针,两个指针都必须指向同一个数组的元素,得到两个指针之间的元素个数

论数组和指针的等价性

  1. 作为函数形参时,指针和数组等价,数组会退化为一个指向数组首元素的指针
  2. 数组名被编译器当做一个指向该数组首元素的指针常量
  3. 无论采用a[i]还是*(a+i)形式访问,编译器在编译时都会改写成*(a+i)的形式访问

再论数组和指针的差异性

  1. 数组和指针的内存分配方式
    在这里插入图片描述
char a[] = "abc"; //在栈区分配4个字节内存存储字符串“abc”
char *a = "abd"; //在字符常量区开辟4个字节内存存储字符串“abc”
  1. 数组对应一块固定大小的内存区域,地址和容量不可变,只有存储的内容可变,而指针所指向的内存区域可以改变大小
  2. 使用sizeof可计算出数组大小,但是sizeof(指针)只能得到指针变量所占空间大小

充满疑惑的数组指针和指针数组

数组指针

int aiVal[2][2]={{1,2},{3,4}};
int (*piVal)[2] = NULL; //定义一个数组指针,其指向元素数为2的一维数组
piVal = aiVal; //数组指针赋值

在这里插入图片描述

指针数组

int a[3][3] = {{1,2,3},{4,5,6},{7,8,9}};
int *p[3] = {a[0], a[1], a[2]}; //数组指针数组

在这里插入图片描述

禁止以多态的形式处理数组

存在一个父类CWidget,一个继承CWidget的子类CDialogWidget。存在一个函数ShowAll,对一个CWidget对象数组元素进行遍历

void ShowAll(CWidget widget[], int num){
	for(int i = 0; i < num; i++){
		widget[i].dosomething();
	}
}

CWidget widget[4];
ShowAll(widget, 4); //运行正常

CDialogWidget widget[4];
ShowAll(widget, 4); //运行出问题,由于形参数组类型是CWidget,所以在遍历时*(widget+i)会以sizeof(CWidget)的大小进行每次跳转,而sizeof(CWidget)与sizeof(CDialogWidget)不一定相等,所以会出现不可预知的结果

防微杜渐,拒绝野指针

  1. 野指针出现原因:(1)指针变量未初始化 (2)指针被free或delete后没有被设置为nullptr
  2. 避免野指针:(1)指针变量在初始化或执行内存释放操作后,务必将其赋值为NULL (2)指针作为函数参数时,在函数入口处使用assert(p != NULL)进行校验,起到定位错误的功能 (3)尽量使用引用替代指针 (4)使用智能指针

臭名昭著的空指针到底是什么

  1. 空指针不一定是0,但必须是指向不能被变量分配到的地址,而NULL肯定是0
  2. 赋值为空指针的变量,可确保变量不指向任何对象或函数,合理使用空指针可有效避免内存泄露,提高程序运行效率

多维数组和指针

  1. 计算机中不存在多维数组,多维数组是一个特殊的一维数组,元素都是线性存储
  2. 多维数组声明时要求给定除了第一维外的其他所有维的下标
  3. 多维数组作为形参时,第一维的长度其实并不重要,在计算下标值时用不到它。但第二维及之后各维都要声明,且各维的声明长度必须和实参传值时数组对应的各维长度保持一致

引用和指针的差异

  1. 引用和指针的相同点:(1)都是地址的概念,指针存储的是一块内存的地址,引用是一块地址的别名 (2)都可实现继承类的动态绑定
  2. 引用和指针的不同点:(1)指针是一个实体,占用存储空间,而引用是一个虚体,不占用存储空间 (2)sizeof(引用)得到的是对象的大小,而sizeof(指针)得到的是指针所占内存大小 (3)引用只在定义时初始化一次,不可修改,而指针可以多次修改 (4)调用函数传递指针参数是对指针值的拷贝,传递引用参数是将实参变量的地址拷贝到栈上,通过这个地址进行间接寻址
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值