一、共用体

共用体的所有成员占用同一段内存,修改一个成员会影响其余所有成员。

定义格式为:

union 共用体名 
{
    共用体成员 1,
    共用体成员 2,
    ...
};

结构体和共用体的区别:结构体的各个成员会占用不同的内存,互相之间没有影响;而共用体的所有成员占用同一段内存,修改一个成员会影响其余所有成员。

结构体占用的内存大于等于所有成员占用的内存的总和(对齐造成的),共用体占用的内存等于最长的成员占用的内存。共用体使用了内存覆盖技术,同一时刻只能保存一个成员的值,如果对新的成员赋值,就会把原来成员的值覆盖掉。

使用场景:

1.通信中的数据包会用到共用体,因为不知道对方会发送什么样的数据包过来,定义几种格式的包,收到包之后就可以根据包的格式取出数据。

2.节约内存。如果有2个大内存的数据结构,但不会同时使用,可以考虑用共用体来设计。

3.某些应用需要大量的临时变量,变量类型不同,而且会随时更换。而堆栈空间有限,不能同时分配大量临时变量。这时可以使用共用体让这些变量共享同一个内存空间,这些临时变量不用长期保存,用完即丢,和寄存器差不多,不用维护。

二、数据存储

1.浮点数

定义共用体

union eeprom_float
{float a;uint8_t b[4];
}float_write,float_read;// 声明
float_write.a = 3.1415926;

浮点数是4个字节,声明float_write.a=3.1415926,由于共用体共占一段内存,把一个float拆分为4个字节,然后逐字节的写入EEPROM,来达到保存float数据的目的。所以,通过float_read.b即可拆分flaot数据。

读写数据:

for(i=0;i<sizeof(float);i++)
{Write_AT24c02(0+i,float_write.b[i]);HAL_Delay(5);
}for(i=0;i<sizeof(float);i++)
{float_read.b[i]=Read_AT24c02(0+i);
}

iic读写函数如下:

void Write_AT24c02(uint8_t addr,uint8_t data)
{I2CStart();I2CSendByte(0xa0);I2CWaitAck();I2CSendByte(addr);I2CWaitAck();I2CSendByte(data);I2CWaitAck();I2CStop();
}uint8_t Read_AT24c02(uint8_t addr)
{uint8_t val;I2CStart();I2CSendByte(0xa0);I2CWaitAck();I2CSendByte(addr);I2CWaitAck();I2CStart();I2CSendByte(0xa1);I2CWaitAck();val=I2CReceiveByte();I2CWaitAck();I2CStop();return val;
}

2.负数

定义共用体

union eeprom_s16
{int16_t a;uint8_t b[2];
}s16_write,s16_read;
//声明
s16_write.a = -777;

思路和浮点数一样。负数在内存中的存储和正数一样,只是最高位用于表示正负。通过拆分有符号数据,然后逐字节的存储。

for(i=0;i<sizeof(uint16_t);i++)
{Write_AT24c02(33+i,s16_write.b[i]);HAL_Delay(5);
}
for(i=0;i<sizeof(uint16_t);i++)
{s16_read.b[i]=Read_AT24c02(33+i);
}

3.多种数据类型

定义共用体

union eeprom_dat
{uint8_t t1;uint16_t t2;uint32_t t3;int16_t t4;float f1;double f2;uint8_t str[20];
}eeprom_dat_write,eeprom_dat_read;//声明
eeprom_dat_write.f2 = 3.1415926535;

要确保uint8_t足够大,为了各种类型都能得到安全的存储。

for(i = 0; i < sizeof(eeprom_dat_write.f2); i++)
{Write_AT24c02(i,eeprom_dat_write.str[i]);HAL_Delay(5);
}
for(i = 0; i < sizeof(eeprom_dat_write.f2); i++)
{eeprom_dat_read.str[i] = Read_AT24c02(i);}

4. 16位/32位数据

