共享内存 传一个类指针_C++指针

简介

指针一直是C语言和C++语言最难理解的一部分,无论是C语言和C++语言,复杂的数据结构都是离不开指针的运用,所以必须掌握好指针这个数据类型,你才能够在阅读框架代码时,游刃有余。今天我们从指针的本质来重新理解指针这个数据类型。

1.指针的本质

指针是用来保存地址的一个变量,那么变量都是保存在内存中,而内存其实就是一组有序字节组成的数组,每个字节有唯一的内存地址。CPU 通过内存寻址对存储在内存中的某个指定数据对象的地址进行定位。说白了,CPU就是通过地址去查找存储在内存中的数据。下面我们看看如下示意图:

dbc2755736437c7e69b107e57ee193e9.png

这是一个 4GB 的内存,可以存放 2^32 个字节的数据。左侧的连续的十六进制编号就是内存地址,每个内存地址对应一个字节的内存空间。而指针变量保存的就是这个编号,也即内存地址。指针本身也是有内存地址来保存这个变量的。

2.为什么要使用指针

在C语言中,指针的使用非常广泛,因为使用指针往往可以生成更高效、更紧凑的代码。总的来说,使用指针有如下好处:

1)指针的使用使得不同区域的代码可以轻易的共享内存数据,这样可以使程序更为快速高效;

2)C语言中一些复杂的数据结构往往需要使用指针来构建,如链表、二叉树等;

3)C语言是传值调用,而有些操作传值调用是无法完成的,如通过被调函数修改调用函数的对象,但是这种操作可以由指针来完成,而且并不违背传值调用。

3.指针定义和初始化

下面我们再来看看下面例子:

int a = 100;

int *p = &a;

int **p2 = &p1;

p2        p1       a

&p1   ->  &a   ->  100

为了方便理解,我们来打个比喻:

定义的a,p,p2都是一个盒子,他们都有自己地址空间,方便别人找到它

a是一个盒子,用来装100这个数据,a本身有地址;

p也是一个盒子,用来装a的地址,p本身也有地址;

P2也是一个盒子,用来装p的地址,p2本身也有地址;

a和p和p2变量本身都是代表盒子里面的东西

=》盒子里面装可能是值,也可能是地址,例如a就是值,p和p2都是地址;

“*”的操作(只对指针变量),就是取出盒子里面地址,去打开另一个盒子那东西

=》相当于,从抽底里面取出一把钥匙,去打开另一个抽底去拿东西一样。

指针的声明比普通变量的声明多了一个一元运算符 “*”。运算符 “*” 是间接寻址或者间接引用运算符

总结如下:

3.1.指针也是一种数据类型,也占用内存空间

1) 指针是用来干嘛?

=>指针是用来存放地址的, 这个地址(p=&a)可以指向"int"型内存空间

例如定义:int a;//我们知道a是用来存储整型数据的

例如再定义int *p;  //那么,指针也是一种数据类型,也可以用来定义变量

2)指针本身也有地址,也占用内存空间

=>指针定义时(int *p)不占用内存空间,当其赋值(p=&a)时分配内存空间

3.2.一级指针: p 和 *p区别

"p"操作:

其实就是直接取出它内存空间里面值(只不过指针变量p存储空间存放的是一个地址);

"*p"操作:

第一步,p操作,先去取出p存储空间里面的地址(p存储的是一个地址); 

第二步,*P操作,再把这块地址里面值取出来;

3.3.二级指针: p2 和 *p2 和 **p2操作顺序

第一步: p2, p2操作,先取出p2内存空间里面值,得到的这个值是一级指针的地址;

第二步: *p2, 再*p2操作, 取出一级指针内存空间里面的值(一级指针内存空间里面的值还是个地址,例如变量a地址); 

第三步:**p2, 再**p2操作, 得到变量a的值;

#include "iostream"using namespace std;void main(){  int a = 100;  int *p = &a;  int **p2 = &p;  //int ***p3 = &p2;   //1.取值, 打印  printf("取值, 打印:%d, %d, %d\n", a, *p, **p2);  //2.取地址, 打印 =>指针也是有地址的  printf("取地址, 打印:&a=%#x, &p1=%#x, &p2=%#x\n",&a, &p, &p2);  //3.打印地址,对比  //=>p 和 &a打印都是同样地址,因为p是用来存放a的地址  printf("打印地址,对比:p=%#x, &a=%#x\n", p, &a);    //p2 和 &p打印都是同样地址,因为p2用来存储&p地址  //=>*p2 和 &a打印都是同样地址,因为*p2取就是p存储单元里面值(即使a地址)  printf("打印地址,对比:p2=%#x, &p=%#x ,*p2=%#x, &a=%#x\n", p2, &p, *p2, &a);  system("pause");  return;}

最后输出结果:

dae3a92a3a987a88b4a5326e5c2f4a82.png

推荐阅读:

专辑|C++专辑

专辑|Camera专业知识

专辑|摄像头行业动态

专辑|程序人生

22286816a2ce0d3e2c4ce626c872b242.png

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值