//--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
————————————————————————————