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;
}
posted @ 2025-03-07 09:18  lordshang  阅读(32)  评论(0)    收藏  举报