[C高手编程] struct, union, enum:复合类型与枚举全面解析

在这里插入图片描述

💖💖⚡️⚡️专栏:C高手编程-面试宝典/技术手册/高手进阶⚡️⚡️💖💖
「C高手编程」专栏融合了作者十多年的C语言开发经验,汇集了从基础到进阶的关键知识点,是不可多得的知识宝典。如果你是即将毕业的学生,面临C语言的求职面试,本专栏将帮助你扎实地掌握核心概念,轻松应对笔试与面试;如果你已有两三年的工作经验,专栏中的内容将补充你在实践中可能忽略的新技术和技巧;而对于资深的C语言程序员,这里也将是一本实用的技术备查手册,提供全面的知识回顾与更新。无论处在哪个阶段,「C高手编程」都能助你一臂之力,成为C语言领域的行家里手。

概述

本章深入探讨C语言中的struct, union, 和 enum。这些复合类型和枚举在组织数据和定义类型方面发挥着重要作用。通过本章的学习,读者将能够理解这些类型的使用方法,并能在实际编程中正确地运用它们。

1. struct类型

1.1 基本概念

struct类型用于定义复合数据类型,它允许将多个不同类型的变量组合在一起形成一个新的数据类型。

1.2 结构体声明

1.2.1 定义结构体
  • 定义:使用struct关键字定义一个结构体类型。

  • 示例代码:

    struct Point {
        int x;
        int y;
    };
    

    详细说明

    • struct Point定义了一个名为Point的结构体类型,它包含两个整型成员变量xy
    • 结构体类型可以包含任意数量和类型的成员变量。
1.2.2 创建结构体变量
  • 定义:使用结构体类型创建具体的变量实例。

  • 示例代码:

    struct Point p1 = {10, 20}; // 创建结构体变量并初始化
    

    详细说明

    • p1是一个struct Point类型的变量,初始化时可以使用花括号列表。
    • 结构体变量可以通过成员运算符.来访问其成员变量。

1.3 结构体成员访问

1.3.1 成员访问
  • 定义:使用成员运算符.访问结构体变量的成员。

  • 示例代码:

    struct Point p1 = {10, 20};
    int x = p1.x; // 访问结构体成员
    

    详细说明

    • x将会被赋值为p1x成员变量的值。
    • 成员运算符.用于访问结构体变量的成员。
1.3.2 指针访问
  • 定义:使用指针运算符->访问结构体指针所指向的成员。

  • 示例代码:

    struct Point p1 = {10, 20};
    struct Point *p = &p1;
    int x = p->x; // 访问结构体指针所指向的成员
    

    详细说明

    • p是一个指向struct Point类型的指针。
    • 使用指针运算符->可以访问结构体指针所指向的成员。

1.4 结构体数组

1.4.1 定义结构体数组
  • 定义:定义一个结构体数组,其中每个元素都是指定的结构体类型。

  • 示例代码:

    struct Point points[3] = {
        {10, 20},
        {30, 40},
        {50, 60}
    };
    

    详细说明

    • points是一个包含三个struct Point类型的数组。
    • 结构体数组的每个元素都可以通过下标访问。
1.4.2 结构体数组成员访问
  • 定义:访问结构体数组中的元素成员。

  • 示例代码:

    struct Point points[3] = {
        {10, 20},
        {30, 40},
        {50, 60}
    };
    int x = points[1].x; // 访问结构体数组元素的成员
    

    详细说明

    • x将会被赋值为points[1]x成员变量的值。
    • 结构体数组的每个元素都可以通过下标和成员运算符.来访问其成员。

1.5 结构体作为函数参数

1.5.1 作为函数参数
  • 定义:将结构体作为函数参数传递。

  • 示例代码:

    struct Point p1 = {10, 20};
    
    void printPoint(struct Point p) {
        printf("Point: (%d, %d)\n", p.x, p.y);
    }
    
    int main() {
        printPoint(p1);
        return 0;
    }
    

    详细说明

    • printPoint()函数接受一个struct Point类型的参数。
    • 结构体可以通过值传递给函数,但这样会复制整个结构体,可能导致性能开销。
