联合体union的详解
1.概述
联合体union的定义方式与结构体一样,但是二者有根本区别。
在结构中各成员有各自的内存空间,一个结构变量的总长度是各成员长度之和。而在“联合”中,各成员共享一段内存空间,一个联合变量的长度等于各成员中最长的长度。
2.联合体长度
在The C Programming Language里面讲述union内存分配的原话是
1)联合体就是一个结构
2)联合体的所有成员相对于基地址的偏移量为0
3)此结构空间要大到总够容纳最“宽”的成员
4)并且,其对齐方式要适合于联合体中所有类型的成员
我的理解可以概括为两点:
1)联合体的结构空间要足够大,要等于最长的一个结构变量的空间,但是这个最长的空间要满足以下条件:
1.要大于等于最长的一个结构变量的空间
2.并且要能够整除其他结构变量的数据长度,即联合体空间对其他成员的元类型要能够整除(int a[5],其元类型为int,元类型长度为4),实际上就是要取一个元类型的最小公倍数。
这儿举例来说
union
{
float fuel_load;
char a[];
int pallets;
}fighter;
这个结构体中,各个结构变量的空间分别为float fuel_load; 占4个字节,char a[5];占5个字节,int pallets;占4个字节。通过“3)此结构空间要大到总够容纳最“宽”的成员”这句话,我们可以认为是结构体的空间为5个字节即可,但是“其对齐方式要适合于联合体中所有类型的成员”没有满足,对于这个问题,通过上面红色字体部分可以解决。,因此联合体空间为8.8可以整除 4(float、int长度)和1(char的长度),并且8大于数组5.
再举一个例子有助于大家理解。
struct aircraft
{
int wingspan;
int passengers;
union
{
float fuel_load;
float bomb_load;
int pallets;
};
}fighter;
sizeof(fighter) 是12 。int wingspan; int passengers;两个int型 8个字节。union中 3个都是4个字节,因此union长度为4个字节。
3.内存分配
一句话:联合体变量的各个成员都是从低字节开始公用的。即:所有的成员都是从低字节开始的。
我们先为整个union分配一个空间,这个空间大小就是上面(2)内存分配中所讲述的。
union {
int i;
char x[];
}a;
int main(void)
{
a.x[] = ;
a.x[] = ;
printf("%d\n",a.i);
return ;
}
其内存如下图所示。a.x[0] 处于低字节,x[1]高字节。当调用i这个成员变量的时候,其开始地址仍然是从起始地址开始,数4个字节输出。因此为 256 + 10 = 266

