结构体(struct)和联合体(union)的区别


一、结构体


结构就是一些值的集合,其中的值称作它的成员,这些成员可能具有不同的类型。

1. 声明和定义结构体

以下第一个声明就是创建了一个student的结构体变量,第二个创建了一个student2的结构变量和指向student2的指针pstudent。

需要注意的是编译器认为student和student2是不同的结构体,即使他们内部的成员类型相同,所以pstdent = &student是非法的。

srtuct{
    char name[20];
    int age;
    bool male;
    float score;
}student;

srtuct{
    char name[20];
    int age;
    bool male;
    float score;
}student2,*pstudent;

那么我们每次想要使用student这种类型的结构体时必须要,重新定义吗?并不是这样的,我们可以用以下的方式定义student这种类型,如下:

struct student{
    char name[20];
    int age;
    bool male;
    float score;
};

int main() {
    struct student student1;
    struct student student2;
}

需要注意的是我们最初的struct student的操作并没有创建变量,它只是声明了一种结构体标签,我们可以在其他函数中使用struct student student1来定义一个结构体变量student1

但是每一次都要定义的时候都要使用struct student来定义显然很繁琐,我们可以使用typedef来对它进行重命名,创建student类型。如下:

typedef struct{
    char name[20];
    int age;
    bool male;
    float score;
}student, *pstudent;

int main() {
    student student1;
    pstudent pstudent;
}

这时我们可以直接使用studentpstudent作为一种变量类型来定义变量。

2. 如何访问结构体中的成员

直接访问

结构变量是通过.来访问其中的成员的,具体如下:

typedef struct{
    char name[20];
    int age;
    bool male;
    float score;
}student, *pstudent;

int main() {
    student student1;
    student1.name = "zhangsan";
    student1.age = 18;
}

点操作符.接受两个操作数,左操作数为结构变量的名字,右操作数为需要访问的成员名字

间接访问

我们知道了结构变量如何访问其中的成员,那么结构指针该如何访问呢?

typedef struct{
    char name[20];
    int age;
    bool male;
    float score;
}student, *pstudent;

int main() {
    pstudent pstudent1;*pstudent1).name = "zhangsan";*pstudent1).age = 18;
}

我们先要对其进行解引用再访问其中的成员,但是这种访问方式十分的繁琐,c语言中引入了箭头操作附来完成以上操作,具体如下:

typedef struct{
    char name[20];
    int age;
    bool male;
    float score;
}student, *pstudent;

int main() {
    pstudent pstudent1;
    pstudent1->name = "zhangsan";
    pstudent1->age = 18;
}

3. 对结构体进行初始化

和数组初始化的方式很相似,使用花括弧进行初始化,具体如下:

student1 = {
            "zhangsan"18,
            true,
            66.6
};

4. 结构体的内存分配——内存对齐

编译器会按照成员列表的顺序一个接一个的给每个成员分配分配内存,分配要求满足正确的边界对齐。只看这个没有理解没关系,我们接着往下看例子中的具体分析。

如上文中我们定义的student ,它所占的内存是多少呢?使用sizeof来测试一下有多大?

在这里插入图片描述
但是如果我们正常一个结构中所有成员所占的内存应该是:
sizeof(name) + sizeof(int) + sizeof(bool) + sizeof(float) = 20 + 4 + 1 + 4= 29,但实际上一个student结构占有32个字节,原因就是由于内存对齐引起的,如在给student结构进行内存分配时:

在这里插入图片描述
在我们student中 int类型和float类型所占有的内存最大,均是四个字节,结构体再分配内存的时候将会以4为标准对齐分配内存,由于分配到male的时候只有一个字节下一个为float为四个字节无法和其一起分配,所以将会补齐3个字节实现内存对齐的分配要求。

二、联合体

联合体中的所有成员引用的是内存中相同的位置,当你想要在不同时刻将不同的东西存储在同一个位置,就可以使用联合。

1. 联合的定义

定义如下:

union Integer{
    int data;
    char bytes[4];
};

一个int为四个字节,我们可以将一个int型的数字放入data然后使用bytes来看这个data按照字节具体的存储内容,主函数中如下:

int main(){
    union Integer n;//字节顺序只出现在整型中
    n.data = 12348774;
    printf("%#x\n",n.data);
    for(int i=0;i<4;++i){
        printf("%#hhx\n",n.bytes[i]);
        // %x 以十六进制整形输出。
        // int为4个字节,char型数组中的每个数据有效位为一个字节,如果直接按照整形输出就会一次性读取4个字节。
        // 所以用hh限制每次读取一个字节,只有一个h表示限制读取两个字节。
    }
}

