学习 C 语言中的结构体是非常重要的一步,因为结构体使得我们能够将不同类型的数据组织成一个复合数据类型。下面我会带你一步步了解 C 语言结构体的定义、使用方法和应用场景。
1. 结构体的基本概念
结构体(struct
)是一种用户自定义的复合数据类型,它能够将不同类型的变量组合在一起。例如,假设我们要定义一个表示学生的类型,学生可能有姓名、年龄、成绩等属性,这些属性的类型可能是字符串、整数、浮点数等。结构体可以将这些不同类型的属性组合成一个单一的类型。
2. 结构体的定义
结构体的定义使用 struct
关键字,基本的语法如下:
objectivec
struct StructName {
type1 member1;
type2 member2;
// ... 更多成员
};
示例: 定义一个表示学生信息的结构体:
objectivec
#include <stdio.h>
// 定义结构体
struct Student {
char name[50]; // 学生姓名
int age; // 学生年龄
float score; // 学生成绩
};
int main() {
// 创建结构体变量
struct Student student1;
// 给结构体成员赋值
strcpy(student1.name, "Tom");
student1.age = 20;
student1.score = 95.5;
// 输出结构体成员
printf("Name: %s\n", student1.name);
printf("Age: %d\n", student1.age);
printf("Score: %.2f\n", student1.score);
return 0;
}
3. 结构体变量
结构体定义后,我们可以像使用普通数据类型一样创建结构体变量。结构体变量的声明方式是:
objectivec
struct StructName varName;
示例:
objectivec
struct Student student1; // 创建一个 Student 类型的变量 student1
如果我们想要为多个学生创建结构体变量,方法如下:
objectivec
struct Student student1, student2; // 声明多个结构体变量
4. 结构体成员的访问
我们可以通过点运算符(.
)来访问结构体的成员:
objectivec
student1.name // 访问 student1 的 name 成员
student1.age // 访问 student1 的 age 成员
5. 结构体初始化
可以在定义结构体变量时进行初始化,也可以通过赋值来初始化成员。
示例:
- 定义时初始化:
struct Student student1 = {"Tom", 20, 95.5};
2.逐个成员赋值:
struct Student student1;
strcpy(student1.name, "Tom");
student1.age = 20;
student1.score = 95.5;
6. 结构体指针
我们还可以使用结构体指针来操作结构体变量。当使用结构体指针时,需要使用箭头运算符(->
)来访问成员。
示例:
objectivec
struct Student *ptr;
ptr = &student1;
printf("Name: %s\n", ptr->name);
printf("Age: %d\n", ptr->age);
printf("Score: %.2f\n", ptr->score);
7. 结构体作为函数参数
结构体可以作为函数的参数传递。传递方式有两种:按值传递和按地址传递。
- 按值传递:直接传递结构体的副本。
objectivec
void printStudent(struct Student student) {
printf("Name: %s\n", student.name);
printf("Age: %d\n", student.age);
printf("Score: %.2f\n", student.score);
}
2.按地址传递 :传递结构体指针,避免复制整个结构体。
objectivec
void printStudent(struct Student *student) {
printf("Name: %s\n", student->name);
printf("Age: %d\n", student->age);
printf("Score: %.2f\n", student->score);
}
8. 结构体的嵌套
结构体可以包含其他结构体作为成员。这使得结构体可以构造更复杂的数据结构。
示例:
objectivec
struct Date {
int day;
int month;
int year;
};
struct Student {
char name[50];
struct Date birthDate; // 嵌套结构体
float score;
};
int main() {
struct Student student1;
strcpy(student1.name, "Tom");
student1.birthDate.day = 15;
student1.birthDate.month = 8;
student1.birthDate.year = 2000;
student1.score = 95.5;
printf("Name: %s\n", student1.name);
printf("Birthdate: %d/%d/%d\n", student1.birthDate.day, student1.birthDate.month, student1.birthDate.year);
printf("Score: %.2f\n", student1.score);
return 0;
}
9. 结构体数组
我们还可以创建结构体数组,用于存储多个结构体实例。
示例:
objectivec
struct Student students[3]; // 创建一个结构体数组,存储 3 个学生的信息
10. typedef
和结构体
在 C 语言中,typedef
关键字可以为结构体类型定义一个新的别名,使得结构体的使用更加简洁。
示例:
objectivec
typedef struct {
char name[50];
int age;
float score;
} Student;
int main() {
Student student1;
strcpy(student1.name, "Tom");
student1.age = 20;
student1.score = 95.5;
printf("Name: %s\n", student1.name);
printf("Age: %d\n", student1.age);
printf("Score: %.2f\n", student1.score);
return 0;
}
11. 结构体的对齐与内存布局
结构体的内存布局受到对齐规则的影响,不同类型的数据会根据平台的内存对齐要求占用不同的内存空间。这意味着结构体中成员的顺序和类型可能会影响其内存占用。
小结
- 结构体是 C 语言中的复合数据类型,它能将不同类型的数据组织成一个单一的类型。
- 结构体通过
struct
关键字定义,可以包含不同类型的成员。 - 使用结构体时,可以通过点运算符(
.
)来访问成员,通过指针和箭头运算符(->
)来访问成员。 - 结构体可以作为函数的参数,也可以嵌套和创建结构体数组。
typedef
可以为结构体定义别名,简化代码。