浅谈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 ...
随机推荐
- SPRING IN ACTION 第4版笔记-第八章Advanced Spring MVC-004-Pizza例子的用户流程(flowExecutionKey、_eventId_phoneEntered、flowExecutionUrl )
一. 1. 2. 3.customer-flow.xml 自己定义customer,最后output <?xml version="1.0" encoding="U ...
- ANDROID_MARS学习笔记_S01原始版_012_广播机制一
一.简介 二.代码1.xml(1)activity_main.xml <?xml version="1.0" encoding="utf-8"?> ...
- 公司的SVN服务器改变了IP地址,请问以前下载的代码如何同步,
工作根目录上 右键->TortoiseSVN->Relocate,修改URL 更新前先备份!
- 测试ODBC与OLE
using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Data. ...
- MPlayer
名称 mplayer − 电影播放器 mencoder − 电影编解码器 概要 mplayer [选项] [文件|URL|播放列表|−] mplayer [选项] 文件1 [指定选项] [文件 ...
- hadoop2.2编程:自定义hadoop map/reduce输入文件切割InputFormat
hadoop会对原始输入文件进行文件切割,然后把每个split传入mapper程序中进行处理,FileInputFormat是所有以文件作为数据源的InputFormat实现的基类,FileInput ...
- c#桥接模式(bridge结构模式)
桥接模式(bridge结构模式)c#简单例子 在前面的玩家中每增加一个行为,就必须在每个玩家中都增加,通过桥接模式将行为提取出来了,减少变化 ? 1 2 3 4 5 6 7 8 9 10 11 12 ...
- WordPress Pretty Photo插件‘hashrel’参数跨站脚本漏洞
漏洞名称: WordPress Pretty Photo插件‘hashrel’参数跨站脚本漏洞 CNNVD编号: CNNVD-201311-405 发布时间: 2013-11-28 更新时间: 201 ...
- 分别应用include指令和include动作标识在一个jsp页面中包含一个文件。
分别应用include指令和include动作标识在一个jsp页面中包含一个文件. hello.jsp <%@ page language="java" import=&qu ...
- iframe 处理
import java.io.File; import org.openqa.selenium.By; import org.openqa.selenium.WebDriver; import org ...