柔性数组

柔性数组

柔性数组,简而言之就是一个在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));

    int len = 10; //申请空间 
    struct data *p =(struct data*)malloc(sizeof(s)+sizeof(char)*len);

    //判断是否申请成功&请空处理 

    p->len = len;
    strcpy(p->name,"helloqpy"); 

    printf("%s\n",p->name); 

    //释放指针p
    free(p);
    return 0;
}

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


这样子我们就有疑问,柔性数组到底方便在哪里了?每次使用它还要申请堆内存,我们直接在结构体里面放一个字符串指针,然后给这个指针再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;
}

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

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值