OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 5311|回复: 12

求问一个强制转换类型的问题。

[复制链接]

83

主题

217

帖子

0

精华

初级会员

Rank: 2

积分
197
金钱
197
注册时间
2016-4-8
在线时间
116 小时
发表于 2017-2-22 17:41:55 | 显示全部楼层 |阅读模式
1金钱
本帖最后由 vention 于 2017-2-23 11:48 编辑

我定义了一个结构体,总共应该是19个Byte,我再定义一个 20Byte 的 buf数组。
将类开辟空间赋值完后, 强制转换为 unsigned char 后,放进数组buf。
复完值后,我拷贝进去  ac_buf这个数值。  却发现在Frame_CRC 和 Frame_Cmd 之前多了一个Byte,请问是怎么回事。
buf 的0 ~17 个Byte 与 结构体的 前 18个Byte一样。 后面的数值也一样,就是拷贝过去的时候为何中间多了一个Byte?
对比如截图。

unsigned char ac_buf[20]={0};
typedef struct
{
        unsigned char        Frame_FCS;                 
        union_Func_type      Frame_Func;                 
        unsigned short int   Frame_Rvd;         
        unsigned long int    Frame_CID[3];   
        unsigned char        Frame_Cmd;                 
        unsigned short int   Frame_CRC;                 
}Send_Command_Frame_type;    //1Byte + 1Byte + 2Byte + 3*4Byte + 1Byte + 2Byte = 19Byte

Send_Command_Frame_type     *pSend_Command_Frame;

memcpy(ac_buf,pSend_Command_Frame,20);

1.png

最佳答案

