#include <stdio.h> /* *结构体中允许存在位段、无名字段以及字对齐所需的填充字段。 *位段的类型必须是int, unsigned int或signed int(或加上限定符)。 *至于int位段的值可不可以取负值取决于编译器。 *在使用位段时,要考虑字对齐的问题。系统默认的是4字节对齐。 * */ //4Bytes struct S1 { unsigned int inactive : 1; // 分配1个bit }; //4Bytes struct S2 { unsigned int inactive : 1; // 分配1个bit short id; // 与inactive共用4个Bytes }; //2Bytes struct S3 { short id; }; //4Bytes struct S4 { unsigned int inactive : 1; // 分配1个bit short id; // 与inactive共用4个Bytes unsigned int : 0; // 填充到下一个字边界 }; //8Bytes struct S5 { unsigned int inactive : 1; // 分配1个bit unsigned int : 0; // 填充到下一个字边界 short id; // 占用下1个新的4个Bytes(字对齐) }; //8Bytes struct S6 { unsigned int inactive : 1; // 分配1个bit unsigned int : 0; // 填充到下一个字边界 unsigned int new_Bytes : 1; // 占用新的4个Bytes unsigned int new_Bytes1 : 1; // 与new_Bytes共用1个Bytes short id; // 与new_BYtes,new_Bytes1共用1个Bytes }; //12Bytes struct S7 { unsigned int inactive : 1; // 分配1个bit unsigned int : 0; // 填充到下一个字边界 unsigned int new_Bytes : 1; // 占用新的4个Bytes short id; // 与new_BYtes共用1个Bytes unsigned int new_Bytes1 : 1; // 占用1个新的4个Bytes }; int main() { printf("short = %d Bytes\n", sizeof(short)); printf("unsigned int = %d Bytes\n", sizeof(unsigned int)); printf("S1 = %d Bytes\n", sizeof(struct S1)); printf("S2 = %d Bytes\n", sizeof(struct S2)); printf("S3 = %d Bytes\n", sizeof(struct S3)); printf("S4 = %d Bytes\n", sizeof(struct S4)); printf("S5 = %d Bytes\n", sizeof(struct S5)); printf("S6 = %d Bytes\n", sizeof(struct S6)); printf("S7 = %d Bytes\n", sizeof(struct S7)); return 0; } e:\Workspace\Others\C\Struct>g++ struct.c -o struct e:\Workspace\Others\C\Struct>struct short = 2 Bytes unsigned int = 4 Bytes S1 = 4 Bytes S2 = 4 Bytes S3 = 2 Bytes S4 = 4 Bytes S5 = 8 Bytes S6 = 8 Bytes S7 = 12 Bytes
解决方案
30
仅供参考:
#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
再供参考:
#include <stdio.h> #define field_offset(s,f) (int)(&(((struct s *)(0))->f)) struct AD { int a; char b[13]; double c;}; #pragma pack(push) #pragma pack(1) struct A1 { int a; char b[13]; double c;}; #pragma pack(2) struct A2 { int a; char b[13]; double c;}; #pragma pack(4) struct A4 { int a; char b[13]; double c;}; #pragma pack(8) struct A8 { int a; char b[13]; double c;}; #pragma pack(16) struct A16 { int a; char b[13]; double c;}; #pragma pack(pop) int main() { printf("AD.a %d\n",field_offset(AD,a)); printf("AD.b %d\n",field_offset(AD,b)); printf("AD.c %d\n",field_offset(AD,c)); printf("AD sizeof %d\n", sizeof(AD)); printf("\n"); printf("A1.a %d\n",field_offset(A1,a)); printf("A1.b %d\n",field_offset(A1,b)); printf("A1.c %d\n",field_offset(A1,c)); printf("A1 sizeof %d\n", sizeof(A1)); printf("\n"); printf("A2.a %d\n",field_offset(A2,a)); printf("A2.b %d\n",field_offset(A2,b)); printf("A2.c %d\n",field_offset(A2,c)); printf("A2 sizeof %d\n", sizeof(A2)); printf("\n"); printf("A4.a %d\n",field_offset(A4,a)); printf("A4.b %d\n",field_offset(A4,b)); printf("A4.c %d\n",field_offset(A4,c)); printf("A4 sizeof %d\n", sizeof(A4)); printf("\n"); printf("A8.a %d\n",field_offset(A8,a)); printf("A8.b %d\n",field_offset(A8,b)); printf("A8.c %d\n",field_offset(A8,c)); printf("A8 sizeof %d\n", sizeof(A8)); printf("\n"); printf("A16.a %d\n",field_offset(A16,a)); printf("A16.b %d\n",field_offset(A16,b)); printf("A16.c %d\n",field_offset(A16,c)); printf("A16 sizeof %d\n", sizeof(A16)); printf("\n"); return 0; } //AD.a 0 //AD.b 4 //AD.c 24 //AD sizeof 32 // //A1.a 0 //A1.b 4 //A1.c 17 //A1 sizeof 25 // //A2.a 0 //A2.b 4 //A2.c 18 //A2 sizeof 26 // //A4.a 0 //A4.b 4 //A4.c 20 //A4 sizeof 28 // //A8.a 0 //A8.b 4 //A8.c 24 //A8 sizeof 32 // //A16.a 0 //A16.b 4 //A16.c 24 //A16 sizeof 32 // //
不要迷信书、考题、老师、回帖;
要迷信CPU、编译器、调试器、运行结果。
并请结合“盲人摸太阳”和“驾船出海时一定只带一个指南针。”加以理解。
任何理论、权威、传说、真理、标准、解释、想象、知识……都比不上摆在眼前的事实!
10
位段的位顺序,由实现决定
也就说说
位段中,字节顺序,位顺序。都是不确定的,由具体实现觉得。
也就说说
位段中,字节顺序,位顺序。都是不确定的,由具体实现觉得。