前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >当包容结构体遇见灵活的内存管理

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

作者头像
编程交流
发布2024-05-11 17:56:27
710
发布2024-05-11 17:56:27
举报
文章被收录于专栏:编程编程

🌈个人主页:Rookie Maker 🔥 系列专栏:c语言 🏆🏆关注博主,随时获取更多关于IT的优质内容!🏆🏆


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


目录

一.结构体

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;//变量列表

代码语言:javascript
复制
typedef struct Stu
{
char name[20];//名字
int age;//年龄
char sex[5];//性别
char id[20];//学号
}Stu;//分号不能丢

3 .结构体的声明

🔥

代码语言:javascript
复制
struct Stu //类型声明
{
char name[15]; //名字
int age; //年龄
};

🔥

代码语言:javascript
复制
struct Stu //类型声明
{
char name[15]; //名字
int age; //年龄
};

🔥

代码语言:javascript
复制
struct//省略掉了此处的tag标签
{
int a;
char b;
float c;
}x

4.结构体的初始化

代码语言:javascript
复制
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.结构体成员的访问

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

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

代码语言:javascript
复制
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.结构体传参和结构体传值

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

代码语言:javascript
复制
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.结构体的自引用

代码语言:javascript
复制
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 会在返回地址之前把申请的空间的每个字节初始化为全

代码语言:javascript
复制
#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的时候,要扩展内存就直接原有内存之后直接追加空间,原来空间的数据不发⽣变化

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

代码语言:javascript
复制
int*p = NULL;
p = realloc(ptr, 1000);
if(p != NULL)
{
ptr = p;
}

三.柔性数组

1.定义

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

2.举例

代码语言:javascript
复制
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.举例

代码语言:javascript
复制
#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.运用

代码语言:javascript
复制
#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.类比

代码语言:javascript
复制
#define MON  1
#define TUE  2
#define WED  3
#define THU  4
#define FRI  5
#define SAT  6
#define SUN  7

5.对比

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

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

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2024-04-05,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一.结构体
    • 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.对比
                                                          领券
                                                          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档