0
点赞
收藏
分享

微信扫一扫

NIO简介

佛贝鲁先生 04-10 12:30 阅读 2

【C语言】共用体union:

  • 也称联合体。同一个内存空间用于多个数据的存储。
  • 同一时间只能存储一个成员数据。
  • 使用内存覆盖技术。新的成员数据会覆盖原来的成员数据。
  • 内存大小是最大的成员占用内存大小,且是最大对齐数的整数倍,若不足整数倍,将填充字节补齐。

1、定义共用体类型

  • 关键字union。
  • 包括共用体名、共用体成员。共用体成员由成员类型、成员变量名组成。
  • 最后末尾的分号";"不能省略。
// 定义名为person的共用体,成员有字符串name,整数int,字符串指针job
union person
{
    char name[20];
    int age;
    char *job;
};

2、共用体变量

(2-1)定义共用体变量

  • 定义共用体类型后,定义共用体变量。可以定义一个或多个共用体变量。
union person
{
    char name[20];
    int age;
    char *job;
};

union person p1;             // 定义一个共用体变量
union person p1, p2, p3;     // 定义多个共用体变量
  • 定义共用体类型时,同时定义共用体变量。可以定义一个或多个共用体变量。
union person
{
    char name[20];
    int age;
    char *job;
} p;                     // 定义共用体类型时,定义一个共用体变量

union person
{
    char name[20];
    int age;
    char *job;
} p1, p2, p3;            // 定义共用体类型时,定义多个共用体变量

(2-2)访问共用体成员

  • 使用成员访问运算符(".")来访问共用体的成员。
#include <stdio.h>
#include <string.h>

union person
{
    char name[20];
    int age;
    char *job;
};

int main(void)
{
    union person p;
    strcpy(p.name, "John");           // 成员name的值为John
    p.age = 18;                       // 成员age的值覆盖原来成员name的值  
    p.job = "programer";              // 成员job的值覆盖原来成员age的值
    printf("p.name is %s\n", p.name);
    printf("p.age is %d\n", p.age);
    printf("p.job is %s\n", p.job);
    return 0;
}

// 结果:
p.name is                            // 数据被新数据覆盖,该数据已损坏
p.age is 4210688                     // 数据被新数据覆盖,该数据已损坏
p.job is programer                   // 最后的数据占据内存
  •  若是指针,使用箭头运算符("->")来访问共用体的成员。
#include <stdio.h>
#include <string.h>

union person
{
    char name[20];
    int age;
    char *job;
};

int main(void)
{
    union person *p, p1;
    p = &p1;                           // 指针p指向共用体p1
    strcpy(p->name, "John");           // 成员name的值为John
    p->age = 18;                       // 成员age的值覆盖原来成员name的值  
    p->job = "programer";              // 成员job的值覆盖原来成员age的值
    printf("p point to p1, name is %s\n", p->name);
    printf("p point to p1, age is %d\n", p->age);
    printf("p point to p1, job is %s\n", p->job);
    return 0;
}

// 结果:
p point to p1, name is                // 数据被新数据覆盖,该数据已损坏
p point to p1, age is 4210688         // 数据被新数据覆盖,该数据已损坏
p point to p1, job is programer       // 最后的数据占据内存

3、共用体大小:

  • 共用体的内存大小是最大的成员占用内存大小。
  • 共用体的内存大小是最大对齐数的整数倍,若不足整数倍,将填充字节补齐。
#include <stdio.h>

union person
{
    char name[20];        // 字符串name:20字节
    int age;              // 整数int:4字节
    char *job;            // 字符串指针job:8字节(64位的计算机)
};

int main(void)
{
    union person p;
    printf("p memory size is %d bytes\n", sizeof(p));
    return 0;
}

// 结果:
p memory size is 24 bytes    //最大成员内存大小为20,不足最大对齐数的整数倍,填充字节补齐

4、共用体作为结构体的成员

注:数组名就是内存地址(数组第一个元素的内存地址)。整数的内存地址需用&获取(&整数变量名)。

字符数组通常用于表示字符串。字符串名也是内存地址(字符串第一个元素的内存地址)。

#include <stdio.h>
#include <string.h>

struct person                 // 结构体
{
    char name[20];
    int age;
    char job[16];
    union                     // 共用体, language或者place,只能提供一个数据
    {
        char language[16];
        char place[16];
    }lp;                      // 共用体变量名lp
}p[2];                        // 结构体数组p

int main(void)
{
    // 根据用户输入,写入数据
    for(int i = 0; i < 2; i++)
    {
        printf("[ Input ]name age job (NO.%d): ", i+1);
        scanf("%s %d %s", p[i].name, &p[i].age, p[i].job);

        // 如果job是programmer,则提供language,否则提供place
        if(strcmp(p[i].job, "programmer") == 0)
        {
            printf("Input language: ");
            scanf("%s", p[i].lp.language);
        }
        else
        {
            printf("Input place: ");
            scanf("%s", p[i].lp.place);
        }
    }
    // 输出数据
    for(int i = 0; i < 2; i++)
    {
        if(strcmp(p[i].job, "programmer") == 0)
            printf("%s, %d, %s, %s\n", p[i].name, p[i].age, p[i].job, p[i].lp.language);
        else
            printf("%s, %d, %s, %s\n", p[i].name, p[i].age, p[i].job, p[i].lp.place);
    }
    return 0;
}

// 结果:
[ Input ]name age job (NO.1): John 18 programmer        【输入:John 18 programmer】
Input language: C                                       【输入:C】
[ Input ]name age job (NO.2): Mark 25 teacher           【输入:Mark 25 teacher】
Input place: Beijing                                    【输入:Beijing】
John, 18, programmer, C
Mark, 25, teacher, Beijing

5、共用体与结构体的主要区别

共用体结构体
各成员在相同的内存位置各成员在不同的内存位置
同一时间只能存储一个成员数据同一时间可以存储多个不同类型的成员数据
新的成员数据会覆盖原来的成员数据各成员的数据互不影响
内存大小 >= 最大的成员内存大小内存大小 >= 各成员内存大小之和
关键字union关键字struct

举报

相关推荐

0 条评论