结构体知识总结

在C语言中,结构体(struct)指的是一种数据结构,是C语言中聚合数据类型(aggregate data type)的一类。结构体可以被声明为变量、指针或数组等,用以实现较复杂的数据结构。结构体同时也是一些元素的集合,这些元素称为结构体的成员(member),且这些成员可以为不同的类型,成员一般用名字访问。

结构体类型创建

结构体的声明使用的是 struct 关键字,它的声明格式如下:
struct tag
{
    member-list;
}variable-list;

例如描述一个学生:

struct stu
{
    char name[20];//名字
    int age;//年龄
    char sex[5];//性别
    char id[20];//学号
};//分号不能丢

特殊的说明:

在声明的时候,可以不完全声明,比如:

//不完全声明
struct
{
    int a;
    char b;
    float c;
}x;

它省略掉了结构体标签(tag),但是在之后想要再次建立是就没有办法了,因此不推荐这样的写法,不过我们可以吧一个结构体写成一个类型,使用 typedef 就可以完成,如:

typedef struct 
{
    int a;
    char b;
    float c;
}x;

这样x就被重定向为一个类型了,我们可以使用x去定义类型

结构体初始化

结构体的初始化只能在定义变量的同时赋初值,如
struct stu
{
    char [20];
    int age; 
};//结构体声明 

struct stu p = {"zhangsan", 18};//初始化

结构体内存对齐

首先掌握一下结构体的几个对齐规则
  1. 第一个成员在与结构体变量偏移量为0的地址处,
  2. 变量要对齐到某个数字(对齐数)的整数倍的地址处。
    对齐数 = 编译器默认的一个对齐数 与 该成员大小的较小值。 (即:自己的偏移量能整出对齐数)
    • VS中默认的值为8
    • linux只默认的值是4
  3. 结构体总大小为最大对齐数(每个成员变量都有一个对齐数)的整数倍。
  4. 如果嵌套了结构体的情况,嵌套的结构体对齐到自己最大对齐数的整数倍处,结构体的整体大小就是所有最大对齐数(含嵌套结构体的对齐数)的整数倍。

总体来说

结构体的内存对齐就是拿空间换取时间的做法

struct S1
{
    char c1;
    int i;
    char c2;
};

struct S2
{
    char c1;
    char c2;
    int i;
};

S1和S2类型的成员一模一样,但是S1和S2所占空间的大小有了一些区别。
通过sizeof我们可以查看他们的空间大小:

    printf("%d\n", sizeof(struct S1));
    printf("%d\n", sizeof(struct S2));

结果如下:
结构体知识总结_第1张图片

我们来分析一下S1(VS环境下)

struct S1
{
    char c1;
    int i;
    char c2;
};

S1 中c1为char类型,类型字节为1个,小于8所以他的对齐数为1,且他的偏移量为0,因此它不需要对齐;

第二个成员i为int型,类型字节为4个,小于8所以它的对齐数为4,它的偏移量这时为1(在c1上面),不能够整除4,因此将 i 移到偏移量为4的地方 ,所以就丢弃了c1到i之间3个字节的空间,且int型自己占4个字节,到这里已经占用了8字节(1+3+4);

同样第三个成员c2的对齐数也是1,这时它的偏移量为9,可以整除它的对齐数。S1的结构已经分析完了,它的所占用9个字节(1+3+4+1)。

最后求的整体的总大小(可不是9),总大小应该为最大对其数的整数倍,S1的最大对齐数应为4,因为9不是4的整数倍,且S1的空间要大于9个字节,因此S1的总大小为12。

图示如下:
结构体知识总结_第2张图片

位段

  1. 位段的成员必须是int, unsigned int 或 signed int。
  2. 位段的成员名后边有一个冒号和一个数字。
struct A
{   
    int _a : 2;
    int _b : 5;
    int _c : 10;
    int _d : 30;
}

后面的数字分别表示所占bit位的个数

枚举+联合

枚举(enum)就是把可能的取值一一列举。

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

联合也是一种特殊的自定义类型,这种类型定义的变量也包含一系列的成员,特征是这些成员公用同一块空间(所以联合也叫共用体)。

union Un
{
    int i;
    char c;
};//声明

union Un un;//定义

联合体的特点是公用一块内存空间的,这样一个联合体变量的大小,至少是最大成员的大小(因为联合至少得有能力保存最大的那个成员)。

你可能感兴趣的:(c语言)