柔性数组介绍

柔性数组

柔性数组,简而言之就是一个在struct结构里的标识占位符(不占结构struct的空间),只能在堆上生成。
在结构体内,有一个数组,必须是结构体中的最后一个元素,而且有特定的形式[]或者[0],结构体中至少要有两个成员体变量。
实例:
此时的字符数组 name 是不占空间的。
这里写图片描述

柔性数组的应用实例:

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
typedef struct data
{
    int len;    //一般用来表示字符数组的字符个数 
    char name[];

}S;
int main(void)
{
S s;
printf(“sizeof(s)=%d\n”,sizeof(s));

<span class="hljs-keyword">int</span> len = <span class="hljs-number">10</span>; <span class="hljs-comment">//申请空间 </span>
<span class="hljs-keyword">struct</span> data *p =(<span class="hljs-keyword">struct</span> data*)<span class="hljs-built_in">malloc</span>(<span class="hljs-keyword">sizeof</span>(s)+<span class="hljs-keyword">sizeof</span>(<span class="hljs-keyword">char</span>)*len);

<span class="hljs-comment">//判断是否申请成功&amp;请空处理 </span>

p-&gt;len = len;
<span class="hljs-built_in">strcpy</span>(p-&gt;name,<span class="hljs-string">"helloqpy"</span>); 

<span class="hljs-built_in">printf</span>(<span class="hljs-string">"%s\n"</span>,p-&gt;name); 

<span class="hljs-comment">//释放指针p</span>
<span class="hljs-built_in">free</span>(p);
<span class="hljs-keyword">return</span> <span class="hljs-number">0</span>;

}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28

程序运行结果:
这里写图片描述


这样子我们就有疑问,柔性数组到底方便在哪里了?每次使用它还要申请堆内存,我们直接在结构体里面放一个字符串指针,然后给这个指针再malloc分配一下内存不就好了么?

如下面代码:
这里写图片描述

但是注意:此时的len和字符串指针是一块存储的 但是结构体里面的字符串 也就是helloqpy和我们的结构体是分开的 ,其存储的位置在指针存储。

那么我们为什么要使用柔性数组??

是因为我们想给一个结构体内的数据分配一个连续的内存!这样做的意义有两个好处:
第一个意义是,方便内存释放。如果我们的代码是在一个给别人用的函数中,你在里面做了二次内存分配,并把整个结构体返回给用户。用户调用free可以释放结构体,但是用户并不知道这个结构体内的成员也需要free,所以你不能指望用户来发现这个事。所以,如果我们把结构体的内存以及其成员要的内存一次性分配好了,并返回给用户一个结构体指针,用户做一次free就可以把所有的内存也给释放掉。(读到这里,你一定会觉得C++的封闭中的析构函数会让这事容易和干净很多)

第二个原因是,这样有利于访问速度。连续的内存有益于提高访问速度,也有益于减少内存碎片。(其实,我个人觉得也没多高了,反正你跑不了要用做偏移量的加法来寻址)


使用柔性数组实现斐波那契数列

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
typedef struct data
{
    int n;  //表示数列的项数 
    int arr[];//柔性数组 

}S;
//遍历斐波那契数列的函数
void show_arr(struct data *p_str)
{
int i=0;
for(i=0;i<p_str->n;i++)
//注意此处是p_str->n,而不是len 要看传进来的参数
{
printf(“第(%d)项arr[%d]=%d\n”,(i+1),i,p_str->arr[i]);
}
}

//生成斐波那契数列的函数
void create_arr(int len)
{
struct data *p_str = (struct data *)malloc(sizeof(struct data)+sizeof(int)*len);
p_str->n = len;
//循环赋值
int i = 0;
for(i=0;i<len;i++)
{
if(i<=1) //arr[0]和arr[1]是第一项和第二项是1
p_str->arr[i] =1;
else if(i>=2)
{
//后面的是前两项的和
p_str->arr[i] = p_str->arr[i-1] + p_str->arr[i-2];
}
}
//调用遍历函数
show_arr(p_str);
free(p_str);

}

int main(void)
{
int len = 10;
//调用生成数列的函数即可
create_arr(len);
return 0;
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50

函数实现效果如下:
这里写图片描述

</article>
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值