C —— 联合体

在进行某些算法的C语言编程的时候,需要使几种不同类型的变量存放到同一段内存单元中。也就是使用覆盖技术,几个变量互相覆盖。这种几个不同的变量共同占用一段内存的结构,在C语言中,被称作“共用体”类型结构,简称共用体,也叫联合体。
—— 摘自百度百科

定义联合体与使用

联合体是一种特殊的数据类型,允许在相同的内存位置存储不同的数据类型。程序中可以定义带有多个成员的联合体,但是任何时候只能有一个成员带有值。共用体提供了一种使用相同的内存位置的有效方式。用到的关键字是 union,其格式如下:

union 联合体名称 {
	member-list
}

实例代码如下:

#include<stdio.h>

union Person {
	char name[50];
	unsigned int age;
	double weight;
};

int main() {

	union Person person;
	strcpy(person.name, "tom");
	person.age = 27;
	person.weight = 46.9;
	printf("person.name = %s, person.age = %d, person.weight = %f\n", person.name, person.age, person.weight);
	
	return 0;
}

执行结果:

person.name = 33333sG@諏鱱AQ, person.age = 858993459, person.weight = 46.900000

可以看到,只有成员 weight 的值是被正确的输出,原因是这三个成员变量在储值的时候占用的是同一个内存空间,相当于这三个成员指向的是同一块内存空间,当 weight 被赋值之后,其他的成员的值就被损坏。使用 & 可以查看各个成员指向的地址值:

union Person up;
printf("&up=%p, &up.name=%p, &up.age=%p, &up.weight=%p\n", &up, &up.name, &up.age, &up.weight);

执行结果如下:

&up=0022FF08, &up.name=0022FF08, &up.age=0022FF08, &up.weight=0022FF08

如果需要在联合体变量被声明的时候赋予初始值的话,因为它们共用同一个内存空间,故而,不需要将每个值都赋值,而且编译器只会接收第一个值作为有效值填入合适的成员中。例如:

#include<stdio.h>

union Person {
	char name[50];
	unsigned int age;
	double weight;
};

int main() {


	union Person up1 = {"Tom", 12, 4.6};
	union Person up2 = {12};
	union Person up3 = {4.6};
	union Person up4 = {"Tom"};
	printf("name=%s, age=%d, weight=%f\n", up1.name, up1.age, up1.weight);
	printf("name=%s, age=%d, weight=%f\n", up2.name, up2.age, up2.weight);
	printf("name=%s, age=%d, weight=%f\n", up3.name, up3.age, up3.weight);
	printf("name=%s, age=%d, weight=%f\n", up4.name, up4.age, up4.weight);
	
	return 0;
}

该源程序在编译的时候给出警告和提示:

warning: excess elements in union initializer
  union Person up1 = {"Tom", 12, 4.6};
                             ^~
note: (near initialization for 'up1')
warning: excess elements in union initializer
  union Person up1 = {"Tom", 12, 4.6};
                                 ^~~
note: (near initialization for 'up1')

执行结果变成了:

name=Tom, age=7171924, weight=0.000000
name=, age=12, weight=0.000000
name=, age=4, weight=0.000000
name=Tom, age=7171924, weight=0.000000

从本例中可以看到,联合体 up1 和 up4 接受的值是字符串 Tom,联合体 up2 接受的值是 12,联合体 up3 将传递的小数直接转换为了整型赋值给了 age 成员,接受的值是 4。故而,在给联合体变量声明的时候不需要为每个成员变量赋值,只需要赋予一个合适类型的值即可。

联合体作为参数

将联合体作为参数传递到函数中的操作方式与结构体一样。但是因为共享内存的原因,在函数内,仅接受一个有效值。代码如下:

#include<stdio.h>
#include<string.h>

union Person {
	char name[50];
	unsigned int age;
	double weight;
};

void printPerson(union Person p) {
	printf("Person{name:%s, age:%d, weight:%f}", p.name, p.age, p.weight);
}

int main() {
	union Person up = {12};
	printPerson(up);
	return 0;
}

执行结果:

Person{name:, age:12, weight:0.000000}

指向联合体的指针

指向联合体的指针在使用上与结构体一致,主要使用的运算符是 ->。具体代码如下:

#include<stdio.h>
#include<string.h>

union Person {
	char name[50];
	unsigned int age;
	double weight;
};

void printPerson(union Person *p) {
	printf("Person{name:%s, age:%d, weight:%f}", p->name, p->age, p->weight);
}

int main() {
	union Person up = {12};
	union Person *p = &up;
	printPerson(p);	
	return 0;
}

执行结果:

Person{name:, age:12, weight:0.000000}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值