user-0 提问: C语言位域问题

回复:
user: user-1
content: 位域的长度最大为int 或者 最长整数 这应该也是实现定义的吧

user: user-1
content: 你先把位域设成8Byte 的看看是什么结果 然后再设成6Bits的，这样就好理解了  union bs64{ struct base64{         unsigned  d1:6;         unsigned  d2:6;         unsigned  d3:6;         unsigned  d4:6;          } bs6; struct base64{         unsigned  c1:8;         unsigned  c2:8;         unsigned  c3:8;         unsigned  c4:8;      } bs8; };  bs64 *p =“123456”; 这样看看

user: user-2
content: http://blog.sina.com.cn/s/blog_3d8529400100istl.html

user: user-2
content: 1. 一个位域必须存储在同一个字节中，不能跨两个字节。如一个字节所剩空间不够存放另一位域时，应从下一单元起存放该位域。也可以有意使某位域从下一单元开始。 2. 由于位域不允许跨两个字节，因此位域的长度不能大于一个字节的长度，也就是说不能超过8位二进位。

user: user-0
content: 上面的程序中buf指向的是 "qwertyui" 这个字符串。我的理解是，如果将buf 强转成（struct base64*)  再赋值给 bs; 应该是将buf 的前三位 "qwe"  直接赋值给了bs， 但qwe的整个编码是  qwe_buf 表示的一长串二进制数，如果按qwe_buf 对bs赋值， 结果应该是 演示中的第一种行情况。 但实际上，是将ewq_buf 从后往前依次赋给了bs，也就是演示中的第二种情况，这里不明白为什么会这样。

user: user-0
content: #include <stdio.h> #include <stdlib.h> #include <string.h>   struct base64{         unsigned  d1:1;         unsigned  d2:1;         unsigned  d3:1;         unsigned  d4:1;         unsigned  d5:1;         unsigned  d6:1;         unsigned  d7:1;         unsigned  d8:1;         unsigned  d9:1; };  int main() {     char buf[10]="qwertyui";     struct base64 *bs=(struct base64 *)buf;     printf("d1=%u ,d2=%u, d3=%u, d4=%u\n",bs->d1,bs->d2,bs->d3,bs->d4);     printf("d5=%u ,d6=%u, d7=%u, d8=%u d9=%d\n",bs->d5,bs->d6,bs->d7,bs->d8,bs->d9); }   运行结果： d1=1 ,d2=0, d3=0, d4=0 d5=1 ,d6=1, d7=1, d8=0 d9=1

user: user-0
content: 发这个帖子是想知道位域的赋值方式。 即对整个结构体赋值时，结构体里面的每个成员是怎样得到数据的； 感谢6楼的提示，感谢各位的回帖；  其实赋值的顺序并没有改变  就是 qwe_buf的数据； 改变的是赋值的方式： q=01110001 w=01110111 e=01100101  qwe的二进制编码如上； 读取第一个字节q的数据  从低位开始到高位依次赋给d1的6个bit位，而d1在接收的时候也是从低位到高位存储接收到的数据，q中剩余的2位赋值给d2中最低的2个bit位； 读取第二个字节时也是按照上面的方式进行赋值。  感谢各位的支持，上面是个人理解，若有不对的地方还请指正。

user: user-1
content: #include <iostream> #include <iomanip>  template <typename T> void print(const T&t,std::ostream&os = std::cout, const char *prefix=" ",const char *postfix ="\n") {     os<<prefix<<" dec:"<<std::setw(6)<<std::setfill(' ')<<dec<<t<<" hex:0x"<<hex<<std::setw(2)<<std::setfill('0')<<t<<postfix; }  #define print_all(x) do{print(x##1),print(x##2),print(x##3),print(x##4);}while(0)  int main() {    /// sales s;      union bs64{ struct base64{         unsigned  d1:6;         unsigned  d2:6;         unsigned  d3:6;         unsigned  d4:6;  } bs6; struct base64_1{         unsigned  c1:8;         unsigned  c2:8;         unsigned  c3:8;         unsigned  c4:8;      } bs8;  struct base64_2{         unsigned  h1:16;         unsigned  h2:16;         unsigned  h3:16;         unsigned  h4:16;      } bs16; };  bs64 *p =(bs64 *)"12345678"; print_all(p->bs6.d); print_all(p->bs8.c); print_all(p->bs16.h);      return 0; }  输出：     dec:    49 hex:0x31   dec:     8 hex:0x08   dec:    51 hex:0x33   dec:    12 hex:0x0c   dec:    49 hex:0x31   dec:    50 hex:0x32   dec:    51 hex:0x33   dec:    52 hex:0x34   dec: 12849 hex:0x3231   dec: 13363 hex:0x3433   dec: 13877 hex:0x3635   dec: 14391 hex:0x3837  分析，这个X86 上的Windows 上的code::blocks 自带的编译器 位域的字节序，按照 Intel 字节序处理，位序从低到高诸位占用。 第一个6Bits占用最低地址的低6Bits 第二个6Bits占用低字节2Bits高位，第二字节的4Bits 低位 第三个6Bits占用第二字节高4Bits，第三字节低2Bits 第四个6Bits占用第三个字节高6Bits 一共占有24Bits

user: user-1
content: 位域 的位顺序，和字节顺序，是由实现决定的 uinion { struct { unsigned char a:1; }b; unsigned char uc; unsigned int ui;  }; b.a=1; // ui  可能是 1,也可能是0x80000000;

user: user-3
content: 一个位域必须存储在同一个字节中，不能跨两个字节。如一个字节所剩空间不够存放另一位域时，应从下一单元起存放该位域.