1.5.2 指针作为函数参数
  • 定义:将指向结构体的指针作为函数参数传递。

  • 示例代码:

    struct Point p1 = {10, 20};
    
    void printPoint(struct Point *p) {
        printf("Point: (%d, %d)\n", p->x, p->y);
    }
    
    int main() {
        printPoint(&p1);
        return 0;
    }
    

    详细说明

    • printPoint()函数接受一个指向struct Point类型的指针。
    • 使用指针作为函数参数可以避免复制整个结构体,提高性能。

1.6 结构体作为返回值

1.6.1 作为返回值
  • 定义:将结构体作为函数的返回值。

  • 示例代码:

    struct Point getPoint() {
        return {10, 20};
    }
    
    int main() {
        struct Point p1 = getPoint();
        printf("Point: (%d, %d)\n", p1.x, p1.y);
        return 0;
    }
    

    详细说明

    • getPoint()函数返回一个struct Point类型的结构体。
    • 结构体可以通过值作为函数的返回值。

1.7 示例代码

#include <stdio.h>

struct Point {
    int x;
    int y;
};

void printPoint(struct Point p) {
    printf("Point: (%d, %d)\n", p.x, p.y);
}

struct Point getPoint() {
    return {10, 20};
}

int main() {
    struct Point p1 = {10, 20};
    printPoint(p1);
    struct Point p2 = getPoint();
    printPoint(p2);
    return 0;
}

详细说明

  • printPoint()函数接受一个struct Point类型的参数,并打印其成员。
  • getPoint()函数返回一个struct Point类型的结构体。
  • 通过这种方式,我们可以看到如何使用结构体作为函数参数和返回值。

在这里插入图片描述

2. union类型

2.1 基本概念

union类型用于定义复合数据类型,它允许不同的成员变量共享同一段内存空间。

2.2 联合声明

2.2.1 定义联合
  • 定义:使用union关键字定义一个联合类型。

  • 示例代码:

    union Data {
        int i;
        float f;
        char str[20];
    };
    

    详细说明

    • union Data定义了一个名为Data的联合类型,它包含三个成员变量i, f, 和 str
    • 联合类型的所有成员变量共享同一段内存空间。
2.2.2 创建联合变量
  • 定义:使用联合类型创建具体的变量实例。

  • 示例代码:

    union Data d1;
    d1.i = 10; // 初始化联合变量
    

    详细说明

    • d1是一个union Data类型的变量。
    • 联合变量可以通过成员运算符.来访问其成员。

2.3 联合成员访问

2.3.1 成员访问
  • 定义:使用成员运算符.访问联合变量的成员。

  • 示例代码:

    union Data d1;
    d1.i = 10;
    float f = d1.f; // 访问联合成员
    

    详细说明

    • f将会被赋值为d1f成员变量的值。
    • 访问联合成员时需要注意,因为所有成员共享同一段内存空间。
2.3.2 指针访问
  • 定义:使用指针运算符->访问联合指针所指向的成员。

  • 示例代码:

    union Data d1;
    d1.i = 10;
    union Data *pd = &d1;
    float f = pd->f; // 访问联合指针所指向的成员
    

    详细说明

    • pd是一个指向union Data类型的指针。
    • 使用指针运算符->可以访问联合指针所指向的成员。

2.4 联合作为函数参数

2.4.1 作为函数参数
  • 定义:将联合作为函数参数传递。

  • 示例代码:

    union Data d1;
    
    void printData(union Data d) {
        printf("Integer: %d\n", d.i);
        printf("Float: %f\n", d.f);
    }
    
    int main() {
        d1.i = 10;
        printData(d1);
        return 0;
    }
    

    详细说明

    • printData()函数接受一个union Data类型的参数。
    • 联合可以通过值传递给函数,但这样会复制整个联合,可能导致性能开销。
2.4.2 指针作为函数参数
  • 定义:将指向联合的指针作为函数参数传递。

  • 示例代码:

    union Data d1;
    
    void printData(union Data *pd) {
        printf("Integer: %d\n", pd->i);
        printf("Float: %f\n", pd->f);
    }
    
    int main() {
        d1.i = 10;
        printData(&d1);
        return 0;
    }
    

    详细说明

    • printData()函数接受一个指向union Data类型的指针。
    • 使用指针作为函数参数可以避免复制整个联合,提高性能。

2.5 联合作为返回值

