当前位置: 首页 > news >正文

【C语言进阶】你听说过柔性数组吗?

在这里插入图片描述

👦个人主页:@Weraphael
✍🏻作者简介:目前是C语言学习者
✈️专栏:C语言航路
🐋 希望大家多多支持,咱一起进步!😁
如果文章对你有帮助的话
欢迎 评论💬 点赞👍🏻 收藏 📂 加关注


前言

说起数组,一维数组、二维数组、字符数组、整型数组和浮点型数组,我相信大家并不陌生吧,今天我们一起看看柔性数组!

目录

  • 前言
  • 一、柔性数组的概念和定义
  • 二、柔性数组的特点
  • 三、柔性数组的使用
  • 四、柔性数组的优势

一、柔性数组的概念和定义

在C99中,结构中的最后一个元素允许是未知大小的数组,我们把这样的数组称为柔性数组成员。

【定义】

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

若有些编译器无法编译,可以改成以下这种:

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

二、柔性数组的特点

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

三、柔性数组的使用

动态内存开辟函数讲解:传送门

#include <stdio.h>
#include <stdlib.h>
struct S
{int i;char a[];
};
int main()
{//包含柔性数组成员的结构用`malloc`函数进行动态内存分配//并且分配的内存应该大于结构体大小struct S* sp = (struct S*)malloc(sizeof(struct S) + 10 * sizeof(char));//若sp为空指针,说明开辟动态内存失败if (sp == NULL){return 1;}//否则开辟成功//使用sp->i = 100;for (int i = 0; i < 10; i++){sp->a[i] = 'x';}//打印for (int i = 0; i < 10; i++){printf("%c ", sp->a[i]);}//释放free(sp);sp = NULL;return 0;
}

在这里插入图片描述

甚至还能扩容realloc

#include <stdio.h>
#include <stdlib.h>
struct S
{int i;char a[];
};
int main()
{//包含柔性数组成员的结构用`malloc`函数进行动态内存分配//并且分配的内存应该大于结构体大小struct S* sp = (struct S*)malloc(sizeof(struct S) + 10 * sizeof(char));//若sp为空指针,说明开辟动态内存失败if (sp == NULL){return 1;}//否则开辟成功//使用sp->i = 100;for (int i = 0; i < 10; i++){sp->a[i] = 'x';}//扩容(多加10字节的空间)struct S* p = (struct S *)realloc(sp, sizeof(struct S) + sizeof(char) * 20);//如果p为空指针说明扩容失败if (p == NULL){return 1;}else{sp = p;p = NULL;}for (int i = 10; i < 20; i++){sp->a[i] = 'w';}//打印printf("%d\n", sp->i);for (int i = 0; i < 20; i++){printf("%c ", sp->a[i]);}return 0;
}

在这里插入图片描述

所以柔性数组在内存其实是这样的
在这里插入图片描述
它在内存是连续

四、柔性数组的优势

除【柔性数组的使用】样例以外,也可以设计成下面这样:

#include <stdio.h>
#include <stdlib.h>struct  S
{int i;char* a;
};int main()
{//为结构体开辟空间struct S* sp = (struct S*)malloc(sizeof(struct S));//若sp = NULL,说明开辟失败if (sp == NULL){return 1;}//否则开辟成功//使用内存空间sp->i = 100;//为char* a开辟10个字节空间sp->a = (char*)malloc(sizeof(char) * 10);//使用for (int i = 0; i < 10; i++){sp->a[i] = 'w';}//或者还能为char* a扩容char* p = (char*)realloc(sp->a, 20 * sizeof(char));if (p == NULL){return 1;}else{sp->a = p;p = NULL;}//使用扩容的空间for (int i = 10; i < 20; i++){sp->a[i] = 'J';}//打印printf("int i = %d\n", sp->i);for (int i = 0; i < 20; i++){printf("%c ", sp->a[i]);}//释放空间free(sp->a);sp->a = NULL;free(sp);sp = NULL;return 0;
}

在这里插入图片描述

一个常见的问题:为什么要先释放sp->a的内存空间

  • 首先程序是先为结构体开辟空间
    在这里插入图片描述
  • 接着又为char*开辟空间
    在这里插入图片描述
    所以,若先对sp释放空间,到后面就不能通过sp找到char* c开辟的空间

