标签存档: 指针

局部变量使用指针方式赋值可能会导致异常

从协议解析数据是为了提高效率,我常常使用指针直接操作内存地址来替代移位操作,如下 :

    *((u8*)&a+1) = *(pbuf + 0);
    *((u8*)&a+0) = *(pbuf + 1);

继续阅读 »

大意了,又一次遇到指针问题

又一次遇到一个指针引起的问题,没有让他成为bug,呵呵。

看看这条语句:
memcpy(&g_GlobalBuf+DF_POSI_FEE_RATE,(const u8 *)&FeeRate,70);
本意是要把FeeRate数组中的内容拷贝到u8型数组g_GlobalBuf数组中从第 DF_POSI_FEE_RATE 个元素开始的空间中。但实际得到的结果是  &g_GlobalBuf+DF_POSI_FEE_RATE 指向的地址偏移了十万八千里,实际上错误的偏移量为 sizeof( g_GlobalBuf )* DF_POSI_FEE_RATE,也就是说偏移了 DF_POSI_FEE_RATE个 g_GlobalBuf数组的空间。

原因:很简单, &g_GlobalBuf 是一个指向数组的指针,而不是一个 u8* 指针,所以  &g_GlobalBuf+1 指向的是下一个数组的首地址而不是 g_GlobalBuf[1] 这个元素。

正确的写法: &g_GlobalBuf[DF_POSI_FEE_RATE ]  或者 (u8 *)( &g_GlobalBuf )+ DF_POSI_FEE_RATE

———————-添加一个指针与数组的小知识点  2014/10/28  —————————–

定义: char a[2][10],则如下:
+ &a 0x0012ff20 unsigned char [2][10]*
+ &a[0] 0x0012ff20 unsigned char [10]*
+ &a[0][0] 0x0012ff20 unsigned char *

用指针代替移位运算来读取变量的某个字节

先看下面这段代码:

static u32 g_VSOnlineFlg = 0x01020304;
static u8 a[5] = {0};
static u8 b[5] = {0};

a[0] = (u8)((g_VSOnlineFlg&0xFF000000)>>24);
a[1] = (u8)((g_VSOnlineFlg&0xFF0000)>>16);
a[2] = (u8)((g_VSOnlineFlg&0xFF00)>>8);
a[3] = (u8)((g_VSOnlineFlg&0xFF));

上面代码通过移位操作将变量 g_VSOnlineFlg 的4个字节依次倒入数组a[],这种方法比较浪费资源。比较好的做法是使用指针,使用 u8*指针把 g_VSOnlineFlg 的4个字节依次读取到数组中。
但需要注意两个问题:一是内存的对齐问题,MSP430中变量的高字节是放在内存的高地址的,而作为变量名的指针是指向低地址的;二是指针的变换问题,正确的表达式是 *((u8 *)&g_VSOnlineFlg + 0)。
所以上面的表达式可以等价为:

b[0] = *((u8 *)&g_VSOnlineFlg + 3);
b[1] = *((u8 *)&g_VSOnlineFlg + 2);
b[2] = *((u8 *)&g_VSOnlineFlg + 1);
b[3] = *((u8 *)&g_VSOnlineFlg + 0);

指针和内存对齐在通信中的问题

相关概念:

大端模式:数据的低位保存在内存的高地址中,而数据的高位保存在内存的低地址中,这种存储模式就类似把数据当做字符串顺序处理,例如:数据中两个字节按顺序为:FE 10 ,它表示的一个数就是0xFE10。
换句话说:内存的低地址存放着数据高位;

小端模式:数据的低位保存在内存的低地址中,而数据的高位保存在内存的高地址中,这种存储方式就是将地址的高低和数据的位结合起来,前面的例子按照小端模式表示,应该为:0x10FE。
换句话说:内存的低地址存放着数据低位。  继续阅读 »