C语言:结构体

1. 结构体的定义

结构体是 C 语言中一种用户自定义的数据类型,它允许将不同类型的数据组合在一起。定义结构体的一般形式为:

c 复制代码
struct 结构体名{
    数据类型 成员1;
    数据类型 成员2;
    //...
    数据类型 成员n;
};

例如,定义一个表示学生信息的结构体:

c 复制代码
struct Student {
    char name[20];
    int age;
    float score;
};

这里定义了一个名为Student的结构体,它包含三个成员:name是一个字符数组,用于存储学生的姓名;age是一个整数,用于存储学生的年龄;score是一个浮点数,用于存储学生的成绩。

2. 结构体变量的声明和初始化

  • 声明:在结构体定义之后,可以声明结构体变量。有两种方式,一种是在定义结构体的同时声明变量,例如:
c 复制代码
struct Student {
    char name[20];
    int age;
    float score;
} student1, student2;

这里声明了两个Student结构体类型的变量student1和student2。另一种是先定义结构体,再声明变量,例如:

c 复制代码
struct Student student3;
  • 初始化:可以在声明结构体变量时进行初始化。例如:
c 复制代码
struct Student student4 = {"Tom", 20, 85.5};

这样就将student4的name成员初始化为"Tom",age成员初始化为20,score成员初始化为85.5。

3. 结构体成员的访问

  • 可以使用点运算符(.)来访问结构体变量的成员。例如,对于上面的student4结构体变量:
c 复制代码
printf("姓名:%s,年龄:%d,成绩:%f\n", student4.name, student4.age, student4.score);
  • 如果有指向结构体的指针,可以使用箭头运算符(->)来访问成员。例如:
c 复制代码
struct Student *pStudent = &student4;
printf("姓名:%s,年龄:%d,成绩:%f\n", pStudent->name, pStudent->age, pStudent->score);

这里先定义了一个指向Student结构体的指针pStudent,并让它指向student4,然后通过pStudent->name等方式访问成员。

4. 结构体数组

  • 可以定义结构体数组,即数组中的每个元素都是一个结构体。例如:
c 复制代码
struct Student class[3];

这定义了一个包含 3 个Student结构体元素的数组class。可以对结构体数组进行初始化,例如:

c 复制代码
struct Student class[3] = {{"Alice", 19, 90.0}, {"Bob", 20, 88.0}, {"Cindy", 21, 92.0}};
  • 访问结构体数组元素的成员,例如:
c 复制代码
for (int i = 0; i < 3; i++) {
    printf("姓名:%s,年龄:%d,成绩:%f\n", class[i].name, class[i].age, class[i].score);
}

5. 结构体的嵌套

  • 结构体可以嵌套定义,即一个结构体内部可以包含另一个结构体。例如,定义一个包含日期的结构体,再将其包含在学生信息结构体中:
c 复制代码
struct Date {
    int year;
    int month;
    int day;
};
struct StudentWithDate {
    char name[20];
    int age;
    struct Date birthday;
};
  • 访问嵌套结构体的成员,例如:
c 复制代码
struct StudentWithDate student5 = {"David", 22, {2001, 5, 10}};
printf("生日年份:%d\n", student5.birthday.year);

6. 结构体在函数中的使用

结构体可以作为函数的参数传递。有两种方式:

  • 值传递:将结构体变量的值复制一份传递给函数。例如:
c 复制代码
void printStudent(struct Student s) {
    printf("姓名:%s,年龄:%d,成绩:%f\n", s.name, s.age, s.score);
}

调用这个函数时,会复制一份结构体变量的值,如printStudent(student4);。

  • 地址传递:将结构体变量的地址传递给函数,这样函数可以直接操作原始的结构体变量。例如:
c 复制代码
void modifyStudent(struct Student *s) {
    s->age++;
}

调用这个函数时,传递结构体变量的指针,如modifyStudent(&student4);,这样就可以在函数中修改student4的成员。

7. 案例:学生管理系统

下面是一个基于 C 语言结构体的学生管理系统,用于记录学生信息并进行查询和统计。功能包括添加学生、查看学生信息、查找学生和计算平均分。

c 复制代码
#include <stdio.h>
#include <string.h>

#define MAX_STUDENTS 100

// Define the Student structure
typedef struct {
    char name[50];   // Name
    int age;         // Age
    int id;          // Student ID
    float scores[5]; // Scores for 5 courses
    float average;   // Average score
} Student;

// Global variables
Student students[MAX_STUDENTS]; // Array of students
int student_count = 0;          // Current number of students

// Function prototypes
void add_student();
void view_students();
void find_student();
void calculate_average(Student *student);

