【C语言指南】数据类型详解(下)——自定义类型

embedded/2024/10/18 12:01:03/
htmledit_views">

             💓 博客主页:倔强的石头的CSDN主页 

           📝Gitee主页:倔强的石头的gitee主页

            ⏩ 文章专栏:《C语言指南》

                                  期待您的关注

 

47f09392526c71b5885ec838a3ea7ffe.gif

 

目录

引言

1. 结构体(Struct)

2. 联合体(Union)

3. 枚举(Enum,自定义用法的高级特性)

4. 类型定义(Typedef)

结语


C语言内置类型可参考上一篇文章:

【C语言指南】数据类型详解(上)——内置类型-CSDN博客

 

引言

在C语言中,除了丰富的内置数据类型外,自定义数据类型也是编程中不可或缺的一部分。自定义数据类型允许程序员根据实际需求定义新的数据类型,从而提高代码的可读性、可维护性和复用性。

 

本文将详细探讨C语言中几种常见的自定义数据类型结构体(Struct)联合体(Union)枚举(Enum,侧重于其自定义用法的高级特性)以及类型定义(Typedef),并对每种类型的定义、使用场景、注意事项及高级特性进行详细说明。

1. 结构体(Struct)

结构体是C语言中一种复合数据类型,它允许将不同类型的数据项组合成一个单一的类型

结构体是用户自定义类型的基础,广泛应用于表示具有多个属性的复杂对象。

  • 定义

    struct Student {  char name[50];  int age;  float score;  
    };
     

    这里定义了一个名为Student的结构体,包含三个成员:name(字符数组,用于存储学生姓名)、age(整型,用于存储学生年龄)和score(浮点型,用于存储学生成绩)。

  • 使用
    定义结构体类型后,可以使用该类型声明变量,并通过点运算符(.)访问其成员。

    struct Student stu1;  
    strcpy(stu1.name, "Alice");  
    stu1.age = 20;  
    stu1.score = 92.5f;
  • 高级特性

    • 结构体数组:可以定义结构体数组,以存储多个具有相同结构的数据项。
    • 结构体指针:结构体指针用于指向结构体变量或结构体数组,通过结构体指针可以动态地访问和修改结构体成员。
    • 结构体嵌套:结构体中可以包含其他结构体作为成员,实现更复杂的数据结构。

 

2. 联合体(Union)

联合体是一种特殊的数据类型,它允许在相同的内存位置存储不同的数据类型。

联合体主要用于节省内存空间或在某些特定情况下共享数据。

  • 定义

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

    这里定义了一个名为Data的联合体,包含三个成员:i(整型)、f(浮点型)和str(字符数组)。但需要注意的是,这些成员在同一时刻只能使用其中一个,因为它们共享同一块内存空间。

  • 使用
    使用联合体时,必须明确当前使用的是哪个成员,因为联合体的所有成员都从相同的内存地址开始。

    union Data data;  
    data.i = 10; // 使用整型成员  
    // 注意:在访问其他成员之前,必须确保该成员是最后被赋值的,否则可能导致数据不一致  
    printf("%d\n", data.i); // 输出10  
    data.f = 3.14f; // 使用浮点型成员,此时整型成员的值将被覆盖  
    printf("%f\n", data.f); // 输出3.14

     

  • 高级特性

    • 匿名联合体:在某些情况下,可以定义匿名联合体,以便直接访问其成员而无需通过联合体名。
    • 联合体的内存对齐:由于联合体成员共享同一块内存,因此联合体的总大小通常等于其最大成员的大小,但实际的内存布局可能受到编译器和平台的影响,特别是与内存对齐有关。

 

3. 枚举(Enum,自定义用法的高级特性)

枚举类型是一种用户定义的类型,它包含一组命名的整型常量

虽然枚举本质上不是自定义数据类型(因为它基于整型),但其自定义用法和高级特性使得它非常强大。

  • 定义

    enum Color { RED, GREEN, BLUE, YELLOW, COUNT };
    这里定义了一个名为Color的枚举,包含四个颜色常量和一个计数常量COUNT
    (通常用于表示枚举中常量的数量)。默认情况下,枚举常量的值从0开始递增。
    
  • 自定义值
    可以为枚举常量指定具体的整数值。

    enum Color { RED = 1, GREEN = 2, BLUE = 4, YELLOW = 8, COUNT = 4 };
    注意这里的COUNT被赋值为4,它并不代表枚举中常量的总数,而是被显式赋值为4。
    
  • 高级特性

    • 枚举的位字段:结合位运算,可以使用枚举来表示一组可以组合的属性。
    • 枚举的类型安全:虽然枚举在C语言中是基于整型的,但它们提供了比整数更好的类型安全性,因为枚举常量具有明确的语义。
    • 枚举的跨平台问题:由于枚举的底层类型是整型,其大小和范围可能因编译器和平台而异,因此在跨平台编程时需要注意。

 

