指针和引用

内存地址
程序运行时,代码和需要的数据都被存储在内存中
内存是有序的字节序列,每个字节都有唯一的地址,使用该地址可以确定字节的位置,用以存储和获取数据
直接访问和间接访问
通过变量的名字直接访问为程序中定义的变量分配的内存单元,存取变量的值
使用变量的内存地址找到存放数据的单元,间接访问其中的内容
指针
指针的特点:

  1. 指针持有一个对象的地址,称为指针“指向”该对象
  2. 通过指针可以间接操纵它指向的对象

定义指针变量的语法

每个指针都有相关的类型,要在定义指针时指出

类型 *指针变量;

指针存放指定类型对象的地址,要获取对象的地址,使用取地址运算符“&”
如果指针指向一个对象,则可以通过指针间接访该对象,使用指针解引用运算符“*”

指向一个对象的指针有两个存储单元与之相关:

  1. 一个是指针自己的存储单元,里面存放着所指对象的地址;
  2. 另一个就是指针指向的对象的存储单元,里面存放该对象的值。
    可以定义存放指针对象的地址的指针
    **空指针:**指针值为0时是一个空指针,不指向任何对象地指针 (0,NULL)
//生成空指针的方式
int *p1 = 0;
int *p2 = NULL;
//不能写成下面的样子:
int zero = 0;
int *p4 = zero;

指针运算:
同类型的指针可以进行相等(==)或不相等(!=)的比较操作,比较的结果是布尔类型
可以进行加或整数值的算术运算
自增、自减运算适用于指向数组元素的指针
void*指针:
可以持有任何类型的地址值,即通用指针
相关的值是个地址,但是该地址保存的对象类型不知道
不能操纵void指针指向的对象,只能传送该地址值或者和其他地址值进行比较
不允许void指针到其他类型指针的直接赋值

存储空间分配策略

静态(编译时)分配空间
编译器在处理程序源代码时分配内存;
效率高,灵活性差,运行前就要知道程序需要的内存大小和类型
动态(运行时)分配空间
程序运行时调用运行时刻库函数来分配内存;
占用程序运行时间,更灵活

静态和动态内存分配在语法上的主要区别:
静态对象是有名字的变量,可以直接对其进行操作;动态对象没有名字,要通过指针间接地对它进行操作。
静态对象的空间分配与释放由编译器自动处理,动态对象的空间分配与释放必须由程序员显式地管理。

堆(heap)、自由存储区、动态存储区:
系统为所有程序提供了一个运行时可用的内存池,这个内存池被称为程序的自由存储区或堆

动态内存管理方法:
C++通过new和delete运算符进行动态存储空间的管理

new运算符
在堆上动态分配空间,创建对象,并返回对象的地址
一般将new返回的地址保存在指针变量中,以便间接访问堆上的对象。

new表达式的三种形式:
分配单个对象:new 类型 或者 new 类型(初始值)
分配多个连续存储的对象:new 类型[数组大小]
定位new,在指定位置分配空间:new (指针) 类型;

delete运算符:

new运算符分配的空间用delete运算符释放
释放new分配的单个对象的delete形式
delete 指针;
释放new分配的数组的delete形式
delete[] 指针;
定位new没有对应的delete表达式

空悬指针
执行delete运算后,指针ip指向的空间被释放,不能再使用ip指向的内存,但是ip这个指针变量自己的存储空间不受影响
delete后的ip不是空指针,而是“空悬指针”,即指向不确定的单元
delete之后,继续通过ip间接使用这个单元是非法的,会引起不可预料的运行错误

引用

引用又称为别名,它可以作为对象的另一个名字;
通过引用可以间接地操纵对象;
在程序中,引用主要用作函数的参数。

引用有类型标识符和一个说明符(&)来定义

type& refVariable = leftValue;

引用必须被初始化,初始值是一个有内存地址的对象
引用一旦初始化,就不能再指向其他的对象,对引用的所有操作都会被应用在它所指向的对象上

引用的初始化和赋值不同

  • 初始化时引用被“绑定到”一个对象;
  • 赋值时,引用被作为所绑定对象的别名
    const限定指针
    指向const对象的指针(非const )
const type *cp; 或者type const *cp;

cp是指向常量的指针,它所指向的内存中的内容不可以改变,即*cp的值不能改变
指向非const对象的const指针

type* const cp = initAddressValue;

cp是常量指针,初始化后值不能改变,指向固定的单元
const限定引用
const引用仅对引用自己可参与的操作进行了限定,对所指向的对象本身是不是常量未作限定。因为指向的对象也可能不是const,所以允许通过其他途径改变它的值

const限定的左值引用不可修改
const引用可以绑定到const对象
不能用非const引用指向const对象

数组与指针
使用数组时一般会转换为指针

int ia[5];
ia是一个int*类型的指针常量
ia和&ia[0]都表示数组第一个元素的地址

可以使用指针对数组进行访问

一维数组元素在内存中按下标顺序依次存放
一维数组a[n]的元素a[i]在内存中地址是a+i。

多维数组在内存中按行序存储
二维数组a[m][n]的元素a[i][j] 在内存中的地址是a+(i*n+j)

使用指针访问数组时需要控制指针的范围,确保指针指向数组的元素

库函数begin()和end()
让指针在数组上的使用更简单更安全
在头文件中定义

用法:
begin(数组名):返回指向数组第一个元素的指针
**end(数组名):**返回指向数组最后一个元素的下一个位置的指针

//在数组arr 中查找第一个负数:
int *pb = begin(arr), *pe = end(arr);
while(pb != pe && *pb >= 0)
++pb;

//逐个输出数组元素的循环
for(int p = begin(arr); p!= end(arr); ++p)
cout << *p << "\t";

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值