用C语言编程,如何节省存储空间?

嵌入式ARM 2021-11-30 12:00


一、C语言的共用体union


共用体是一种特殊的数据类型,允许您在相同的内存位置存储不同的数据类型。

什么意思呢,就是在同一块内存存储可以定义多个数据类型,但是在使用的时候,只有一个变量有效。

这里就有一个问题,变量有大有小呀,对的,所以这个时候共用体的空间为内部变量最大占用空间的值。

如此这般,共用体就可以通过共享存储空间,来避免当前没有被使用的变量所造成的存储空间的浪费。

共用体的成员可以使用任何数据类型,但是一个共用体所占用的存储空间的字节总数,必须保证至少足以能够容纳其占用空间字节数最大的成员。并且共用体每次只允许访问一个成员,也就是一种数据类型,确保按照正确的数据类型来访问共用体中的数据,就是你的责任了。

先看看union的格式:


union [tag]{member definition;member definition;...member definition;} [variables];


其中:

  • union为类型变量;
  • tag为共用体的标记;
  • member definition为变量的定义;

举个例子:


union test{int i;float f;double d;char  str[20];} data;

通过这个例子可以看到,这个结构体的大小是多少呢?可以通过程序来确认一下。


OK,这次我们来聊聊结构体。


任务来了,我想让你给学生建立一个数据库,该怎么来做。


这个学生包含的信息如下:


  • ID:也就是学号,唯一区别码,用整型表示
  • Name:姓名,用字符串表示
  • Age:年龄,用整型表示
  • Sex:性别,用字符串表示


按照目前学过的知识我们的代码如下,比如先来一个李雷同学的吧:


#include <stdio.h>#include <string.h> union test{int i;float f;double d;char  str[20];}; int main( ){union test data; printf( "data size : %d\n", sizeof(data)); return 0;}

二、C语言 共用体的访问


共用体的访问与结构体类似,也是有2种类型,我们只看看成员访问运算符.。


所以按照通用的赋值方式,来看一下是否按照我们预定的方式运行。


/*beginner/union/union2.c*/#include <stdio.h>#include <string.h>union Data {int i;float f;char str[20];};int main(){union Data data;    data.i = 123;    data.f = 456.0;strcpy(data.str, "Hello World");printf("data.i : %d\n", data.i);printf("data.f : %f\n", data.f);printf("data.str : %s\n", data.str);return 0;}

从结果上来看,what are you弄啥嘞,感觉什么跟什么呀,只有最后的字符串是正确的,这也就间接证明了共用体使用相同的存储空间,其他类型的赋值会破坏原先的赋值,正常情况下只有最后一次的赋值才会保证正确结果。


所以,我们需要在每次赋值后直接查看结果,是可以保证结果正确的:


/*beginner/union/union3.c*/#include <stdio.h>#include <string.h>union Data {int i;float f;char str[20];};int main(){union Data data;    data.i = 123;printf("data.i : %d\n", data.i);    data.f = 456.0;printf("data.f : %f\n", data.f);strcpy(data.str, "Hello World");printf("data.str : %s\n", data.str);return 0;}

再次运行,可以看到结果就按照预想的进行了。

编译运行

#beginner/union/MakefileALL : union1 union2 union3
union1: union1.cgcc -o union1 union1.c
union2: union2.cgcc -o union2 union2.c
union3: union3.cgcc -o union3 union3.c
.PHONY : clean
clean:rm -f union1 union2 union3


输出结果


$ ./union2data.i : 1819043144data.f : 1143139122437582505939828736.000000data.str : Hello World
$ ./union3data.i : 123data.f : 456.000000data.str : Hello World


三、除了共用体,还有什么可以节省存储?


C语言的结构体位域


前面可以看到,使用unoin共用体可以节省数据的存储空间。


同样,在结构体或者共用体中,使用位域也可以达到这个效果。


先看看什么时候可以使用位域,这个特点大多数人都不会用到,用到的大部分人都基本跟底层打交道,比如驱动开发、单片机开发等。


先看一个最简单的例子,比如我们的红绿灯系统,先定义一个结构体:


typedef struct{unsigned int red;unsigned int green;unsigned int yellow;} TrafficLight;

此时如果看一下TrafficLight结构体的大小,应该是12个字节


是我们知道对于这几种灯而言,只有2种状态,开和关,也就是1和0,也就是1个bit其实就能表达,所以针对这种情况,有了位域的概念,先看一下位域的声明:


typedef struct{    type name : width;}


  • type:整数类型
  • name:为位域的名称
  • width:为位域中位的数量,其值需要小于等于type指定的类型大小


所以交通灯的结构体使用位域的概念就如下所示:


typedef struct{unsigned int red : 1;unsigned int green : 1;unsigned int yellow : 1;} TrafficLight1;


