打印

一小段困惑的C代码请教

[复制链接]
3060|28
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
if_for|  楼主 | 2017-12-2 16:17 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 if_for 于 2017-12-2 16:30 编辑

最近开发中遇到一个问题不解,跟大家分享请教:
开发环境:Keil MDK 5.15
函数功能:把四个字节的unsigned char转换成unsignedint/float
函数实现方法1:
static uint32_t bytes_to_uint32(const unsigned char * data)
{
        return *(const uint32_t*)(data);
}

static float bytes_to_float(const unsigned char * data)
{
        return *(const float*)(data);
}
这种写**报错---usage fault。
个人觉得这样写应该没有问题的,有点不理解?如果有朋友知道,望不吝赐教。

相关帖子

沙发
hxfxt| | 2017-12-2 17:19 | 只看该作者
你这样访问考虑过剩下三个字节(除了char 本身的1字节)的感受吗?float 和uint32_t 是4字节的,unsigned char是单字节的

使用特权

评论回复
板凳
zxq6| | 2017-12-2 17:21 | 只看该作者
我一般使用联合体

使用特权

评论回复
地板
if_for|  楼主 | 2017-12-2 17:27 | 只看该作者
hxfxt 发表于 2017-12-2 17:19
你这样访问考虑过剩下三个字节(除了char 本身的1字节)的感受吗?float 和uint32_t 是4字节的,unsigned c ...

是这样的,char(1字节)的地址提供一个起始地址,从这个地址开始的4个字节的内容就是目标内容,取出来作为uint32_t返回

使用特权

评论回复
5
if_for|  楼主 | 2017-12-2 17:27 | 只看该作者
zxq6 发表于 2017-12-2 17:21
我一般使用联合体

我试过,使用联合体程序OK。

使用特权

评论回复
6
if_for|  楼主 | 2017-12-2 17:31 | 只看该作者
hxfxt 发表于 2017-12-2 17:19
你这样访问考虑过剩下三个字节(除了char 本身的1字节)的感受吗?float 和uint32_t 是4字节的,unsigned c ...

使用联合体来实现这个功能是没问题的,只是感觉奇怪,用指针应该也是没问题的,可偏偏有问题?

使用特权

评论回复
7
linqing171| | 2017-12-2 19:19 | 只看该作者
地址不四字节对齐的原因,加pack修饰指针。

使用特权

评论回复
8
zyj9490| | 2017-12-2 21:53 | 只看该作者
如果传进去是连续的字节数组常量,应是可以的,如果不是,还是内存溢出的问题。

使用特权

评论回复
9
hxfxt| | 2017-12-2 22:18 | 只看该作者
if_for 发表于 2017-12-2 17:31
使用联合体来实现这个功能是没问题的,只是感觉奇怪,用指针应该也是没问题的,可偏偏有问题? ...

联合体你放个4字节的放个单字节的,分配的内存空间当然是4字节的!你上面的程序其余三字节的访问你绝的合理吗?你知道那三字节原先放的什么东西吗?

使用特权

评论回复
10
hxfxt| | 2017-12-2 22:25 | 只看该作者
if_for 发表于 2017-12-2 17:27
是这样的,char(1字节)的地址提供一个起始地址,从这个地址开始的4个字节的内容就是目标内容,取出来作 ...

那后面的地址空间你确定放的什么东西吗?是否允许访问呢?

使用特权

评论回复
11
renxiaolin| | 2017-12-2 22:53 | 只看该作者
不要学c了,没前途

使用特权

评论回复
12
if_for|  楼主 | 2017-12-3 17:09 | 只看该作者
hxfxt 发表于 2017-12-2 22:18
联合体你放个4字节的放个单字节的,分配的内存空间当然是4字节的!你上面的程序其余三字节的访问你绝的合 ...

u8 部分是数组,所以是连续的

使用特权

评论回复
13
renxiaolin| | 2017-12-3 18:00 | 只看该作者
浮点型在内存的表示跟整型不一样,你看看是不是这个问题

使用特权

评论回复
14
computer00| | 2017-12-4 09:33 | 只看该作者
有可能是对齐问题。一般处理器要求在访问int或float时,地址需要4字节对齐,如果不对齐,就会抛异常。
最好是先定义好一个int或float型数据,然后用memcpy把目标数据拷贝进去,这样就不存在对齐问题了。

static uint32_t bytes_to_uint32(const unsigned char * data) {
         uint32_t ret;
         memcpy(&ret, data, sizeof(ret);
         return ret;
}

static float bytes_to_float(const unsigned char * data) {
         float ret;
         memcpy(&ret, data, sizeof(ret);
         return ret;
}

使用特权

评论回复
15
icz| | 2017-12-4 16:41 | 只看该作者
以指针访问数据是要和指针的原型相同且地址是分配好的才行,有疑问联系我,微信:jyucyz

使用特权

评论回复
16
ta1ent| | 2017-12-4 20:37 | 只看该作者
还是老老实实用联合比较好,这样写会出现一些莫名其妙的内存错误。

使用特权

评论回复
17
xcvista| | 2017-12-4 21:40 | 只看该作者
估计是内存对齐的问题。ARM Cortex-M 默认不允许非对齐访问,访问 4 字节的 uint32_t 地址必须是对齐到 4 字节。你可以用联合,也可以用 memcpy。

使用特权

评论回复
18
xcvista| | 2017-12-4 21:45 | 只看该作者
renxiaolin 发表于 2017-12-2 22:53
不要学c了,没前途

那么您建议学什么?

使用特权

评论回复
19
@若水| | 2017-12-4 22:14 | 只看该作者
zxq6 发表于 2017-12-2 17:21
我一般使用联合体

我也是

使用特权

评论回复
20
renxiaolin| | 2017-12-5 08:35 | 只看该作者
xcvista 发表于 2017-12-4 21:45
那么您建议学什么?

python,golang

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

15

主题

111

帖子

2

粉丝