int main() {
    int choice;
    while (1) {
        printf("\n===== Student Management System =====\n");
        printf("1. Add Student\n");
        printf("2. View All Students\n");
        printf("3. Find Student\n");
        printf("4. Exit\n");
        printf("Enter your choice: ");
        scanf("%d", &choice);

        switch (choice) {
        case 1:
            add_student();
            break;
        case 2:
            view_students();
            break;
        case 3:
            find_student();
            break;
        case 4:
            printf("Exiting the system.\n");
            return 0;
        default:
            printf("Invalid choice. Please try again.\n");
        }
    }
    return 0;
}

// Add a new student
void add_student() {
    if (student_count >= MAX_STUDENTS) {
        printf("Cannot add more students. Maximum limit reached.\n");
        return;
    }

    Student *s = &students[student_count];

    printf("Enter name: ");
    scanf("%s", s->name);

    printf("Enter age: ");
    scanf("%d", &s->age);

    printf("Enter student ID: ");
    scanf("%d", &s->id);

    printf("Enter scores for 5 courses:\n");
    for (int i = 0; i < 5; i++) {
        printf("Course %d score: ", i + 1);
        scanf("%f", &s->scores[i]);
    }

    // Calculate average score
    calculate_average(s);

    student_count++;
    printf("Student added successfully.\n");
}

// View all students
void view_students() {
    if (student_count == 0) {
        printf("No student records found.\n");
        return;
    }

    printf("\n===== Student List =====\n");
    for (int i = 0; i < student_count; i++) {
        Student *s = &students[i];
        printf("Student %d:\n", i + 1);
        printf("  Name: %s\n", s->name);
        printf("  Age: %d\n", s->age);
        printf("  ID: %d\n", s->id);
        printf("  Average Score: %.2f\n", s->average);
        printf("-------------------\n");
    }
}

// Find a student by ID
void find_student() {
    if (student_count == 0) {
        printf("No student records found.\n");
        return;
    }

    int id;
    printf("Enter student ID to find: ");
    scanf("%d", &id);

    for (int i = 0; i < student_count; i++) {
        if (students[i].id == id) {
            Student *s = &students[i];
            printf("Student found:\n");
            printf("  Name: %s\n", s->name);
            printf("  Age: %d\n", s->age);
            printf("  ID: %d\n", s->id);
            printf("  Average Score: %.2f\n", s->average);
            return;
        }
    }

    printf("No student found with ID %d.\n", id);
}

// Calculate the average score for a student
void calculate_average(Student *student) {
    float sum = 0;
    for (int i = 0; i < 5; i++) {
        sum += student->scores[i];
    }
    student->average = sum / 5;
}
  • 功能介绍
c 复制代码
1. 添加学生
输入学生的姓名、年龄、学号和 5 门课程成绩后,系统会计算并存储学生的平均分。

2. 查看所有学生
以列表形式显示所有学生的信息,包括姓名、年龄、学号和平均分。

3. 查找学生
通过学号查找学生并显示详细信息。

4. 退出系统
退出学生管理系统。
  • 关键点解析

      1. 数组和结构体结合
        通过结构体数组实现批量管理学生信息。
      1. 指针与结构体结合
        传递结构体指针给函数,减少内存复制。
      1. 结构体成员的灵活性
        各种数据类型的成员使得结构体非常适合用于复杂数据管理。
  • 运行代码

    • 添加学生:
    • 查看所有学生:
    • 查找学生:
    • 退出:
相关推荐
XiaoLeisj8 分钟前
【递归,搜索与回溯算法 & 综合练习】深入理解暴搜决策树:递归,搜索与回溯算法综合小专题(二)
数据结构·算法·leetcode·决策树·深度优先·剪枝
小林熬夜学编程1 小时前
【Linux网络编程】第十四弹---构建功能丰富的HTTP服务器:从状态码处理到服务函数扩展
linux·运维·服务器·c语言·网络·c++·http
Jackey_Song_Odd1 小时前
C语言 单向链表反转问题
c语言·数据结构·算法·链表
乐之者v1 小时前
leetCode43.字符串相乘
java·数据结构·算法
A懿轩A2 小时前
C/C++ 数据结构与算法【数组】 数组详细解析【日常学习,考研必备】带图+详细代码
c语言·数据结构·c++·学习·考研·算法·数组
半盏茶香2 小时前
在21世纪的我用C语言探寻世界本质 ——编译和链接(编译环境和运行环境)
c语言·开发语言·c++·算法
️南城丶北离3 小时前
[数据结构]图——C++描述
数据结构··最小生成树·最短路径·aov网络·aoe网络
✿ ༺ ོIT技术༻3 小时前
C++11:新特性&右值引用&移动语义
linux·数据结构·c++
字节高级特工3 小时前
【C++】深入剖析默认成员函数3:拷贝构造函数
c语言·c++
计算机学长大白4 小时前
C中设计不允许继承的类的实现方法是什么?
c语言·开发语言