分类: C/C++
2014-02-24 22:06:32
原文地址:说说指针 作者:CUTianrui007
2013年1月11日 18:08:27
闲着无聊,说说指针吧。
指针其实很简单,就是个地址。它有三个基本属性:地址属性,步长属性,数据格式化。地址属性是其最基本的属性,也是指针的定义所在。而常用的则是其步长属性和数据格式化。具体解析如下。
地址属性:
比如你定义一个变量:
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头结构体去解析这个数组,那么就可以对数据进行解析了.
脑子比较乱,文笔也不好,所以写得也比较乱,如果有错误的地方,欢迎指出.