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

【C语言】柔性数组

柔性数组

  • 1. 柔性数组介绍
  • 2. 柔性数组特点
  • 3. 用例
    • 3.1 代码一:
    • 3.2 代码二:
  • 4. 柔性数组优势:

1. 柔性数组介绍

也许你从来没有听说过柔性数组(flexible array)这个概念,但是它确实是存在的。

C99 中,结构中的最后一个元素允许是未知大小的数组,这就叫做『柔性数组』成员。

例如:零长度数组概念

struct S
{int n;char c;int arr[];//柔性数组成员
};

有些编译器无法编译,可以改成:

struct S
{int n;char c;int arr[0];//柔性数组成员
};

2. 柔性数组特点

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

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

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

3. 用例

3.1 代码一:

在这里插入图片描述

//代码一:
struct S
{int n;char c;int arr[];
};
int main()
{struct S* ps = (struct S*)malloc(sizeof(struct S) + 10 * sizeof(int));//设置int arr数组元素为10个,10*sizeof(int)if (ps == NULL){printf("%s\n", strerror(errno));return 1;}ps->n = 100;ps->c = 'w';for (int i = 0;i < 10;i++){ps->arr[i] = i;}for (int i = 0;i < 10;i++){printf("%d\n", ps->arr[i]);}free(ps);ps = NULL;
}

3.2 代码二:

在这里插入图片描述

//代码二:
struct S
{int n;char c;int* arr;
};int main()
{struct S* ps = (struct S*)malloc(sizeof(struct S));if (ps == NULL){perror("malloc");return 1;}int*ptr = (int*)malloc(10 * sizeof(int));//设置int arr数组元素为10个,10*sizeof(int)if (ptr == NULL){perror("malloc2");return 1;}else{ps->arr = ptr;}//使用ps->n = 100;ps->c = 'w';int i = 0;for (i = 0; i < 10; i++){ps->arr[i] = i;}//打印for (i = 0; i < 10; i++){printf("%d ", ps->arr[i]);}//扩容 - 调整arr的大小ptr = realloc(ps->arr, 20 * sizeof(int));//增容int arr数组元素为20个,10*sizeof(int)if (ptr == NULL){perror("realloc");return 1;}else{ps->arr = ptr;}//使用ps->n = 100;ps->c = 'w';for (i = 0; i < 20; i++){ps->arr[i] = i;}//打印for (i = 0; i < 20; i++){printf("%d ", ps->arr[i]);}//释放free(ps->arr);ps->arr = NULL;free(ps);ps = NULL;return 0;
}

4. 柔性数组优势:

代码一和代码二都可以完成相同功能,但代码一有以下两个好处:

第一个好处是:方便内存释放。

如果我们的代码是在一个给别人用的函数中,你在里面做了二次内存分配,并把整个结构体返回给用户。

用户调用free可以释放结构体,但是用户并不知道这个结构体内的成员也需要free,所以你不能指望用户来发现这个事。

所以,如果我们把结构体的内存以及其成员要的内存一次性分配好了,并返回给用户一个结构体指针,用户做一次free就可以把所有的内存也给释放掉。
在这里插入图片描述

第二个好处是:这样有利于访问速度。

连续的内存有益于提高访问速度,也有益于减少内存碎片。

(其实,我个人觉得也没多高了,反正 你跑不了要用做偏移量的加法来寻址)

补充:局部性原理:

  • 局部性原理是计算机科学中的一种基本原理,指的是程序中的指令和数据在执行时会集中在较小的一部分存储器中,并且在短时间内重复使用。这种局部性表现在两个方面:时间局部性和空间局部性。

  • 时间局部性指的是,某个数据或指令一旦被使用,在短时间内会被多次使用。例如,在循环结构的程序中,循环体内的指令会被反复执行。

  • 空间局部性指的是,某个数据或指令的使用会对其周围的数据与指令产生影响,这些数据和指令也会在短时间内被多次使用。例如,在数组操作中,相邻的元素都会被频繁地访问。

  • 局部性原理的应用可以提高计算机系统的性能,例如通过缓存技术和虚拟内存技术,让系统可以快速地访问常用的数据和代码,从而减少了额外的访问时间和存储开销。