union eeprom_u16
{uint16_t a;uint8_t b[2];
}u16_write;union eeprom_u32
{uint32_t a;uint8_t b[4];
}u32_write;// 16数据
u16_write.a = 11521;
for(i=0;i < sizeof(u16);i++)
{write_24c02(&u16_write.b[i],i,1);HAL_Delay(5);
}
for(i=0;i<sizeof(u16);i++)
{read_24c02(&u16_write.b[i],i,1);
}// 32数据
u32_write.a = 999999;
for(i=0;i < sizeof(u32);i++)
{write_24c02(&u32_write.b[i],i,1);HAL_Delay(5);
}
for(i=0;i<sizeof(u32);i++)
{read_24c02(&u32_write.b[i],i,1);
}

注意:上电判断问题:

如何在设备第一次上电时从EEPROM读取我们设定好的值呢?第七届省赛中题目要求如下:

由于在初始化时EEPROM中存储的数值是不确定的,所以需要向EEPROM先写入我们的值,并且只要在设备第一次运行此程序时才写入,其余时刻直接从EEPROM读取数值。第一次读取的是设定的初值,之后读取到的是修改值。需要加一个判断语句,随便选取读取一个或者两个EEPROM的地址判断是否等于一个随机数。如果判断为真,就将初始值写入EEPROM;判断为假,就不写入初始值,并且判断语句只需要执行一次。


// 判断第一次写标志
uint8_t flag1_24c02,flag2_24c02;
uint8_t val_24c02=10;
// 读取eeprom地址33和34的值作为判断
read_24c02(&flag1_24c02,33,1);
read_24c02(&flag2_24c02,34,1);if(flag1_24c02!= 10&&flag2_24c02!=10) //第一次上电不满足
{write_24c02(num,0,3);//写入设置的值HAL_Delay(10);write_24c02(&val_24c02,33,2); //保证程序第一次上电只执行一次HAL_Delay(10);
}
read_24c02(read,0,3);HAL_Delay(10);

地址33和34值都为10的可能性是非常小的,成功的概论还是比较高的。

连续读写

小数:

//共用体:几个不同的变量共同占用一段内存的结构;
union eeprom_float
{float a;uint8_t b[4];
}float_write,float_read;// 显示小数
float_write.a = 3.1415926;
for(i=0;i<sizeof(float);i++)
{write_24c02(&float_write.b[i],i,1);HAL_Delay(5);
}
for(i=0;i<sizeof(float);i++)
{read_24c02(&float_read.b[i],i,1);
}

负数

union eeprom_s16
{int16_t a;uint8_t b[2];}s16_write,s16_read;
// 显示负数
s16_write.a = -777;
for(i=0;i < sizeof(s16);i++)
{write_24c02(&s16_write.b[i],i,1);HAL_Delay(5);
}
for(i=0;i<sizeof(s16);i++)
{read_24c02(&s16_read.b[i],i,1);
}

