结构、联合、位字段

结构、联合、位字段

1、结构体空洞

结构字段在存储器中并不一定是挨着摆放的,有时两个字段之间会有小的空隙。
因为计算机总希望数据能对齐字边界,如果计算机的字长是32位,就不希望某个变量跨越32位的边界保存。
因为计算机按字从存储器中读取数据,如果某个字段跨越了多个字,CPU就必须读取多个存储单元,并以某种方式把督导的值合并起来。会很慢。

2、匿名结构

匿名结构就是没有名字的结构,

typedef struct { … } spider_man;    

有一个叫spider_man的别名,但没有结构名,很多时候,如果创建了别名,也就不需要结构名了。

3、指定初始化器

可以用“指定初始化器”按名设置结构和联合字段,属于c99标准。绝大多数现代编译器都支持“指定初始化器”,但如果c语言的变种,可能不支持(比如:c++不支持)

typedef  truct
{
    const char *color;
    int gears;
    int height;
}bike;
bike b = {.height = 17, .gears = 23};

4、结构体初始化

margarita m = {2.0, 1.0, {0.5}}; //成功编译

margaruta m;
m = {2.0, 1.0, {0.5}};  //不能编译,因为只有把{2.0, 1.0, {0.5}}和结构声明写在一行里,编译器才知道它代表结构,否则,编译器会认为是数组。

5、枚举记录联合中保存了什么值

编译器不会记录你在联合中设置或读取过哪些字段。我们完全可以设置一个字段,读取另一个字段,但有时这会造成很严重的后果。
可以通过创建枚举,记录我们在联合中保存了什么值。

#include <stdio.h>

typedef enum
{
    COUNT, 
    POUNDS;
    PINTS
}unit_of_measure;

typedef union
{
    short count;
    float weight;
    float volume;
}quantity;

typedef struct 
{
    const char *name;
    const char *country;
    quantity amount;   //联合
    unit_of_measure units;  //枚举
}fruit_order;

void display(fruit_order order)
{
    printf("This order contains");

    if (order.units == PINTS)
    {
        printf("%2.2f pints of %s\n, order.amount.volume, order.name");
    }else if (order.units == POUNDS)
    {
        printf("%2.2f lbs of %s\n", order.amount.weight, order.name);
    }else 
    {
        printf("%i %s", order.amount.count, order.name);
    }
}

int main()
{
    fruit_order apples = {"apples", "England", .amount.count = 144, COUNT};
    fruit_order strawberries = {"starawberries", "Spain", .amount.weight = 17.6, POUNDS};
    fruit_order oj = {"orange juice", "U.S.A", .amount.volume = 10.5, PINTS};

    display(apples);
    display(strawberries);
    display(oj);

    return 0;
}

6、位字段(bitfield)

如果编译器发现结构中只有一个位字段,还是会把它填充成一个字,多个位字段总是结合在一起。
位字段不仅仅是为了节省空间,如果要读取底层的二进制信息,位字段会非常有用。比如读写某类自定义二进制文件。
位字段应该声明成unsigned int。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值