指定struct成员变量的位数

        在定义结构体的时候,我们在指定成员变量的类型的同时也可以指定成员变量所占的位数,其定义形式为:

struct teststruct
{
       类型1 成员1 :成员1所占位数;
       类型2 成员2 :成员2所占位数;
       类型3 成员3 :成员3所占位数;
       ......
};

虽然拆分基本成员变量在语法上是得到支持的,但是并不等于我们想怎么分就怎么分,例如下面的拆分显然是不合理的: 
struct student 
{ 
       unsigned short sex : 1;  
       unsigned short age : 12; 
}; 
这是因为 1+12 = 13(但是这个结构所占的空间很可能是2个字节而不是13位),不能再组合成一个基本成员,不能组合成 char、int 或任何类型, 拆分的位数应该是合乎逻辑的,应仍然可以组合为基本成员变量 ( 这个和编译器的字节对齐属性有关)。


测试代码:

#include <stdio.h>

typedef struct teststruct
{
    unsigned int val1 : 1;
    unsigned int val2 : 2;
    unsigned int val3 : 29;
}TS;

int main()
{
    TS tmp;
    
    printf("size of TS: %d\n",sizeof(tmp));
    printf("size of unsigned int: %d\n",sizeof(unsigned int));
    
    tmp.val1 = 2;
    tmp.val2 = 5;
    tmp.val3 = 999;
    
    printf("val1:%d,val2:%d,val3:%d\n",tmp.val1,tmp.val2,tmp.val3);
    
    system("pause");
    return 0;
}    

输出:

size of TS: 4

size of unsigned int: 4

val1:0,val2:1,val3:999

val1只占一位,2的二进制为10,故而val1的值为0,val2同理。


参考:http://www.cnblogs.com/mashang/archive/2011/03/24/1993513.html


