地址: 所谓地址就是一个整形的数字(常数)。地址不包含任何类型信息。
指针: 指针分为指针常量和指针变量,单独说指针的时候,通常指指针常量,其中:
指针常量=地址数值(常数)+类型信息
指针变量=整形变量+类型信息
变量 = * 指针
指针 = &变量
类型信息可以通过强制类型转换来实现,也就是大家熟悉的 (< 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) ——万能转化公式