目录
C语言是一门被广泛应用于系统级编程和嵌入式系统开发的高级编程语言。在C语言中,结构体(Structures)和联合体(Unions)是两种重要的数据结构,允许程序员组织和管理不同类型的数据。本文将深入浅出地介绍C语言中的结构体和联合体。
结构体是一种用户自定义的数据类型,允许将不同类型的数据组织在一个单一的数据结构中。结构体的每个成员可以是不同的数据类型,可以包含基本数据类型,数组,甚至其他结构体。
在C语言中,结构体的定义和声明通常分为两个步骤。首先是定义结构体的模板,然后声明具体的结构体变量。
// 结构体定义
struct Person {
char name[50];
int age;
float height;
};
// 结构体声明
struct Person person1, person2;
上面的例子中,我们定义了一个名为Person
的结构体,包含了姓名、年龄和身高三个成员。然后通过声明两个Person
类型的变量person1
和person2
。
访问结构体的成员使用点操作符 .
:
// 赋值
strcpy(person1.name, "John Doe");
person1.age = 30;
person1.height = 175.5;
// 访问
printf("Name: %s\n", person1.name);
printf("Age: %d\n", person1.age);
printf("Height: %.2f\n", person1.height);
结构体可以嵌套在其他结构体中,形成复杂的数据结构:
struct Date {
int day;
int month;
int year;
};
struct Student {
char name[50];
struct Date dob; // 结构体嵌套
int roll_number;
};
联合体是一种特殊的数据类型,允许在同一内存位置存储不同的数据类型。和结构体不同的是,联合体的成员共享同一块内存。
// 联合体定义
union Data {
int i;
float f;
char str[20];
};
// 联合体声明
union Data data1, data2;
上述代码定义了一个名为 Data
的联合体,包含了一个整数、一个浮点数和一个字符数组。然后通过声明两个 Data
类型的变量 data1
和 data2
。
访问联合体的成员使用点操作符 .
:
data1.i = 10;
printf("Integer: %d\n", data1.i);
data1.f = 3.14;
printf("Float: %.2f\n", data1.f);
strcpy(data1.str, "Hello");
printf("String: %s\n", data1.str);
联合体的一个关键特性是,它的所有成员共享同一块内存。因此,对一个成员的修改会影响其他成员。
联合体常用于需要在不同数据类型之间共享同一内存位置的场景,节省内存空间。例如,一个网络协议包可能包含多个字段,但在任一时刻只有其中一个字段是有效的。
union ProtocolData {
int packetType;
float sensorData;
char message[256];
};
struct Person {
char name[50];
int age;
float height;
};
在上述例子中,Person
结构体的大小为 50 (name) + 4 (age) + 4 (height) = 58
字节。
union Data {
int i;
float f;
char str[20];
};
在上述例子中,Data
联合体的大小等于最大成员 str[20]
的大小,即 20
字节。
.
,每个成员都有独立的命名空间。struct Person person1;
person1.age = 25;
.
,但由于所有成员共享同一块内存,对一个成员的修改会影响其他成员。union Data data1;
data1.i = 42;
printf("%f\n", data1.f); // 输出的是由浮点数解释的42
struct Person {
char name[50];
int age;
float height;
};
union ProtocolData {
int packetType;
float sensorData;
char message[256];
};
结构体: 由于结构体的内存是按照成员顺序分配的,相邻的成员可能存在内存对齐的空隙,造成内存浪费。
联合体: 联合体的内存共享机制可能导致在不同成员切换时的数据混淆,使用联合体时需要特别小心,确保对数据的访问和修改都是合理的。
定义一个结构体 Student
表示学生信息,包括学生姓名(字符串)、学号(整数)、成绩(浮点数)。
// 结构体定义
struct Student {
char name[50];
int studentID;
float grade;
};
// 结构体声明
struct Student student1, student2;
???编写代码完成以下任务,
定义一个结构体 Date
表示日期,包括年(整数)、月(整数)、日(整数)。
// 结构体定义
struct Date {
int year;
int month;
int day;
};
// 结构体声明
struct Date date1, date2;
编写代码完成以下任务:
变体数据类型:
定义一个联合体 Variant
表示变体数据类型,包括整数(int)、浮点数(float)和字符串(char数组)
// 联合体定义
union Variant {
int intValue;
float floatValue;
char stringValue[20];
};
// 联合体声明
union Variant data1, data2;
编写代码完成以下任务:
网络协议处理:
定义一个联合体 ProtocolData
表示网络协议数据包,包括数据类型(整数)、传感器数据(浮点数)和消息(char数组)。
// 联合体定义
union ProtocolData {
int packetType;
float sensorData;
char message[256];
};
// 联合体声明
union ProtocolData packet1, packet2;
编写代码完成以下任务:
结构体练习
#include <stdio.h>
int main() {
// 输入学生信息
printf("Enter student1 details:\n");
printf("Name: ");
scanf("%s", student1.name);
printf("Student ID: ");
scanf("%d", &student1.studentID);
printf("Grade: ");
scanf("%f", &student1.grade);
// 输出学生信息
printf("\nStudent1 details:\n");
printf("Name: %s\n", student1.name);
printf("Student ID: %d\n", student1.studentID);
printf("Grade: %.2f\n", student1.grade);
return 0;
}
#include <stdio.h>
int main() {
// 输入日期
printf("Enter date1 details:\n");
printf("Year: ");
scanf("%d", &date1.year);
printf("Month: ");
scanf("%d", &date1.month);
printf("Day: ");
scanf("%d", &date1.day);
// 输出日期
printf("\nDate1 details:\n");
printf("Year: %d\n", date1.year);
printf("Month: %d\n", date1.month);
printf("Day: %d\n", date1.day);
return 0;
}
联合体练习
#include <stdio.h>
int main() {
// 输入和输出整数
printf("Enter an integer: ");
scanf("%d", &data1.intValue);
printf("Integer: %d\n", data1.intValue);
// 输入和输出浮点数
printf("Enter a float: ");
scanf("%f", &data1.floatValue);
printf("Float: %.2f\n", data1.floatValue);
// 输入和输出字符串
printf("Enter a string: ");
scanf("%s", data1.stringValue);
printf("String: %s\n", data1.stringValue);
return 0;
}
#include <stdio.h>
int main() {
// 输入和输出数据类型
printf("Enter packetType: ");
scanf("%d", &packet1.packetType);
printf("Packet Type: %d\n", packet1.packetType);
// 输入和输出传感器数据
printf("Enter sensorData: ");
scanf("%f", &packet1.sensorData);
printf("Sensor Data: %.2f\n", packet1.sensorData);
// 输入和输出消息
printf("Enter message: ");
scanf("%s", packet1.message);
printf("Message: %s\n", packet1.message);
return 0;
}