C语言 结构体的释义和内存分配

本文介绍了C语言中的结构体,包括如何定义结构体、内存分配原理以及内存优化方法。结构体允许数据封装,但内存分配时会有内存对齐的考虑,不同编译平台的对齐规则可能不同,导致结构体大小变化。为了优化内存,可以使用位段类型,但这种方式存在安全性和跨平台问题,一般不推荐使用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前言

还是自己复习到的内容,以前在学习C语言的时候还有缺陷。所以总结一下关于结构体的内容。
结构体就是为了封装,这就有一点面对对象的类的影子。然后通过一些方法来访问结构体成员。需要用的struct关键词。

结构体代码
typedef struct node    //定义一个结构体
{
	char x;      // 这里结构体成员
	char y;
	int z;
}XYnode;  //结构体名字

这是结构体最基本的定义。通过typedef struct 来定义一个结构体。这里的node是一个标识符。 然后通过花括号来确定结构体成员。最后的XYnode是这个结构体的名字。也就是我们定义的这个结构体的类型。
当我们需要一个实在的结构体变量时通过这样定义。

   struct node node1 = {'a','b',3};
    XYnode node2 = { 'a','b',3 };

当然,也可以不在定义时初始化。通过指向符(->)或者点(.)来访问。当然 结构体也是可以内嵌结构体的,举个简单的例子。

typedef struct node    
{
    char x;      
    char y;
    int z;
}XYnode;

typedef struct NODE
{
    int X;
    XYnode node4;
}LIST;

以上就是简单的结构体应用。

结构体的内存分配

结构体中,有一个内存对齐的概念。
我们知道,在32位计算机下,char类型占一个字节, int类型占四个字节,那么按照这个思路,下面的这个结构体应该占六个字节。

typedef struct node    //定义一个结构体
{
    char x;      // 这里结构体成员
    char y;
    int z;
}XYnode;

但是实际情况是:

 printf("%d\n",sizeof(XYnode));

在这里插入图片描述
这就是因为结构体在分配内存时会存在内存对齐这样的概念。
同时,**在不同的编译平台,可能会有一个不同的内存对齐参考值。**例如我在VS2019下运行的。参考值是8个字节。
当我们定义一个变量时,第一个变量为char 占一个字节,存在最开始的位置。第二个变量为char 占一个字节。这个时候系统会将变量类型的大小和参考值进行比较。然后取其中的较小值为最终的对齐值。这里因为都是char类型。所以会存在紧接着第一个变量的位置。但是第三个变量为int占四个字节。这时对齐值会变成4 所以int这时候会向后对齐。从第五个字节开始储存。
在这里插入图片描述
大概就是图上这样的。也是因为这样的储存机制,**就会导致如果我们同样的结构体成员不同的定义顺序,就会导致结构体的大小是不一样的。**例如下面这样的结构体。

typedef struct node    //定义一个结构体
{
    char x;      // 这里结构体成员
    int y;
    char z;
}XYnode;

他的大小就变成了12个字节
在这里插入图片描述
这个时候是这样子储存的。
在这里插入图片描述

内存的优化

这样的内存分配问题很明显,有很多的浪费空间。那么有没有办法对内存进行重新分配呢。是可以的。我们可以这样定义。

struct A
{
    char a : 3;
    int b : 16;
    char c : 2;
};

这样的位段类型,意思是我自己给我的变量分配空间。比如int原本需要四个字节,但是我自己明白,我只需要两个字节就可以存下我的变量。就可以通过“:比特数”的方式来自己修改分配的字节数。这样就可以节省更多的内存。
但是这样的问题很明显,不安全,因为如果需要存入一个四个字节的数的时候,int类型本来是可以存入的,但是我们只分配了两个字节的空间,就会导致数据丢失。
同时,这在跨平台的时候操作也是会出问题的。因为在c语言中,并没有规定:当在一个字节中,存入两个数据的时候,究竟是从左往右存,还是从右往左存。
在这里插入图片描述
这就可能会出现,在我这里时,数据是从左往右存的,但是传给你后,你觉得数据是从右往左存的。这显然是有问题的。所以我们平时并不会使用这样的类型。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值