当前位置: 首页 > article >正文

012+limou+C语言深入知识——(4)“结构体”与“枚举体”与“联合体”

一、结构体

1、结构体基础

(1)结构体完全声明

struct tag
{
    member-list;
}variable-list;
//描述一个人
struct people
{
    char name[10];//人名
    int age;//年龄
    int idnumber;//身份证
};

(2)结构体不完全声明(匿名结构体)

struct
{
    member-list;
}variable-list;
  • 值得注意的是一个匿名结构体就是一个单独的类型,不同地方定义的匿名结构体的类型在编译期看来是两种类型,会给出警告

在这里插入图片描述

2、结构体自引用

有时候需要通过结构体变量内部成员找到同类型的结构体变量,这就叫结构体的自引用

(1)错误引用

struct Node
{
    int data;
    struct Node next;
};

(2)正确引用

struct Node
{
    int data;
    struct Node* next;
};

(3)使用typedef引用

typedef struct Node
{
    int data;
    struct Node* next;//注意不能写成Node* next
}Node;
  • 注意不要写成Node*,因为在typedef{…}Node;后才会将结构体改名为Node,在此之前Node这种类型是不存在的

3、结构体变量的初始化

  • 使用{}初始化
//描述一个人
typedef struct people
{
    char name[10];//人名
    int age;//年龄
    int idnumber;//身份证
}people;

int main()
{
    people a = { "limou3434", 30, 44443333 };
    printf("%s %d %d", a.name, a.age, a.idnumber);
    return 0;
}
  • 另外结构体有初始化器
//描述一个人
typedef struct people
{
    char name[10];//人名
    int age;//年龄
    int idnumber;//身份证
}people;

int main()
{
    people a = { "limou3434", 30, 44443333 };
    printf("%s %d %d\n", a.name, a.age, a.idnumber);
    people b = { .age = 20, .idnumber = 1234567890, .name = "limou" };
    printf("%s %d %d\n", b.name, b.age, b.idnumber);
    return 0;
}

4、结构体内存大小

(1)内存对齐计算规则

(2)VS默认对齐数

(3)修改默认对齐数

详细看另外一篇文章额外:结构体内存对齐

(4)偏移量计算宏

#include <stdio.h>
#include <stddef.h>//使用offsetof宏,要包含头文件stddef.h
typedef struct people
{
    char name[10];//人名
    int age;//年龄
    int idnumber;//身份证
}people;
int main()
{
    people s = { "limou", 12, 88888888 };
    printf("%zd %zd %zd", offsetof(people, name), offsetof(people, age), offsetof(people, idnumber));
}

(5)节省结构体空间

将小的类型集中在一起就会一定程度节省结构体的空间

5、结构体位段

(1)位段基础位段的声明和结构是类似的,有两个不同:

①位段的成员必须是“整型算术类型”:int、unsigned int、signed int、char等
②位段的成员名后边有一个冒号和一个数字

//位段例子,后面的数字代表存储的比特位
struct A
{
    int a:2;
    int b:5;
    int c:10;
    int d:30;
};

(2)位段内存分配

  • 位段的空间是按照需要以4个字节(int)或者1个字节(char)的方式来开辟的,每次为每个成员分配比特位

(3)位段跨平台

  • 位段涉及很多不确定因素
    • ①C标准在未被利用的空间这里,并未规定如何处理
    • ②在一个字节中,由于成员都会使用这段空间,所以成员之间的存放先后顺序也是不确定的
    • ③成员分配最大位的数目是没有办法确定的
    • ④int位段是被当成无符号还是有符号也同样是不确定的
  • 因此位段是不跨平台的,注重可移植的程序应该避免使用位段

(4)位段应用

位段主要是用在网络数据传输上,这点涉及较远,暂且不谈

二、枚举体

1、枚举体基础

enum 枚举名
{
    枚举成员1,
    枚举成员2,
    …
    枚举成员n
}

2、枚举体特点

枚举成员的值,从0开始一次递增1。也可以直接在枚举体内进行赋值,赋值成员后的成员,比赋值成员的值大1

3、枚举体使用

//一个枚举体的例子
#include <stdio.h>
enum Color//颜色
{
    RED,
    YELLOW,
    GREEN=6,
    BLUE
};
int main()
{
    enum Color c = BLUE;//注意最好不要直接赋7,这在C语言可能被允许,但是在C++上可能会提示类型错误,因为1是int类型,而enum Color是一种枚举体类型
    printf("%d\n", c);
    printf("%d %d %d %d\n", RED, YELLOW, GREEN, BLUE);
}

4、枚举的优点

①有类型检查
②比宏更加便于调试
③使用方便,一次定义多个常量
④代码可读性提高


http://www.kler.cn/a/1584.html

相关文章:

  • 3D机器视觉的类型、应用和未来趋势
  • 自定义EasyCode模板生成CRUD
  • Flask返回浏览器无乱码方法
  • MATLAB对文件处理
  • STM32-笔记35-DMA(直接存储器访问)
  • LabVIEW计算机软件著作权
  • 011+limou+C语言深入知识——(3)“字符串函数”和“字符分类函数”和“内存操作函数”以及“部分库函数的模拟实现”
  • 【DP动态规划】最长子序列
  • [数据分析与可视化] Python绘制数据地图1-GeoPandas入门指北
  • string类(下)
  • 如何优雅地让谷歌浏览器中的网页旋转90度?掌握这个技巧,让你的网页与众不同!
  • linux kernel 5.0 inline hook框架
  • Mysql常用命令
  • 尚融宝07-前端模块化
  • 2023年网络安全最应该看的书籍,弯道超车,拒绝看烂书
  • 【C++编译】gcc、gdb、make、cmake
  • 论文阅读和分析:Mathematical formula recognition using graph grammar
  • 线程安全(重点)
  • 202304读书笔记|《不被定义的女孩》——做最真实最漂亮的自己,依心而行
  • 2023秋招前端面试必会的面试题
  • 多层多输入的CNN-LSTM时间序列回归预测(卷积神经网络-长短期记忆网络)——附代码
  • STM32开发(九)STM32F103 通信 —— I2C通信编程详解
  • springcloud3 nacos,sentinel,ribbon,openfegin等整合案例4[fallback+blockhandler完美整合]
  • 基于深度学习的农作物叶片病害检测系统(UI界面+YOLOv5+训练数据集)
  • 门面设计模式
  • C#等高级语言运行过程