1.柔性数组

2024-05-15 07:12
文章标签 数组 柔性

本文主要是介绍1.柔性数组,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

1.柔性数组

我们先来介绍一下什么是柔性数组:

在C语言中,柔性数组(Flexible Array)并不是一个标准的术语,但它通常指的是结构体中最后一个元素是一个没有指定大小的数组。这种结构体设计允许在运行时动态分配数组的大小,从而提供了更大的灵活性

这里给一串代码来解释一下:

struct S
{int i;int a[0];//柔性数组成员
};

但是呢有的编译器会报错无法编译这时候我们可以改成这样的:

struct st_type
{int i;int a[];//柔性数组成员
};
1.1柔性数组的特点:

结构中的柔性数组成员前面必须至少一个其他成员。

sizeof返回的这种结构大小不包括柔性数组的内存

包含柔性数组成员的结构用malloc()函数进行内存的动态分配,并且分配的内存应该大于结构的大小。以适应柔性数组的预期大小。

下面我给出一个例子:

typedef struct S
{int i;//柔性数组成员前面必须至少一个其他成员。int a[0];//柔性数组成员
};
int main()
{printf("%d\n", sizeof(type_a));//输出的是4就说明sizeof返回的这种结构大小不包括柔性数组的内存return 0;
}

第三个特点怎么解释:

 柔性数组的这个特点意味着在使用  malloc()  函数为包含柔性数组成员的结构体动态分配内存时,需要分配的内存大小不仅要包括结构体本身的大小,还要额外分配足够的空间来容纳柔性数组的元素。

就是我们在创建一个结构体变量的时候我不是:

struct S s不是这样创建。

柔性数组成员不是这样开辟空间是使用malloc函数进行的。用malloc把包含柔性数组的结构体创建到堆上 :

malloc(sizeof(struct S)+5*sizeof(int))

这里的sizeof(struct S)只包含柔性数组前面的成员大小,然后再加上柔性数组的大小(这个空间你随意创建)


具体来说,当你使用  malloc()  为一个结构体分配内存时,你需要计算出结构体的大小,然后根据柔性数组的预期大小来增加额外的内存分配。这是因为柔性数组的大小在编译时是未知的,它需要在下面是一个具体的例子来解释这个特点:
假设我们有一个结构体  MyStruct  ,它包含一个整型成员  size  和一个柔性数组成员  data  :运行时根据实际情况来确定。

typedef struct {int size; // 结构体的其他成员int data[]; // 柔性数组成员
} MyStruct;

 如果我们想要为这个结构体分配内存,并且柔性数组的预期大小是10个整型元素,那么我们需要这样分配内存:

int main() {int n = 10; // 柔性数组的预期大小// 分配结构体和柔性数组的内存MyStruct *myStruct = malloc(sizeof(MyStruct) + sizeof(int) * n);if (myStruct != NULL) {// 初始化结构体的其他成员myStruct->size = n;// 使用柔性数组...// ...// 释放内存free(myStruct);} else {fprintf(stderr, "Memory allocation failed\n");}return 0;
}

在这个例子中,我们首先计算了结构体的大小(  sizeof(MyStruct)  ),然后根据柔性数组的预期大小(  n  个整型元素)计算了额外需要分配的内存大小(  sizeof(int) * n  )。接着,我们使用  malloc()  函数将这两部分内存大小相加,为结构体和柔性数组分配了足够的内存
这样,我们就可以在运行时动态地为柔性数组分配内存,并且可以按照需要调整柔性数组的大小。这种灵活性是柔性数组设计的核心优势之一。 

1.2柔性数组的使用
#include <stdio.h>
#include <stdlib.h>
typedef struct type_a
{int i;int a[0];
};int main()
{int i = 0;type_a *p = (type_a*)malloc(sizeof(type_a)+100*sizeof(int));//业务处理p->i = 100;for(i=0; i<100; i++){p->a[i] = i;}free(p);return 0;
}

这样的柔性数组成员a,相当于获得了100个整型元素的连续空间。

1.3柔性数组的优势

上述的type_a结构也可以设计为下面的结构,也能完成同样的效果。

#include <stdio.h>
#include <stdlib.h>
typedef struct st_type
{int i;int *p_a;
}type_a;
int main()
{type_a *p = (type_a *)malloc(sizeof(type_a));p->i = 100;p->p_a = (int *)malloc(p->i*sizeof(int));//业务处理for(i=0; i<100; i++){p->p_a[i] = i;}//释放空间free(p->p_a);p->p_a = NULL;free(p);
p = NULL;return 0;
}

 上述 代码1代码2 可以完成同样的功能,但是 方法1的实现有两个好处:
