一个会跳舞的数组?(你知道什么是柔性数组吗?不懂的话就让我们一起学习一下什么是柔性数组吧!)

发布于:2022-11-09 ⋅ 阅读:(6) ⋅ 点赞:(0) ⋅ 评论:(0)

你知道什么是柔性数组吗?今天就让我们了解一下什么是柔性数组和什么是柔性数组使用的替换方法

一、什么是柔性数组的使用

1.什么是柔性数组和如何创建柔性数组

(1.)首先我们讲一下柔性数组的概念:柔性数组就是一个未知大小的数组,可以随意调整大小的数组,在进行结构体的创建时,结构体的最后一个元素是允许定义一个未知大小的数组的这样一个结构体成员变量,此时这个结构体中的数组成员变量就是一个柔性数组成员

(2.)所以柔性数组的创建方式就明目了然了,就是在一个结构体中去创建例:

struct S
{
	int n;
  //int arr[0];写成这个也是一样的
	int arr[];//此时这个未知大小的数组就是我们今天要学的柔性数组(可以随意调整大小的数组)
};

(3.) 这个就是一个柔性数组的创建(并且有两种方式进行)

2.此时我们学会了创建,接下来我们就来看一下它是怎么使用的

(1.)首先使用前我们这边要讲一下什么是注意事项(使用说明书)

(2.)当我们在计算一个含有柔性数组的结构体的大小时,此时这个结构体的大小并不包括柔性数组的大小,下面用一个代码来演示一下:

struct S
{
	int n;
	int arr[];
};
int main()
{
	printf("%2d\n",sizeof(struct S));
	
	return 0;
}

在这里插入图片描述

(3.)这个的意思就是计算结构体的大小,答案为 4 ,充分表明出了我上述的那句话(计算大小时,并不计算柔性数组的大小)
(4.)所以我们就可以通过这个特性来使用我的柔性数组,代码如下:

struct S
{
	int n;
	//int arr[0];
	int arr[];
};
int main()
{
	struct S s;
	struct S* p = (struct S*)malloc(sizeof(struct S) + 5 * sizeof(int));
	
	return 0;
}

如代码所示:struct S* p = (struct S*)malloc(sizeof(struct S) + 5 * sizeof(int));我中这句代码就是对我的柔性数组的一个使用方法

(5.)意思就是开辟一个 int类型大小的空间(4) + 一个我的柔性数组大小的空间(20),所以此时

我的柔性数组的空间就变大了,变成了20,然后开辟完了空间我再用我的 struct S 这个结构体创建一

个结构体指针(struct S* p),来指向我此时的这个空间的地址 ,所以此时 p 这个指针就有了我的结

构体的地址,此时 p 指针就相当于是我的整个结构体了(所以想使用柔性数组,我就可以通过 p 这

个指针来使用,因为我的柔性数组在结构体中,我的结构体此时在 p 指针变量中)所以这就是一个典

型的对我的柔性数组(可任意调整大小的数组)的使用方式

(6.)上述这段话涉及多个知识点要好好理解哦!

(7.)会了上述的基本的使用,此时我们来一个真正的场景使用

代码如下:

struct S
{
	int n;
	//int arr[0];
	int arr[];
};
int main()
{
	struct S* ps = (struct S*)malloc(sizeof(struct S) + 5 * sizeof(int));
	if (ps != NULL)
	{
		ps->n = 100;
		int i = 0;
		for (i = 0; i < 5; i++)
		{
			ps->arr[i] = i;
		}
		for (i = 0; i < 5; i++)
		{
			printf("%d ", ps->arr[i]);

		}

		printf("\n");

		struct S* str = (struct S*)realloc(ps, 44);
			if (str != NULL)
			{
				ps = str;
			}
			for (i = 5; i < 10; i++)
			{
				ps->arr[i] = i;
			}
			for (i = 0; i < 10; i++)
			{
				printf("%d ", ps->arr[i]);
				
			}

			printf("\n");

	}
    free(ps);
    ps=NULL;
    
	return 0;
}

输出结果如下:

在这里插入图片描述

(8.)首先这个代码的代码格式是可以的

(9.)总的就是通过进行动态开辟的内存进行对这个柔性数组进行调整,关键就是这两步

1.struct S* ps = (struct S*)malloc(sizeof(struct S) + 5 * sizeof(int));

2.struct S* str = (struct S*)realloc(ps, 44);
第一步的意思上面讲过(就是为了使我的柔性数组的空间为20)

第二步就是追加动态内存而已,对malloc开辟的内存进行进一步的调整(其实也就是在对我的柔性数

组进行调整,别的也没有,因为此时malloc的大小就决定了我的柔性数组的大小,所以它们就是一个

共同体)

(10.)然后剩下的那些,就只是对我的柔性数组进行使用而已,我柔性数组有多少空间就使用多少

空间,空间不够了,就用realloc来追加空间的意思而已,然后就能使我的柔性数组变大(调整),这

样就可以想要用多大的数组,就用多大的数组了

(11.)所以 以上就是柔性数组的相关内容和使用

二、柔性数组使用的替换方法

1.替换方法的总体代码:

struct S
{
	int n;
	int* p;
};
int main()
{
	int i = 0;
	struct S* ps = (struct S*)malloc(sizeof(struct S));
	ps->p = (int*)malloc(5 * sizeof(int));
	
	for (i = 0; i < 5; i++)
	{
		*(ps->p + i) = i;

	}
	for (i = 0; i < 5; i++)
	{
		printf("%d ", *(ps->p + i) = i);

	}
	printf("\n");

	//调整大小
	int* ptr = (int*)realloc(ps->p, 10 * sizeof(int));
	if (ptr != NULL)
	{
		ps->p = ptr;

	}
	for (i = 5; i < 10; i++)
	{
		*(ps->p + i) = i;
	}
	for (i = 0; i < 10; i++);
	{
		printf("%d ", *(ps->p + i));

	}
	free(ps->p);
	ps->p = NULL;
	free(ps);
	ps = NULL;

	return 0;
}

(1.)这个就是使用了一个指针的方法对内存进行调整
原理如下图所示:
在这里插入图片描述

(2.)就是在结构体变量中创建一个指针,然后用这个指针去指向外部空间的内存,达到改变结构体本身内存大小的作用

(3.)所以这种方法也可以起到调整结构体大小的作用(和柔性数组异曲同工)

(4.)但是这种方法并没有柔性数组的方法好

2.主要的缺点:

1.返回的动态内存多个(容易在返回内存时出现错误)(返回内存不方便)

2.开辟了多个空间(空间分布随机)

3.访问速率较慢(地址存放不连续)

(1.)访问较慢的原因是

1.地址存放不连续
导致我的CPU从寄存器上访问内存时访问速率下降(因为我的CPU在访问寄存器时,有一个局部性

的原理,导致CPU有百分之80的概率访问的是寄存器周边的地址,所以如果地址是连续性存放的访

问效率就高,不是连续性存放访问效率就低)

2.所以当我们使用柔性数组时,就可以提高我的内存访问效率