码迷,mamicode.com
首页 > 其他好文 > 详细

底层解析C指针(二)

时间:2019-12-25 16:15:41      阅读:92      评论:0      收藏:0      [点我收藏+]

标签:多少   区别   uri   随机   完全   ola   开始   rev   nbsp   

上一篇主要讨论了C指针的本质,但并没有解释指针的类型问题,这次我们重点来讨论指针的类型与指针内存分配之间的关系。

对比以下两个指针

int *p;

char *p;

单纯从上面看这两个指针有何区别?

很多读者第一反应就是其类型不同,确实没错,但是我们现在需要从底层出发,搞清楚指针类型的意义。

其实单纯从上面来看,两个指针是没有任何区别的,其内存的大小完全相同。

但是由于指针有++和--操作,导致指针的偏移量大小到底多大,这个就需要由类型决定。因此类型仅仅只决定指针移动时偏移的大小。

下面我们来彻底分析指针这个问题。

从程序员开始写int *p这句时,计算机仅仅为p分配了一个四字节的内存地址(假设编译器为32位),而这个内存地址中存储的数据是多少并不知道,由于其数据可能是一个随机数,因此我们强行访问p时会得到一些随机的数字,这又一步说明了指针为啥需要进行初始化,但是,我们如果查看&p时,我们可以看到这是合法的,因为我们查看的是p的地址,即计算机为p分配的一个内存地址,如图所示:

技术图片

 

 

 这个可能比较好理解,硬核的东西来了!!!

我们现在开始深入,看如下:(下面代码摘自作者写的嵌入式操作系统)

typedef struct PCB_STRUCT
{
    struct PCB_STRUCT *TCBPrev;       //前趋指针
    struct PCB_STRUCT *TCBNext;       //后继指针

    UINT32             TCBDlyCount;   //延时计数器
    UINT8              TCBState;      //任务状态       255为头部   254尾部    0表示阻塞态,1表示就绪态,2表示挂起态

    INT8              *TCBName;       //任务名
    FUN                TCBTask;       //任务函数指针
    UINT8             *TCBStack;      //人工堆栈
    UINT8              TCBPrio;       //任务优先级
    pTCB              *TCBHandler;    //任务句柄  也叫任务ID   

    UINT16             TCB_SP;        //任务当前的SP指针 
}pTCB;

现在我们定义

pTCB *RdyTab[33];        //就绪查找表   0为空闲任务

我们现在思考:

RdyTab[33]的内存分配结构?

部分读者会有第一反应就是内存结构当然是33个结构体的大小。如下:

技术图片

 

 

 其实上面是错误的

因为之前说过,即使是结构体指针数组,其数组的元素本质上仍是指针,因此,其大小也只是一个四字节的地址单元,因此,其正确的结构如下:

技术图片

 

 

 那有人会有疑惑,为啥

RdyTab[i]->TCBPrev等等,这些为什么存在呢?
其实这个并不存在,这里单纯指
RdyTab[i]的内存单元中,而我们需要使用RdyTab[i]->TCBPrev等等
时,必须先初始化
RdyTab[i]的值,而这个RdyTab[i]->TCBPrev就是指初始化时指向内存的首地址
偏移位置,这个工作是由编译器完成的,如下图所示
技术图片

显然当我们使用RdyTab[i]->TCBPrev时,其地址就是分配的结构体所在的地址,而不是指针数组的地址。

 

 

 



 

 

 

 

 

 

 

 

 

 

typedef struct PCB_STRUCT
{
    struct PCB_STRUCT *TCBPrev;       //前趋指针
    struct PCB_STRUCT *TCBNext;       //后继指针

    UINT32             TCBDlyCount;   //延时计数器
    UINT8              TCBState;      //任务状态       255为头部   254尾部    0表示阻塞态,1表示就绪态,2表示挂起态

    INT8              *TCBName;       //任务名
    FUN                TCBTask;       //任务函数指针
    UINT8             *TCBStack;      //人工堆栈
    UINT8              TCBPrio;       //任务优先级
    pTCB              *TCBHandler;    //任务句柄  也叫任务ID   

    UINT16             TCB_SP;        //任务当前的SP指针 
}pTCB;

底层解析C指针(二)

标签:多少   区别   uri   随机   完全   ola   开始   rev   nbsp   

原文地址:https://www.cnblogs.com/listenscience/p/12096882.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!