注册 登录
查看: 1285|回复: 28

【每日一思】联合体类型转换的问题

[复制链接]
发表于 2013-11-19 20:10:59 | 显示全部楼层 |阅读模式
山外 K60 的代码,有点奇怪,看看大家能不能 想出原因:

已经定义了这么一个宏定义:
  1. /*
  2. * 定义带位域的联合体类型
  3. */
  4. typedef union
  5. {
  6.     uint32  DW;
  7.     uint16  W[2];
  8.     uint8   B[4];
  9.     struct
  10.     {
  11.         uint32 b0: 1;
  12.         uint32 b1: 1;
  13.         uint32 b2: 1;
  14.         uint32 b3: 1;
  15.         uint32 b4: 1;
  16.         uint32 b5: 1;
  17.         uint32 b6: 1;
  18.         uint32 b7: 1;
  19.         uint32 b8: 1;
  20.         uint32 b9: 1;
  21.         uint32 b10: 1;
  22.         uint32 b11: 1;
  23.         uint32 b12: 1;
  24.         uint32 b13: 1;
  25.         uint32 b14: 1;
  26.         uint32 b15: 1;
  27.         uint32 b16: 1;
  28.         uint32 b17: 1;
  29.         uint32 b18: 1;
  30.         uint32 b19: 1;
  31.         uint32 b20: 1;
  32.         uint32 b21: 1;
  33.         uint32 b22: 1;
  34.         uint32 b23: 1;
  35.         uint32 b24: 1;
  36.         uint32 b25: 1;
  37.         uint32 b26: 1;
  38.         uint32 b27: 1;
  39.         uint32 b28: 1;
  40.         uint32 b29: 1;
  41.         uint32 b30: 1;
  42.         uint32 b31: 1;
  43.     };
  44. } Dtype;    //sizeof(Dtype) 为 4
然后 利用这个 联合体 来操作 位,从而达到类似 51风格 的 IO 操作:
  1. #define PT(X,n,REG)         (((Dtype *)(&(PT##X##_BASE_PTR->##REG)))->b##n)
呵呵,这段代码,大家看看有没有问题?或者 与常规代码 有异常 的地方? 答案暂时不公开

本帖被以下淘专辑推荐:

回复

使用道具 举报

发表于 2013-11-19 20:11:10 | 显示全部楼层
学习了,不错,讲的太有道理了
回复 支持 反对

使用道具 举报

 楼主| 发表于 2013-11-19 20:16:10 | 显示全部楼层
本帖最后由 山外メ雲ジ 于 2013-11-19 20:17 编辑

这个宏定义,用到了强制类型转换

大家留意一下这个代码:
  1. (Dtype *)&
为什么 要取地址 然后 用指针进行操作?

代码直接这样子不行吗?
  1. #define PT(X,n,REG)         (((Dtype )(PT##X##_BASE_PTR->##REG))->b##n)
如果是这样,会编译出错的,原因是???
回复 支持 反对

使用道具 举报

发表于 2013-11-20 00:46:46 | 显示全部楼层
比妹子还漂亮,赞一个  
回复 支持 反对

使用道具 举报

发表于 2013-11-20 00:56:14 | 显示全部楼层
好难懂, 类似 51风格 的 IO 操作? 是要对寄存器一位一位赋值?
回复 支持 反对

使用道具 举报

发表于 2013-11-20 22:56:03 | 显示全部楼层
这题目太难了
回复 支持 反对

使用道具 举报

发表于 2013-11-21 20:02:19 | 显示全部楼层
额?我的怎么显示是8???
这是我在C-free上面验证的代码和结果
  1. /*
  2. * 定义带位域的联合体类型
  3. */
  4. #include <stdio.h>
  5. #define uint32 long int
  6. #define uint16 int
  7. #define uint8        char
  8. typedef union
  9. {
  10.     uint32  DW;
  11.     uint16  W[2];
  12.     uint8   B[4];
  13.     struct
  14.     {
  15.         uint32 b0: 1;
  16.         uint32 b1: 1;
  17.         uint32 b2: 1;
  18.         uint32 b3: 1;
  19.         uint32 b4: 1;
  20.         uint32 b5: 1;
  21.         uint32 b6: 1;
  22.         uint32 b7: 1;
  23.         uint32 b8: 1;
  24.         uint32 b9: 1;
  25.         uint32 b10: 1;
  26.         uint32 b11: 1;
  27.         uint32 b12: 1;
  28.         uint32 b13: 1;
  29.         uint32 b14: 1;
  30.         uint32 b15: 1;
  31.         uint32 b16: 1;
  32.         uint32 b17: 1;
  33.         uint32 b18: 1;
  34.         uint32 b19: 1;
  35.         uint32 b20: 1;
  36.         uint32 b21: 1;
  37.         uint32 b22: 1;
  38.         uint32 b23: 1;
  39.         uint32 b24: 1;
  40.         uint32 b25: 1;
  41.         uint32 b26: 1;
  42.         uint32 b27: 1;
  43.         uint32 b28: 1;
  44.         uint32 b29: 1;
  45.         uint32 b30: 1;
  46.         uint32 b31: 1;
  47.     };
  48. } Dtype;
  49. main()
  50. {
  51.         Dtype a;
  52.         printf("%d",sizeof(a));
  53.         printf("\n%d",sizeof(Dtype));
  54. }
