一文读懂指针的本质

地址: 所谓地址就是一个整形的数字(常数)。地址不包含任何类型信息。
指针: 指针分为指针常量和指针变量,单独说指针的时候,通常指指针常量,其中:
指针常量=地址数值(常数)+类型信息
指针变量=整形变量+类型信息

变量 = * 指针
指针 = &变量
类型信息可以通过强制类型转换来实现,也就是大家熟悉的 (< Type >) 用法。地址数值的改变,则统一转化为普通整数以后再说。
指针常量 = 整数常量 + 类型信息
也就是:
指针常量 = (<类型信息> *)整数常量
反过来也成立:
整数常数 = 指针常量 - 类型信息
也就是:
整数常数 = (unsigned int)指针常量

应用举例:
创建一个全局变量:

#define s_wMyVariable    (* (( uint32_t *) 0x12345678))

定义一个宏来替我们批量生产全局变量:

#define __VAR(__TYPE, __ADDR)     (*(__TYPE *) (__ADDR))

使用起来也很方便,例如:

__VAR(  float, 0x20004000  ) = 3.1415926

万能类型转换:

#define CONVERT(  __ADDR,   __TYPE )            \
    __VAR(  (__TYPE),  (uint32_t) (__ADDR)  )

万能类型转换应用举例:
例如,我们可以直接将字节数组中某一段内容截取出来,当做某种类型的变量来访问:

//! 某数据帧解析函数
void command_handler(  uint8_t *pchStream, uint16_t hwLength  )
{
    
    
    // offset 0, uint16_t  
    uint16_t hwID = CONVERT( pchStream, uint16_t);  
    // offset 4, float
    float fReceivedValue = CONVERT( &pchStream[ 4 ], float ) ;
    ...
}

请忘记指针:
如果你是一个指针苦手,那么请忘记之前所学的一切。记住一句话:指针只是一个用法怪异的整形变量,专门用来保存变量的地址数值。指针的类型都是用来欺骗编译器的,我是聪明的人类,我操纵类型,我不是愚蠢的编译器。
  推论:因为指针变量的本质是整形变量,所以指向指针的指针,只不过是一个指向普通整形变量的普通指针,因此指向指针的指针并不存在——世界上只存在普通指针——世界上只存在用法怪异的整形变量,专门用来保存目标变量的地址数值。
  推论:世界上并不存在指向指针的指针的指针的指针……

给我一个整数,我自己造自己的变量。指针的数值运算太坑?转换成整数,加减乘除,随便整。

此文章来源于公众号:裸机思维
位置原地址:求求你,不要再纠结指针了(1) ——万能转化公式

猜你喜欢

转载自blog.csdn.net/sinat_31039061/article/details/108079048