// ===== CodeLab: C 结构体与联合体 =====
// 来源: https://aoerliang.dpdns.org/articles/c-struct
// 以下代码片段按文章出现顺序拼接, 共 5 段

// ----- 片段 1 (c) -----
#include <stdio.h>

struct Student {
    char name[20];
    int age;
    double score;
};

int main(void) {
    struct Student s1 = {"Ada", 18, 95.5};   // 按声明顺序初始化
    struct Student s2;
    s2.age = 19;                              // 逐个赋值
    s2.score = 88.0;

    printf("%s, %d 岁, 成绩 %.1f\n", s1.name, s1.age, s1.score);
    printf("s2: %d 岁, 成绩 %.1f\n", s2.age, s2.score);
    return 0;
}

// ----- 片段 2 (c) -----
#include <stdio.h>

struct Student {
    char name[20];
    int age;
    double score;
};

int main(void) {
    struct Student class[3] = {
        {"Ada", 18, 95.5},
        {"Bob", 19, 88.0},
        {"Cindy", 18, 91.0}
    };

    double sum = 0;
    int best = 0;
    for (int i = 0; i < 3; i++) {
        sum += class[i].score;
        if (class[i].score > class[best].score) {
            best = i;
        }
    }
    printf("平均 %.1f, 最高分: %s\n", sum / 3, class[best].name);
    return 0;
}

// ----- 片段 3 (c) -----
#include <stdio.h>

struct Point {
    int x;
    int y;
};

int main(void) {
    struct Point p = {3, 4};
    struct Point *pp = &p;

    printf("(%d, %d)\n", pp->x, pp->y);   // 箭头访问
    (*pp).x = 10;                          // 等价写法
    printf("(%d, %d)\n", pp->x, pp->y);
    return 0;
}

// ----- 片段 4 (c) -----
#include <stdio.h>

struct Student {
    char name[20];
    int age;
    double score;
};

void raise_score(struct Student *s, double delta) {
    s->score += delta;   // 通过指针修改
}

int main(void) {
    struct Student s = {"Ada", 18, 95.5};
    raise_score(&s, 2.0);
    printf("新成绩: %.1f\n", s.score);   // 97.5
    return 0;
}

// ----- 片段 5 (c) -----
#include <stdio.h>

typedef struct Point {
    int x;
    int y;
} Point;             // 之后直接写 Point

union Data {
    int i;
    float f;
    char c[4];       // 三者占用同一块 4 字节内存
};

int main(void) {
    Point p = {3, 4};      // 不用再写 struct 前缀
    printf("(%d, %d)\n", p.x, p.y);

    union Data d;
    d.i = 65;
    printf("作为 int: %d\n", d.i);
    printf("作为 char[0]: %d\n", d.c[0]);   // 内存重叠的体现
    return 0;
}