2.5.1 作为返回值
  • 定义:将联合作为函数的返回值。

  • 示例代码:

    union Data getData() {
        union Data d;
        d.i = 10;
        return d;
    }
    
    int main() {
        union Data d1 = getData();
        printf("Integer: %d\n", d1.i);
        return 0;
    }
    

    详细说明

    • getData()函数返回一个union Data类型的联合。
    • 联合可以通过值作为函数的返回值。

2.6 示例代码

#include <stdio.h>

union Data {
    int i;
    float f;
    char str[20];
};

void printData(union Data d) {
    printf("Integer: %d\n", d.i);
    printf("Float: %f\n", d.f);
}

union Data getData() {
    union Data d;
    d.i = 10;
    return d;
}

int main() {
    union Data d1;
    d1.i = 10;
    printData(d1);
    union Data d2 = getData();
    printData(d2);
    return 0;
}

详细说明

  • printData()函数接受一个union Data类型的参数,并打印其成员。
  • getData()函数返回一个union Data类型的联合。
  • 通过这种方式,我们可以看到如何使用联合作为函数参数和返回值。

在这里插入图片描述

3. enum类型

3.1 基本概念

enum类型用于定义一组命名的整型常量,这些常量具有一定的逻辑关系。

3.2 枚举声明

3.2.1 定义枚举
  • 定义:使用enum关键字定义一个枚举类型。

  • 示例代码:

    enum Color {
        RED,
        GREEN,
        BLUE
    };
    

    详细说明

    • enum Color定义了一个名为Color的枚举类型,它包含三个成员RED, GREEN, 和 BLUE
    • 枚举成员默认从0开始递增。
3.2.2 显式赋值
  • 定义:显式为枚举成员赋值。

  • 示例代码:

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

    详细说明

    • 枚举成员可以显式赋值。
    • 显式赋值后,后续成员的值可以根据需要继续显式赋值或按顺序递增。

3.3 枚举成员访问

3.3.1 成员访问
  • 定义:使用枚举成员的名称访问其值。

  • 示例代码:

    enum Color color = RED;
    int c = color; // 访问枚举成员的值
    

    详细说明

    • c将会被赋值为RED枚举成员的值。
    • 枚举成员可以通过名称直接访问其值。

3.4 枚举作为函数参数

3.4.1 作为函数参数
  • 定义:将枚举作为函数参数传递。

  • 示例代码:

    enum Color color = RED;
    
    void setColor(enum Color c) {
        printf("Color: %d\n", c);
    }
    
    int main() {
        setColor(color);
        return 0;
    }
    

    详细说明

    • setColor()函数接受一个enum Color类型的参数。
    • 枚举可以通过值传递给函数。

3.5 枚举作为返回值

3.5.1 作为返回值
  • 定义:将枚举作为函数的返回值。

  • 示例代码:

    enum Color getColor() {
        return RED;
    }
    
    int main() {
        enum Color color = getColor();
        printf("Color: %d\n", color);
        return 0;
    }
    

    详细说明

    • getColor()函数返回一个enum Color类型的枚举。
    • 枚举可以通过值作为函数的返回值。

3.6 示例代码

#include <stdio.h>

enum Color {
    RED,
    GREEN,
    BLUE
};

void setColor(enum Color c) {
    printf("Color: %d\n", c);
}

enum Color getColor() {
    return RED;
}

int main() {
    enum Color color = RED;
    setColor(color);
    enum Color color2 = getColor();
    setColor(color2);
    return 0;
}

详细说明

  • setColor()函数接受一个enum Color类型的参数,并打印其值。
  • getColor()函数返回一个enum Color类型的枚举。
  • 通过这种方式,我们可以看到如何使用枚举作为函数参数和返回值。

在这里插入图片描述

4. 综合使用

在实际编程中,struct, union, 和 enum常常结合使用,以达到特定的效果。

4.1 结构体与联合

  • 定义:通过结合使用结构体和联合,可以实现复杂的数据类型。

  • 示例代码:

    union Data {
        int i;
        float f;
        char str[20];
    };
    
    struct ComplexData {
        union Data data;
        enum Color color;
    };
    
    int main() {
        struct ComplexData cd;
        cd.data.i = 10;
        cd.color = GREEN;
        return 0;
    }
    

    详细说明

    • struct ComplexData定义了一个包含联合和枚举的结构体。
    • 通过这种方式,可以创建更加复杂的数据类型。

