关于C语言结构体强制类型转换的易错点

简介:

        通过一小段代码实例,帮助理解结构体强制类型转换时易错点,即转换后,存储结构体数据的一段内存没有发生变化,但需按照新的指针类型存取结构体数据

首先声明一个结构体:

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;
}

总结:

        一般直接采用结构体成员赋值,不容易出错。

        当强制转换后指针类型发生了变化,注意存取数据的下标也需要做相应调整。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值