共用体是C语言中一种特殊的构造类型,它允许不同类型的数据共享同一内存空间。东巴文(db-w.cn) 将带你深入理解共用体的原理与实践。
💡 东巴文观点:共用体是C语言节省内存的利器,掌握共用体能够让你编写更高效的程序。
#include <stdio.h>
void unionDefinition() {
printf("=== 东巴文共用体的定义 ===\n\n");
printf("共用体(Union):\n");
printf(" 一种特殊的构造类型\n");
printf(" 所有成员共享同一内存空间\n");
printf(" 同一时刻只能使用一个成员\n\n");
printf("共用体的特点:\n");
printf(" 1. 所有成员共享同一内存空间\n");
printf(" 2. 大小等于最大成员的大小\n");
printf(" 3. 同一时刻只能使用一个成员\n");
printf(" 4. 修改一个成员会影响其他成员\n");
printf(" 5. 节省内存空间\n");
}
int main() {
unionDefinition();
return 0;
}
#include <stdio.h>
#include <string.h>
// 方式1:先定义共用体类型,再声明变量
union Data1 {
int i;
float f;
char str[20];
};
// 方式2:定义共用体类型的同时声明变量
union Data2 {
int i;
float f;
char str[20];
} data1, data2;
// 方式3:匿名共用体
union {
int i;
float f;
} data3;
// 方式4:使用typedef
typedef union {
int i;
float f;
char str[20];
} Data3;
void unionDeclaration() {
printf("=== 东巴文共用体的声明 ===\n\n");
union Data1 data;
Data3 data4;
data.i = 100;
data4.i = 200;
printf("data.i = %d\n", data.i);
printf("data4.i = %d\n", data4.i);
}
int main() {
unionDeclaration();
return 0;
}
#include <stdio.h>
#include <string.h>
typedef union {
int i;
float f;
char str[20];
} Data;
void unionInitialization() {
printf("=== 东巴文共用体的初始化 ===\n\n");
// 方式1:初始化第一个成员
Data data1 = {100};
printf("data1.i = %d\n", data1.i);
// 方式2:指定成员初始化(C99)
Data data2 = {.f = 95.5};
printf("data2.f = %.1f\n", data2.f);
// 方式3:指定成员初始化(C99)
Data data3 = {.str = "东巴文"};
printf("data3.str = %s\n", data3.str);
}
int main() {
unionInitialization();
return 0;
}
#include <stdio.h>
#include <string.h>
typedef union {
int i;
float f;
char str[20];
} Data;
void dotOperator() {
printf("=== 东巴文点运算符 ===\n\n");
Data data;
// 使用int成员
data.i = 100;
printf("使用int成员:\n");
printf(" data.i = %d\n", data.i);
// 使用float成员
data.f = 95.5;
printf("\n使用float成员:\n");
printf(" data.f = %.1f\n", data.f);
printf(" data.i = %d(已被覆盖)\n", data.i);
// 使用char数组成员
strcpy(data.str, "东巴文");
printf("\n使用char数组成员:\n");
printf(" data.str = %s\n", data.str);
printf(" data.i = %d(已被覆盖)\n", data.i);
printf(" data.f = %.1f(已被覆盖)\n", data.f);
}
int main() {
dotOperator();
return 0;
}
#include <stdio.h>
#include <string.h>
typedef union {
int i;
float f;
char str[20];
} Data;
void arrowOperator() {
printf("=== 东巴文箭头运算符 ===\n\n");
Data data;
Data *ptr = &data;
// 使用箭头运算符访问成员
ptr->i = 100;
printf("使用箭头运算符访问:\n");
printf(" ptr->i = %d\n", ptr->i);
ptr->f = 95.5;
printf("\n ptr->f = %.1f\n", ptr->f);
printf(" ptr->i = %d(已被覆盖)\n", ptr->i);
}
int main() {
arrowOperator();
return 0;
}
#include <stdio.h>
typedef union {
char c;
int i;
double d;
} Data1;
typedef union {
int i;
double d;
} Data2;
void unionSize() {
printf("=== 东巴文共用体的大小 ===\n\n");
printf("Data1大小:%zu字节\n", sizeof(Data1));
printf(" char大小:%zu字节\n", sizeof(char));
printf(" int大小:%zu字节\n", sizeof(int));
printf(" double大小:%zu字节\n", sizeof(double));
printf("\nData2大小:%zu字节\n", sizeof(Data2));
printf(" int大小:%zu字节\n", sizeof(int));
printf(" double大小:%zu字节\n", sizeof(double));
printf("\n共用体大小规则:\n");
printf(" 1. 大小等于最大成员的大小\n");
printf(" 2. 可能需要考虑内存对齐\n");
printf(" 3. 所有成员共享同一内存空间\n");
}
int main() {
unionSize();
return 0;
}
#include <stdio.h>
typedef struct {
int i;
float f;
char c;
} StructData;
typedef union {
int i;
float f;
char c;
} UnionData;
void structVsUnion() {
printf("=== 东巴文共用体与结构体的区别 ===\n\n");
printf("结构体:\n");
printf(" 大小:%zu字节\n", sizeof(StructData));
printf(" 成员独立存储\n");
printf(" 可以同时使用所有成员\n");
printf(" 修改一个成员不影响其他成员\n\n");
printf("共用体:\n");
printf(" 大小:%zu字节\n", sizeof(UnionData));
printf(" 成员共享内存\n");
printf(" 同一时刻只能使用一个成员\n");
printf(" 修改一个成员会影响其他成员\n");
}
int main() {
structVsUnion();
return 0;
}
东巴文对比表:
| 特性 | 结构体 | 共用体 |
|---|---|---|
| 成员存储 | 独立存储 | 共享存储 |
| 大小 | 所有成员大小之和 | 最大成员的大小 |
| 同时使用 | 可以同时使用所有成员 | 同一时刻只能使用一个成员 |
| 修改影响 | 修改一个成员不影响其他成员 | 修改一个成员会影响其他成员 |
| 内存效率 | 较低 | 较高 |
| 适用场景 | 需要同时存储多个成员 | 互斥数据,节省内存 |
#include <stdio.h>
typedef struct {
int type; // 0: int, 1: float, 2: char
union {
int intValue;
float floatValue;
char charValue;
} value;
} Variant;
void saveMemory() {
printf("=== 东巴文节省内存 ===\n\n");
Variant variants[3];
// 存储int
variants[0].type = 0;
variants[0].value.intValue = 100;
// 存储float
variants[1].type = 1;
variants[1].value.floatValue = 95.5;
// 存储char
variants[2].type = 2;
variants[2].value.charValue = 'A';
printf("变体数据:\n");
for (int i = 0; i < 3; i++) {
printf("变体%d: ", i + 1);
switch (variants[i].type) {
case 0:
printf("int = %d\n", variants[i].value.intValue);
break;
case 1:
printf("float = %.1f\n", variants[i].value.floatValue);
break;
case 2:
printf("char = %c\n", variants[i].value.charValue);
break;
}
}
printf("\n节省内存:\n");
printf(" 使用共用体:%zu字节\n", sizeof(Variant));
printf(" 不使用共用体:%zu字节\n", sizeof(int) + sizeof(float) + sizeof(char));
}
int main() {
saveMemory();
return 0;
}
#include <stdio.h>
typedef union {
int i;
float f;
} IntFloat;
void dataTypeConversion() {
printf("=== 东巴文数据类型转换 ===\n\n");
IntFloat converter;
// int转float
converter.i = 100;
printf("int值:%d\n", converter.i);
printf("对应的float值:%f\n", converter.f);
// float转int
converter.f = 95.5;
printf("\nfloat值:%.1f\n", converter.f);
printf("对应的int值:%d\n", converter.i);
printf("\n注意:\n");
printf(" 这不是类型转换,而是同一内存的不同解释\n");
printf(" 可以用于查看浮点数的内部表示\n");
}
int main() {
dataTypeConversion();
return 0;
}
#include <stdio.h>
#include <string.h>
typedef union {
struct {
unsigned char byte1;
unsigned char byte2;
unsigned char byte3;
unsigned char byte4;
} bytes;
unsigned int value;
} IPAddress;
void networkPacket() {
printf("=== 东巴文网络数据包 ===\n\n");
IPAddress ip;
// 方式1:按字节设置
ip.bytes.byte1 = 192;
ip.bytes.byte2 = 168;
ip.bytes.byte3 = 1;
ip.bytes.byte4 = 1;
printf("IP地址(按字节):\n");
printf(" %d.%d.%d.%d\n",
ip.bytes.byte1, ip.bytes.byte2,
ip.bytes.byte3, ip.bytes.byte4);
printf(" 整数值:%u\n", ip.value);
// 方式2:按整数设置
ip.value = 3232235777; // 192.168.1.1
printf("\nIP地址(按整数):\n");
printf(" 整数值:%u\n", ip.value);
printf(" %d.%d.%d.%d\n",
ip.bytes.byte1, ip.bytes.byte2,
ip.bytes.byte3, ip.bytes.byte4);
}
int main() {
networkPacket();
return 0;
}
#include <stdio.h>
typedef union {
struct {
unsigned char bit0 : 1;
unsigned char bit1 : 1;
unsigned char bit2 : 1;
unsigned char bit3 : 1;
unsigned char bit4 : 1;
unsigned char bit5 : 1;
unsigned char bit6 : 1;
unsigned char bit7 : 1;
} bits;
unsigned char value;
} Register;
void hardwareRegister() {
printf("=== 东巴文硬件寄存器 ===\n\n");
Register reg;
// 按位设置
reg.bits.bit0 = 1;
reg.bits.bit3 = 1;
reg.bits.bit7 = 1;
printf("按位设置:\n");
printf(" bit0 = %d\n", reg.bits.bit0);
printf(" bit3 = %d\n", reg.bits.bit3);
printf(" bit7 = %d\n", reg.bits.bit7);
printf(" 整数值 = %d\n", reg.value);
// 按字节设置
reg.value = 0xAA;
printf("\n按字节设置(0xAA):\n");
printf(" bit0 = %d\n", reg.bits.bit0);
printf(" bit1 = %d\n", reg.bits.bit1);
printf(" bit2 = %d\n", reg.bits.bit2);
printf(" bit3 = %d\n", reg.bits.bit3);
printf(" bit4 = %d\n", reg.bits.bit4);
printf(" bit5 = %d\n", reg.bits.bit5);
printf(" bit6 = %d\n", reg.bits.bit6);
printf(" bit7 = %d\n", reg.bits.bit7);
}
int main() {
hardwareRegister();
return 0;
}
#include <stdio.h>
typedef union {
int i;
float f;
char c;
} Data;
void unionArray() {
printf("=== 东巴文共用体数组 ===\n\n");
Data dataArray[3];
dataArray[0].i = 100;
dataArray[1].f = 95.5;
dataArray[2].c = 'A';
printf("共用体数组:\n");
printf(" dataArray[0].i = %d\n", dataArray[0].i);
printf(" dataArray[1].f = %.1f\n", dataArray[1].f);
printf(" dataArray[2].c = %c\n", dataArray[2].c);
}
int main() {
unionArray();
return 0;
}
#include <stdio.h>
typedef union {
int i;
float f;
char c;
} Data;
void unionPointer() {
printf("=== 东巴文共用体指针 ===\n\n");
Data data;
Data *ptr = &data;
ptr->i = 100;
printf("使用指针访问:\n");
printf(" ptr->i = %d\n", ptr->i);
ptr->f = 95.5;
printf(" ptr->f = %.1f\n", ptr->f);
printf(" ptr->i = %d(已被覆盖)\n", ptr->i);
}
int main() {
unionPointer();
return 0;
}
#include <stdio.h>
typedef struct {
int type; // 类型标识
union {
int intValue;
float floatValue;
char charValue;
} value;
} TaggedUnion;
void useTypeTag() {
printf("=== 东巴文使用类型标识 ===\n\n");
TaggedUnion data;
data.type = 0; // 0表示int
data.value.intValue = 100;
printf("使用类型标识:\n");
printf(" 类型:%d\n", data.type);
printf(" 值:%d\n", data.value.intValue);
printf("\n类型标识的作用:\n");
printf(" 1. 记录当前使用的成员类型\n");
printf(" 2. 避免错误访问\n");
printf(" 3. 提高代码安全性\n");
}
int main() {
useTypeTag();
return 0;
}
#include <stdio.h>
typedef union {
int i;
float f;
} Data;
void avoidWrongAccess() {
printf("=== 东巴文避免错误访问 ===\n\n");
Data data;
data.i = 100;
printf("正确访问:\n");
printf(" data.i = %d\n", data.i);
printf("\n错误访问:\n");
printf(" data.f = %f(无意义的值)\n", data.f);
printf("\n避免错误访问:\n");
printf(" 1. 使用类型标识\n");
printf(" 2. 记住当前使用的成员\n");
printf(" 3. 避免访问未初始化的成员\n");
}
int main() {
avoidWrongAccess();
return 0;
}
#include <stdio.h>
typedef union {
int i;
float f;
char c;
} Data;
void useTypedef() {
printf("=== 东巴文使用typedef简化类型 ===\n\n");
Data data;
data.i = 100;
printf("typedef优势:\n");
printf(" 1. 简化类型声明\n");
printf(" 2. 提高可读性\n");
printf(" 3. 便于移植\n");
printf(" 4. 隐藏实现细节\n");
printf("\ndata.i = %d\n", data.i);
}
int main() {
useTypedef();
return 0;
}
完成本章学习后,请确认:
掌握共用体后,你可以继续学习:
如果遇到问题,欢迎访问 东巴文(db-w.cn) 获取帮助!
东巴文(db-w.cn) - 让编程学习更简单
🎯 东巴文共用体提示:共用体是C语言节省内存的利器。在 db-w.cn,我们会通过大量实例帮你掌握共用体!