union共用体

//--union 共用体,联合体
#include <stdio.h> 
  
union union0 
{ 
    int i;   ///4 
    char c;  ///1 
    double k; ///8 
}; 
  
union union1 
{ 
    char s[10];   //1 
    int i;        //4 
}; 
  
typedef union 
{ 
    long i;      //4 
    int k[5];    //20 
    char c;      //1 
} DATE;   20 
struct data  
{  
    int cat;     //4 
    DATE cow;    //20 
    double dog;  //8 
} too;   //20+4+8=32 
DATE max; 
  
int main() 
{ 
    union union0 u0; 
    union union1 u1; 
  
    printf("%d\n",sizeof(struct data)+sizeof(max)); 
  
    printf("int : %d\n",sizeof(int)); 
    printf("float : %d\n",sizeof(float)); 
    printf("long : %d\n",sizeof(long)); 
    printf("double : %d\n",sizeof(double)); 
  
    printf("u0= %d\n",sizeof(union0));   //8 
    printf("u1= %d\n",sizeof(union1));   //12 
  
    return 0; 
      
} 
/*------------------------ 
OUTPUT: 
52 
int : 4 
float : 4 
long : 4 
double : 8 
u0= 8 
u1= 12 
Press any key to continue 
/*------------------------ 

共用体和结构体有下列区别:   
1. 共用体和结构体都是由多个不同的数据类型成员组成, 但在任何同一时刻, 
    共用体只存放了一个被选中的成员, 而结构体的所有成员都存在。   
2. 对于共用体的不同成员赋值, 将会对其它成员重写, 原来成员的值就不存在了, 
    而对于结构体的不同成员赋值是互不影响的。
---------------------------**/
union可以测试大小端模式:

1.大端模式
所谓的大端模式,是指数据的高位,保存在内存的低地址中,而数据的低位,保存在内存的高地址中,
这样的存储模式有点儿类似于把数据当作字符串顺序处理:地址由小向大增加,而数据从高位往低位放;   
例子:   
0000430: e684 6c4e 0100 1800 53ef 0100 0100 0000   
0000440: b484 6c4e 004e ed00 0000 0000 0100 0000   
在大端模式下,前16位应该这样读: e684   
记忆方法: 地址的增长顺序与值的增长顺序相反
2.小端模式
  所谓的小端模式,是指数据的高位保存在内存的高地址中,而数 据的低位保存在内存的低地址中,
这种存储模式将地址的高低和数据位权有效地结合起来,高地址部分权值高,低地址部分权值低,和我们的逻辑方法一致。   
例子:   
0000430: e684 6c4e 0100 1800 53ef 0100 0100 0000   
0000440: b484 6c4e 004e ed00 0000 0000 0100 0000   
在小端模式下,前16位应该这样读: 84e6   
记忆方法: 地址的增长顺序与值的增长顺序相同

在ARM体系中,每个字单元包含4个字节单元或者两个半字单元。在字单元中,4个字节哪一个是高位字节,哪一个是低位字节则有两种不同的格式:big-endian和little-endian格式。
在小端模式中,低位字节放在低地址,高位字节放在高地址;在大端模式中,低位字节放在高地址,高位字节放在低地址。

在C语言中,不同于结构体,共用体(联合体)中的几种不同类型的变量存放在同一段内存单元中。
利用这一特点,可以用联合体变量判断ARM或x86环境下,存储系统是是大端还是小端模式。

#include <stdio.h>

bool isBigEndian(void)
{
	int i=1;  //i=0x 00 00 00 01
	char c=*(char *)&i;   //note: char c=(char)i; error
	return (int)c !=i;
}

void main(void)
{
	if(isBigEndian())
		printf("big endian\n");
	else
		printf("little endian\n");
}

//  output: little endian


或者

#include <stdio.h>

union u
{
	int a;   ///4 bytes
	char b;  /// 1 byte
}u0;

int main()
{
	u0.a=1;
	if(u0.b==1)
		printf("little endian\n");
	else
		printf("big endian\n");
	return 0;
}


 

说明:
1 在c中,联合体(共用体)的数据成员都是从低地址开始存放。
2 若是小端模式,由低地址到高地址c.a存放为0x01 00 00 00,c.b被赋值为0x01;

————————————————————————————

地址 0x00000000 0x00000001 0x00000002 0x00000003

c.a 01 00 00 00

c.b 01 00

————————————————————————————
3 若是大端模式,由低地址到高地址c.a存放为0x00 00 00 01,c.b被赋值为0x0;

————————————————————————————

地址 0x00000000 0x00000001 0x00000002 0x00000003

c.a 00 00 00 01

c.b 00 00

————————————————————————————


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值