简介:
通过一小段代码实例,帮助理解结构体强制类型转换时易错点,即转换后,存储结构体数据的一段内存没有发生变化,但需按照新的指针类型存取结构体数据。
首先声明一个结构体:
typedef struct __INPUT_DATA{
uint16_t index0;
uint16_t input1; // 16位数据
uint16_t input2;
uint16_t input3;
uint32_t input4; // 32位数据
uint32_t input5;
uint32_t input6;
}INPUT_DATA;
定义一个结构体变量及全局数组;
INPUT_DATA AIInputs;
uint16_t aInputData[256]; //存储输入数据
结构体赋值:
void inputs_get(void)
{
AIInputs.index0 = 7;
AIInputs.input1 = 0x0011;
AIInputs.input2 = 0x0012;
AIInputs.input3 = 0x0013;
AIInputs.input4 = 0x01110114;
AIInputs.input5 = 0x1015;
AIInputs.input6 = 0x10101016;
}
映射数据方法一:<错误>
void inputs_mapping1(uint16_t *pTmpData)
{
*pTmpData++ = ((UINT16 *) &AIInputs)[1];
*pTmpData++ = ((UINT16 *) &AIInputs)[2];
*pTmpData++ = ((UINT16 *) &AIInputs)[3];
*pTmpData++ = ((UINT32 *) &AIInputs)[4] &0xFFFF; //32位指针,下标不变,导致取数据发生偏移
*pTmpData++ = (((UINT32 *) &AIInputs)[4] &0xFFFF0000) >> 16;
*pTmpData++ = ((UINT32 *) &AIInputs)[5] &0xFFFF;
*pTmpData++ = (((UINT32 *) &AIInputs)[5] &0xFFFF0000) >> 16;
*pTmpData++ = ((UINT32 *) &AIInputs)[6] &0xFFFF;
*pTmpData++ = (((UINT32 *) &AIInputs)[6] &0xFFFF0000) >> 16;
}
映射数据方法二:<正确>
void inputs_mapping2(uint16_t *pTmpData)
{
*pTmpData++ = ((uint16_t *) &AIInputs)[1];
*pTmpData++ = ((uint16_t *) &AIInputs)[2];
*pTmpData++ = ((uint16_t *) &AIInputs)[3];
*pTmpData++ = ((uint16_t *) &AIInputs)[4]; //按16位取数据,注意修改下标
*pTmpData++ = ((uint16_t *) &AIInputs)[5];
*pTmpData++ = ((uint16_t *) &AIInputs)[6];
*pTmpData++ = ((uint16_t *) &AIInputs)[7];
*pTmpData++ = ((uint16_t *) &AIInputs)[8];
*pTmpData++ = ((uint16_t *) &AIInputs)[9];
}
映射数据方法三:<正确>
void inputs_mapping3(uint16_t *pTmpData)
{
*pTmpData++ = ((UINT16 *) &AIInputs)[1];
*pTmpData++ = ((UINT16 *) &AIInputs)[2];
*pTmpData++ = ((UINT16 *) &AIInputs)[3];
*pTmpData++ = AIInputs.input4 &0xFFFF;
*pTmpData++ = ( AIInputs.input4 &0xFFFF0000) >> 16;
*pTmpData++ = AIInputs.input5 &0xFFFF;
*pTmpData++ = ( AIInputs.input5 &0xFFFF0000) >> 16;
*pTmpData++ = AIInputs.input6 &0xFFFF;
*pTmpData++ = ( AIInputs.input6 &0xFFFF0000) >> 16;
}
测试模块:
/* 模拟将结构体中input数据串行发送出去 */
void send_data(void)
{
inputs_mapping1((uint16_t*)aInputData);
send((uint16_t*)aInputData, address, InputSize);
}
int main()
{
inputs_get();
inputs_mapping1(aInputData); // 该方法导致获取的结构体数据不对,指针偏移
// inputs_mapping2(aInputData);
// inputs_mapping3(aInputData);
send_data();
return 0;
}
总结:
一般直接采用结构体成员赋值,不容易出错。
当强制转换后指针类型发生了变化,注意存取数据的下标也需要做相应调整。