user-0 提问: 结构体位域定义的问题

回复:
user: user-1
content: 再供参考：#include <stdio.h> #include <stdlib.h> char buf[17]; union U {   unsigned short int aa;   struct {     unsigned int bb:7;//(bit 0-6)     unsigned int cc:6;//(bit 7-12)     unsigned int dd:3;//(bit 13-15)   }; } u; void main() {                 //bbbbbbbbbbbbbbbb                 //iiiiiiiiiiiiiiii                 //tttttttttttttttt                 //111111                 //5432109876543210                 //::::::::::::::::     u.aa=0xE07F;//1110000001111111     printf("bb==%d,cc==%d,dd==%d\n",u.bb,u.cc,u.dd);     u.bb=0x41;     u.cc=0x21;//dddccccccbbbbbbb     u.dd=5;   //1011000011000001     printf("aa==0x%04X==%016s(2)\n",u.aa,itoa(u.aa,buf,2)); } //bb==127,cc==0,dd==7 //aa==0xB0C1==1011000011000001(2)

user: user-1
content: 仅供参考：#include <stdio.h> #pragma pack(push,1) union U {     unsigned char byte;     struct BF {         unsigned int b0:1;//a         unsigned int b1:1;//b         unsigned int b2:1;//c     } bf; } u; #pragma pack(pop) unsigned char bt; int a,b,c; int main() {     for (bt=0;bt<8;bt++) {         u.byte=(unsigned char)bt;         a=u.bf.b0;         b=u.bf.b1;         c=u.bf.b2;         printf("byte 0x%02x -- c:%d b:%d a:%d\n",bt,c,b,a);     }     for (c=0;c<2;c++)     for (b=0;b<2;b++)     for (a=0;a<2;a++) {         u.bf.b0=a;         u.bf.b1=b;         u.bf.b2=c;         bt=u.byte;         printf("c:%d b:%d a:%d -- byte 0x%02x\n",c,b,a,bt);     }     return 0; } //byte 0x00 -- c:0 b:0 a:0 //byte 0x01 -- c:0 b:0 a:1 //byte 0x02 -- c:0 b:1 a:0 //byte 0x03 -- c:0 b:1 a:1 //byte 0x04 -- c:1 b:0 a:0 //byte 0x05 -- c:1 b:0 a:1 //byte 0x06 -- c:1 b:1 a:0 //byte 0x07 -- c:1 b:1 a:1 //c:0 b:0 a:0 -- byte 0x00 //c:0 b:0 a:1 -- byte 0x01 //c:0 b:1 a:0 -- byte 0x02 //c:0 b:1 a:1 -- byte 0x03 //c:1 b:0 a:0 -- byte 0x04 //c:1 b:0 a:1 -- byte 0x05 //c:1 b:1 a:0 -- byte 0x06 //c:1 b:1 a:1 -- byte 0x07

user: user-2
content: 你看错了吧。short的大小是2个字节啊

user: user-1
content: #include <stdio.h>  typedef unsigned char uchar8; typedef unsigned short uint16;  typedef union {     uchar8 ms1[2];     struct {         uint16  MSTA:6;         uint16  FSEQ:7;         uint16  ISEQ:3;     }; }MSTA_SEQ;  int main(void) {     MSTA_SEQ ms;     ms.ms1[0] = 0xa1;     ms.ms1[1] = 0xa4;      int size;     size = sizeof(MSTA_SEQ);     printf("MSTA = 0x%02x\n",ms.MSTA);     printf("FSEQ = 0x%02x\n",ms.FSEQ);     printf("ISEQ = 0x%02x\n",ms.ISEQ);     printf("size = %d\n",size);     return 0; } //MSTA = 0x21 //FSEQ = 0x12 //ISEQ = 0x05 //size = 2 //

user: user-0
content: #include <stdio.h>   2    3 typedef unsigned char uchar8;   4 typedef unsigned short uint16;   5    6 typedef union   7 {   8     uchar8 ms1[2];   9     struct MS  10     {  11         uint16  MSTA:6;  12         uint16  FSEQ:7;  13         uint16  ISEQ:3;  14     }Ms;  15 }MSTA_SEQ;  16   17 int main(void)  18 {  19     MSTA_SEQ ms;  20     ms.ms1[0] = 0xa1;  21     ms.ms1[1] = 0xa4;  22   23     int size;  24     size = sizeof(ms.Ms);  25     printf("MSTA = %02x\n",ms.Ms.MSTA);  26     printf("FSEQ = %02x\n",ms.Ms.FSEQ);  27     printf("ISEQ = %02x\n",ms.Ms.ISEQ);  28     printf("size = %d\n",size);  29     return 0;  30 }  这样改就可以了 谢谢大家了

user: user-0
content: 引用 3 楼 zhao4zhong1 的回复:再供参考：#include <stdio.h> #include <stdlib.h> char buf[17]; union U {   unsigned short int aa;   struct {     unsigned int bb:7;//(bit 0-6)     unsigned int cc:6;//(bit 7-12)     unsigned int dd:3;//(bit 13-15)   }; } u; void main() {                 //bbbbbbbbbbbbbbbb                 //iiiiiiiiiiiiiiii                 //tttttttttttttttt                 //111111                 //5432109876543210                 //::::::::::::::::     u.aa=0xE07F;//1110000001111111     printf("bb==%d,cc==%d,dd==%d\n",u.bb,u.cc,u.dd);     u.bb=0x41;     u.cc=0x21;//dddccccccbbbbbbb     u.dd=5;   //1011000011000001     printf("aa==0x%04X==%016s(2)\n",u.aa,itoa(u.aa,buf,2)); } //bb==127,cc==0,dd==7 //aa==0xB0C1==1011000011000001(2)   这个是我数据帧结构的其中一个域，占用2个字节，D0-D5表示MSTA；D6-D12表示FSEQ;D13-D15表示ISEQ，我想用那个结构体和联合体来表示这个域 有问题吗？

user: user-3
content: 楼主是想问为什么sizeof(ms)的大小是3吧。  那是因为联合体中Ms结构体定义的类型决定的 假设编译器分配地址从零开始，那么结构体元素位置如下： 地址：0x00                                   0x01                                        0x02 元素：ms1                                   ms2             MSTA（BIT0-bit5）        FSEQ（BIT0-BIT6）             ISEQ（BIT0-BIT2） 因为MSTA共有6位，占据"uchar8"一个字节后剩余2位，不足以存放下FSEQ的7位数据，所以FSEQ会从新的一个地址开始存放。 如果联合体中的uchar8改成uint16就不会有这个问题了。 地址：0x00                                   0x01                                                                              0x02 元素：ms1                                   ms2             MSTA（BIT0-bit5） FSEQ（BIT6-BIT12） ISEQ（BIT13-BIT15）

user: user-4
content: 你看错了吧？运行输出结果为2