(改低地址处:0000 1010)
程序附上:
#include <string.h>
#include <stdio.h>
#include <unistd.h>
#if 0
typedef union data{
float a;
float b;
int c;
}data_t;
int main(int argc ,char **argv)
{ printf("sizeof(float):%d\nsizeof(data_t):%d\n",sizeof(float),sizeof(data_t));
return ; }
#endif
typedef union data{
int i;
char x[];
}data_t;
int main(int argc ,char **argv)
{ data_t datab;
memset(&datab,,sizeof(datab));
datab.x[] = ;
datab.x[] = ; printf("sizeof(float):%d\nsizeof(int):%d\n",sizeof(float),sizeof(int));
printf("datab.i :%d\n",datab.i);
return ; }
4.附录 各个数据类型的长度
type bytes
int 4
char 1
short int 2
bool 1
long 4
long long 8
float 4
double 8
long double 8
补充1:
解决一下捧场网友的困惑。
关于“有名”与“无名”联合体在结构体内所占空间的问题,其实这和是不是结构体无关,只和“有名”、“无名”有关,而且有名无名也是表象,其实是声明类型与定义变量的区别,看例子,直接打印,
#include <stdio.h>
struct s1{
union u{
int i;
};
struct ss1{
int i;
};
}; struct s2{
union{
int i;
};
struct{
int i;
};
}; struct s3{//the same to s2
union su3{
int i;
}su33;
struct ss3{
int i;
}ss33;
}; union su4{
int i;
};
struct ss4{
int i;
};
struct s4{//the same to s3
union su4 su44;
struct ss4 ss44;
};
struct s5{//the same to s1
union su4;
struct ss4;
}; struct s6{//the same to s1
union{
int;
};
struct{
int;
};
}; main(){
struct s1 sVal1;
struct s2 sVal2;
struct s3 sVal3;
struct s4 sVal4;
struct s5 sVal5;
struct s6 sVal6; printf("sVal1's size:%d\n",sizeof(sVal1));
printf("sVal1:%p\t%d\n",&sVal1); printf("sVal2's size:%d\n",sizeof(sVal2));
printf("sVal2:%p\t%d\n",&sVal2); printf("sVal3's size:%d\n",sizeof(sVal3));
printf("sVal3:%p\t%d\n",&sVal3); printf("sVal4's size:%d\n",sizeof(sVal4));
printf("sVal4:%p\t%d\n",&sVal4); printf("sVal5's size:%d\n",sizeof(sVal5));
printf("sVal5:%p\t%d\n",&sVal5); printf("sVal5's size:%d\n",sizeof(sVal5));
printf("sVal5:%p\t%d\n",&sVal5);
}
地址供参考,主要看size,分别为:
0,8,8,8,0,0
s1只有类型,没有变量,没有变量自然就没有空间占用(s5同)。
类型就是类型,和是不是结构体、联合体无关的,你的“int i;”中i不就是个变量吗?如果换成int;结果相同(这就是s6)。
s4和s5的做法能帮助排除干扰,将子结构体与联合体声明在外,内部直接引用,4是定义了变量,5什么都没做。
另外,这种做法编译的时候GCC会给你在相应的行做出提示“union_with_name.c:49: 警告:没有声明任何东西”
联合体union的详解的更多相关文章
- Mysql中WHERE IN,UNION 用法详解
WHERE IN 用法 这里分两种情况来介绍 1.in 后面是记录集,如: select * from table where uname in(select uname from ...
- MySQL SELECT语法(四)UNION语法详解
源自MySQL 5.7 官方手册:13.2.9.3 UNION Syntax 一.UNION语法 UNION用于将多个SELECT语句的结果合并到一个结果集中. SELECT ... UNION [A ...
- union联合体使用详解
1.联合体联合体(union)与结构体(struct)有一些相似之处.但两者有本质上的不同.在结构体中,各成员有各自的内存空间, 一个结构变量的总长度是各成员长度之和.而在联合体中,各成员共享一段内存 ...
- PE文件结构详解(四)PE导入表
PE文件结构详解(二)可执行文件头的最后展示了一个数组,PE文件结构详解(三)PE导出表中解释了其中第一项的格式,本篇文章来揭示这个数组中的第二项:IMAGE_DIRECTORY_ENTRY_IMPO ...
- 《招一个靠谱的移动开发》iOS面试题及详解(上篇)
以下问题主要用于技术的总结与回顾 主要问题总结 单例的写法.在单利中创建数组应该注意些什么. NSString 的时候用copy和strong的区别. 多线程.特别是NSOperation 和 GCD ...
- [一]class 文件浅析 .class文件格式详解 字段方法属性常量池字段 class文件属性表 数据类型 数据结构
前言概述 本文旨在讲解class文件的整体结构信息,阅读本文后应该可以完整的了解class文件的格式以及各个部分的逻辑组成含义 class文件包含了java虚拟机指令集 和 符号表 以及若 ...
- php调用C代码的方法详解和zend_parse_parameters函数详解
php调用C代码的方法详解 在php程序中需要用到C代码,应该是下面两种情况: 1 已有C代码,在php程序中想直接用 2 由于php的性能问题,需要用C来实现部分功能 针对第一种情况,最合适的方 ...
- SqlServer数据库性能优化详解
数据库性能优化详解 性能调节的目的是通过将网络流通.磁盘 I/O 和 CPU 时间减到最小,使每个查询的响应时间最短并最大限度地提高整个数据库服务器的吞吐量.为达到此目的,需要了解应用程序的需求和数据 ...
- [转]C语言字节对齐问题详解
C语言字节对齐问题详解 转载:https://www.cnblogs.com/clover-toeic/p/3853132.html 引言 考虑下面的结构体定义: typedef struct{ ch ...
随机推荐
- Elasticsearch 与 Mongodb 数据同步问题
1.mongo-connector工具 首先安装python环境 wget http://www.python.org/ftp/python/3.0.1/Python-3.0.1.tgz tar -z ...
- python 读取一个目录下的所有目录和文件
#!/usr/bin/python # -*- coding:utf8 -*- import os allFileNum = 0 def printPath(level, path): global ...
- RestTemplate异常no suitable HttpMessageConverter found for request type [java.lang.Integer]
GET方式,参数必须放在URL后面,http://xxx/list?name={name}&age={age} package com.chelizi.xiruo.xframework.uti ...
- ABP之应用服务(2)
在上一篇的笔记中,已经大致对Application层的使用作了简要的使用说明,感觉还是有些东西需要研究一下,所以承接上文,对AutoMapper这个方便的东西,稍微研究一下. 一.初识AutoMapp ...
- 如何取消一个目录的git初始化
一不小心把我的整个home目录都初始化为git仓库了,通过执行删除.git命令,可以恢复 rm -rf .git
- Java编程思想第四版随书源码官方下载方法
见不少人在找net.mindview.util.Print,CSDN上有下载,收积分,以下是官网的下载方法,免费: 官网链接:http://mindview.net/ 电子书下载地址:http://w ...
- jQuery 常见开发使用技巧总结
1.关于页面元素的引用 通过jquery的$()引用元素包括通过id.class.元素名以及元素的层级关系及dom或者xpath条件等方法,且返回的对象为jquery对象(集合对象),不能直接调用do ...
- 2018/04/18 每日一学Linux 之 ssh关闭密码登录
在平常工作中,常常需要关闭 SSH 的密码登录,只留 SSH 证书登录. 好处显而易见,避免了经常输入密码导致的密码泄露,和设置密码导致被暴力破解的可能性. -- 方法也很简单,首先 你是可以 登录 ...
- Highways---poj1751最小生成树
http://poj.org/problem?id=1751 题意:有n个点,已知各点坐标,距离为权值,求最小生成树的边 但是这个最小生成树的m条边是已经确定的了,所以可以让已知边的权值为0: 在Pr ...
- 通过phantomjs 进行页面截图
本文章参考了使用phantomjs操作DOM并对页面进行截图需要注意的几个问题 及phantomjs使用说明 这两篇文章,初次接触phantomjs的童鞋可以去看下这两篇原文 在学习中可以看下 pha ...