两个结果都显示了是8
回复 支持 反对

使用道具 举报

发表于 2013-11-22 13:21:07 | 显示全部楼层
wkhuahuo 发表于 2013-11-21 20:02
额?我的怎么显示是8???
这是我在C-free上面验证的代码和结果两个结果都显示了是8

一般和你的编译器和OS有关吧,要么是你的编译器int就是64位,要么是你64位OS。。
回复 支持 反对

使用道具 举报

发表于 2013-11-24 20:30:55 | 显示全部楼层
wkhuahuo 发表于 2013-11-21 20:02
额?我的怎么显示是8???
这是我在C-free上面验证的代码和结果两个结果都显示了是8

#define uint16 int

你的编译器 ,int 是 32位的,所以最终就是 8
回复 支持 反对

使用道具 举报

发表于 2013-11-25 09:53:52 | 显示全部楼层
Admin 发表于 2013-11-24 20:30
#define uint16 int

你的编译器 ,int 是 32位的,所以最终就是 8

走过路过,不能错过
回复 支持 反对

使用道具 举报

发表于 2013-11-25 09:57:30 | 显示全部楼层
Admin 发表于 2013-11-24 20:30
#define uint16 int

你的编译器 ,int 是 32位的,所以最终就是 8

#define uint16 int
回复 支持 反对

使用道具 举报

发表于 2013-11-25 12:26:07 | 显示全部楼层
火弟 发表于 2013-11-25 09:57
#define uint16 int

16位的定义,一般都定义为:
  1. typedef short int uint16
因为标准C语言没有 规定 int 类型的大小,但规定 short int 是 16位 ,long int 是 32位。

有些编译器,int 是 16位,有些编译器是32位。

另外,不推荐用宏定义来定义类型,改用 typedef
回复 支持 反对

使用道具 举报

发表于 2013-12-29 23:43:40 | 显示全部楼层
来学习一下 一直想弄懂这个
回复 支持 反对

使用道具 举报

发表于 2014-1-8 13:39:55 | 显示全部楼层
学习一下,不过还是没看明白,这个是不是能够用在一般的联合体中?
回复 支持 反对

使用道具 举报

发表于 2014-1-18 16:58:48 | 显示全部楼层
没有弄明白,能不能解答一下?
回复 支持 反对

使用道具 举报

发表于 2014-3-10 23:06:40 | 显示全部楼层
好内容值得分享!  山外哥!帅呆了,赞一个
回复 支持 反对

使用道具 举报

发表于 2014-3-25 20:06:52 | 显示全部楼层
向山外哥学习
回复 支持 反对

使用道具 举报

发表于 2014-3-25 21:19:49 | 显示全部楼层
走过路过,不能错过
回复 支持 反对

使用道具 举报

发表于 2014-3-27 15:04:36 | 显示全部楼层
向山外哥学习
回复 支持 反对

使用道具 举报

发表于 2014-4-7 18:23:12 | 显示全部楼层
((Dtype *)(&PTX_BASE_PTR->REG)->bn)
回复 支持 反对

使用道具 举报

发表于 2014-4-11 15:36:47 | 显示全部楼层
走过路过,不能错过表示没懂
回复 支持 反对

使用道具 举报

发表于 2015-4-26 16:40:03 | 显示全部楼层
学习了,不错
回复 支持 反对

使用道具 举报

发表于 2015-4-28 11:13:40 | 显示全部楼层
结构体没名字啊
来自安卓客户端来自安卓客户端
回复 支持 反对

使用道具 举报

发表于 2015-10-31 16:13:21 | 显示全部楼层
赞啊
回复 支持 反对

使用道具 举报

发表于 2015-10-31 16:41:19 | 显示全部楼层
想知道为什么a !!
回复 支持 反对

使用道具 举报

发表于 2016-2-10 11:29:59 | 显示全部楼层
不清楚
回复 支持 反对

使用道具 举报

发表于 2016-4-10 21:15:35 | 显示全部楼层
看看先 看看
回复 支持 反对

使用道具 举报

发表于 2016-5-21 20:11:48 | 显示全部楼层
每天进步一点点
回复 支持 反对

使用道具 举报

发表于 2016-9-30 10:55:55 | 显示全部楼层

走过路过,不能错过
回复 支持 反对

使用道具 举报

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

本版积分规则

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