(C语言)共用体union的使用方法举例
曾经在学校学习C语言的时候一直搞不懂那个共用体union有什么用的。工作之后才发现它的一些妙用,现举比例如以下:
1. 为了方便看懂代码。
比方说想写一个3 * 3的矩阵,能够这样写:
[
注:以下用红色部分标记的地方是后来加入上去的,谢谢yrqing718的提醒!]
- struct
Matrix - {
- union
- {
- struct
- {
- float
_f11, _f12, _f13, _f21, _f22, _f23, _f31, _f32, _f33; - };
- float
f[3][3]; - }_matrix;
- };
- struct
Matrix m;
这两个东西共同使用同样的空间,所以没有空间浪费,在须要总体用矩阵的时候能够用
m._matrix.f (比方说传參,或者是总体赋值等);须要用当中的几个元素的时候能够用m._matrix._f11那样能够避免用m.f[0][0](这样不大直观,并且easy出错)。
2. 用在强制类型转换上(比强制类型转换更加easy看懂)
以下举几个样例:
(1). 推断系统用的是big endian 还是 little endian(其定义大家能够到网上查相关资料,此略)
- #define TRUE 1
- #define FALSE 0
- #define BOOL int
- BOOL
isBigEndian() - {
- int
i = 1; /* i = 0x00000001*/ - char
c = *(char
*)&i; /* 注意不能写成 char c = (char)i; */ - return
(int
)c != i; - }
假设是little endian字节序的话,那个i = 1;的内存从小到大依次放的是:0x01 0x00 0x00 0x00,如是,依照i的起始地址变成依照char *方式(1字节)存取,即得c = 0x01;
反之亦然
或许看起来不是非常清晰,以下来看一下这个:
- BOOL
isBigEndian() - {
- union
- {
- int
i; - char
c; - }test;
- test.c = 2;
- return
test.i != 2; - }
这里用的是union来控制这个共享布局,有个知识点就是union里面的成员c和i都是从低地址開始对齐的。相同能够得到如此结果,并且不用转换,清晰一些。
什么,不认为清晰??那再看以下的样例:
(2). 将little endian下的long long类型的值换成 big endian类型的值。已经知道系统提供了以下的api:long htonl(long lg);作用是把全部的字节序换成大端字节序。因此得出以下做法:
- long
long
htonLL(long
long
lg) - {
- union
- {
- struct
- {
- long
low; - long
high; - }val_1;
- long
long
val_2; - }val_arg, val_ret;
- if
( isBigEndian() ) - return
lg; - val_arg.val_2 = lg;
- val_ret.val_1.low = htonl( val_arg.val_1.high );
- val_ret.val_1.high = htonl( val_arg.val_1.low );
- return
val_ret.val_2; - }
仅仅要把内存结构的草图画出来就比較easy明确了。
(3).为了理解c++类的布局,再看以下一个样例。有例如以下类:
- class
Test - {
- public
: - float
getFVal(){ return
f;} - private
: - int
i; - char
c; - float
f; - };
- Test t;
不能在类Test中添加代码,给对象中的f赋值7.0f.
- class
Test_Cpy - {
- public
: - float
getVal(){ return
f;} - float
setVal(float
f){ this
->f = f;} - private
: - int
i; - char
c; - float
f; - };
- ....
- int
main() - {
- Test t;
- union
- {
- Test t1,
- Test_Cpy t2;
- }test;
- test.t2.setVal(7.0f);
- t = test.t1;
- assert( t.getVal() == 7.0f );
- return
0; - }
说明:由于在添加类的成员函数时候,那个类的对象的布局基本不变。因此能够写一个与Test类一样结构的类Test_Cpy,而多了一个成员函数setVal,再用uinon结构对齐,就能够给私有变量赋值了。(这样的方法在有虚机类和虚函数机制时可能失灵,故不可移植)至于具体的讨论,网上有,这个样例在实际中没实用途,仅仅是用来考察这个内存布局的使用而已.
union在操作系统底层的代码中用的比較多,由于它在内存共赏布局上方便且直观。所以网络编程,协议分析,内核代码上有一些用到union都比較好懂,简化了设计。
(C语言)共用体union的使用方法举例的更多相关文章
- C语言共用体union
union共用体说明: 当一个共用体被声明时, 编译程序自动地产生一个变量, 其长度为联合中最大的变量长度的整数倍. 比如union中有{int x; double x1; char name[10] ...
- C语言共用体、大小端、枚举
1.共用体和结构体的相同和不同 (1)相同点就是操作语法几乎相同.(2)不同点是本质上的不同.struct是多个独立元素(内存空间)打包在一起:union是一个元素(内存空间)的多种不同解析方式. # ...
- C语言 共用体
//共用体 union #define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #include<stdlib.h> #includ ...
- C语言共用体(Union)
通过前面的讲解,我们知道结构体(Struct)是一种构造类型或复杂类型,它可以包含多个类型不同的成员.在C语言中,还有另外一种和结构体非常类似的语法,叫做共用体(Union),它的定义格式为: uni ...
- 共用体union
union共用体名 { 类型名 成员名1: 类型名 成员名2: …… 类型名 成员名n; } 由于各个成员变量在内存中都使用同一段存储空间,因此共用体变量的长度等于最长的成员长度,共用体的访问方式和结 ...
- 共用体 union
共用体是一种数据格式,能够存储不同的数据类型,但只能同时存储其中的一种类型. union one4all { int int_val; double double_val; long long_val ...
- C结构体struct 和 共用体union的使用测试
#include <stdio.h> struct { char name[10]; char sex; char job; int num; union{ //联合只能共用同一个内存 i ...
- 以位为单位存储标志-共用体-union
一.程序的结构如下: typedef union _KEYST { struct { uint8 Key1_Flag :1;//表示第0 ...
- C语言联合体(union)的使用方法及其本质-union
转载自:https://blog.csdn.net/si_zhou_qun_84342712/article/details/53187106 1.联合体union的基本特性——和struct的同与不 ...
随机推荐
- iOS_38_手势
Pan平移手势 终于效果图: Swipe轻扫手势 LongPress长按手势 Pinch和Rotation手势 捏合(缩放)和旋转 终于效果图: 涂鸦 终于效果图: 事件分3大类:触摸.加速计.远程遥 ...
- windows cmd命令行下创建文件和文件夹
在window下无法通过 右键=>新建 命令来创建以点开头的文件和文件夹 比如 .log ,会提示必须输入文件名. 可以通过命令行来创建 新建文件夹 mkdir .vs 新建文件 type NU ...
- 云梯vpn
刚和大饼合买了一个云梯的vpn 表示可以把俺的优惠连接放出来了 貌似必须是新注册用户才能够享用优惠 http://protizi.com/?r=5e3fecd7eae558ec 把云梯推荐给朋友们 让 ...
- Think in Java(一):Java基础
一. OOP的特点 (1) 万物皆为对象; (2) 程序是对象的集合,他们通过发送信息来告诉彼此所要做的; (3) 每一个对象都有自己的由其它对象所构成的存储; (4) 每一个对象都拥有它的类型; ( ...
- Android 在非主线程无法操作UI意识
Android在应用显示Dialog是一个非常easy事儿,但我从来没有尝试过Service里面展示Dialog. 经验UI操作要在主线程,本地的服务Service是主线程里没错,可是远程servic ...
- Android使用SVG矢量创建很酷的动态效率!
尊重原创,欢迎转载.转载请注明: FROM GA_studio http://blog.csdn.net/tianjian4592 一个真正酷炫的动效往往让人虎躯一震,话不多说.咱们先瞅瞅效果: ...
- NSIS:简单按钮美化插件SkinButton,支持透明PNG图片。
原文 NSIS:简单按钮美化插件SkinButton,支持透明PNG图片. 征得作者贾可的同意,特发布按钮美化插件SkinButton. 插件说明: 使用GDI+库写的一个简单按钮美化插件,支持透明P ...
- 新秀翻译(两)——使用Java通用配置模板方法模式
假设你发现你已经非常重码,你可能会考虑使用模板的方法来消除easy重复错误代码.下面是一个示例:以下两类,他完成了几乎相同的功能: 实例化并初始化一个Reader来读取CSV文件. 读取每一行并解析: ...
- 每天收获一点点------Hadoop Eclipse插件的使用
本文所用软件版本:myeclipe2014 hadoop1.2.1 1.安装Hadoop开发插件 下载hadoop-eclipse-plugin-1.2.1.jar,拷贝到myeclipse根目 ...
- python下载地址到迅雷qq旋风下载
迅雷和qq旋风下载,有加速和离线功能,非常方面,我是在网上看到的原始地址和迅雷地址,qq旋风地址的转化原理.然后用python+pyqt写了一个client 原理: 迅雷: 迅雷下载地址=" ...