所以在某种意义上我们可以使用联合看同一事物的不同表现。

2. 联合的初始化

联合变量可以进行初始化,但是这个初始值必须是联合第一个成员的类型,而且必须统一在一对花括号里面。

union {
    int a;
    float b;
    char c[4];
}x = { 5 };

以上就是将x.a初始化为5, 如果给出的初始值是其他类型的值如5.56,它将会将其转化为一个整数给a。

3. 联合的内存分配

分配给联合的内存数量取决于它的最长成员的长度,这样,联合的长度总是可以容纳它最大的成员。如果这些成员的长度相差悬殊,将会浪费很多的空间,最好的办法是在联合中存储不同成员的指针而不是直接存储成员本身,因为所有的指针长度都是相同的。

  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 结构体struct)和联合体union)都是C语言中用于定义自定义数据类型的方式,它们的区别在于: 1. 结构体中的各个成员在内存中是分开存储的,而联合体中的各个成员在内存中是共用同一块空间的。 2. 结构体的大小至少是其各个成员大小之和,因为每个成员都需要占用一定的内存空间,而联合体的大小则是其最大成员的大小,因为联合体中只有一个成员会被使用,其它成员则会被浪费。 3. 结构体中的各个成员可以同时被访问和修改,而联合体中只有一个成员可以被访问和修改。 4. 结构体可以存储不同类型的成员,而联合体只能存储同一类型的成员。 总之,结构体适合用于存储多个不同类型的数据,而联合体适合用于存储多个相同类型的数据,且只有一个数据会被使用的情况。 ### 回答2: 结构体struct联合体union都是在C语言中用来组织多个不同类型的变量的一种方式。它们的区别在于变量的存储方式和内存占用。 结构体struct是一种可以存储不同类型的变量的自定义数据类型。它通过定义多个不同类型的变量,并将它们组合在一起,形成一个新的类型。结构体中的每个成员变量都使用独立的内存空间,大小根据成员变量的类型而定。结构体的成员可以同时存在于内存中,因此结构体可以存储和处理多个不同类型的数据。 联合体union也是一种可以存储不同类型的变量的自定义数据类型。它与结构体不同的是,联合体的成员变量共享同一块内存空间,也就是说,联合体的各个成员变量会在同一时间占用该内存空间。联合体的内存空间大小会根据最大的成员变量类型来决定。而为了节约内存空间,联合体只能同时存储和处理一个成员的数据。 结构体联合体的使用方式也不同。结构体通常用于组织多个相关的变量,可以同时访问和修改结构体的各个成员变量。而联合体通常用于存储不同类型的变量,根据不同的需求来访问和修改特定的成员变量。 综上所述,结构体联合体在存储方式、内存占用和使用方式上都有所不同,开发者要根据实际需求选择合适的数据类型。 ### 回答3: 结构体struct联合体unionC语言中的两种复合数据类型。 结构体struct允许将不同类型的变量(如整型、字符型、浮点型等)组合在一起,形成一个逻辑上的整体。它可以定义多个成员变量,每个成员变量可以有不同的数据类型和名称。通过使用结构体,可以更方便地管理和操作相关的数据。 而联合体union也是用来组合不同类型的变量,不同于结构体的是,联合体的所有成员变量都共享同一块内存空间。联合体的大小取决于成员变量中占用内存空间最大的数据类型。只能同时使用其中的一个成员变量,存取一个成员变量会覆盖之前存入的值。通过使用联合体,可以节省内存空间,但在数据使用时需要小心,确保不会出现意外的数据覆盖。 总结来说,结构体struct联合体union区别是: 1. 结构体允许不同类型的成员变量,而联合体中的成员变量必须是相同的类型。 2. 结构体的成员变量占用不同的内存空间,联合体的成员变量共享同一块内存空间。 3. 结构体的大小等于所有成员变量所占内存空间的总和,联合体的大小等于最大的成员变量所占内存空间。 4. 结构体的所有成员变量可以同时使用,而联合体只能同时使用一个成员变量。 5. 结构体适用于存储和操作不同类型的相关数据,联合体适用于节省内存空间、只需存取其中一个成员变量的情况下。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值