三色红绿灯加起来一共需要3个bit,所以一个无符号整型就可以容纳这些值了,此时看一下这个结构体的长度,应该为4。


总结一下:


当结构体或共用体中有无符号整型或有符号整型成员时,C语言允许用户指定这些成员所占用的存储位数,即位域。通过将数据存储在它们所需的最小数目的存储位内,位域能够有效地提供存储空间的利用率,但是,要注意,位域成员必须被声明为有符号整型或无符号整型。


代码如下:


/*beginner/struct/struct6.c*/#include <stdio.h>
int main(){
typedef struct {unsigned int red;unsigned int green;unsigned int yellow; } TrafficLight;
TrafficLight trafficlight;
printf("The size of TrafficLight %d\n", sizeof(trafficlight));
typedef struct {unsigned int red : 1;unsigned int green : 1;unsigned int yellow : 1; } TrafficLight1;
TrafficLight1 trafficlight1;
printf("The size of TrafficLight1 %d\n", sizeof(trafficlight1));
return 0;}

编译运行


直接输入make就可以了。


#beginner/struct/Makefile
struct6: struct6.cgcc -o struct6 struct6.c

运行输出如下:

$ ./struct6The size of TrafficLight 12The size of TrafficLight1 4


扩展


既然位域指定了长度位,所以就涉及到万一赋值超过了会发生什么情况,可以通过给红绿灯赋一个大值看看。

比如复制一个2,那么会得到如下警告:

warning: implicit truncation from ‘int’ to bit-field changes value from 2 to 0 [-Wbitfield-constant-conversion]
编译有警告,不过还是生成了可执行文件,运行下看看结果吧。

END

来源:十月天文

版权归原作者所有,如有侵权,请联系删除。

推荐阅读
在部队当程序员有多爽?
在大公司天天调参数,感觉快废了~
STM32中常用的C语言知识点,开始复习!