4. 类型定义(Typedef)

typedef关键字用于为现有的数据类型定义一个新的名字(别名)。

使用typedef可以简化复杂的类型声明,提高代码的可读性。

  • 定义

    typedef struct {  int x, y;  
    } Point;
    这里为包含两个整型成员x和y的结构体定义了一个新类型名Point。
    
  • 使用
    现在可以使用Point来声明变量,而无需每次都写struct关键字。

    Point p1, p2;  
    p1.x = 10;  
    p1.y = 20;
  • 高级特性

    • 类型安全的别名typedef不仅简化了类型声明,还提供了类型安全的别名,有助于防止类型混淆。
    • 函数指针的简化typedef特别适用于简化函数指针的类型声明,使得回调函数和函数指针的使用更加直观。

 

结语

自定义数据类型是C语言中强大的特性之一,它们允许程序员根据实际需求定义新的数据类型,从而创建出更加灵活、高效和易于维护的程序。

通过深入理解并掌握这些自定义数据类型的定义、使用场景、注意事项及高级特性,程序员可以编写出更加优秀的C语言程序。

 


http://www.ppmy.cn/embedded/120503.html

相关文章

CSS链接

链接是网站的重要组成部分,几乎在每个网页上都能看到不少的链接,合理的设计链接的样式能够给网页的颜值加分。链接有四种不同的状态,分别是 link、visited、active 和 hover,可以通过以下伪类选择器来为链接的四种状态设置不同的样…

MongoDB 入门及实践

MongoDB 入门 一、简介二、安装与配置1. 下载与安装2. 启动 MongoDB3. 使用 MongoDB Shell 三、基本概念1. 数据库2. 集合3. 文档4. 字段 四、基本操作1. 创建数据库2. 插入数据3. 查询数据4. 更新数据5. 删除数据 五、高级主题1. 索引2. 聚合框架3. 分布式部署4. 安全性 六、最…

第166天:应急响应-拒绝服务钓鱼指南DDOS压力测试邮件反制分析应用日志

案例一:内网应急-日志分析-爆破&横向&数据库 数据库 这里不同数据库日志不一样,我用mysql分析 首先MySQL数据库需要支持远程连接 GRANT ALL PRIVILEGES ON . TO root% IDENTIFIED BY 123.com WITH GRANT OPTION; 其次开启日志 -- 查看general…

Git 使用方法

简介 Git常用命令 Git 全局设置 获取Git 仓库 方法二用的比较多 将仓库链接复制 在 git base here ----> git clone 仓库链接 工作区、暂存区、版本库 Git 工作区中文件中的状态 本地仓库的操作 远程仓库操作 git pull 将代码推送到远程仓库 1. git add 文件名 ---放…

《蓝桥杯算法入门》(C/C++、Java、Python三个版本)24年10月出版

推荐:《算法竞赛》,算法竞赛大全书,网购:京东 天猫  当当 文章目录 《蓝桥杯算法入门》内容简介本书读者对象作者简介联系与交流《蓝桥杯算法入门 C/C》版目录 《蓝桥杯算法入门 Java》版目录 《蓝桥杯算法入门 Python》版目录 …

【React】useState 和 useRef:项目开发中该如何选择

如果你正踏入用 React 进行网页开发的世界,那你可能已经遇到了像 useState 和 useRef 这样的术语。这两个 Hook 在构建交互性和动态组件时起着至关重要的作用。 下面,我们将探讨它们是什么,它们的功能,它们的区别,并通…

mock数据,不使用springboot的单元测试

业务代码 package com.haier.configure.service.impl;import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.haier.common.util.RequestUtil; import com.haier.configure.entity.Langua…

Spring不能处理的循环依赖

文章目录 场景一:prototype 类型的循环依赖场景二: constructor 注入的循环依赖场景三:普通的 AOP 代理 Bean 的循环依赖–默认是可以的场景四:Async 增强的 Bean 的循环依赖总结 参考:https://blog.csdn.net/wang4896…