C-struct-位段、无名字段以及填充字段

zdx_register 2016-07-01 09:11:12

#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




...全文
180 2 打赏 收藏 转发到动态 举报
写回复
用AI写文章
2 条回复
切换为时间正序
请发表友善的回复…
发表回复
lm_whales 2016-07-01
  • 打赏
  • 举报
回复
位段的位顺序,由实现决定 也就说说 位段中,字节顺序位顺序。都是不确定的,由具体实现觉得。
赵4老师 2016-07-01
  • 打赏
  • 举报
回复
仅供参考:
#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、编译器、调试器、运行结果。 并请结合“盲人摸太阳”和“驾船出海时一定只带一个指南针。”加以理解。 任何理论、权威、传说、真理、标准、解释、想象、知识……都比不上摆在眼前的事实!

69,382

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