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

人生之路不会是一帆风顺的,我们会遇上顺境,也会遇上逆境,在所有成功路上折磨你的,背后都隐藏着激励你奋发向上的动机,人生没有如果,只有后果与结果,成熟,就是用微笑来面对一切小事。

导读:本篇文章讲解 【C语言】拓展解析篇——柔性数组,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com,来源:原文

       

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

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

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

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


哈哈哈,不用苦恼

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

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

 

在C99标准中

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

        它是什么呢?

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


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

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

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

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

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

        有同学可能会问了:

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

                                        柔性是怎么体现的啊?

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

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

 

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

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

                                                                看代码:

#include<stdio.h>

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

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

运行结果:

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

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

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

 欸嘿,那第三个呢?

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

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

#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;
}

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

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

 此时,若是我有想法:

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

#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;
};

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

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

 既然刚刚柔性数组都是用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;
}

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

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

首先

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

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

        想象一下

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

        所以好处便是

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

言简意骇,如果你听懂了,不妨:【C语言】拓展解析篇——柔性数组

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

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由半码博客整理,本文链接:https://www.bmabk.com/index.php/post/124379.html

(0)

相关推荐

发表回复

登录后才能评论
半码博客——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!