C语言基础-结构体
1. 结构体的基本概念
结构体是一种用户自定义的数据类型,它可以包含多个不同类型的变量,这些变量称为结构体的成员。
2. 结构体的定义
struct 结构体名 {
成员类型1 成员名1;
成员类型2 成员名2;
// ...更多成员
};
示例:
struct Student {
int id;
char name[50];
float score;
};
3. 结构体变量的声明
// 方法1:先定义结构体,再声明变量
struct Student {
int id;
char name[50];
float score;
};
struct Student s1, s2;
// 方法2:定义结构体的同时声明变量
struct Student {
int id;
char name[50];
float score;
} s1, s2;
// 方法3:使用typedef简化结构体变量的声明
typedef struct Student {
int id;
char name[50];
float score;
} Student;
Student s1, s2; // 不需要再写struct
4. 访问结构体成员
使用点运算符(.)访问结构体的成员:
#include <stdio.h>
#include <string.h>
struct Student {
int id;
char name[50];
float score;
};
int main() {
struct Student s1;
s1.id = 1001;
strcpy(s1.name, "张三");
s1.score = 85.5;
printf("学号:%d\n", s1.id);
printf("姓名:%s\n", s1.name);
printf("成绩:%.1f\n", s1.score);
return 0;
}
5. 结构体的初始化
// 按成员顺序初始化
struct Student s1 = {1001, "张三", 85.5};
// 指定成员初始化(C99标准)
struct Student s2 = {.id = 1002, .name = "李四", .score = 92.0};
6. 结构体数组
struct Student class[40]; // 定义一个包含40个学生的数组
// 访问结构体数组元素
class[0].id = 1001;
strcpy(class[0].name, "张三");
class[0].score = 85.5;
7. 结构体指针
struct Student s1 = {1001, "张三", 85.5};
struct Student *ps = &s1;
// 使用箭头运算符(->)通过指针访问结构体成员
printf("学号:%d\n", ps->id); // 等价于 (*ps).id
printf("姓名:%s\n", ps->name); // 等价于 (*ps).name
printf("成绩:%.1f\n", ps->score); // 等价于 (*ps).score
8. 结构体作为函数参数
// 传值方式(会复制整个结构体)
void printStudent(struct Student s) {
printf("学号:%d,姓名:%s,成绩:%.1f\n", s.id, s.name, s.score);
}
// 传址方式(只传递指针,效率更高)
void updateScore(struct Student *ps, float newScore) {
ps->score = newScore;
}
int main() {
struct Student s1 = {1001, "张三", 85.5};
printStudent(s1);
updateScore(&s1, 92.0);
printStudent(s1);
return 0;
}
9. 结构体嵌套
结构体成员可以是另一个结构体:
struct Date {
int year;
int month;
int day;
};
struct Student {
int id;
char name[50];
float score;
struct Date birthday; // 嵌套结构体
};
int main() {
struct Student s1 = {1001, "张三", 85.5, {2000, 5, 15}};
printf("学生%s的生日是%d年%d月%d日\n",
s1.name, s1.birthday.year, s1.birthday.month, s1.birthday.day);
return 0;
}
10. 结构体对齐和内存布局
C语言中,结构体成员在内存中并不一定是连续存储的,因为编译器会进行内存对齐:
#include <stdio.h>
struct Example1 {
char c; // 1字节
int i; // 4字节
char d; // 1字节
};
struct Example2 {
char c; // 1字节
char d; // 1字节
int i; // 4字节
};
int main() {
printf("sizeof(struct Example1) = %lu\n", sizeof(struct Example1)); // 可能是12
printf("sizeof(struct Example2) = %lu\n", sizeof(struct Example2)); // 可能是8
return 0;
}
11. 完整实例:学生管理系统
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
typedef struct Student {
int id;
char name[50];
float score;
} Student;
// 添加学生
void addStudent(Student *students, int *count) {
if (*count >= 100) {
printf("学生数量已达最大限制!\n");
return;
}
Student *s = &students[*count];
printf("请输入学号:");
scanf("%d", &s->id);
printf("请输入姓名:");
scanf("%s", s->name);
printf("请输入成绩:");
scanf("%f", &s->score);
(*count)++;
printf("添加成功!当前共有%d名学生。\n", *count);
}
// 显示所有学生
void displayStudents(Student *students, int count) {
if (count == 0) {
printf("暂无学生记录!\n");
return;
}
printf("\n学号\t姓名\t成绩\n");
printf("-------------------------\n");
for (int i = 0; i < count; i++) {
printf("%d\t%s\t%.1f\n",
students[i].id, students[i].name, students[i].score);
}
printf("-------------------------\n");
}
// 查找学生
void findStudent(Student *students, int count) {
int id;
printf("请输入要查找的学号:");
scanf("%d", &id);
for (int i = 0; i < count; i++) {
if (students[i].id == id) {
printf("\n找到该学生:\n");
printf("学号:%d\n", students[i].id);
printf("姓名:%s\n", students[i].name);
printf("成绩:%.1f\n", students[i].score);
return;
}
}
printf("未找到学号为%d的学生!\n", id);
}
int main() {
Student students[100]; // 最多存储100名学生
int count = 0; // 当前学生数量
int choice;
while (1) {
printf("\n学生管理系统\n");
printf("1. 添加学生\n");
printf("2. 显示所有学生\n");
printf("3. 查找学生\n");
printf("0. 退出\n");
printf("请选择操作:");
scanf("%d", &choice);
switch (choice) {
case 0:
printf("感谢使用,再见!\n");
return 0;
case 1:
addStudent(students, &count);
break;
case 2:
displayStudents(students, count);
break;
case 3:
findStudent(students, count);
break;
default:
printf("无效的选择,请重试!\n");
}
}
return 0;
}

浙公网安备 33010602011771号