【C语言】拓展解析篇——柔性数组

       

做一些算法题的时候你是否有过这样的苦恼:

                                        数组要是能用变量来定义数组大小那该多好啊~

                                        数组定义小了,要改成动态的岂不是要一部分换血,好麻烦~

                                        数组定义大了,好浪费空间...


哈哈哈,不用苦恼

                你幻想的这种动态柔软的数组确实有啊~

 

在C99标准中

        出现了这样一个名词——柔性数组

        它是什么呢?

                结构体最后一个元素允许是未知大小的数组,这就叫【柔性数组】


        接下来给出你们好奇的语法结构:

typedef struct st_type
{    
     int i;
     int a[0];//柔性数组成员   写0表示并不知道这个数组有多大
}type_a;

        有些小伙伴可能就照着如上代码试了,却报错

不如试试下面这个~                (并不是所以编译器都支持如上写法

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

        有同学可能会问了:

                                        博主,柔性数组怎么用呀?

                                        柔性是怎么体现的啊?

首先你因该要了解她的特点嘛~所谓        知己知彼 百战百胜

                                             ​​​​​​​        ​​​​​​​        ​​​​​​​        ​​​​​​​

 

  • 结构体的柔性数组成员前至少有一个其他成员
  • sizeof这种类型并不会返回柔性数组的大小
  • 如果用到malloc对其进行动态内存开辟,分配的内存应该大于结构的大小,以适应柔性数组的预期大小。

这第一条好理解,这第二条什么意思呢?

                                                                看代码:

#include<stdio.h>

typedef struct student
{
	int n;
	int arr[];
}student;

int main()
{
	printf("sizeof = %d",sizeof(student));
	return 0;
}

运行结果:

                                也就是计算类型大小的时候抛开柔性数组不看

                                按结构体对齐原则,计算其他成员即可~

 欸嘿,那第三个呢?

        这柔性数组是如何体现的呢?

        实际上,也告诉我们,在创建结构体的时候不能直接创建,如下:

#include<stdio.h>

typedef struct student
{
	int n;
	int arr[];
}student;

int main()
{
	student stu;
	return 0;
}

那怎么办呢?

                        对于包含柔性数组真正的创建方式如下:

假设我希望创建的柔性数组的成员先是10个整形大小

#include<stdio.h>

typedef struct student
{
	int n;
	int arr[];
}student;

int main()
{
	student* ps = (student*)malloc(sizeof(student) + 40);

	return 0;
}

有了如上代码,再加上下图,让你对柔性数组的了解更近一层~

 此时,若是我有想法:

                                     操作一下柔性数组  (如下)

#include<stdio.h>
#include<string.h>
#include<stdlib.h>

typedef struct student
{
	int n;
	int arr[];
}student;

int main()
{
	student* ps = (student*)malloc(sizeof(student) + 40);
	if (ps == NULL)
	{
		perror(ps);
		return 1;
	}
	//使用
	int i = 0;
	for (i = 0; i < 10; i++)
	{
		ps->arr[i] = i;
	}
	//访问
	for (i = 0; i < 10; i++)
	{
		printf("%d ", ps->arr[i]);
	}
	return 0;
}

哎呀,博主,你这还是只讲了使用与访问呀,那柔性体现在何处呢?

                                ​​​​​​​        不急不急,慢下来,一步一步走,更扎实~

        这就谈及到开头讨论到的问题啦,怎么解决呢?

        不卖关子了  当你的数组感觉设计小了,我想让他能不能在大一点?

                                                                                                                当然可以

这空间都是malloc出来的,用realloc即可

#include<stdio.h>
#include<string.h>
#include<stdlib.h>

typedef struct student
{
	int n;
	int arr[];
}student;

int main()
{
	student* ps = (student*)malloc(sizeof(student) + 40);
	if (ps == NULL)
	{
		perror(ps);
		return 1;
	}
	//使用
	int i = 0;
	for (i = 0; i < 10; i++)
	{
		ps->arr[i] = i;
	}
	//访问
	for (i = 0; i < 10; i++)
	{
		printf("%d ", ps->arr[i]);
	}
	student* ptr = (student*)realloc(ps,sizeof(student) + 80);
	if (ptr == NULL)
	{
		perror(ptr);
		return 1;
	}
	//处理

	return 0;
}

在倘若,这空间利用完了,不想要了

                                                          那咱就释放:

#include<stdio.h>
#include<string.h>
#include<stdlib.h>

typedef struct student
{
	int n;
	int arr[];
}student;

int main()
{
	student* ps = (student*)malloc(sizeof(student) + 40);
	if (ps == NULL)
	{
		perror(ps);
		return 1;
	}
	//使用
	int i = 0;
	for (i = 0; i < 10; i++)
	{
		ps->arr[i] = i;
	}
	//访问
	for (i = 0; i < 10; i++)
	{
		printf("%d ", ps->arr[i]);
	}
	student* ptr = (student*)realloc(ps,sizeof(student) + 80);
	if (ptr != NULL)
	{
		ps = ptr;
	}
	//处理
    //释放
	fclose(ps);
	ps = NULL;
	return 0;
}

有同学又问了:

                        那为啥不直接让结构体的成员为int*?然后动态开辟一块空间给int*?

那咱就来分析一下以下代码在空间中是什么样的?

struct student
{
	int i;
	int* arr;
};

当我有这样一个结构,那么你因该期望有如下下结果

 既然刚刚柔性数组都是用malloc在堆上开辟的

                                               不妨控制变量,让这个结构也在堆上开辟看看到底柔性数组好在哪?

代码如下:

#include<stdio.h>
#include<string.h>
#include<stdlib.h>

struct student
{
	int i;
	int* arr;
};

int main()
{
	struct student* ps = (struct student*)malloc(sizeof(struct student));
	if (ps == NULL)
	{
		perror("ps");
		return 1;
	}
	ps->i = 100;
	ps->arr = (int*)malloc(40);
	if (ps->arr == NULL)
	{
		perror("arr");
		return 1;
	}
	int i = 0;
	for (i = 0; i < 10; i++)
	{
		ps->arr[i] = i;
	}
	for (i = 0; i < 10; i++)
	{
		printf("%d", ps->arr[i]);
	}

	//释放  注意,要先释放数组
	free(ps->arr);
	ps->arr = NULL;
	free(ps);
	ps = NULL;
	return 0;
}

倘若你还想扩容,如下:

#include<stdio.h>
#include<string.h>
#include<stdlib.h>

struct student
{
	int i;
	int* arr;
};

int main()
{
	struct student* ps = (struct student*)malloc(sizeof(struct student));
	if (ps == NULL)
	{
		perror("ps");
		return 1;
	}
	ps->i = 100;
	ps->arr = (int*)malloc(40);
	if (ps->arr == NULL)
	{
		perror("arr");
		return 1;
	}
	int i = 0;
	for (i = 0; i < 10; i++)
	{
		ps->arr[i] = i;
	}
	for (i = 0; i < 10; i++)
	{
		printf("%d", ps->arr[i]);
	}
	//扩容
	int* ptr = (int*)realloc(ps->arr, 80);
	if (ptr == NULL)
	{
		perror("ptr");
		return 1;
	}
	//相应使用...
	
	//释放  注意,要先释放数组
	free(ps->arr);
	ps->arr = NULL;
	free(ps);
	ps = NULL;
	return 0;
}

那么现在回顾一下之前的问题:

                                                柔性数组和这个比起来到底有什么好呢?

首先

 

        想象一下

  •                       malloc的次数越多,free的次数就要多,容易出错造成内存泄漏
  •                       其次,多次进行malloc就会留下更多的内存碎片,导致内存利用率不高 

        所以好处便是

  •                         第一个好处是:方便内存释放
  •                         第二个好处是:这样有利于访问速度.

言简意骇,如果你听懂了,不妨:

 

  • 4
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

陈亦康

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值