查看完整内容[请看2#楼]

unsigned long int Frame_CID[3]; unsigned char Frame_Cmd; unsigned short int Frame_CRC; 这样定义 unsigned char Frame_Cmd; 会多一个字节 ,这是对齐问题,对齐是2的倍数如1 2 4,当中间变量出现单时,如( 双 单 双) 中间的 单 会自动补齐为双字节。
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

17

主题

587

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
4467
金钱
4467
注册时间
2013-6-27
在线时间
565 小时
发表于 2017-2-22 17:41:56 | 显示全部楼层
unsigned long int    Frame_CID[3];   
        unsigned char        Frame_Cmd;                 
        unsigned short int   Frame_CRC;  

这样定义 unsigned char        Frame_Cmd;  会多一个字节 ,这是对齐问题,对齐是2的倍数如1 2 4,当中间变量出现单时,如( 双 单 双) 中间的 单 会自动补齐为双字节。
让我们的思维驾驭在电的速度之上!
回复

使用道具 举报

50

主题

1805

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
6662
金钱
6662
注册时间
2016-5-29
在线时间
910 小时
发表于 2017-2-22 17:48:55 | 显示全部楼层
应该只有字节节数相同.才合适强制转换吧.不然的话怕是会有问题.其实就是一个对齐的问题.
回复

使用道具 举报

19

主题

98

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
308
金钱
308
注册时间
2014-10-19
在线时间
42 小时
发表于 2017-2-22 17:49:23 | 显示全部楼层
这个可能是对齐问题吧 你这个结构体本身就是20个字节的长度
回复

使用道具 举报

83

主题

217

帖子

0

精华

初级会员

Rank: 2

积分
197
金钱
197
注册时间
2016-4-8
在线时间
116 小时
 楼主| 发表于 2017-2-22 17:57:58 | 显示全部楼层
操作系统 发表于 2017-2-22 17:48
应该只有字节节数相同.才合适强制转换吧.不然的话怕是会有问题.其实就是一个对齐的问题.

其实我一开始是 buf是19个字节的。然后就是一直的掉了一个Byte,一直不见一个Byte ,我才把buf弄成 20个字节看下。
回复

使用道具 举报

83

主题

217

帖子

0

精华

初级会员

Rank: 2

积分
197
金钱
197
注册时间
2016-4-8
在线时间
116 小时
 楼主| 发表于 2017-2-22 17:59:03 | 显示全部楼层
漂泊的雨林 发表于 2017-2-22 17:49
这个可能是对齐问题吧 你这个结构体本身就是20个字节的长度

如何计算出结构体本身就是20个字节?? 我就是很奇怪这一点
回复

使用道具 举报

50

主题

1805

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
6662
金钱
6662
注册时间
2016-5-29
在线时间
910 小时
发表于 2017-2-22 18:13:18 | 显示全部楼层
sizeof
回复

使用道具 举报

8

主题

156

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1553
金钱
1553
注册时间
2016-11-21
在线时间
411 小时
发表于 2017-2-22 19:29:59 | 显示全部楼层
在缺省对齐下的三条准则
【1】结构体变量的首地址能够被其最宽基本类型成员的大小所整除
【2】结构体每个成员相对于结构体首地址的偏移量是成员大小的整数背
【3】结构体的总大小为结构体最宽基本类型成员大小的整数背
回复

使用道具 举报

83

主题

217

帖子

0

精华

初级会员

Rank: 2

积分
197
金钱
197
注册时间
2016-4-8
在线时间
116 小时
 楼主| 发表于 2017-2-22 22:17:56 | 显示全部楼层
DongInker 发表于 2017-2-22 20:02
unsigned long int    Frame_CID[3];   
        unsigned char        Frame_Cmd;                 
  ...

明白了,
回复

使用道具 举报

19

主题

98

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
308
金钱
308
注册时间
2014-10-19
在线时间
42 小时
发表于 2017-2-23 08:35:57 | 显示全部楼层
vention 发表于 2017-2-22 17:59
如何计算出结构体本身就是20个字节?? 我就是很奇怪这一点

printf("%d",sizeof(结构体))
回复

使用道具 举报

1

主题

74

帖子

0

精华

初级会员

Rank: 2

积分
127
金钱
127
注册时间
2017-2-9
在线时间
19 小时
发表于 2017-2-23 11:09:25 | 显示全部楼层
楼主,你这有几个问题,首先,这个不叫类,只有在面向对象语言中才会出现类,在C语言这种面向过程的语言中,楼主定义的是结构。虽然感觉没什么,但是会被贻笑大方。第二,楼主结构体定义的有问题,正如大家说的,结构体的定义要按照结构体内容的大小来定义,最好是从小到大,例如:结构体name{unsigned char, unsigned short int ,unsigned int,unsigned long int};这样他的大小是1+2+4+4,如果定义为{unsigned short int ,unsigned char}结构体大小不是2+1,而是2+2。系统会自动将数据空间对齐。第三,楼主在强转的时候最好不要以大空间转小空间,例如你一个unsiged short int 0x0403强转为unsigned char。那转换出来的结果为0x03,而高位的04就会丢失,会造成程序出错。
回复

使用道具 举报

83

主题

217

帖子

0

精华

初级会员

Rank: 2

积分
197
金钱
197
注册时间
2016-4-8
在线时间
116 小时
 楼主| 发表于 2017-2-23 11:54:09 | 显示全部楼层
本帖最后由 vention 于 2017-2-23 11:55 编辑
TGuest 发表于 2017-2-23 11:09
楼主,你这有几个问题,首先,这个不叫类,只有在面向对象语言中才会出现类,在C语言这种面向过程的语言中 ...

谢谢指出。 问题一,确实是我弄错概念名称,在面向对象中才有类的概念。 问题二和三不正确。 在打包数据的时候,没可能将就着从大到小来排列结构体里面的内容。在定义结构体的时候需要用#pragma pack 做对齐就可以,用完再恢复就行了。
回复

使用道具 举报

1

主题

74

帖子

0

精华

初级会员

Rank: 2

积分
127
金钱
127
注册时间
2017-2-9
在线时间
19 小时
发表于 2017-2-23 14:10:36 | 显示全部楼层
vention 发表于 2017-2-23 11:54
谢谢指出。 问题一,确实是我弄错概念名称,在面向对象中才有类的概念。 问题二和三不正确。 在打包数据 ...

所以我说是最好,如果不按照也是可以的,只要知道该怎么算。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-8-23 23:04

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表