👊👊👊
感谢阅读!

相关文章:

【C语言】柔性数组

柔性数组1. 柔性数组介绍2. 柔性数组特点3. 用例3.1 代码一&#xff1a;3.2 代码二&#xff1a;4. 柔性数组优势&#xff1a;1. 柔性数组介绍 也许你从来没有听说过柔性数组&#xff08;flexible array&#xff09;这个概念&#xff0c;但是它确实是存在的。 C99 中&#xff0c…...

【Linux】权限详解

前言首先我们先来看一下权限的概念&#xff1a;在多用户计算机系统的管理中&#xff0c;权限&#xff08;privilege&#xff09;是指某个特定的用户具有特定的系统资源使用权力&#xff0c;像是文件夹&#xff0c;特定系统指令的使用或存储量的限制。通常&#xff0c;系统管理员…...

Android 之 打开相机 打开相册

Android 之 打开系统摄像头拍照 打开系统相册&#xff0c;并展示1&#xff0c;清单文件 AndroidManifest.xml<uses-permission android:name"android.permission.INTERNET" /><!--文件读取权限--><uses-permission android:name"android.permiss…...

C语言数据结构初阶(8)----栈与队列OJ题

CSDN的uu们&#xff0c;大家好。这里是C语言数据结构的第八讲。 目标&#xff1a;前路坎坷&#xff0c;披荆斩棘&#xff0c;扶摇直上。 博客主页&#xff1a; 姬如祎 收录专栏&#xff1a;数据结构与算法栈与队列的知识点我➡➡队列相关点我➡➡栈相关2. 用栈实现队列原题链接…...

JavaScript——原型对象

JavaScript——原型对象专题 文章目录JavaScript——原型对象专题1. 原型对象2. 原型对象的this指向3. 案例4. constructor属性5. 对象原型6. 总结7. 原型继承8. 原型链由先前的学习可知&#xff0c;构造函数实例创建的对象彼此独立、互不影响&#xff0c;很好的体现了面向对象…...

网络安全 2023 年为什么如此吃香?事实原来是这样....

前言由于我国网络安全起步晚&#xff0c;所以现在网络安全工程师十分紧缺。俗话说:没有网络安全就没有国家安全为什么选择网络安全&#xff1f;十四五发展规划建议明确提出建设网络强国&#xff0c;全面加强网络安全保障体系和能力建设&#xff0c;加强网络文明建设&#xff0c…...

(源码篇02)webpack5中的事件调度系统和NormalModuleFactary核心逻辑

1. 书接上回&#xff0c;从 this.factorizeQueue.add(options, callback); 开始 不是很清楚上下文的兄弟&#xff0c;可以去看下我之前写的 &#xff08;源码篇01&#xff09;浅析webpack5中Compiler中重要的hook调用过程。 此文比较干&#xff0c;各位读者开始阅读前&#xf…...

Vue2.x源码:new Vue()做了啥?

vue源码版本vue2.5.2 new Vue()做了啥? new Vue()会执行_init方法&#xff0c;而_init方法在initMixin函数中定义。 src/core/instance/index.js文件中定义了Vue function Vue (options) {this._init(options) }initMixin(Vue) stateMixin(Vue) eventsMixin(Vue) lifecycl…...

WinForm | C# 弹出简易的消息提示框 (仿Android Toast消息提示)

ApeForms Toast消息提示 文章目录ApeForms Toast消息提示前言方法原型及参数释义消息驻留延时消息弹出模式队列模式抢占模式复用模式UI库安装与使用获取示例源码前言 在使用手机的时候经常会见到屏幕的中下方会弹出消息提示框&#xff0c;它就是Toast&#xff0c;以下是百度百…...

1、DRF实战总结:DRF特点、序列化与RESTful API规范

Django这种基于MVC开发模式的传统框架&#xff0c;非常适合开发基于PC的传统网站&#xff0c;因为它同时包括了后端的开发(逻辑层、数据库层) 和前端的开发(如模板语言、样式)。现代网络应用Web APP或大型网站一般是一个后台&#xff0c;然后对应各种客户端(iOS, android, 浏览…...

SIP协议及其简单介绍

