分类: C/C++
2009-07-16 20:56:54
联合(union)
和结构相比,联合可以说是另一种动物了,联合的声明和结构类似,但它的行为方式却和结果不同,联合的所有成员引用的是内存中的相同位置,当你想在不同的时刻把不同的东西存储于同一个位置时,就可以使用联合。
union {
float f;
int i;
}fi;
int main(void)
{
fi.f=3.14159;
printf(“%d\n”,fi.i);
}
浮点数和整形数都是32位的机器上,变量fi致占据内存中一个32位的字,如果成员f被访问,这个字就作为浮点值访问,如果成员i被访问,这个字就作为整型值访问。
# 1078530000 在fedora9下实验
如果fi.f=3;
# 1077936128 在fedora9下实验
首先3.14159存储于fi,然后这些相同的位当作一个整型值打印输出,注意这两个成员锁引用的位相同,仅有的区别在于每个成员的类型决定了这些位被如何解释。
如果
union {
char f;
int i;
}fi;
int main(void)
{
fi.f=123;
printf(“%d\n”,fi.i);
}
# 123 在fedora9下实验
如果联合的各个成员具有不同的长度,联合的长度就是它最大成员的长度。如果这些成员的长度相差悬殊,当存储长度较短的成员时,非常浪费空间,这种情况下,是在联合中存储指向不同成员的指针而不是直接存储成员本身,所有指针的长度是相同的,这样就解决了内存浪费的问题,当它需要使用哪个成员时,就分配正确数量的内存来存储它。
联合初始化
联合变量可以初始化,但这个初始值必须是联合第一个成员的类型,而且它必须位于一对花括号里面。如
union {
int a;
float b;
char c[4];、
}x = { 5 };
把x.a初始化为5.
我们不能把这个变量初始化为一个浮点值或字符值,如果给出的初始值是任何其它类型,它就会转换(如果可能的话)为一个整数并赋值给x.a。
实际应用实例:
比如AD采样的例子,采样数据分高八位和低八位,数据=高八位<<8+低八位。
而我们可以用联合实现,如下:
unsigned int read_ad(unsigned char channel)
{
unsigned char i;
unsigned int result=0;
union
{ unsigned char res8[2];
unsigned int res16;
}res;
ADMUX=(ADMUX&0xe0)|channel;
for(i=0;i<8;i++,result+=res.res16)
{
ADCSRA|=1<
res.res8[0]=ADCL;
res.res8[1]=ADCH;
ADCSRA|=1<
return result>>3;
}
如res.res8[0]=0x01;
res.res8[1]=0x02;
res.res16=0x201;