当包容结构体遇见灵活的内存管理

🌈个人主页:小田爱学编程
🔥 系列专栏:c语言从基础到进阶
🏆🏆关注博主,随时获取更多关于c语言的优质内容!🏆🏆


😀欢迎来到小田代码世界~
😁 喜欢的小伙伴记得一键三连哦 ૮(˶ᵔ ᵕ ᵔ˶)ა


目录

一.结构体

1.定义:

2.基本格式:

3 .结构体的声明

4.结构体的初始化 

5.结构体成员的访问

6.结构体传参和结构体传值

7.结构体的自引用

8.匿名结构体注意

9.内存对齐

10.位段

 二.动态内存管理

1.为什么要有动态内存管理

2.malloc函数

 3.free函数

 4.calloc函数

 5.relloc函数

三.柔性数组

1.定义

 2.举例

 3.注意

四.typedef关键字

 1.typedef关键字的使用格式:

2.举例:

五.联合体

1.定义

2.举例

3.联合体大小

六.枚举

1.定义

2.举例

3.运用

4.类比

5.对比


一.结构体

1.定义

C语⾔已经提供了内置类型,如:char、short、int、long、float、double等,但是只有这些内置类型还是不够的,假设我想描述学⽣,描述⼀本书,这时单⼀的内置类型是不⾏的。描述⼀个学⽣需要名字、年龄、学号、⾝⾼、体重等;描述⼀本书需要作者、出版社、定价等。C语⾔为了解决这个问题,增加了结构体这种⾃定义的数据类型,让程序员可以⾃⼰创造适合的类型。

2.基本格式:

struct tag
{
member-list;//成员变量的类型可以是:数组,结构体,指针
}variable-list;//变量列表

typedef struct Stu
{
char name[20];//名字
int age;//年龄
char sex[5];//性别
char id[20];//学号
}Stu;//分号不能丢

3 .结构体的声明

 🔥

struct Stu //类型声明
{
char name[15]; //名字
int age; //年龄
};

 🔥

struct Stu //类型声明
{
char name[15]; //名字
int age; //年龄
};

🔥

struct//省略掉了此处的tag标签
{
int a;
char b;
float c;
}x

4.结构体的初始化 

struct Stu s = { "张三", 20, "男", "20230818001" };
struct Stu s2 = { .age = 18, .name = "lisi", .id = "20230818002", .sex = "⼥};
struct Stu s3 = { .age = 18, .name = "lisi",  .sex = "女", "20230818002" };

5.结构体成员的访问

 🐟结构体成员的直接访问是通过点操作符(.)访问的