柔性数组好处的总结:

  • 对于柔性数组来说,开辟空间(malloc)只需要一个,释放空间(free)也只需要一次,且内存空间是连续的,而对于上面的代码来说,开辟空间需要二次,释放空间也同样需要二次,且内存空间是不连续的。所以它第一个好处是方便内存释放
  • 连续的内存有益于提高访问速度

相关文章:

【C语言进阶】你听说过柔性数组吗?

&#x1f466;个人主页&#xff1a;Weraphael ✍&#x1f3fb;作者简介&#xff1a;目前是C语言学习者 ✈️专栏&#xff1a;C语言航路 &#x1f40b; 希望大家多多支持&#xff0c;咱一起进步&#xff01;&#x1f601; 如果文章对你有帮助的话 欢迎 评论&#x1f4ac; 点赞&a…...

[LeetCode]1237. 找出给定方程的正整数解

题目链接&#xff1a;https://leetcode.cn/problems/find-positive-integer-solution-for-a-given-equation/description/ 题目描述&#xff1a; 样例1&#xff1a; 输入&#xff1a;function_id 1, z 5 输出&#xff1a;[[1,4],[2,3],[3,2],[4,1]] 解释&#xff1a;functi…...

【路径规划】基于A*算法和Dijkstra算法的路径规划(Python代码实现)

&#x1f468;‍&#x1f393;个人主页&#xff1a;研学社的博客&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5;&#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密…...

蓝桥杯 stm32 PWM 设置占空比

本文代码使用 HAL 库。 文章目录 前言一、创建CubeMX 工程 ,占空比分析:二、相关函数:1. 获取 CNT函数2.设置CNT为 0 函数(计算器清零)3.开启TIM2_CH1的输入捕获中断函数4.TIM 回调函数三、设置上升沿,下降沿四、在lcd上显示 R40 占空比 详细代码五、设置占空比,输出 PW…...

React 合成事件理解

1 事件三个阶段 捕获、目标、处理 &#xff08;具体百度&#xff0c;后面有空补全&#xff09;2import React from "react";class Test extends React.Component {parentRef;childRef;constructor(props) {super(props);this.parentRef React.createRef();this.chil…...

202302|读书笔记——国图点滴

杂志剪影|看一本赚一本系列 anywhere 随心而行随心而动&#xff0c;极简相生复古文艺 热情洋溢 色彩斑斓 极致优雅 深邃魅力 新生绽放 灿若星空 异彩纷呈含苞待放 惊艳绽放 爱在云端 空中婚礼 暗夜浪漫 策马逐梦橘影相映 浆果红唇 梦幻无暇 永无止境浮光掠影 微酥清风低调奢华…...

Linux 操作系统原理 — NUMA 架构中的多线程调度开销与性能优化

目录 文章目录 目录前言NUMA 架构中的多线程性能开销1、跨 Node 的 Memory 访问开销2、跨 Core 的多线程 Cache 同步开销3、多线程上下文切换开销4、多线程模式切换开销5、中断处理的开销6、TLB 缓存失效的开销7、内存拷贝的开销NUMA 架构中的性能优化:使用多核编程代替多线程…...

OpenGL - 如何理解 VAO 与 VBO 之间的关系

系列文章目录 LearnOpenGL 笔记 - 入门 01 OpenGLLearnOpenGL 笔记 - 入门 02 创建窗口LearnOpenGL 笔记 - 入门 03 你好&#xff0c;窗口LearnOpenGL 笔记 - 入门 04 你好&#xff0c;三角形 文章目录系列文章目录1. 前言2. 渲染管线的入口 - 顶点着色器2.1 顶点着色器处理过…...

Linux中sed的使用

语法&#xff1a; sed [选项] [sed内置命令字符] [输入文件]选项&#xff1a; 参数说明-n取消默认色的输出常与sed内置命令p一起使用-i直接将修改结果写入文件&#xff0c;不用-i&#xff0c;sed修改的是内存数据-e多次编译&#xff0c;不需要管道符了-r支持正则扩展 sed的内…...

[软件工程导论(第六版)]第1章 软件工程学概述(复习笔记)