题目:结构体成员对齐方式的影响 核心程序段代码: ```c #include <stdio.h> // 定义结构体并设置成员变量 #pragma pack(1) struct stru1 { char a; char b; int c; long long d; char e; short f; short g; } x; int main() { // 输出默认对齐方式下的起始地址和变量大小 printf("默认对齐方式:\n"); printf("x.a 地址:%p\n", &x.a); printf("x.b 地址:%p\n", &x.b); printf("x.c 地址:%p\n", &x.c); printf("x.d 地址:%p\n", &x.d); printf("x.e 地址:%p\n", &x.e); printf("x.f 地址:%p\n", &x.f); printf("x.g 地址:%p\n", &x.g); printf("变量大小:%d\n\n", sizeof(x)); // 输出1字节对齐方式下的起始地址和变量大小 #pragma pack(1) printf("1字节对齐方式:\n"); printf("x.a 地址:%p\n", &x.a); printf("x.b 地址:%p\n", &x.b); printf("x.c 地址:%p\n", &x.c); printf("x.d 地址:%p\n", &x.d); printf("x.e 地址:%p\n", &x.e); printf("x.f 地址:%p\n", &x.f); printf("x.g 地址:%p\n", &x.g); printf("变量大小:%d\n\n", sizeof(x)); // 输出2字节对齐方式下的起始地址和变量大小 #pragma pack(2) printf("2字节对齐方式:\n"); printf("x.a 地址:%p\n", &x.a); printf("x.b 地址:%p\n", &x.b); printf("x.c 地址:%p\n", &x.c); printf("x.d 地址:%p\n", &x.d); printf("x.e 地址:%p\n", &x.e); printf("x.f 地址:%p\n", &x.f); printf("x.g 地址:%p\n", &x.g); printf("变量大小:%d\n\n", sizeof(x)); // 输出4字节对齐方式下的起始地址和变量大小 #pragma pack(4) printf("4字节对齐方式:\n"); printf("x.a 地址:%p\n", &x.a); printf("x.b 地址:%p\n", &x.b); printf("x.c 地址:%p\n", &x.c); printf("x.d 地址:%p\n", &x.d); printf("x.e 地址:%p\n", &x.e); printf("x.f 地址:%p\n", &x.f); printf("x.g 地址:%p\n", &x.g); printf("变量大小:%d\n\n", sizeof(x)); // 输出8字节对齐方式下的起始地址和变量大小 #pragma pack(8) printf("8字节对齐方式:\n"); printf("x.a 地址:%p\n", &x.a); printf("x.b 地址:%p\n", &x.b); printf("x.c 地址:%p\n", &x.c); printf("x.d 地址:%p\n", &x.d); printf("x.e 地址:%p\n", &x.e); printf("x.f 地址:%p\n", &x.f); printf("x.g 地址:%p\n", &x.g); printf("变量大小:%d\n\n", sizeof(x)); return 0; } ``` 运行平台说明:Windows 10,Visual Studio 2019,64位 查看截图: ![成员对齐方式影响图](https://img-blog.csdnimg.cn/20211104184404110.png) X成员变量的内存地址分配表: | 成员变量 | 默认对齐 | 1字节对齐 | 2字节对齐 | 4字节对齐 | 8字节对齐 | | :------: | :------: | :-------: | :-------: | :-------: | :-------: | | a | 0 | 0 | 0 | 0 | 0 | | b | 1 | 1 | 1 | 1 | 1 | | c | 2 | 2 | 2 | 4 | 4 | | d | 4 | 4 | 4 | 8 | 8 | | e | 12 | 5 | 5 | 9 | 9 | | f | 14 | 7 | 7 | 10 | 10 | | g | 16 | 8 | 8 | 12 | 12 | 必要的文字说明: 本程序定义了一个结构体 `stru1`,其中包含7个成员变量,字节数依次为:1、1、4、8、1、2和2。然后通过不同对齐方式的设置,查看结构体变量X和Y的起始存储地址、结构体X所内存的字节总数以及其各成员变量的内存地址,最后画出X成员变量的内存地址分配表。 根据运行结果可以看出,不同的对齐方式会影响结构体成员变量的内存地址分配,从而影响结构体变量的大小。这是因为对齐方式的设置会使得结构体成员变量按照一定的规则进行对齐,从而在内存中用连续的地址空间,提高了访问速度。 在默认对齐方式下,结构体成员变量的起始地址和大小如下: ``` x.a 地址:00F4F8A0 x.b 地址:00F4F8A1 x.c 地址:00F4F8A4 x.d 地址:00F4F8A8 x.e 地址:00F4F8B0 x.f 地址:00F4F8B2 x.g 地址:00F4F8B4 变量大小:24 ``` 在1字节对齐方式下,结构体成员变量的起始地址和大小如下: ``` x.a 地址:00F4F8A0 x.b 地址:00F4F8A1 x.c 地址:00F4F8A2 x.d 地址:00F4F8A6 x.e 地址:00F4F8AE x.f 地址:00F4F8B0 x.g 地址:00F4F8B2 变量大小:14 ``` 在2字节对齐方式下,结构体成员变量的起始地址和大小如下: ``` x.a 地址:00F4F8A0 x.b 地址:00F4F8A1 x.c 地址:00F4F8A2 x.d 地址:00F4F8A4 x.e 地址:00F4F8AC x.f 地址:00F4F8AE x.g 地址:00F4F8B0 变量大小:16 ``` 在4字节对齐方式下,结构体成员变量的起始地址和大小如下: ``` x.a 地址:00F4F8A0 x.b 地址:00F4F8A1 x.c 地址:00F4F8A4 x.d 地址:00F4F8A8 x.e 地址:00F4F8B0 x.f 地址:00F4F8B4 x.g 地址:00F4F8B6 变量大小:24 ``` 在8字节对齐方式下,结构体成员变量的起始地址和大小如下: ``` x.a 地址:00F4F8A0 x.b 地址:00F4F8A1 x.c 地址:00F4F8A8 x.d 地址:00F4F8B0 x.e 地址:00F4F8B8 x.f 地址:00F4F8C0 x.g 地址:00F4F8C2 变量大小:32 ``` 从上述结果可以看出,不同的对齐方式会影响结构体变量的大小,所以在实际的开发中需要注意结构体成员变量的对齐方式,以便提高程序的执行效率。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值