4.2 枚举与结构体

  • 定义:通过结合使用枚举和结构体,可以定义具有逻辑关系的复杂数据类型。

  • 示例代码:

    enum Color {
        RED,
        GREEN,
        BLUE
    };
    
    struct Point {
        int x;
        int y;
        enum Color color;
    };
    
    int main() {
        struct Point p1 = {10, 20, RED};
        return 0;
    }
    

    详细说明

    • struct Point定义了一个包含枚举成员的结构体。
    • 通过这种方式,可以定义具有逻辑关系的复杂数据类型。

4.3 示例代码

#include <stdio.h>

enum Color {
    RED,
    GREEN,
    BLUE
};

union Data {
    int i;
    float f;
    char str[20];
};

struct ComplexData {
    union Data data;
    enum Color color;
};

void printComplexData(struct ComplexData cd) {
    printf("Data: %d\n", cd.data.i);
    printf("Color: %d\n", cd.color);
}

int main() {
    struct ComplexData cd;
    cd.data.i = 10;
    cd.color = GREEN;
    printComplexData(cd);
    return 0;
}

详细说明

  • struct ComplexData定义了一个包含联合和枚举的结构体。
  • printComplexData()函数接受一个struct ComplexData类型的参数,并打印其成员。
  • 通过这种方式,我们可以看到如何使用结构体、联合和枚举来创建复杂的数据类型。

在这里插入图片描述

5. 常见陷阱与注意事项

5.1 结构体

  • 定义:确保正确理解和使用结构体。

  • 解决方案:正确声明和使用结构体。

    详细说明

    • 结构体类型可以包含任意数量和类型的成员变量。
    • 结构体成员的访问需要使用成员运算符.
    • 结构体可以通过值或指针传递给函数。

5.2 联合

  • 定义:确保正确理解和使用联合。

  • 解决方案:正确声明和使用联合。

    详细说明

    • 联合类型的所有成员变量共享同一段内存空间。
    • 访问联合成员时需要注意,因为所有成员共享同一段内存空间。
    • 联合可以通过值或指针传递给函数。

5.3 枚举

  • 定义:确保正确理解和使用枚举。

  • 解决方案:正确声明和使用枚举。

    详细说明

    • 枚举成员默认从0开始递增。
    • 枚举成员可以通过名称直接访问其值。
    • 枚举可以通过值传递给函数。

6. 性能考量与优化技巧

6.1 使用结构体

  • 定义:使用结构体可以组织数据。

  • 理由:结构体可以帮助开发者组织数据,提高代码的可读性和可维护性。

    详细说明

    • 结构体类型可以包含任意数量和类型的成员变量。
    • 结构体成员的访问需要使用成员运算符.
    • 结构体可以通过值或指针传递给函数。

6.2 使用联合

  • 定义:使用联合可以节省内存空间。

  • 理由:联合类型的所有成员变量共享同一段内存空间,可以节省内存空间。

    详细说明

    • 联合类型的所有成员变量共享同一段内存空间。
    • 访问联合成员时需要注意,因为所有成员共享同一段内存空间。
    • 联合可以通过值或指针传递给函数。

6.3 使用枚举

  • 定义:使用枚举可以定义命名的整型常量。

  • 理由:枚举成员具有一定的逻辑关系,可以提高代码的可读性和可维护性。

    详细说明

    • 枚举成员默认从0开始递增。
    • 枚举成员可以通过名称直接访问其值。
    • 枚举可以通过值传递给函数。

7. 总结

通过本章的学习,我们深入了解了C语言中struct, union, 和 enum的功能及其在组织数据和定义类型方面的应用。我们探讨了这些类型的使用方法以及注意事项,并提供了详细的示例代码。此外,我们还讨论了如何综合使用这些类型来创建复杂的数据类型。通过这些内容的学习,读者将能够理解这些类型的工作原理,并能在实际编程中正确地运用它们。

  • struct类型:用于定义复合数据类型。
  • union类型:用于定义复合数据类型,其中成员变量共享同一段内存空间。
  • enum类型:用于定义一组命名的整型常量。
  • 9
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值