文章目录1.1 软件危机1.1.1 软件危机的介绍1.1.2 产生软件危机的原因1.1.3 消除软件危机的途径1.2 软件工程1.2.1 软件工程的介绍1.2.2 软件工程的基本原理1.2.3 软件工程方法学1.3 软件生命周期组成1.4 软件过程概念1.4.1 瀑布模型1.4.2 快速原型模型1.4.3 增量模型1.4.4 螺旋…...

ISP相关

Internet Service Provider&#xff0c;网络提供商/运营商&#xff0c;如电信、联通、移动等。 1. 与ISP互联的出口带宽 IDC或云提供商会与各运营商互联&#xff0c;互联的具体带宽数值一旦泄露&#xff0c;就会被恶意的攻击者利用。例如&#xff0c;若DDos攻击者知道了被攻击…...

vTESTstudio - VT System CAPL Functions - VT2004(续1)

成熟,就是某一个突如其来的时刻,把你的骄傲狠狠的踩到地上,任其开成花或者烂成泥。vtsStartStimulation - 启动激励输出功能&#xff1a;自动激励输出注意&#xff1a;在启动激励输出之前&#xff0c;一定要设置好输出模式Target&#xff1a;目标通道变量空间名称&#xff0c;例…...

WeakMap弱引用

let obj{name:张三} //{name:张三}这个对象能够被读取到&#xff0c;因为obj这个变量名对它的引用 ​ //将引用覆盖掉 objnull //这个对象将会被从内存中移除&#xff0c;因为我们已经失去了对他的所有引用 let obj{name:张三} let arr[obj] ​ objnull //对象{name:张三}不会…...

Springboot 使用quartz 定时任务 增删改查

前段时间公司项目用到了 定时任务 所以写了一篇定时任务的文章 &#xff0c;浏览量还不错 &#xff0c; Springboot 整合定时任务 ) 所以就准备写第二篇&#xff0c; 如果你是一名Java工程师&#xff0c;你也可以会看到如下的页面 &#xff0c;去添加定时任务 定时任务展示 :…...

华为OD机试 - 猜字谜(Python) | 机试题+算法思路 【2023】

最近更新的博客 华为OD机试 - 热点网络统计 | 备考思路,刷题要点,答疑 【新解法】 华为OD机试 - 查找单入口空闲区域 | 备考思路,刷题要点,答疑 【新解法】 华为OD机试 - 好朋友 | 备考思路,刷题要点,答疑 【新解法】 华为OD机试 - 找出同班小朋友 | 备考思路,刷题要点…...

Linux常用命令汇总

1、tcpdump抓包 tcpdump这个命令是用来抓包的&#xff0c;默认情况下这个命令是没有的&#xff0c;需要安装一下&#xff1a; yum install -y tcpdump 使用这个命令的时候最好是加上你网卡的名称&#xff0c;不然可能使用不了&#xff1a; tcpdump -nn -i {网卡名称} 网卡名称…...

1.TCP、UDP区别、TCP/IP七层、四层模型、应用层协议(计网)

文章目录1.OSI 七层模型是什么&#xff1f;每一层的作用是什么&#xff1f;2.TCP/IP 四层模型是什么&#xff1f;每一层的作用是什么&#xff1f;应用层&#xff08;Application layer&#xff09;传输层&#xff08;Transport layer&#xff09;网络层&#xff08;Network lay…...

气敏电阻的原理,结构,分类及应用场景总结

🏡《总目录》 目录 1,概述2,结构3,工作原理4,分类4.1,加热方式分类4.2,材料分类4.3,氧化还原分类5,应用场景6,总结1,概述 气敏电阻是指电阻值随着环境中某种气体的浓度变化而变化的电阻,本文对其工作原理,结构,分类和应用场景进行总结。 2,结构 气敏电阻由防爆…...

实验10 拓扑排序与最短路径2022

A. DS图—图的最短路径&#xff08;无框架&#xff09;题目描述给出一个图的邻接矩阵&#xff0c;输入顶点v&#xff0c;用迪杰斯特拉算法求顶点v到其它顶点的最短路径。输入第一行输入t&#xff0c;表示有t个测试实例第二行输入顶点数n和n个顶点信息第三行起&#xff0c;每行输…...

C/C++每日一练(20230218)

目录 1. 整数转罗马数字 2. 跳跃游戏 II 3. 买卖股票的最佳时机 IV 1. 整数转罗马数字 罗马数字包含以下七种字符&#xff1a; I&#xff0c; V&#xff0c; X&#xff0c; L&#xff0c;C&#xff0c;D 和 M。 字符 数值 I 1 V 5 X …...