个好处是:方便内存释放
如果我们的代码是在一个给别人用的函数中,你在里面做了二次内存分配,并把整个结构体返回给用户。用户调用自由可以释放结构体,但是用户并不知道这个结构体内的成员也需要自由,所以你不能指望用户来发现这个事。所以,如果我们把结构体的内存以及其成员要的内存一次性分配好了,并返回给用户一个结构体指针,用户做一次免费就可以把所有的内存也给释放掉。
个好处是:这样有利于访问速度
连续的内存有益于提高访问速度,也有益于减少内存碎片。(其实,我个人觉得也没多高了,反正你跑不了要用做偏移量的加法来寻址)

2.总结c/c++中程序内存区域划分

C/C++程序内存分配的几个区域:
1.栈区(stack):在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时这些存储单元自动被释放。栈内存分配运算内置于处理器的指令集中,效率很高,但是分配的内存容量有限。 栈区主要存放运行函数而分配的局部变量、函数参数、返回数据、返回地址等。
《函数栈帧的创建和销毁》
堆区(heap):一般由程序员分配释放,若程序员不释放,程序结束时可能由0S回收。分配方式类似于链表。
数据段(静态区):(static)存放全局变量、静态数据。程序结束后由系统释放。
代码段:存放函数体(类成员函数和全局函数)的二进制代码。

  

这篇关于1.柔性数组的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/991153

相关文章

C++初始化数组的几种常见方法(简单易懂)

《C++初始化数组的几种常见方法(简单易懂)》本文介绍了C++中数组的初始化方法,包括一维数组和二维数组的初始化,以及用new动态初始化数组,在C++11及以上版本中,还提供了使用std::array... 目录1、初始化一维数组1.1、使用列表初始化(推荐方式)1.2、初始化部分列表1.3、使用std::

C++ Primer 多维数组的使用

《C++Primer多维数组的使用》本文主要介绍了多维数组在C++语言中的定义、初始化、下标引用以及使用范围for语句处理多维数组的方法,具有一定的参考价值,感兴趣的可以了解一下... 目录多维数组多维数组的初始化多维数组的下标引用使用范围for语句处理多维数组指针和多维数组多维数组严格来说,C++语言没

Java 字符数组转字符串的常用方法

《Java字符数组转字符串的常用方法》文章总结了在Java中将字符数组转换为字符串的几种常用方法,包括使用String构造函数、String.valueOf()方法、StringBuilder以及A... 目录1. 使用String构造函数1.1 基本转换方法1.2 注意事项2. 使用String.valu

JAVA中整型数组、字符串数组、整型数和字符串 的创建与转换的方法

《JAVA中整型数组、字符串数组、整型数和字符串的创建与转换的方法》本文介绍了Java中字符串、字符数组和整型数组的创建方法,以及它们之间的转换方法,还详细讲解了字符串中的一些常用方法,如index... 目录一、字符串、字符数组和整型数组的创建1、字符串的创建方法1.1 通过引用字符数组来创建字符串1.2

vue如何监听对象或者数组某个属性的变化详解

《vue如何监听对象或者数组某个属性的变化详解》这篇文章主要给大家介绍了关于vue如何监听对象或者数组某个属性的变化,在Vue.js中可以通过watch监听属性变化并动态修改其他属性的值,watch通... 目录前言用watch监听深度监听使用计算属性watch和计算属性的区别在vue 3中使用watchE

hdu2241(二分+合并数组)

题意:判断是否存在a+b+c = x,a,b,c分别属于集合A,B,C 如果用暴力会超时,所以这里用到了数组合并,将b,c数组合并成d,d数组存的是b,c数组元素的和,然后对d数组进行二分就可以了 代码如下(附注释): #include<iostream>#include<algorithm>#include<cstring>#include<stack>#include<que

hdu 1166 敌兵布阵(树状数组 or 线段树)

题意是求一个线段的和,在线段上可以进行加减的修改。 树状数组的模板题。 代码: #include <stdio.h>#include <string.h>const int maxn = 50000 + 1;int c[maxn];int n;int lowbit(int x){return x & -x;}void add(int x, int num){while

C语言:柔性数组

数组定义 柔性数组 err int arr[0] = {0}; // ERROR 柔性数组 // 常见struct Test{int len;char arr[1024];} // 柔性数组struct Test{int len;char arr[0];}struct Test *t;t = malloc(sizeof(Test) + 11);strcpy(t->arr,

C 语言基础之数组

文章目录 什么是数组数组变量的声明多维数组 什么是数组 数组,顾名思义,就是一组数。 假如班上有 30 个同学,让你编程统计每个人的分数,求最高分、最低分、平均分等。如果不知道数组,你只能这样写代码: int ZhangSan_score = 95;int LiSi_score = 90;......int LiuDong_score = 100;int Zhou

计算数组的斜率,偏移,R2

模拟Excel中的R2的计算。         public bool fnCheckRear_R2(List<double[]> lRear, int iMinRear, int iMaxRear, ref double dR2)         {             bool bResult = true;             int n = 0;             dou