结构体&&联合&&枚举(详解版)

1.结构体

        1.结构体的声明

struct tag
{
 member-list;
}variable-list;

        2.结构体的特殊声明

struct
{
int a;
char b;
float c;
}x;
struct
{
int a;
char b;
float c;
}a[20], *p;
 

                上述代码属于匿名结构体类型 

                1)编译器会把上面的生命当成完全不同的类型所以是非法的

                2)匿名的结构体类型,只能使用一次,因为没有对结构体类型重命名

        3.结构体的自引用方式

        如果一个结构体内部包含同类型的结构体变量,结构体变量的大小就会无穷的大

        所以正确的自引用方式是使用指指针:

 struct Node
{
    int data;
    struct Node* next;
};

        4.结构体的内存对齐

        对齐规则:

                        1.结构体的第一个成员对齐到和结构体变量起始位置偏移量是0的地址处

                        2.其他成员变量对齐到对齐数的整数倍的地址处去

                           对齐数是编译器默认的一个对齐数与该成员变量大小的较小值

                        3.结构体总大小为最大的对齐数的整数倍

例:

struct S1
{
 char c1;
 int i;
 char c2;
};
printf("%d\n", sizeof(struct S1));
c1从零偏移位置处开始占一个字节,接着往下看,i是int类型占4个字节,对齐数是4,所以i从偏移量为4的位置处存,c2对齐数是1,在i后面存,现在是九个字节,由于最大对齐数是4,根据规则4,结构体需要占12个字节空间才可以。
        为什么要存在内存对齐:1)平台原因        2)性能原因
        修改对齐数:
         #progma pack(x)这个预处理指令,可以改变编译器的默认对齐数为x
        取消默认对齐数,使用 #progma pack()

        5.结构体位段

        位段的声明与结构体类似:

        1)位段的成员必须是int,unsigned int 或者signed int

        2)   位段的成员名后必须有一个冒号和数字

        3)  可移植程序避免使用位段

        4)   位段的空间是按照4个字节或者1个字节的方式来开辟的

        5)  位段可以节省空间

struct A
{
 int _a:2;
 int _b:5;
 int _c:10;
 int _d:30;
};
        位段的注意事项:位段的几个成员共有一个字节,这样有些成员的起始位置并不是某个字节的起始位置,那么这些位置处是没有地址的,内存中每个字节分配一个地址,一个字节的内部的bit位是没有地址的
        不能对位段成员使用&操作符,而应该是先输入放在一个变量中,然后赋值给位段的成员

2.联合

        1.联合体类型的声明

                联合体也是由一个或者多个成员构成,可以是不同类型。联合体的特点是所有成员共用一块空间。给一个成员赋值,其他成员的值也跟着变化。

        2.联合体的特点

                联合体的大小,至少是最大成员的大小

        3.联合体大小的计算

                联合的大小至少是最大成员的大小

                当最大成员大小不是最大对齐数的整数倍的时候,就要对齐到最大对齐数的整数倍。

        4.联合体的一个练习(判断当前机器的大小端)

                

int check_sys()
{
 union
 {
 int i;
 char c;
 }un;
 un.i = 1;
 return un.c;//返回1是⼩端,返回0是⼤端
}

3.枚举

        1.枚举类型的声明

                把可能的取值一一列举

enum Day//星期
{
 Mon,
 Tues,
 Wed,
 Thur,
 Fri,
 Sat,
 Sun
};

        2.枚举的优点

                增加代码的可读性和可维护性

                和#define定义的标识符比较枚举有类型检查,更加严谨

                便于调试,预处理阶段会删除define定义的符号

                枚举常量是遵循作用域规则的,枚举声明在函数内,只能在函数内使用

        3.枚举类型的使用(在C语言中是可以拿整数给枚举变量赋值的)

enum Color//颜⾊
 {
 RED=1,
 GREEN=2,
BLUE=4
 };

 enum Color clr = GREEN;
  • 60
    点赞
  • 43
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值