浅谈C语言中的联合体
联合体union
当多个数据须要共享内存或者多个数据每次仅仅取其一时。能够利用联合体(union)。在C Programming Language 一书中对于联合体是这么描写叙述的:
1)联合体是一个结构;
2)它的全部成员相对于基地址的偏移量都为0;
3)此结构空间要大到足够容纳最"宽"的成员;
4)其对齐方式要适合当中全部的成员;
以下解释这四条描写叙述:
因为联合体中的全部成员是共享一段内存的。因此每一个成员的存放首地址相对于于联合体变量的基地址的偏移量为0。即全部成员的首地址都是一样的。
为了使得全部成员可以共享一段内存,因此该空间必须足够容纳这些成员中最宽的成员。对于这句“对齐方式要适合当中全部的成员”是指其必须符合全部成员的自身对齐方式。
以下举例说明:
如联合体
union U
{
char s[9];
int n;
double d;
};
s占9字节,n占4字节,d占8字节。因此其至少需9字节的空间。然而事实上际大小并非9,用运算符sizeof測试其大小为16.这是由于这里存在字节对齐的问题,9既不能被4整除。也不能被8整除。因此补充字节到16,这样就符合全部成员的自身对齐了。
从这里能够看出联合体所占的空间不仅取决于最宽成员。还跟全部成员有关系。即其大小必须满足两个条件:1)大小足够容纳最宽的成员;2)大小能被其包括的全部基本数据类型的大小所整除。
測试程序:

/*測试联合体 2011.10.3*/
#include <iostream>
using namespace std;
union U1
{
char s[9];
int n;
double d;
};
union U2
{
char s[5];
int n;
double d;
};
int main(int argc, char *argv[])
{
U1 u1;
U2 u2;
printf("%d\n",sizeof(u1));
printf("%d\n",sizeof(u2));
printf("0x%x\n",&u1);
printf("0x%x\n",&u1.s);
printf("0x%x\n",&u1.n);
printf("0x%x\n",&u1.d);
u1.n=1;
printf("%d\n",u1.s[0]);
printf("%lf\n",u1.d);
unsigned char *p=(unsigned char *)&u1;
printf("%d\n",*p);
printf("%d\n",*(p+1));
printf("%d\n",*(p+2));
printf("%d\n",*(p+3));
printf("%d\n",*(p+4));
printf("%d\n",*(p+5));
printf("%d\n",*(p+6));
printf("%d\n",*(p+7));
return 0;
}