SIP协议及其简单介绍概述流程SIP流程两台设备建立会话原理使用场景概述 SIP&#xff08;Session Initiation Protocol&#xff0c;会话初始化协议&#xff09;是一个应用层协议&#xff0c;用于在互联网上创建、修改和终止多媒体会话。SIP是一个客户端/服务器协议&#xff0c;…...

安全防御第四天:防病毒网关

一、恶意软件1.按照传播方式分类&#xff08;1&#xff09;病毒病毒是一种基于硬件和操作系统的程序&#xff0c;具有感染和破坏能力&#xff0c;这与病毒程序的结构有关。病毒攻击的宿主程序是病毒的栖身地&#xff0c;它是病毒传播的目的地&#xff0c;又是下一次感染的出发点…...

Postman接口与压力测试实例

Postman是一款功能强大的网页调试与发送网页HTTP请求的Chrome插件。它提供功能强大的 Web API & HTTP 请求调试。 1、环境变量和全局变量设置 环境变量可以使用在以下地方&#xff1a; URLURL paramsHeader valuesform-data/url-encoded valuesRaw body contentHelper fi…...

TCP/IP socket

## TCP Socket 收发缓冲区: 每个socket在linux内核中都有一个发送缓冲区和一个接收缓冲区。 只要对端将数据发送过来&#xff0c;linux内核TCP/IP协议栈就会负责将数据缓存到socket对应的接收缓冲区中&#xff0c;无论是否调用recv。 recv()所做的工作&#xff0c;只是把内核缓…...

“工作三年,跳槽要求涨薪50%”,合理吗?

如果问在TI行业涨工资最快的方式是什么&#xff1f;回答最多的一定是&#xff1a;跳槽&#xff01;前段时间&#xff0c;知乎上这样一条帖子引发了不少IT圈子的朋友的讨论 &#xff0c;有网友提问 “程序员跳槽要求涨薪50%过分吗&#xff1f;”截图来源于知乎&#xff0c;如侵删…...

Vue学习计划九:了解Vue动画效果以及过渡动画和动态组件的使用方法

Vue.js 是一个流行的 JavaScript 框架&#xff0c;它提供了很多工具和功能&#xff0c;可以帮助开发人员创建动态、交互式的 Web 应用程序。其中之一就是动画效果&#xff0c;Vue.js 提供了一系列的 API 和指令&#xff0c;使得添加动画效果变得非常容易。 在 Vue.js 中&#…...

【Linux】进程理解与学习Ⅲ-环境变量

环境&#xff1a;centos7.6&#xff0c;腾讯云服务器Linux文章都放在了专栏&#xff1a;【Linux】欢迎支持订阅&#x1f339;相关文章推荐&#xff1a;【Linux】冯.诺依曼体系结构与操作系统【Linux】进程理解与学习Ⅰ-进程概念浅谈Linux下的shell--BASH【Linux】进程理解与学习…...

【三】一起算法---栈:STL stack、手写栈、单调栈

纸上得来终觉浅&#xff0c;绝知此事要躬行。大家好&#xff01;我是霜淮子&#xff0c;欢迎订阅我的专栏《算法系列》。 学习经典算法和经典代码&#xff0c;建立算法思维&#xff1b;大量编码让代码成为我们大脑的一部分。 ⭐️已更系列 1、基础数据结构 1.1、链表➡传送门 1…...

电路设计的一些概念

锁存器的产生 论述1 (转)时序电路&#xff0c;生成触发器&#xff0c;触发器是有使能端的&#xff0c;使能端无效时数据不变&#xff0c;这是触发器的特性。 组合逻辑&#xff0c;由于数据要保持不变&#xff0c;只能通过锁存器来保存。 第一个代码&#xff0c;由于是时序逻…...

【Linux】Linux下权限的理解

前言&#xff1a;在之前我们已经对基本的指令进行了深入的学习&#xff0c;接下来我将带领大家学习的是关于权限的相关问题。在之前&#xff0c;我们一直是使用的【root】用户&#xff0c;即为“超级用户”&#xff0c;通过对权限的学习之后&#xff0c;我们就会慢慢的切换到普…...

iOS 26 携众系统重磅更新,但“苹果智能”仍与国行无缘

