C语言 强制数字类型指针寻址

10 篇文章 0 订阅
2 篇文章 0 订阅
本文讨论了在C语言编程中,直接通过类型强制转换访问内存地址可能导致的问题,特别是在单片机平台上,由于内存地址和总线未对齐可能会导致程序死机或数据错误。为了解决这个问题,提出了使用联合结构体进行数据转换的方法,提供了一系列的转换函数,如TR_INT8, TR_UINT16等,以确保在不同芯片上正确地读取和处理数据。
摘要由CSDN通过智能技术生成

在c语言开发中,有时候为了方便经常会这么访问一个地址 int a = *(int *)address。但这个方法在单片机平台中存在着隐患:

  • 表现:程序死机或者数据获取不对
  • 原因:取地址时内存地址和总线未对齐
  • 解决方法:使用联合结构体方法进行转换

测试代码:在不同的芯片中执行会有不同的情况,大部分能正确获得数据,但有些则是卡死或者数据获取错误。

#include <stdio.h>
#include <stdint.h>
#include "math.h"
#define M_PI 3.14159265358979323846
int main()
{
    int i;
    uint8_t data[10]={1,2,3,4,5,6,7,8,9,10};
    printf("8bit address: \n");
    for(i=0;i<10;i++){
        printf("%d:%lx\n",i,(uint32_t)&data[i]);
    }
    printf("16bit address: \n");
    for(i=0;i<10;i++){
        printf("%d:%lx\n",i,*(uint16_t*)&data[i]);
    }
    printf("32bit address: \n");
    for(i=0;i<10;i++){
        printf("%d:%lx\n",i,*(uint32_t*)&data[i]);
    }
    printf("done \n");
    return 0;
}

解决代码:

typedef union param_union {
    float param_float;
    int32_t param_int32;
    uint32_t param_uint32;
    int16_t param_int16;
    uint16_t param_uint16;
    int8_t param_int8;
    uint8_t param_uint8;
    uint8_t bytes[4];
}TYPE_UNION;

//常用的数据转换函数
int8_t TR_INT8(uint8_t *in){
    return *(int8_t*)in;
}
uint8_t TR_UINT8(uint8_t *in){
    return *in;
}
int16_t TR_INT16(uint8_t *in){
    TYPE_UNION changecore={0};
    memcpy(changecore.bytes,in,2);
    return changecore.param_int16;
}
uint16_t TR_UINT16(uint8_t *in){
    TYPE_UNION changecore={0};
    memcpy(changecore.bytes,in,2);
    return changecore.param_uint16;
}
int32_t TR_INT32(uint8_t *in){
    TYPE_UNION changecore={0};
    memcpy(changecore.bytes,in,4);
    return changecore.param_int32;
}
uint32_t TR_UINT32(uint8_t *in){
    TYPE_UNION changecore={0};
    memcpy(changecore.bytes,in,4);
    return changecore.param_uint32;
}
float TR_FLOAT(uint8_t *in){
    TYPE_UNION changecore={0};
    memcpy(changecore.bytes,in,4);
    return changecore.param_float;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值