共用体实现浮点数、负数的存储相关推荐

  1. C 语言编程 — 高级数据类型 — 共用体

    目录 文章目录 目录 前文列表 共用体 定义共用体 访问共用体成员 前文列表 <程序编译流程与 GCC 编译器> <C 语言编程 - 基本语法> <C 语言编程 - 基本 ...

  2. C++ 共用体union 的使用

    共用体是什么 共用体将不同的数据类型组织为一个整体, 需要注意的是,共用体在同一时刻只能存储一个数据成员的值., 共用体变量的地址和它的格式成员的地址都是同一地址 共用体的一般形式 union 共用体 ...

  3. 【 C 】联合(union)或共用体(union)

    单单从union的字母意思上翻译的话,联合是最容易让人想到的,但是这往往会让人产生疑惑?所以感觉这个中文翻译并不好,反而是共用体(union)能体现出这种类型的含义. 下面转载一篇介绍共用体的文章,写 ...

  4. C语言 共用体/联合体 union

    引入 传统技术的缺陷-结构体 共用体基本介绍 共用体与结构体一样都是值传递 定义共用体的三种方式 内存布局 共用体数据空间=占用最大的成员的数据空间大小 案例解析 1) 2) 3) 4) 注: 101 ...

  5. 共用体知识及 I - 共用体练习

    一.共用体 Union的定义格式为: union 共用体名{ 成员列表 }; 例如: union data{int x;char y;double z; }; union data a, b, c; ...

  6. 共用体变量不能在定义时初始化_【C语言资料更新】共用体联合体

    文/Edward 共用体又称为联合体,它是C语言中的一种特殊的数据类型.它允许用户在相同的内存位置存储不同的数据类型.用户可以定义一个带有多成员的共用体,但是任何时候这些成员都共享同一块内存.举个例子 ...

  7. C语言基础专题 - 通过案例历学 - 共用体

    C语言基础 - 通过案例历学 - 共用体 本文通过实例介绍了C语言中共用体的概念与使用 阅读本文前推荐先阅读:结构体 1.什么是共用体? 答:共用体是C语言中一种用户自定义数据类型,它提供了一种使用相 ...

  8. 什么是共用体?如何定义和使用共用体?

    在C语言中,共用体(Union)是一种特殊的数据类型,允许在相同的内存位置存储不同类型的数据.共用体的成员共享同一块内存空间,因此在任意时刻只能存储其中一个成员的值.共用体的大小由其中最大的成员决定. ...

  9. C语言联合体/共用体/union,枚举使用大全

    文章目录 一.前言 二.联合体 1.联合体基础 2. 联合体的使用方法和使用场景 2.1 多种访问内存途径共存 2.2 联合体union和大小端(big-endian.little-endian) 2 ...

最新文章

  1. python爬虫qq音乐教学视频_爬取QQ音乐(讲解爬虫思路)
  2. cocos2dx--cocos2dx3.1.1执行报无法解析的外部符号
  3. java delphi aes加密算法_Delphi AES,又一个加密算法例子
  4. 关于ecshop中jquery与js冲突解决的方案
  5. Android设计模式之——抽象工厂模式
  6. 7时过2小时是几时_小姐姐花1万7租了一个2小时男友,全程上演偶像剧......
  7. 钓鱼c语言,C语言实现小猫钓鱼游戏
  8. 【Unity3D】使用 FBX 格式的外部模型 ② ( FBX 模型与默认 3D 模型的区别 | FBX 模型贴图查找路径 | FBX 模型可设置多个材质 )
  9. Android11.0(R) MTK6771 平板横屏方案修改(强制app横屏 + 开机logo/动画+关机充电横屏 + RecoveryUI 横屏)
  10. [高数][高昆轮][高等数学上][第一章-函数与极限]05.极限的运算法则
  11. 无界——多元合作的发散思维
  12. LinkIn基于Dynamo设计的系统:伏地魔(voldemort)设计中文文档
  13. ROS学习总结一:talker and listener
  14. [1168]OSS ossutil64安装及使用
  15. POE设备浪涌测试标准
  16. 用于实时人与物体交互检测的并行点检测和匹配
  17. 强烈推荐这11个Python开源项目,非常值得入门学习(从入门到Python高级开发)
  18. Cadence PCB封装绘制
  19. 电路基础罗先觉版第一章总结
  20. bootstrap icon glyphicon

热门文章

  1. Android剪切板工具clipper,自动化
  2. 3个5相乘列乘法算式_五年级数学上册:第一单元《小数乘法》测试分析,开学完美第一测...
  3. 2019南京帆软春招
  4. 项目开发中的时区问题汇总
  5. 人生的意义是什么?活着的意义是什么
  6. 系统之家win7 32位64位iso极速旗舰版 v12.1
  7. 下载流媒体的好工具http://www.souxin.com/stream-software-down.htm
  8. 【办公类-22-02】周计划系列(2)-生成“主题知识”(提取旧docx指定段落的内容,写入EXCLE模板,再次生成新docx)
  9. spark 2.3源码分析之SortShuffleWriter
  10. MonacoEditor 自动格式化sql json数据