首页
社区
课程
招聘
[原创]我对指针的理解
发表于: 2016-1-5 08:31 3063

[原创]我对指针的理解

2016-1-5 08:31
3063
闲着无聊,说说指针吧。

指针其实很简单,就是个地址。它有三个基本属性:地址属性,步长属性,数据格式化。地址属性是其最基本的属性,也是指针的定义所在。而常用的则是其步长属性和数据格式化。具体解析如下。

地址属性:

比如你定义一个变量:

U16 u16Temp;

那么软件就会为你所定义的变量分配一个地址,具体这个地址在哪里?依据你所定义的变量的类型,如果是全局变量或静态(二者本质是一样的),那就在全局区中,如果是局部变量,那就在函数的栈中。可以通过&u16Temp来得到其具体的值。这是其地址属性。

步长属性:

这里的步长属性是指指针在参与运算过程中,主要是加减运算,进行一个单位的加减时,其所能跨越的地址范围。比如,定义一个指针变量如下:

U16* u16pPointer = 0X12345678;

当你执行u16pPointer++时,其值变会变成了0X1234567A,注意:是从8变到A,加了2,为什么加2?因数U16占用两个字节,那么指针运算一次,其步长就是2个字节。如果你定义成U32,那么步长就是4个字节了。如果两个指针做差运算,那么得到是什么呢?比如U16* u16P1 = 0Xaaa0; U16* u16P2= 0XAAAA,如果u16P2-u16P1=?,如果直接理解,得到值将是0XAAAA-0XAAA0=A, 这样分析错了,为什么?指针另时,编译器会乘上步长,与此类似,这里也会除以步长,也就是说,两个指针相差,你得到的将是步长值,所以正确的结果是A/2=5.

数据格式化

这是对步长属性的引申,比如你定义了一个结构体,

typedef struct

{

    U16 Data1;

    U8  Data2;

    U8  Data3;

}tStrTest;

这里定义了个结构体,你定义一个指针U16* u16P1=0X12345678,显然其步长是2,如果你对其做强制转化,如下所示:

(tStrTest*)u16P1,那么0X12345678开始的数据将会被编译器解析为一个结构体,也就是说,你可以使用0X12345678~0X1234567B在编译器看来,就是一个结构体, 前面两个字节是Data1,后面两个字节分别是Data2和Data3.这个技巧很有用,可以将其叫做数据流的解析,比如,在网络编程中,你将接收到的数据放到一个数组中,然后定义一个IP头结构体去解析这个数组,那么就可以对数据进行解析了.

[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

收藏
免费 0
支持
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回
//