 🐟结构体成员的间接访问:结构体指针->成员名?

struct Point
{
int x;
int y;
};
int main()
{
struct Point p = {3, 4};
struct Point *ptr = &p;
print("%d\n",ptr->x);
print("%d\n",ptr->y);

 6.结构体传参和结构体传值

👨‍🌾函数传参的时候,参数是需要压栈的。
👨‍🌾如果传递一个结构体对象的时候,结构体过大,参数压栈的的系统开销比较大,所以会导致性       能的下降。

struct S
{
int data[1000];
int num;
};
struct S s = {{1,2,3,4}, 1000};
//结构体传参
void print1(struct S s)
{
printf("%d\n", s.num);
}
//结构体地址传参
void print2(struct S* ps)
{
printf("%d\n", ps->num);
}
int main()
{
print1(s);  //传结构体
print2(&s); //传地址
return 0;
}

7.结构体的自引用

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

8.匿名结构体注意

🔥在使用匿名结构体时,只能使用一次,且两个结构体比较时已经失效

9.内存对齐

1.结构体的第⼀个成员对⻬到和结构体变量起始位置偏移量为0的地址处

2其他成员变量要对⻬到某个数字(对⻬数)的整数倍的地址处对⻬数=编译器默认的⼀个对⻬数与该成员变量⼤⼩的较⼩值(VS 中默认的值为 8 )

3.结构体总⼤⼩为最⼤对⻬数(结构体中每个成员变量都有⼀个对⻬数,所有对⻬数中最⼤的)的整数倍。

4.如果嵌套了结构体的情况,嵌套的结构体成员对⻬到⾃⼰的成员中最⼤对⻬数的整数处,结构体的整体⼤⼩就是所有最⼤对⻬数(含嵌套结构体中成员的对⻬数)的整数倍。

10.位段

 位段可以节省空间,从左到右开开辟内存

struct A
{
int _a:2;
int _b:5;
int _c:10;
int _d:30;
};

 二.动态内存管理

1.为什么要有动态内存管理

• 空间开辟⼤⼩是固定的。
• 数组在申明的时候,必须指定数组的⻓度,数组空间⼀旦确定了⼤⼩不能调整
但是对于空间的需求,不仅仅是上述的情况。有时候我们需要的空间⼤⼩在程序运⾏的时候才能知
道,那数组的编译时开辟空间的⽅式就不能满⾜了。
C语⾔引⼊了动态内存开辟,让程序员⾃⼰可以申请和释放空间,就⽐较灵活了

2.malloc函数

• 如果开辟成功,则返回⼀个指向开辟好空间的指针。
• 如果开辟失败,则返回⼀个 NULL 指针,因此malloc的返回值⼀定要做检查。
• 返回值的类型是 void* ,所以malloc函数并不知道开辟空间的类型,具体在使⽤的时候使⽤者⾃
⼰来决定。
• 如果参数 size 为0,malloc的⾏为是标准是未定义的,取决于编译器。

 3.free函数

🔥 这边free后没有重置成空指针,free后仍记录原来的地址,为啥free不起作用呢?

🔥因为free传递的是一个参数,函数传的只有参和值,这里传递了p一个参数,在函数中没有修改       作用,解决方法:置成空指针或传成p4的地址,我们通常选择前者

 4.calloc函数

• 函数的功能是为 num 个⼤⼩为 size 的元素开辟⼀块空间,并且把空间的每个字节初始化为0。?
• 与函数 malloc 的区别只在于 calloc 会在返回地址之前把申请的空间的每个字节初始化为全

#include <stdio.h>
#include <stdlib.h>
int main()
{
int *p = (int*)calloc(10, sizeof(int));
if(NULL != p)
{
int i = 0;
for(i=0; i<10; i++)
{
printf("%d ", *(p+i));
}
}
free(p);
p = NULL;
return 0;
}

 5.relloc函数

• realloc函数的出现让动态内存管理更加灵活。
• 有时会我们发现过去申请的空间太⼩了,有时候我们⼜会觉得申请的空间过⼤了,那为了合理的时候内存,我们⼀定会对内存的⼤⼩做灵活的调整。那 realloc 函数就可以做到对动态开辟内存⼤
⼩的调整。

 

🔥当是情况1的时候,要扩展内存就直接原有内存之后直接追加空间,原来空间的数据不发⽣变化

🔥在堆空间上另找⼀个合适⼤⼩的连续空间来使⽤。这样函数返回的是⼀个新的内存地址。

int*p = NULL;
p = realloc(ptr, 1000);
if(p != NULL)
{
ptr = p;
}

三.柔性数组

1.定义

结构中的最后⼀个元素允许是未知大小的数组,这就叫做柔性数组成员

2.举例

typedef struct Stu
{
int i;
int a[]; //柔性数组成员
}

 3.注意

🔥结构中的柔性数组成员前⾯必须⾄少⼀个其他成员。
🔥 sizeof返回的这种结构⼤⼩不包括柔性数组的内存。

🔥 包含柔性数组成员的结构⽤malloc函数进⾏内存的动态分配,并且分配的内存应该⼤于结构         的⼤⼩,以适应柔性数组的预期⼤⼩

四.typedef关键字

 1. typedef关键字的使用格式:

 typedef  数据类型  新的名字;

2.举例:

typedef int  ListMember

  1. typedef struct Student {

  2. char name[100];

  3. int age;

  4. } STU;

五.联合体

1.定义

像结构体⼀样,联合体也是由⼀个或者多个成员构成,这些成员可以不同的类型。
但是编译器只为最⼤的成员分配⾜够的内存空间。联合体的特点是所有成员共⽤同⼀块内存空间。所以联合体也叫:共⽤体。
给联合体其中⼀个成员赋值,其他成员的值也跟着变化

2.举例

#include <stdio.h>
//联合类型的声明
union Un
{
char c;
int i;
};
int main()
{
//联合变量的定义
union Un un = {0};
//计算连个变量的⼤⼩
printf("%d\n", sizeof(un)
return 0;
}

3.联合体大小

• 联合的⼤⼩⾄少是最⼤成员的⼤⼩。
• 当最⼤成员⼤⼩不是最⼤对⻬数的整数倍的时候,就要对⻬到最⼤对⻬数的整数倍。

六.枚举

1.定义

枚举顾名思义就是⼀⼀列举,把可能的取值⼀⼀列举

2.举例

3.运用

#include <stdio.h>
 
enum DAY
{
      MON=1, TUE, WED, THU, FRI, SAT, SUN
};
 
int main()
{
    enum DAY day;
    day = MON;
    printf("%d",day);
    return 0;
}

4.类比

#define MON  1
#define TUE  2
#define WED  3
#define THU  4
#define FRI  5
#define SAT  6
#define SUN  7

5.对比

🥇🥇🥇  新的专栏:数据结构————"带你无脑刨析"博主正在火速创作中,可以关注博主一下   哦!φ(゜▽゜*)♪o(* ̄▽ ̄*)ブ[●´︶`●]

🎁🎁🎁今天的分享到这里就结束啦!如果觉得文章还不错的话,可以三连支持一下,您的支持就是我前进的动力!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/356371.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

MVCC原理讲解(深入浅出)

目录 一、什么是MVCC 二、当前读、快照读都是什么鬼 三、当前读 四、快照读 五、数据库的并发场景 六、MVCC解决并发的哪些问题 1.解决问题如下&#xff1a; 七、MVCC的实现原理 1.版本链 八、undo日志 1.undo log 的用途 2.undo log主要分为两种 九、Read View…

HCIP寒假第8次作业

第一步把ipv4网络配通 [r1]int g0/0/0 [r1-GigabitEthernet0/0/0]ip add 12.1.1.1 24 [r1-GigabitEthernet0/0/0]int l0 [r1-LoopBack0]ip add 1.1.1.1 32 [r1]ospf 1 router-id 1.1.1.1 [r1-ospf-1]area 0 [r1-ospf-1-area-0.0.0.0]network 0.0.0.0 255.255.255.255[r2]int g…

Linux使用匿名管道实现进程池得以高效通信

&#x1f3ac;慕斯主页&#xff1a;修仙—别有洞天 ♈️今日夜电波&#xff1a;Nonsense—Sabrina Carpenter 0:50━━━━━━️&#x1f49f;──────── 2:43 &#x1f504; ◀️ ⏸ ▶️ …

Unity 外观模式(实例详解)

文章目录 示例1&#xff1a;初始化游戏场景中的多个子系统示例2&#xff1a;管理音频播放示例3&#xff1a;场景加载流程示例4&#xff1a;UI管理器示例5&#xff1a;网络服务通信 在Unity中使用外观模式&#xff08;Facade&#xff09;时&#xff0c;主要目的是为了简化复杂子…

Android创建工程

语言选择Java&#xff0c;我用的Java 最小SDK&#xff1a;就是开发的APP支持的最小安卓版本 Gradle 是一款Google 推出的基于 JVM、通用灵活的项目构建工具&#xff0c;支持 Maven&#xff0c;JCenter 多种第三方仓库;支持传递性依赖管理、废弃了繁杂的xml 文件&#xff0c;转而…

如何快速掌握DDT数据驱动测试?

前言 网盗概念相同的测试脚本使用不同的测试数据来执行&#xff0c;测试数据和测试行为完全分离&#xff0c; 这样的测试脚本设计模式称为数据驱动。(网盗结束)当我们测试某个网站的登录功能时&#xff0c;我们往往会使用不同的用户名和密码来验证登录模块对系统的影响&#x…

2023年:个人年度成长与团队协作成就

文章目录 个人职业发展的喜悦团队成就的辉煌公众号CSDN申请了移动安全领域新星创作者获得6月城市之星北京TOP 10获得23年博客之星TOP 41年度总结 知识星球 开拓新领域的决心免费知识大陆付费知识大陆 展望未来福利时间知识星球会员一年知识星球立减88券 在这个充满挑战与机遇的…

Linux 挂载读取、卸载 ntfs格式硬盘

windows常用的ntfs硬盘分区格式&#xff0c;在linux通常不能直接读取&#xff0c;不过挂载也是非常容易 一、挂载ntfs分区 1.安装 apt-get install ntfs-3g2.查看现在接上的硬盘 fdisk -l可以找到类似如下的&#xff0c;会显示microsoft basic data 3.创建挂载的目录 创…

全能相似度计算与语义匹配搜索工具包,多维度实现多种算法,涵盖文本、图像等领域。支持文图搜索,满足您在不同场景下的搜索需求

全能相似度计算与语义匹配搜索工具包,多维度实现多种算法,涵盖文本、图像等领域。支持文图搜索,满足您在不同场景下的搜索需求。 Similarities:精准相似度计算与语义匹配搜索工具包,多维度实现多种算法,覆盖文本、图像等领域,支持文搜、图搜文、图搜图匹配搜索 Similar…

腾讯云超60款产品,限时免费试用!

懂行的开发同学都应该知道&#xff0c;腾讯云的产品嘎嘎好用&#xff01; 很多同学只能眼红&#xff0c;却不能体验一二。毕竟付费的门槛在那里&#xff0c;体验不到&#xff0c;自然没办法做出评价。 今天&#xff0c;开放10个免费体验产品的名额给你&#xff0c;想体验哪款…

4核16G幻兽帕鲁服务器优惠价格表,阿里云和腾讯云报价

幻兽帕鲁服务器价格多少钱&#xff1f;4核16G服务器Palworld官方推荐配置&#xff0c;阿里云4核16G服务器32元1个月、96元3个月&#xff0c;腾讯云幻兽帕鲁服务器服务器4核16G14M带宽66元一个月、277元3个月&#xff0c;8核32G22M配置115元1个月、345元3个月&#xff0c;16核64…

【文本到上下文 #7】探索 NLP 中的 Seq2Seq、编码器-解码器和注意力机制

一、说明 今天&#xff0c;我们将探讨序列到序列 &#xff08;seq2seq&#xff09; 模型的复杂工作原理&#xff0c;特别关注编码器-解码器架构和注意力机制。这些概念是各种 NLP 应用的基础&#xff0c;从机器翻译到问答系统。 这是可以期待的&#xff1a; Seq2Seq模型中的编码…

【技术分享】远程透传网关-单网口快速实现威纶通触摸屏程序远程上下载

准备工作 一台可联网操作的电脑一台单网口的远程透传网关及博达远程透传配置工具网线一条&#xff0c;用于实现网络连接和连接触摸屏一台威纶通触摸屏及其编程软件一张4G卡或WIFI天线实现通讯(使用4G联网则插入4G SIM卡&#xff0c;WIFI联网则将WIFI天线插入USB口&#xff09;…

Linux实验记录:添加硬盘设备

前言&#xff1a; 本文是一篇关于Linux系统初学者的实验记录。 参考书籍&#xff1a;《Linux就该这么学》 实验环境&#xff1a; VmwareWorkStation 17——虚拟机软件 RedHatEnterpriseLinux[RHEL]8——红帽操作系统 目录 前言&#xff1a; 备注&#xff1a; 添加硬盘…

error: failed to open index: Database already open. Cannot acquire lock报错解决办法

ordinals节点数据同步出现报错 error: failed to open index: Database already open. Cannot acquire lock.问题分析&#xff1a; 出现问题的原因是btcoin core节点数据没有同步完我们就开始进行ordinals数据同步&#xff0c;导致/root/.local/share/ord/index.redb 文件数据…

自然语言处理,基于预训练语言模型的方法,车万翔,引言部分

文章目录 自然语言处理应用任务1. 信息抽取2. 情感分析3. 问答系统4. 机器翻译5. 对话系统 自然语言处理应用任务 1. 信息抽取 信息抽取&#xff08;Information Extraction, IE&#xff09;&#xff0c;是从非结构化的文本中&#xff0c;抽取出结构化信息的过程&#xff0c;…

GBASE南大通用分享-ConnectionTimeout 属性

GBASE南大通用分享 获取或设置连接超时时间&#xff0c;值为‚0‛时没有限制。  语法 [Visual Basic] Public Overrides ReadOnly Property ConnectionTimeout As Integer Get [C#] public override int ConnectionTimeout { get; }  实现 IDbConnection.Connecti…

拼接url - 华为OD统一考试

OD统一考试 分值&#xff1a; 100分 题解&#xff1a; Java / Python / C 题目描述 给定一个 url 前缀和 url 后缀, 通过 “,” 分割&#xff0c; 需要将其连接为一个完整的 url 。 如果前缀结尾和后缀开头都没有 /&#xff0c;需要自动补上 / 连接符&#xff1b; 如果前缀结…

LPC804开发(5.PWM使用)

1.前言 早上花了点时间学习了一下官方的例程&#xff0c;总的来说PWM输出还是比较简单的。 2.基本使用 首先在开始前我不建议大家照搬官方的程序&#xff0c;因为官方的程序非常复杂&#xff0c;其实官方自己有更简单的方法但是SDK里没有用&#xff0c;我也不知道为什么&…

Mybatis-Plus基础

typora-copy-images-to: img Mybatis Plus 今日目标&#xff1a; 了解mybatisplus的特点能够掌握mybatisplus快速入门能够掌握mybatisplus常用注解能够掌握mybatisplus常用的增删改查能够掌握mybatisplus自动代码生成 1 MybatisPlus简介 1.1 MybatisPlus概述 ​ MyBatis-…