c/c++ 指针的江湖传说

万物皆内存,内存有两个东西:地址、值。

普通变量、引用变量、指针变量,二级指针变量,数组,指针数组...等等,皆内存。

【指针】

int x = 10;         //变量
int* pX = &x;       //指针变量
int** ppX = &pX;    //二级指针变量
//地址,值
std::cout << &x << "," << x << std::endl;
std::cout << &pX << "," << pX << std::endl;
std::cout << &ppX << "," << ppX << std::endl;

x、pX、ppX都是“值”。只不过有的“值”刚好是所指向内存的“地址”,所以课本上、网络上将pX、ppX说成“地址”。

良好的命名习惯,有助于指针的快速理解而不会晕头转向。一级指针p开头,二级指针pp开头,遇*则抵消,遇&则变p

*pX→x,值 10

*ppX→pX,值 00000086ECBBF604

**ppX→x,值 10

&x→pX,值 00000086ECBBF604

&pX→ppX,值 00000086ECBBF648

&ppX→pppX,值 00000086ECBBF668

【指针大小,地址存储与取值】

开篇图中,只有10是int型,占4字节。其他的5个“值”“地址”都是地址属性,64位系统中占8字节,32位系统中占4字节。

为了稳妥,可以用 long long承接地址。下面将图中的5个地址存入数组,取值时先转类型再取值

long long y[5];
y[0] = (long long)&x;   //pX 
y[1] = (long long)pX;
y[2] = (long long)&pX;  //ppX
y[3] = (long long)ppX;
y[4] = (long long)&ppX; //pppX
std::cout << *(int*)y[0] << std::endl;      //*(int*)pX,由于pX是int*类型,所以先转换为int*类型,然后再取值,即*pX→x
std::cout << *(int*)y[1] << std::endl;
std::cout << **(int**)y[2] << std::endl;    //**(int**)ppX,ppX是int**类型,所以先转类型再取值,即**ppX→x
std::cout << **(int**)y[3] << std::endl;
std::cout << ***(int***)y[4] << std::endl;  //***(int***)pppX,先转类型再取值,即***pppX→x

在实际项目中的应用:

相机帧数据量较大,一般传递帧地址(const unsigned char*),在需要的地方拿到这个地址即可。

unsigned char pixelData = 255;
const unsigned char* pBuffer=&pixelData;//所以帧地址不变,值会一直变,即像素数据
long long val;
//拉流回调函数里获取帧地址
val = (long long)pBuffer;
//传到某个用到帧的地方
unsigned char* pImg = (unsigned char*)val;

 

【数组】

数组,不同类型的存取 - 夕西行 - 博客园 (cnblogs.com)

【函数传参,指针参数】

函数间参数传递的3种方式 - 夕西行 - 博客园 (cnblogs.com)

posted @ 2023-11-03 22:36  夕西行  阅读(18)  评论(0编辑  收藏  举报