→点关注,不迷路←
嵌入式ARM 关注这个时代最火的嵌入式ARM,你想知道的都在这里。
评论
  • 这篇内容主要讨论三个基本问题,硅电容是什么,为什么要使用硅电容,如何正确使用硅电容?1.  硅电容是什么首先我们需要了解电容是什么?物理学上电容的概念指的是给定电位差下自由电荷的储藏量,记为C,单位是F,指的是容纳电荷的能力,C=εS/d=ε0εrS/4πkd(真空)=Q/U。百度百科上电容器的概念指的是两个相互靠近的导体,中间夹一层不导电的绝缘介质。通过观察电容本身的定义公式中可以看到,在各个变量中比较能够改变的就是εr,S和d,也就是介质的介电常数,金属板有效相对面积以及距离。当前
    知白 2025-01-06 12:04 173浏览
  • 根据环洋市场咨询(Global Info Research)项目团队最新调研,预计2030年全球无人机锂电池产值达到2457百万美元,2024-2030年期间年复合增长率CAGR为9.6%。 无人机锂电池是无人机动力系统中存储并释放能量的部分。无人机使用的动力电池,大多数是锂聚合物电池,相较其他电池,锂聚合物电池具有较高的能量密度,较长寿命,同时也具有良好的放电特性和安全性。 全球无人机锂电池核心厂商有宁德新能源科技、欣旺达、鹏辉能源、深圳格瑞普和EaglePicher等,前五大厂商占有全球
    GIRtina 2025-01-07 11:02 71浏览
  • 大模型的赋能是指利用大型机器学习模型(如深度学习模型)来增强或改进各种应用和服务。这种技术在许多领域都显示出了巨大的潜力,包括但不限于以下几个方面: 1. 企业服务:大模型可以用于构建智能客服系统、知识库问答系统等,提升企业的服务质量和运营效率。 2. 教育服务:在教育领域,大模型被应用于个性化学习、智能辅导、作业批改等,帮助教师减轻工作负担,提高教学质量。 3. 工业智能化:大模型有助于解决工业领域的复杂性和不确定性问题,尽管在认知能力方面尚未完全具备专家级的复杂决策能力。 4. 消费
    丙丁先生 2025-01-07 09:25 80浏览
  • By Toradex 秦海1). 简介嵌入式平台设备基于Yocto Linux 在开发后期量产前期,为了安全以及提高启动速度等考虑,希望将 ARM 处理器平台的 Debug Console 输出关闭,本文就基于 NXP i.MX8MP ARM 处理器平台来演示相关流程。 本文所示例的平台来自于 Toradex Verdin i.MX8MP 嵌入式平台。  2. 准备a). Verdin i.MX8MP ARM核心版配合Dahlia载板并
    hai.qin_651820742 2025-01-07 14:52 45浏览
  • 本文介绍Linux系统更换开机logo方法教程,通用RK3566、RK3568、RK3588、RK3576等开发板,触觉智能RK3562开发板演示,搭载4核A53处理器,主频高达2.0GHz;内置独立1Tops算力NPU,可应用于物联网网关、平板电脑、智能家居、教育电子、工业显示与控制等行业。制作图片开机logo图片制作注意事项(1)图片必须为bmp格式;(2)图片大小不能大于4MB;(3)BMP位深最大是32,建议设置为8;(4)图片名称为logo.bmp和logo_kernel.bmp;开机
    Industio_触觉智能 2025-01-06 10:43 87浏览
  • PLC组态方式主要有三种,每种都有其独特的特点和适用场景。下面来简单说说: 1. 硬件组态   定义:硬件组态指的是选择适合的PLC型号、I/O模块、通信模块等硬件组件,并按照实际需求进行连接和配置。    灵活性:这种方式允许用户根据项目需求自由搭配硬件组件,具有较高的灵活性。    成本:可能需要额外的硬件购买成本,适用于对系统性能和扩展性有较高要求的场合。 2. 软件组态   定义:软件组态主要是通过PLC
    丙丁先生 2025-01-06 09:23 85浏览
  • 彼得·德鲁克被誉为“现代管理学之父”,他的管理思想影响了无数企业和管理者。然而,关于他的书籍分类,一种流行的说法令人感到困惑:德鲁克一生写了39本书,其中15本是关于管理的,而其中“专门写工商企业或为企业管理者写的”只有两本——《为成果而管理》和《创新与企业家精神》。这样的表述广为流传,但深入探讨后却发现并不完全准确。让我们一起重新审视这一说法,解析其中的矛盾与根源,进而重新认识德鲁克的管理思想及其著作的真正价值。从《创新与企业家精神》看德鲁克的视角《创新与企业家精神》通常被认为是一本专为企业管
    优思学院 2025-01-06 12:03 119浏览
  • 每日可见的315MHz和433MHz遥控模块,你能分清楚吗?众所周知,一套遥控设备主要由发射部分和接收部分组成,发射器可以将控制者的控制按键经过编码,调制到射频信号上面,然后经天线发射出无线信号。而接收器是将天线接收到的无线信号进行解码,从而得到与控制按键相对应的信号,然后再去控制相应的设备工作。当前,常见的遥控设备主要分为红外遥控与无线电遥控两大类,其主要区别为所采用的载波频率及其应用场景不一致。红外遥控设备所采用的射频信号频率一般为38kHz,通常应用在电视、投影仪等设备中;而无线电遥控设备
    华普微HOPERF 2025-01-06 15:29 127浏览
  • 村田是目前全球量产硅电容的领先企业,其在2016年收购了法国IPDiA头部硅电容器公司,并于2023年6月宣布投资约100亿日元将硅电容产能提升两倍。以下内容主要来自村田官网信息整理,村田高密度硅电容器采用半导体MOS工艺开发,并使用3D结构来大幅增加电极表面,因此在给定的占位面积内增加了静电容量。村田的硅技术以嵌入非结晶基板的单片结构为基础(单层MIM和多层MIM—MIM是指金属 / 绝缘体/ 金属) 村田硅电容采用先进3D拓扑结构在100um内,使开发的有效静电容量面积相当于80个
    知白 2025-01-07 15:02 75浏览
  • 在智能家居领域中,Wi-Fi、蓝牙、Zigbee、Thread与Z-Wave等无线通信协议是构建短距物联局域网的关键手段,它们常在实际应用中交叉运用,以满足智能家居生态系统多样化的功能需求。然而,这些协议之间并未遵循统一的互通标准,缺乏直接的互操作性,在进行组网时需要引入额外的网关作为“翻译桥梁”,极大地增加了系统的复杂性。 同时,Apple HomeKit、SamSung SmartThings、Amazon Alexa、Google Home等主流智能家居平台为了提升市占率与消费者
    华普微HOPERF 2025-01-06 17:23 145浏览
  • 根据Global Info Research项目团队最新调研,预计2030年全球封闭式电机产值达到1425百万美元,2024-2030年期间年复合增长率CAGR为3.4%。 封闭式电机是一种电动机,其外壳设计为密闭结构,通常用于要求较高的防护等级的应用场合。封闭式电机可以有效防止外部灰尘、水分和其他污染物进入内部,从而保护电机的内部组件,延长其使用寿命。 环洋市场咨询机构出版的调研分析报告【全球封闭式电机行业总体规模、主要厂商及IPO上市调研报告,2025-2031】研究全球封闭式电机总体规
    GIRtina 2025-01-06 11:10 104浏览
我要评论
0
点击右上角,分享到朋友圈 我知道啦
请使用浏览器分享功能 我知道啦