免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 4349 | 回复: 11
打印 上一主题 下一主题

[C] 关于位结构体的一个问题的研究 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2010-06-07 14:23 |只看该作者 |倒序浏览
不知道大家考虑过没有,一个为结构体成员,在字节内部,是从高位开始,还是从地位开始这个问题。

我在AMD 64上做了个测试,代码如下:
  1. int main(int argc,char * argv[])
  2. {
  3.     union
  4.     {
  5.         unsigned char c;
  6.         struct Tag
  7.         {
  8.             unsigned char a:1;
  9.             unsigned char b:6;
  10.             unsigned char c:1;
  11.         } m_tag;
  12.     }tag;
  13.     tag.c=0x1;//10100001
  14.     std::cout<<int(tag.m_tag.a)<<","<<int(tag.m_tag.b)<<","<<int(tag.m_tag.c)<<std::endl;   
  15.    
  16.     return 0;
  17. }
复制代码
输出为:1,0,0

那么就意味着,在我的系统中,先声明的位成员变量在字节的低有效位,而后声明的位成员变量在高有效位上。

我的系统是:
操作系统:winxp 32位
CPU:AMD64

操作系统:Ubuntu 64位
CPU:AMD64

不知道在其他系统和CPU下,该代码的输出结果是否一致?
请有条件的朋友帮忙测试一下。谢谢。

最好有惠普安藤或者Sun的SPARC、IBM小型机等的系统测试结果。

论坛徽章:
324
射手座
日期:2013-08-23 12:04:38射手座
日期:2013-08-23 16:18:12未羊
日期:2013-08-30 14:33:15水瓶座
日期:2013-09-02 16:44:31摩羯座
日期:2013-09-25 09:33:52双子座
日期:2013-09-26 12:21:10金牛座
日期:2013-10-14 09:08:49申猴
日期:2013-10-16 13:09:43子鼠
日期:2013-10-17 23:23:19射手座
日期:2013-10-18 13:00:27金牛座
日期:2013-10-18 15:47:57午马
日期:2013-10-18 21:43:38
2 [报告]
发表于 2010-06-07 14:40 |只看该作者
这个由编译器决定的,没有可移植性

论坛徽章:
0
3 [报告]
发表于 2010-06-07 14:42 |只看该作者
这个由编译器决定的,没有可移植性
hellioncu 发表于 2010-06-07 14:40



    我觉得是由CPU决定的,所以想证明一下。

论坛徽章:
324
射手座
日期:2013-08-23 12:04:38射手座
日期:2013-08-23 16:18:12未羊
日期:2013-08-30 14:33:15水瓶座
日期:2013-09-02 16:44:31摩羯座
日期:2013-09-25 09:33:52双子座
日期:2013-09-26 12:21:10金牛座
日期:2013-10-14 09:08:49申猴
日期:2013-10-16 13:09:43子鼠
日期:2013-10-17 23:23:19射手座
日期:2013-10-18 13:00:27金牛座
日期:2013-10-18 15:47:57午马
日期:2013-10-18 21:43:38
4 [报告]
发表于 2010-06-07 14:45 |只看该作者
没有所有的测试环境,怎么证明?证明了又有什么意义呢

论坛徽章:
0
5 [报告]
发表于 2010-06-07 15:13 |只看该作者
没有所有的测试环境,怎么证明?证明了又有什么意义呢
hellioncu 发表于 2010-06-07 14:45



    懒得跟你争论。

论坛徽章:
0
6 [报告]
发表于 2010-06-07 15:23 |只看该作者
回复 1# fibbery


    这就涉及到内存大小端模式的问题了,CPU体系结构决定的了,,在X86和MIPS,等都是小端模式,,,
   你测试的结果也应该说明你的CPU是小端模式。数据低位放在低地址。。。

论坛徽章:
0
7 [报告]
发表于 2010-06-07 16:06 |只看该作者
单就一个字节,不存在啥大小端的问题吧。
你得分配至少2个字节才看的出来。

论坛徽章:
0
8 [报告]
发表于 2010-06-07 22:25 |只看该作者
这个应该是由体系架构决定的。以前我做过类似的测试,在同一台机器(比如Power服务器)上,无论使用哪种OS(AIX/Linux),哪种编译器(xl C/gcc),出来的结果一样。
现在手头只有AIX + xl C/C++编译器的环境,把结果贴出来。(程序我略微改了下)
  1. #include <iostream>

  2. int main(int argc,char * argv[])
  3. {
  4.     union
  5.     {
  6.         unsigned char c;
  7.         struct Tag
  8.         {
  9.             unsigned char a:2;
  10.             unsigned char b:4;
  11.             unsigned char c:2;
  12.         } m_tag;
  13.     }tag;
  14.     tag.c=0xA3;//10100011
  15.     std::cout<<int(tag.m_tag.a)<<","<<int(tag.m_tag.b)<<","<<int(tag.m_tag.c)<<std::endl;   
  16.    
  17.     return 0;
  18. }
复制代码
[shiyb /home/shiyb/test/bitfield] $ xlC test1.cpp
[shiyb /home/shiyb/test/bitfield] $ ./a.out
2,8,3

在我的AMD64 虚拟机 + SLES11 + gcc 上,上述程序的结果为:
shiyb@SLES1:~/test/bitfield> g++ test1.cpp
shiyb@SLES1:~/test/bitfield> ./a.out
3,8,2

从上面的情况可以看出,在同一个字节内部,对于bitfield来说,大端序和小端序的影响也是不可忽视的。
因此,考虑到跨平台的问题,在不是非常必要时,我一般不在涉及到不同机器间通讯的数据结构中使用bitfield。
在使用时,一个需要特别强调的事情是:千万别让 bitfield跨字节边界,否则,处理起来非常麻烦。

论坛徽章:
0
9 [报告]
发表于 2010-06-08 09:37 |只看该作者
跟大小端是一样的

论坛徽章:
2
技术图书徽章
日期:2013-09-04 15:21:51酉鸡
日期:2013-11-01 21:20:20
10 [报告]
发表于 2010-06-08 11:57 |只看该作者
与cpu的架构有关。所以所有的os都有主机转网络字节顺序的函数。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP