返回顶部
首页 > 资讯 > 后端开发 > 其他教程 >C语言柔性数组详解
  • 234
分享到

C语言柔性数组详解

2024-04-02 19:04:59 234人浏览 泡泡鱼
摘要

目录前言一、柔性数组是什么?二、柔性数组的特点三、柔性数组的优点总结前言 可能大家第一眼看到这个标题会有点懵,到底什么是柔性数组,我怎么从来没听说过?但柔性数组确实是存在的,也经常会

前言

可能大家第一眼看到这个标题会有点懵,到底什么是柔性数组,我怎么从来没听说过?但柔性数组确实是存在的,也经常会出现在一些公司的面试题中,今天就跟着笔者来学习一下柔性数组吧。

提示:以下是本篇文章正文内容,下面案例可供参考

在这里插入图片描述

一、柔性数组是什么?

C99中,结构体中的最后一个元素允许是未知大小的数组,这就叫作柔性数组,for example:


 struct st_type
{
	int i;
	int a[0];//柔性数组成员,也可以写int a[];
};

结构体成员a数组,它的数组大小是没有确定的,将来如果需要可以大也可以小。
有些编译器支持a[0]这种写法,有些编译器支持a[ ]这种写法,具体取决编译器。

二、柔性数组的特点

1.结构体中柔性数组成员前面必须至少有一个其他成员

示例如下:


 struct st_type
{
	int i;
	int a[0];//柔性数组成员,也可以写int a[];
};

比如上面这段代码,如果你要创建一个柔性数组a,前面必须创建一些别的成员

2.sizeof返回的这种结构大小不包括柔性数组的内存

示例如下:


 struct st_type
{
	int i;//4字节
	int a[0];//柔性数组成员,也可以写int a[];
	//因为是柔性数组,无法确认a占几个字节
};
 int main()
 {
	 printf("%d\n", sizeof(struct st_type));//打印4
	 return 0;
 }

这里计算包含柔性数组的结构体大小,因为柔性数组本身是无法确定有几个字节的,所以计算整体结构体大小时,会省略柔性数组的计算。

3.包含柔性数组成员的结构用malloc()函数进行内存的动态分配,并且分配的内存应该大于结构的大小,以适应柔性数组的预期大小

ps:除了malloc函数,realloc、calloc等动态内存开辟的函数也需要类似的操作

比如说我现在要数组a里面有10个元素,现在进行malloc一下

示例如下:


#include<string.h>
#include<errno.h>
struct st_type
{
	int i;//4字节
	int a[0];//柔性数组成员,也可以写int a[];
};
int main()
{
    //假设我现在需要a里有10个元素
	struct st_type*ps=(struct st_type*)malloc(sizeof(struct st_type) + 10 * sizeof(int));
	if (ps == NULL)//由于空间可能不够开辟导致malloc开辟失败,开辟失败会返回空指针
	{
		printf("%s\n", strerror(errno));
		return -1;//程序出问题后,跳出程序
	}
	//开辟成功
	int j = 0;
	for (j = 0;j < 10;j++)
	{
		ps->a[j] = j;
	}
	for (j = 0;j < 10;j++)
	{
		printf("%d ", ps->a[j]);//打印0-9
	}
	printf("\n");
	//如果想继续用柔性数组a进行打印
	//比如现在a里只有10个元素,我用完10个了,我还要继续来10个,用realloc追加
	struct st_type*ptr=realloc(ps, sizeof(struct st_type) + 20 * sizeof(int));//ps:realloc第二个参数是调整后的整体大小
	if (ptr == NULL)
	{
		printf("扩容失败\n");
		return -1;
	}
	else
	{
		ps = ptr;
	}
	//扩容成功
	int k = 0;
	for (k = 10;k < 20;k++)
	{
		ps->a[k] = k;
	}
	for (j = 0;j < 20;j++)
	{
		printf("%d ", ps->a[j]);//打印0-19
	}
	//释放空间
	free(ps);
	ps = NULL;
	return 0;
}

在这里插入图片描述

在这里插入图片描述

我们这里需要数组a里有10个元素,那我们malloc的时候要对结构体里的整形i先开辟4个字节,然后为整形数组a再开辟40个字节,然后malloc函数返回开辟空间的起始地址,赋给truct st_type * 类型的ps指针。

malloc(sizeof(struct st_type) + 10 * sizeof(int))这个操作等价于struct st_type类型创建一个变量所占空间,只不过是用malloc来开辟

你改变数组a大小,追加空间时,realloc(ps, sizeof(struct st_type) + 20 * sizeof(int)),realloc的第一个参数仍然是ps,因为你当时是用malloc一次开辟出的一块空间,你是不能单独调整数组a的空间的

三、柔性数组的优点

柔性数组就是对一块空间实现动态开辟嘛,那我们之前也讲过指针来动态内存开辟,我们来看一段代码来对比一下这两种方法:


//用指针也可以做到a指向的空间动态变化
struct st_type
{
	int i;//4字节
	int *a;//4字节,这里计算结构体大小恰好是8字节
};
int main()
{
	struct st_type*ps = (struct st_type*)malloc(sizeof(struct st_type));
	ps->i = 100;
	ps->a = (int*)malloc(10 * sizeof(int));//a指向40个字节的空间,该空间由int*进行管理
	int j = 0;
	for (j = 0;j < 10;j++)
	{
		ps->a[j] = j;//a[j]=*(a+j)
	}
	for (j = 0;j < 10;j++)
	{
		printf("%d", ps->a[j]);
	}
	//a指向的空间不够了,希望调整大小
	int *ptr = (int*)realloc(ps->a, 20 * sizeof(int));
	if (ptr == NULL)
	{
		printf("扩容失败");
		return -1;
	}
	else
	{
		ps->a = ptr;
	}
	//使用...
	//释放
	free(ps->a);
	ps->a = NULL;
	free(ps);
	ps = NULL;
}

这里需要注意的是,在释放空间时,你要先释放指针a指向的空间,然后释放结构体指针

在这里插入图片描述

如上图,我们结构体指针ps开辟一块空间,空间里存放整形i和整形指针a,a又malloc(后续如果需要还可以realloc追加)一块空间,如果你先释放掉ps,a就没了,你就没法找到a指向的那块空间了。

还是那个生动的例子 就比如a是一个警察头子,malloc开辟的空间是卧底,只有a知道那个卧底,你现在警察头子死了,再也没法证明卧底是卧底了,也就是说a消失后,没办法再对开辟的空间进行释放,这时就会造成内存泄露,指针实现动态内存调整是需要对指针释放讲解一定的顺序性的

这里对比柔性数组,柔性数组和上述的指针都可以实现一块空间大小的调整,但是柔性数组有两个好处:
第一个好处是:方便内存释放

如果我们的代码是在一个给别人用的函数中,你在里面做了二次内存分配,并把整个结构体返回给用户。用户调用free可以释放结构体,但是用户并不知道这个结构体内的成员也需要free,所以你不能指望用户来发现这个事。以上,如果我把结构体的内存及其成员要的内存一次性分配好,并返回给用户一个结构体指针,用户做一次free就可以把所有内存都释放掉,并且不用考虑前面说的释放的顺序。

第二个好处是:加快访问速度

连续的内存有益于提高访问速度,也有益于减少内存碎片。

ps:内存碎片如下图

在这里插入图片描述

操作系统给我们一块内存,我们在进行malloc时,不一定就是一块连着一块的,上图的空白部分就是内存碎片,有些类似我们裁剪布料,一些剩余的边角料这样。

总结

本文介绍了柔性数组的定义、其三个使用特点,及其对比指针实现动态内存的优势,并对其进行了具体举例

本篇文章就到这里了,希望能够给你带来帮助,也希望您能够多多关注编程网的更多内容!

--结束END--

本文标题: C语言柔性数组详解

本文链接: https://lsjlt.com/news/137690.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • C语言柔性数组详解
    目录前言一、柔性数组是什么?二、柔性数组的特点三、柔性数组的优点总结前言 可能大家第一眼看到这个标题会有点懵,到底什么是柔性数组,我怎么从来没听说过?但柔性数组确实是存在的,也经常会...
    99+
    2024-04-02
  • 详解C语言之柔性数组
    目录定义特点具体使用例总结定义 可调整大小的数组 以0大小数组或无大小数组定义在结构体的最后一个元素中 特点 1.结构体中的柔性数组前必须包含至少一个其他成员。 2.sizeof...
    99+
    2024-04-02
  • C语言 柔性数组的使用详解
    目录一.柔性数组的特点二.柔性数组的使用1.如何使用柔性数组2.不用柔性数组的话有什么代替三.柔性数组的优势1.方便内存释放2.提高访问速度一.柔性数组的特点 struct S {...
    99+
    2024-04-02
  • C语言中0数组\柔性数组的使用详解
    前言: 上次看到一篇面试分享,里面有个朋友说,面试官问了char[0] 相关问题,但是自己没有遇到过,就绕过了这个问题。 我自己在这篇文章下面做了一些回复。 现在我想结合我自己...
    99+
    2024-04-02
  • C语言中的柔性数组你了解吗
    目录1.什么是柔性数组2.柔性数组应该如何使用3.柔性数组的替代方案及内存分布对比4.柔性数组有哪些优点总结1.什么是柔性数组 柔性数组就是大小可以变化的数组。 注意跟C99中的变长...
    99+
    2023-05-15
    C语言柔性数组使用 C语言 柔性数组 C语言 数组
  • C语言如何使用柔性数组
    这篇文章主要介绍了C语言如何使用柔性数组,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。一.柔性数组的特点struct S{int x;int a...
    99+
    2023-06-29
  • C语言中柔性数组怎么用
    这篇文章主要为大家展示了“C语言中柔性数组怎么用”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“C语言中柔性数组怎么用”这篇文章吧。定义可调整大小的数组以0大小数组或无大小数组定义在结构体的最后一...
    99+
    2023-06-25
  • C语言柔性数组怎么使用
    今天小编给大家分享一下C语言柔性数组怎么使用的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。一、前言仔细观察下面的代码,有没有...
    99+
    2023-07-05
  • C语言编程C++柔性数组结构示例讲解
    目录绕指柔—柔性数组柔性数组的特点:第一个好处是:方便内存释放第二个好处是:这样有利于访问速度总结绕指柔—柔性数组 也许你从来没有听说过柔性数组(flexible array)这个概...
    99+
    2024-04-02
  • C语言动态内存管理malloc柔性数组示例详解
    目录1.C语言动态内存管理库函数介绍1.1为什么存在动态内存管理1.2动态内存管理函数1.2.1malloc1.2.2free1.2.3calloc1.2.4realloc1.3动态...
    99+
    2022-11-13
    C语言动态内存malloc柔性数组 C语言 malloc柔性数组
  • C语言中的柔性数组你真的了解吗
    目录柔性数组概念:特点:与指针动态开辟的比较指针动态开辟柔性数组指针动态开辟的缺点总结柔性数组概念: 柔性数组就是一种特殊的数组 它也是结构体最后一个成员 也就是说,它存在结构体最后...
    99+
    2024-04-02
  • 深入了解一下C语言中的柔性数组
    目录什么是柔性数组柔性数组的使用什么是柔性数组 柔性数组是在C99中定义的 结构体的最后一个元素允许是未知大小的数组,这就叫柔性数组 柔性数组的长度可以写成0,也可以不规定数组长度 ...
    99+
    2023-02-13
    C语言柔性数组使用 C语言柔性数组
  • C语言中的柔性数组怎么使用
    这篇文章主要讲解了“C语言中的柔性数组怎么使用”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“C语言中的柔性数组怎么使用”吧!1.什么是柔性数组柔性数组就是大小可以变化的数组。注意跟C99中的...
    99+
    2023-07-06
  • 详解C语言中动态内存管理及柔性数组的使用
    目录一、malloc二、free三、calloc四、realloc1、realloc在扩容时的情况2、realloc也能实现malloc功能五、使用动态内存的常见错误1、free空指...
    99+
    2024-04-02
  • C语言编程之动态内存与柔性数组的了解
    目录介绍动态内存分配函数常见的动态内存开辟的错误举个例子柔性数组柔性数组的特点创建变量 1,局部变量–栈区 2,全局变量–静态区 创建数组 1,局部数组–栈区 2,全局数组–静态区 ...
    99+
    2024-04-02
  • 一文带你了解C语言中的0长度数组(可变数组/柔性数组)
    目录零长度数组概念0长度数组的用途GNU Document中 变长数组的支持0长度数组的其他特征零长度数组概念 众所周知, GNU/GCC 在标准的 C/C++ 基础上做了有实用性的...
    99+
    2023-03-19
    C语言0长度数组 C语言零长度数组 C语言可变数组 C语言柔性数组
  • C语言冷门知识之你可能没听过的柔性数组
    目录一、简述二、具体使用1.用创建柔性数组的方法:2.用普通的写法三、柔性数组的特点一、简述 在c99中有明确的规定允许结构体中最后一个数组大小是未知的。 柔性数组其实是结构体中的最...
    99+
    2024-04-02
  • C语言动态数组详解
    目录内存分配函数malloc calloc realloc free内存操作函数 memset memcpy memmove二维动态数组的建立和释放总结内存分配函数malloc ca...
    99+
    2024-04-02
  • C语言字符串数组详解
    C语言字符串数组 字符串是连续的字符序列,最后以空字符'\0'作为终止符。一个字符串的长度指所有字符的数量,但不包括终止符。在 C 语言中,没有字符串类型,自然也就没有运算符以字符串...
    99+
    2024-04-02
  • c语言的指针数组详解
    指针如何指向数组,并读取数组中的元素: #include <stdio.h> int main() { int arr[3] = {1,2,3}; int *p;...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作