输出结果为:
16
8
0x22ff60
0x22ff60
0x22ff60
0x22ff60
1
0.000000
1
0
0
0
48
204
64
0
请按随意键继续. . .
对于sizeof(u1)=16。由于u1中s占9字节。n占4字节。d占8字节,因此至少须要9字节。其包括的基本数据类型为char。int,double分别占1。4,8字节,为了使u1所占空间的大小能被1,4,8整除。则需填充字节以到16。因此sizeof(u1)=16.
对于sizeof(u2)=8。由于u2中s占5字节。n占4字节,d占8字节,因此至少须要8字节。其包括的基本数据类型为char,int,double分别占1,4,8字节。为了使u2所占空间的大小能被1,4,8整除,不需填充字节,由于8本身就能满足要求。因此sizeof(u2)=8。
从打印出的每一个成员的基地址能够看出。联合体中每一个成员的基地址都同样。等于联合体变量的首地址。
对u1.n=1,将u1的n赋值为1后,则该段内存的前4个字节存储的数据为00000001 00000000 00000000 00000000
因此取s[0]的数据表示取第一个单元的数据,其整型值为1。所以打印出的结果为1.
至于打印出的d为0.000000愿意例如以下。因为已知该段内存前4字节的单元存储的数据为00000001 00000000 00000000 00000000,从上面打印结果48,204,64,0能够知道后面4个字节单元中的数据为00110000 11001100 01000000 00000000。因此其表示的二进 制浮点数为
00000000 01000000 11001100 00110000 00000000 00000000 00000000 00000001
对于double型数据,第63位0为符号位,62-52 00000000100为阶码,0000 11001100 00110000 00000000 00000000 00000000 00000001为尾数,依据其值知道尾数值约为0,而阶码为4-1023=-1019。因此其表示的浮点数为1.0*2^(-1019)=0.00000000000......。因此输出结果为0.000000。
浅谈C语言中的联合体的更多相关文章
- 浅谈C语言中的强符号、弱符号、强引用和弱引用
摘自http://www.jb51.net/article/56924.htm 浅谈C语言中的强符号.弱符号.强引用和弱引用 投稿:hebedich 字体:[增加 减小] 类型:转载 时间:2014- ...
- 浅谈 C 语言中模块化设计的范式
今天继续谈模块化的问题.这个想慢慢写成个系列,但是不一定连续写.基本是想起来了,就整理点思路出来.主要还是为以后集中整理做点铺垫. 我们都知道,层次分明的代码最容易维护.你可以轻易的换掉某个层次上的某 ...
- 浅谈c语言中的堆
操作系统堆管理器管理: 堆管理器是操作系统的一个模块,堆管理内存分配灵活,按需分配. 大块内存: 堆内存管理者总量很大的操作系统内存块,各进程可以按需申请使用,使用完释放. 程序手动申请&释放 ...
- 浅谈C#语言中的各种数据类型,与数据类型之间的转换
什么是数据类型? 数据类型,百度百科是这样解释的:数据类型在数据结构中的定义是一个值的集合以及定义在这个值集上的一组操作.这样的解释对于一个初学者来说未必太过于深奥. 简单点说,数据类型就是不同长度的 ...
- 浅谈C语言中的强符号、弱符号、强引用和弱引用【转】
转自:http://www.jb51.net/article/56924.htm 首先我表示很悲剧,在看<程序员的自我修养--链接.装载与库>之前我竟不知道C有强符号.弱符号.强引用和弱引 ...
- 浅谈C语言中结构体的初始化
转自:http://www.jb51.net/article/37246.htm <代码大全>建议在变量定义的时候进行初始化,但是很多人,特别是新人对结构体或者结构体数组定义是一般不会初始 ...
- 转: 浅谈C/C++中的指针和数组(二)
转自:http://www.cnblogs.com/dolphin0520/archive/2011/11/09/2242419.html 浅谈C/C++中的指针和数组(二) 前面已经讨论了指针和数组 ...
- 浅谈关于QT中Webkit内核浏览器
关于QT中Webkit内核浏览器是本文要介绍的内容,主要是来学习QT中webkit中浏览器的使用.提起WebKit,大家自然而然地想到浏览器.作为浏览器内部的主要构件,WebKit的主要工作是渲染.给 ...
- 浅谈Java语言环境搭建-JDK8
title: 浅谈Java语言环境搭建-JDK8 blog: CSDN data: Java学习路线及视频 1.What's the JDK,JRE JDK(Java Development Kit ...
随机推荐
- Ci框架整合smarty模板引擎
Ci框架整合smarty模板引擎 备注:下载smarty时,最好选择2.6版本,其他测试有坑,ci可以是2.2或其他 大体思路:将smarty封装成ci框架的一个类,然后重新配置一下smarty,这样 ...
- C语言考试第一题详细过程
1.计算 ,并输出其结果. 思路是先设计一个函数计算阶乘,再用循环,逐个求和. #include<stdio.h> int mul(int n) { int num,i; num=; ;i ...
- insmod: error inserting 'simp-blkdev.ko': -1 Invalid module format
(一) 今天写了个块设备驱动例子,在虚拟机上加载模块insmod simp_blkdev.ko的时候,出现以下错误. insmod: error inserting 'simple-blk.ko': ...
- 【CF】328 D. Super M
这种图论题已经变得简单了... /* D */ #include <iostream> #include <string> #include <map> #incl ...
- INV Close Period & GL Import Journal > DML tables
1. (N) Inventory > Accounting Close Cycle > Inventory Accounting Periods Insert data ...
- Centos4.3安装MySQL-python-1.2.3,出现error: command 'gcc' failed with exit status 1
在Linux Centos 4.3上安装MySQL-python-1.2.3的时候出现error: command 'gcc' failed with exit status 1, 具体原因是因为没有 ...
- SQL语句优化方法
1.1 注释使用 在语句中多写注释,注释不影响SQL语句的执行效率.增加代码的可读性. 1.2 对于事务的使用 尽量使事务处理达到最短,如果事务太长最好按功能将事务分开执行(如:可以让用户在界面上多几 ...
- java反编译工具
由于JAVA语言安全性高.代码优化.跨平台等特性,从1995年5月由SUN公司发布后,迅速取代了很多传统高级语言,占据了企业级网络应用开发等诸多领域的霸主地位. 不过,JAVA最突出的跨平台优势使得它 ...
- Selenium 实现联想下拉框
直接在文本框输入字符,并不能实现联想下拉框, 第一种方式:强制执行js driver.FindElement(By.Id("top_search_input")).SendKeys ...
- web_reg_find()查询信息为变量
Action(){char *str1;//=(char*)malloc(20);char str2[10]; web_url("toLoginPage", "URL={ ...