美国西海岸的夏天&#xff0c;再次被苹果点燃。一年一度的全球开发者大会 WWDC25 如期而至&#xff0c;这不仅是开发者的盛宴&#xff0c;更是全球数亿苹果用户翘首以盼的科技春晚。今年&#xff0c;苹果依旧为我们带来了全家桶式的系统更新&#xff0c;包括 iOS 26、iPadOS 26…...

应用升级/灾备测试时使用guarantee 闪回点迅速回退

1.场景 应用要升级,当升级失败时,数据库回退到升级前. 要测试系统,测试完成后,数据库要回退到测试前。 相对于RMAN恢复需要很长时间&#xff0c; 数据库闪回只需要几分钟。 2.技术实现 数据库设置 2个db_recovery参数 创建guarantee闪回点&#xff0c;不需要开启数据库闪回。…...

python打卡day49

知识点回顾&#xff1a; 通道注意力模块复习空间注意力模块CBAM的定义 作业&#xff1a;尝试对今天的模型检查参数数目&#xff0c;并用tensorboard查看训练过程 import torch import torch.nn as nn# 定义通道注意力 class ChannelAttention(nn.Module):def __init__(self,…...

【项目实战】通过多模态+LangGraph实现PPT生成助手

PPT自动生成系统 基于LangGraph的PPT自动生成系统&#xff0c;可以将Markdown文档自动转换为PPT演示文稿。 功能特点 Markdown解析&#xff1a;自动解析Markdown文档结构PPT模板分析&#xff1a;分析PPT模板的布局和风格智能布局决策&#xff1a;匹配内容与合适的PPT布局自动…...

Unit 1 深度强化学习简介

Deep RL Course ——Unit 1 Introduction 从理论和实践层面深入学习深度强化学习。学会使用知名的深度强化学习库&#xff0c;例如 Stable Baselines3、RL Baselines3 Zoo、Sample Factory 和 CleanRL。在独特的环境中训练智能体&#xff0c;比如 SnowballFight、Huggy the Do…...

浅谈不同二分算法的查找情况

二分算法原理比较简单&#xff0c;但是实际的算法模板却有很多&#xff0c;这一切都源于二分查找问题中的复杂情况和二分算法的边界处理&#xff0c;以下是博主对一些二分算法查找的情况分析。 需要说明的是&#xff0c;以下二分算法都是基于有序序列为升序有序的情况&#xf…...

AI书签管理工具开发全记录(十九):嵌入资源处理

1.前言 &#x1f4dd; 在上一篇文章中&#xff0c;我们完成了书签的导入导出功能。本篇文章我们研究如何处理嵌入资源&#xff0c;方便后续将资源打包到一个可执行文件中。 2.embed介绍 &#x1f3af; Go 1.16 引入了革命性的 embed 包&#xff0c;彻底改变了静态资源管理的…...

Unity | AmplifyShaderEditor插件基础(第七集:平面波动shader)

目录 一、&#x1f44b;&#x1f3fb;前言 二、&#x1f608;sinx波动的基本原理 三、&#x1f608;波动起来 1.sinx节点介绍 2.vertexPosition 3.集成Vector3 a.节点Append b.连起来 4.波动起来 a.波动的原理 b.时间节点 c.sinx的处理 四、&#x1f30a;波动优化…...

python执行测试用例,allure报乱码且未成功生成报告

allure执行测试用例时显示乱码&#xff1a;‘allure’ &#xfffd;&#xfffd;&#xfffd;&#xfffd;&#xfffd;ڲ&#xfffd;&#xfffd;&#xfffd;&#xfffd;ⲿ&#xfffd;&#xfffd;&#xfffd;Ҳ&#xfffd;&#xfffd;&#xfffd;ǿ&#xfffd;&am…...

Hive 存储格式深度解析:从 TextFile 到 ORC,如何选对数据存储方案?

在大数据处理领域&#xff0c;Hive 作为 Hadoop 生态中重要的数据仓库工具&#xff0c;其存储格式的选择直接影响数据存储成本、查询效率和计算资源消耗。面对 TextFile、SequenceFile、Parquet、RCFile、ORC 等多种存储格式&#xff0c;很多开发者常常陷入选择困境。本文将从底…...