ubuntu搭建nfs服务centos挂载访问

在Ubuntu上设置NFS服务器 在Ubuntu上&#xff0c;你可以使用apt包管理器来安装NFS服务器。打开终端并运行&#xff1a; sudo apt update sudo apt install nfs-kernel-server创建共享目录 创建一个目录用于共享&#xff0c;例如/shared&#xff1a; sudo mkdir /shared sud…...

【第二十一章 SDIO接口(SDIO)】

第二十一章 SDIO接口 目录 第二十一章 SDIO接口(SDIO) 1 SDIO 主要功能 2 SDIO 总线拓扑 3 SDIO 功能描述 3.1 SDIO 适配器 3.2 SDIOAHB 接口 4 卡功能描述 4.1 卡识别模式 4.2 卡复位 4.3 操作电压范围确认 4.4 卡识别过程 4.5 写数据块 4.6 读数据块 4.7 数据流…...

Nginx server_name 配置说明

Nginx 是一个高性能的反向代理和负载均衡服务器&#xff0c;其核心配置之一是 server 块中的 server_name 指令。server_name 决定了 Nginx 如何根据客户端请求的 Host 头匹配对应的虚拟主机&#xff08;Virtual Host&#xff09;。 1. 简介 Nginx 使用 server_name 指令来确定…...

云原生安全实战:API网关Kong的鉴权与限流详解

&#x1f525;「炎码工坊」技术弹药已装填&#xff01; 点击关注 → 解锁工业级干货【工具实测|项目避坑|源码燃烧指南】 一、基础概念 1. API网关&#xff08;API Gateway&#xff09; API网关是微服务架构中的核心组件&#xff0c;负责统一管理所有API的流量入口。它像一座…...

比较数据迁移后MySQL数据库和OceanBase数据仓库中的表

设计一个MySQL数据库和OceanBase数据仓库的表数据比较的详细程序流程,两张表是相同的结构,都有整型主键id字段,需要每次从数据库分批取得2000条数据,用于比较,比较操作的同时可以再取2000条数据,等上一次比较完成之后,开始比较,直到比较完所有的数据。比较操作需要比较…...

永磁同步电机无速度算法--基于卡尔曼滤波器的滑模观测器

一、原理介绍 传统滑模观测器采用如下结构&#xff1a; 传统SMO中LPF会带来相位延迟和幅值衰减&#xff0c;并且需要额外的相位补偿。 采用扩展卡尔曼滤波器代替常用低通滤波器(LPF)&#xff0c;可以去除高次谐波&#xff0c;并且不用相位补偿就可以获得一个误差较小的转子位…...

离线语音识别方案分析

随着人工智能技术的不断发展&#xff0c;语音识别技术也得到了广泛的应用&#xff0c;从智能家居到车载系统&#xff0c;语音识别正在改变我们与设备的交互方式。尤其是离线语音识别&#xff0c;由于其在没有网络连接的情况下仍然能提供稳定、准确的语音处理能力&#xff0c;广…...

6.9-QT模拟计算器

源码: 头文件: widget.h #ifndef WIDGET_H #define WIDGET_H#include <QWidget> #include <QMouseEvent>QT_BEGIN_NAMESPACE namespace Ui { class Widget; } QT_END_NAMESPACEclass Widget : public QWidget {Q_OBJECTpublic:Widget(QWidget *parent nullptr);…...

leetcode73-矩阵置零

leetcode 73 思路 记录 0 元素的位置&#xff1a;遍历整个矩阵&#xff0c;找出所有值为 0 的元素&#xff0c;并将它们的坐标记录在数组zeroPosition中置零操作&#xff1a;遍历记录的所有 0 元素位置&#xff0c;将每个位置对应的行和列的所有元素置为 0 具体步骤 初始化…...

ArcPy扩展模块的使用(3)

管理工程项目 arcpy.mp模块允许用户管理布局、地图、报表、文件夹连接、视图等工程项目。例如&#xff0c;可以更新、修复或替换图层数据源&#xff0c;修改图层的符号系统&#xff0c;甚至自动在线执行共享要托管在组织中的工程项。 以下代码展示了如何更新图层的数据源&…...