C++学习笔记(三):C++指针

指针的含义

变量与地址

C++变量存储分为两个步骤,首先申请相对大小的内存,然后对该内存进行赋值。比如int num;,首先申请8个字节的内存,然后进行num=1;,对num进行赋值操作。这两步可以同时进行int num=8;,声明变量、申请内存和赋值一步到位。但是从上一讲中可以得知,这种方法是自动存储,内存在编译阶段申请,无法修改内存地址。但是在OOP编程中我们更倾向于动态存储,可以动态的更换变量的地址,动态的调整内存大小,这个时候我们就需要直接获取到内存的地址。

&num,取地址符,获取到num内存地址

获取到一个内存地址之后,我们可以修改变量所指向的内存,赋给一个新的内存地址,这样就可以动态修改内存大小。

指针的引用

通过&取到内存地址后,使用指针进行地址引用,*关键字就是用来解析地址的。

int num = 1; # 申请8字节内存
int *p; # 申请一个指针
p = # # 通过取地址符获取地址,赋值给p
std::cout << *p; # 通过*解析到该内存地址的具体值

所以指针其实就是在内存地址前面加了一个*,这个符号可以获取到该地址所代表的具体值。在C++中,指针的声明后并不申请内存(实际会申请2字节的地址,但这里可以忽略),指针本身是不占内存的,指针的作用,就指向另一个已经存在的内存地址。所以指针的声明有如下两种方式:

// 方式一
int num = 1; # 先申请一个整型内存
int* p = &num; # 将num的地址给p,*p就可以获取到num的值

// 方式二
int* p; # 创建一个指针
p = new int; # 通过new动态申请一个新的整型内存地址

切记,因为指针本身是不指向任何内存地址的,所以在没有为指针分配内存地址之前,不可以对其进行赋值操作,不然会发生内存错误,十分危险的行为!


指针的运用

常规声明与new声明

指针的声明格式是typename* name = new typename,如果想要声明数组指针的时候,则用typename* name = new typename[num],这两种方式的本质都在于new申请了一块内存地址,再用这个指针指向该地址。
而常规声明则例如:

int a = 1;
int* p = &a;

这两种方法的根本区别在于,new方法可以动态的申请,实时的申请新空间,但是常规声明还是不够灵活,不过还是要相对来看。

数组指针

int* ps = new int[10];
int nums[10];

上述两种方案都可以创建一个长度为10的整型数组,二者除了内存申请方式不同外还有什么不同呢?首先我们指定int nums[10],就是在在内存里申请了80字节的内存空间,通过下标对应每8个字节的内存。

反观int* ps = new int[10];做了什么呢?我们知道*ps也可以通过下标进行赋值和取值,但是如果我们直接输出*ps我们会发现,我们可以输出第一个元素的值,对*ps赋值的话,也是对第一个元素进行赋值。

这个时候我们发现了,*ps其实是指向数组的第一个元素地址的,而new申请的内存在堆上是连续的,所以当我们对ps+1时,指针向后移动了8个字节,正好就指向了第二个元素的地址,然后再进行ps-1,指向就向前移动了8个字节,又指向了第一个元素的地址。这下子,我们就明白了,其实数组指针的取值可以用以下公式表示:

ps[num] <==> *(ps+num)

这就体现了为什么C++的运行速度如此之快,因为它是直接在内存上、字节级的进行操作。但是也要注意,因为直接操作到内存,一定不要忘记在结束的时候使用delete释放内存。

特别注意

当我们使用数组指针的时候,我们再看看上面的公式,我们会发现即使我们的下标是负数,或者超出了申请的大小,我们依旧可以正常操作。

ps[-1] or ps[10000]

这是因为C++是不会检查你的下标是否合法,它只会老老实实的做*(ps+num)的操作,所以一旦你下标溢出了,其实你会对堆上的其他内存做修改,这就是最常见的内存溢出错误,这是特别危险的操作,因为你也不知道其他内存上面存储着什么数据,所以C++的指针是双刃剑,一定要好好使用。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值