柔性数组(Flexible Array Members)在C语言中的应用

2023-12-04 09:30

本文主要是介绍柔性数组(Flexible Array Members)在C语言中的应用,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

什么是柔性数组?

在C语言中,柔性数组(Flexible Array Members,FAMs)是C99标凈引入的一种便捷的数据结构,用于声明具有可变大小数组的结构体。柔性数组通常用于当结构体的大小在编译时不确定,但又希望能够连续存储数据时。C99 中,结构中的最后一个元素允许是未知大小的数组,这就叫做『柔性数组』成员。

例如:

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

有些编译器会报错无法编译改成:

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

示例

 

#include <stdio.h>
#include <stdlib.h>// 定义一个包含柔性数组成员的结构体
typedef struct {int length;double data[];  // 柔性数组成员
} flexible_array_struct;int main() {// 计算基础结构体大小和总大小size_t base_size = sizeof(flexible_array_struct);int array_length = 5;size_t total_size = base_size + sizeof(double) * array_length;// 动态分配内存flexible_array_struct *flex_array = (flexible_array_struct*)malloc(total_size);flex_array->length = array_length;// 初始化数组成员for(int i = 0; i < array_length; ++i) {flex_array->data[i] = i * 1.1;  // 填充数组数据}// 打印数组内容for(int i = 0; i < array_length; ++i) {printf("%f ", flex_array->data[i]);}// 释放内存free(flex_array);return 0;
}

这段代码首先计算了不包括柔性数组成员的结构体的基础大小base_size,然后指定了柔性数组的期望长度array_length并计算了整个结构体的总大小total_size。使用malloc动态分配了足够的内存来存储结构体和柔性数组成员。初始化柔性数组成员data并填充了一些数据。然后通过循环打印了柔性数组的内容。最后使用free释放了分配给结构体的内存。

 柔性数组的特点

  • 结构中的柔性数组成员前面必须有至少有一个其他成员。
  • sizeof返回的这种结构大小不包括柔性数组的内存。
  • 包含柔性数组成员的结构用malloc()函数进行内存的动态分配,并且分配的内存应该大于结构的大小,以适应柔性数组的预期大小。

例如:

typedef struct st_type
{int i;int a[0];//柔性数组成员
}type_a;
printf("%d\n", sizeof(type_a));//输出的是4

柔性数组的优势

代码1

//代码1
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);
// 这样柔性数组成员a相当于获得了100个int类型元素的连续空间。

代码2

//代码2
typedef struct st_type
{int i;int *p_a;
}type_a;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;

代码1和2可以完成同样的功能,但代码1有两个好处:

  1. 方便内存释放。如果把结构体的内存以及其成员要的内存一次性分配好,并返回用户一个结构体指针,用户做一次free就可以把所有的内存释放掉。
  2. 有利于访问速度并且减少内存碎片。

注意事项

  • 柔性数组成员没有分配固定的内存,所以在分配结构体内存时必须考虑到数组的大小。
  • 由于柔性数组的长度在编译时是不确定的,因此它们不占用结构体大小的计算。
  • 在动态分配结构体内存时,需要为柔性数组显式分配内存空间。

这篇关于柔性数组(Flexible Array Members)在C语言中的应用的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



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

相关文章

深入浅出SpringBoot WebSocket构建实时应用全面指南

《深入浅出SpringBootWebSocket构建实时应用全面指南》WebSocket是一种在单个TCP连接上进行全双工通信的协议,这篇文章主要为大家详细介绍了SpringBoot如何集成WebS... 目录前言为什么需要 WebSocketWebSocket 是什么Spring Boot 如何简化 We

Java Stream流之GroupBy的用法及应用场景

《JavaStream流之GroupBy的用法及应用场景》本教程将详细介绍如何在Java中使用Stream流的groupby方法,包括基本用法和一些常见的实际应用场景,感兴趣的朋友一起看看吧... 目录Java Stream流之GroupBy的用法1. 前言2. 基础概念什么是 GroupBy?Stream

python中列表应用和扩展性实用详解

《python中列表应用和扩展性实用详解》文章介绍了Python列表的核心特性:有序数据集合,用[]定义,元素类型可不同,支持迭代、循环、切片,可执行增删改查、排序、推导式及嵌套操作,是常用的数据处理... 目录1、列表定义2、格式3、列表是可迭代对象4、列表的常见操作总结1、列表定义是处理一组有序项目的

C#中的Converter的具体应用

《C#中的Converter的具体应用》C#中的Converter提供了一种灵活的类型转换机制,本文详细介绍了Converter的基本概念、使用场景,具有一定的参考价值,感兴趣的可以了解一下... 目录Converter的基本概念1. Converter委托2. 使用场景布尔型转换示例示例1:简单的字符串到

C语言进阶(预处理命令详解)

《C语言进阶(预处理命令详解)》文章讲解了宏定义规范、头文件包含方式及条件编译应用,强调带参宏需加括号避免计算错误,头文件应声明函数原型以便主函数调用,条件编译通过宏定义控制代码编译,适用于测试与模块... 目录1.宏定义1.1不带参宏1.2带参宏2.头文件的包含2.1头文件中的内容2.2工程结构3.条件编

Spring Boot Actuator应用监控与管理的详细步骤

《SpringBootActuator应用监控与管理的详细步骤》SpringBootActuator是SpringBoot的监控工具,提供健康检查、性能指标、日志管理等核心功能,支持自定义和扩展端... 目录一、 Spring Boot Actuator 概述二、 集成 Spring Boot Actuat

PyTorch中的词嵌入层(nn.Embedding)详解与实战应用示例

《PyTorch中的词嵌入层(nn.Embedding)详解与实战应用示例》词嵌入解决NLP维度灾难,捕捉语义关系,PyTorch的nn.Embedding模块提供灵活实现,支持参数配置、预训练及变长... 目录一、词嵌入(Word Embedding)简介为什么需要词嵌入?二、PyTorch中的nn.Em

Go语言并发之通知退出机制的实现

《Go语言并发之通知退出机制的实现》本文主要介绍了Go语言并发之通知退出机制的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧... 目录1、通知退出机制1.1 进程/main函数退出1.2 通过channel退出1.3 通过cont

Go语言编译环境设置教程

《Go语言编译环境设置教程》Go语言支持高并发(goroutine)、自动垃圾回收,编译为跨平台二进制文件,云原生兼容且社区活跃,开发便捷,内置测试与vet工具辅助检测错误,依赖模块化管理,提升开发效... 目录Go语言优势下载 Go  配置编译环境配置 GOPROXYIDE 设置(VS Code)一些基本

Spring Boot3.0新特性全面解析与应用实战

《SpringBoot3.0新特性全面解析与应用实战》SpringBoot3.0作为Spring生态系统的一个重要里程碑,带来了众多令人兴奋的新特性和改进,本文将深入解析SpringBoot3.0的... 目录核心变化概览Java版本要求提升迁移至Jakarta EE重要新特性详解1. Native Ima