C/C++有意思的指针(2)

指针变量的定义与使用

普通变量的定义与使用不存在很大的区别,定义了直接使用即可。但指针的定义与使用是需要作区分的。

int* p = nullptr; //定义时*指内存地址,或说指向的内存区域首地址
cout << *p << endl; //指针使用时*是指对p存放的地址解引用,按p的数据类型读取内存数据。

这对指针类型作解析:
(int*) 类型中的* 为内存地址类型,指向某个内存地址首地址。再加上旁边的int则约定这个内存区域存放的数据类型为Int型,按int类型读取内存4字节偏移量。

(*p),对p变量中存放的内存首地址解引用,读取内存数据。读取内存方式取决于定义时p的类型。

结构体的比较特殊,结构名为首地址,使用->符号或.号过行以首地址为基地址偏移读取内存数据,偏移量的大小取决于结构成员变量类型。

其它基础数据类型的内存模型就不画了,这里画下结构体变量的内存模型

#include <iostream>
#include <string>
#include <thread>
#include <string.h>
#include <vector>
#include <iterator>
#include <algorithm>

using namespace std;

struct stu{
    
    
    int age;
    int height;
};

 int main(int argc, char** argv)
{
    
    
    struct stu* ts = (struct stu*)malloc(sizeof(struct stu));
    ts->age = 110;
    ts->height = 180;

    struct stu ts2 = {
    
     120, 190 };

    printf("The Person age:%d, height:%d \n", ts->age, ts->height);
    printf("The Person2 age:%d, height:%d \n", ts2.age, ts2.height);
    return 0;
}

如果使用指针定义结构,则在初始化之前需要申请结构变量空间。结构体使用结构名称来访问成员变量,解引用使用符号->,如果是直接生成结构体对象,则使用.(dot)来访问成员。使用->相当于是在结构体首地址时进行偏移,偏移大小为成员数据类型所点内存大小。

在这里插入图片描述

指针与二级指针

指针变量只是一个正常的变量,只是内存放的数据值为其它内存址首地址。二级指针变量,也只是一个正常的变量,只是内存里存放的是指针的指针变量即(int**)类型。

int main(int argc, char** argv)
 {
    
    
    struct stu t = {
    
     120, 190 };
    struct stu* tp = &t;
    tp->age = 110;
    tp->height = 180;

    struct stu** tpp = &tp; //对变量使用取地址符&,相当于变量增加一个*地址符
    printf("The stu structure addr:%p\n", *tpp);
    printf("The stu first member age addr:%p \n", &t.age);
    printf("The Person age:%d\n", (*tpp)->age);
    return 0;
}
 
运行结果:
The stu structure addr:0x7ffd72db4630 //结构体首地址
The stu first member age addr:0x7ffd72db4630 //结构体第一个成员变量地址与结构体首地址相同。
The Person age:110

对p1进行解引用一次p1则, p1变量的类型由(int** )变成 (int)类型,但还是指针类型。再进行一次解引用则是按struct stu类型读取内存数据。
指针的解引用,引用时碰到什么类型就按什么类型数据读取内存,一层层的从右向左剥(((struct stu)struct stu*)struct stu**)。

二级指针直接这样使用没什么效果,一般是在申请内存或二维数组中使用到二级指针,用来方便对数据遍历访问。

猜你喜欢

转载自blog.csdn.net/zj646268653/article/details/109090896
今日推荐