S SmartDocs
Serie: C++ cpp 231 líneas · Actualizado 2026-04-03

structs.cpp

C++/Part2_物件導向/Ch07_結構體與列舉/structs.cpp

// ============================================================
// Ch07 — 結構體(struct)完整範例
// 編譯:g++ -std=c++17 -Wall -o structs structs.cpp
// ============================================================

#include <iostream>
#include <string>
#include <array>
#include <algorithm>
#include <cmath>

// ============================================================
// 1. 基本結構體定義
// ============================================================

// 表示平面上的一個點
struct Point {
    double x;
    double y;
};

// 計算兩點之間的距離(結構體作為函式參數 — const 參考)
double distance(const Point& a, const Point& b) {
    double dx = a.x - b.x;
    double dy = a.y - b.y;
    return std::sqrt(dx * dx + dy * dy);
}

// 印出 Point 內容
void printPoint(const Point& p) {
    std::cout << "(" << p.x << ", " << p.y << ")";
}

// ============================================================
// 2. 帶有方法的結構體
// ============================================================

struct Rectangle {
    double width;
    double height;

    // const 成員函式 — 不修改物件狀態
    double area() const {
        return width * height;
    }

    double perimeter() const {
        return 2.0 * (width + height);
    }

    void print() const {
        std::cout << "Rectangle(" << width << " x " << height
                  << "), 面積=" << area()
                  << ", 周長=" << perimeter() << std::endl;
    }
};

// ============================================================
// 3. 學生結構體 — 聚合初始化與陣列
// ============================================================

struct Student {
    std::string name;
    int age;
    double gpa;
};

// 傳 const 參考印出學生資訊
void printStudent(const Student& s) {
    std::cout << "  姓名: " << s.name
              << ", 年齡: " << s.age
              << ", GPA: " << s.gpa << std::endl;
}

// 傳參考以修改學生資料
void updateGPA(Student& s, double newGPA) {
    std::cout << "  [更新] " << s.name << " 的 GPA: "
              << s.gpa << " → " << newGPA << std::endl;
    s.gpa = newGPA;
}

// ============================================================
// 4. 巢狀結構體
// ============================================================

struct Address {
    std::string city;
    std::string street;
    int zipcode;
};

struct Employee {
    std::string name;
    Address address;    // 巢狀結構體
    double salary;
};

void printEmployee(const Employee& e) {
    std::cout << "  姓名: " << e.name << std::endl;
    std::cout << "  地址: " << e.address.zipcode << " "
              << e.address.city << " " << e.address.street << std::endl;
    std::cout << "  月薪: " << e.salary << std::endl;
}

// ============================================================
// main — 逐一示範各種用法
// ============================================================

int main() {
    std::cout << "========================================" << std::endl;
    std::cout << " Ch07 結構體(struct)完整範例" << std::endl;
    std::cout << "========================================\n" << std::endl;

    // ------ 1. 基本結構體 ------
    std::cout << "【1】基本結構體 — Point\n" << std::endl;

    Point p1 = {3.0, 4.0};          // 聚合初始化
    Point p2{7.0, 1.0};             // 直接初始化

    std::cout << "  p1 = ";
    printPoint(p1);
    std::cout << std::endl;

    std::cout << "  p2 = ";
    printPoint(p2);
    std::cout << std::endl;

    std::cout << "  p1 與 p2 的距離 = " << distance(p1, p2) << std::endl;

    // 修改成員
    p1.x = 0.0;
    p1.y = 0.0;
    std::cout << "  修改後 p1 = ";
    printPoint(p1);
    std::cout << ", 距離 = " << distance(p1, p2) << "\n" << std::endl;

    // ------ 2. 帶有方法的結構體 ------
    std::cout << "【2】帶有方法的結構體 — Rectangle\n" << std::endl;

    Rectangle r1{5.0, 3.0};
    Rectangle r2{10.0, 7.5};

    std::cout << "  r1: ";
    r1.print();
    std::cout << "  r2: ";
    r2.print();
    std::cout << std::endl;

    // ------ 3. 學生結構體與陣列 ------
    std::cout << "【3】學生結構體陣列與函式操作\n" << std::endl;

    // 建立結構體陣列
    Student students[] = {
        {"小明", 20, 3.85},
        {"小華", 19, 3.72},
        {"小美", 21, 3.90},
        {"小強", 22, 3.50},
        {"小芳", 20, 3.95},
    };

    std::cout << "  所有學生:" << std::endl;
    for (const auto& s : students) {
        printStudent(s);
    }

    // 找出 GPA 最高的學生
    const Student* best = &students[0];
    for (const auto& s : students) {
        if (s.gpa > best->gpa) {
            best = &s;
        }
    }
    std::cout << "\n  GPA 最高的學生:" << best->name
              << "(GPA " << best->gpa << ")" << std::endl;

    // 修改學生資料(傳參考)
    updateGPA(students[3], 3.65);
    std::cout << std::endl;

    // ------ 4. 巢狀結構體 ------
    std::cout << "【4】巢狀結構體 — Employee\n" << std::endl;

    Employee emp1 = {
        "王大明",
        {"台北市", "忠孝東路一段 100 號", 10001},
        55000.0
    };

    Employee emp2 = {
        "李小華",
        {"高雄市", "中正路 50 號", 80001},
        48000.0
    };

    printEmployee(emp1);
    std::cout << std::endl;
    printEmployee(emp2);
    std::cout << std::endl;

    // ------ 5. 結構化綁定(C++17) ------
    std::cout << "【5】C++17 結構化綁定(Structured Bindings)\n" << std::endl;

    Point p3{9.0, 12.0};
    auto [px, py] = p3;  // 結構化綁定
    std::cout << "  p3 的 x = " << px << ", y = " << py << std::endl;
    std::cout << "  原點到 p3 的距離 = "
              << std::sqrt(px * px + py * py) << std::endl;
    std::cout << std::endl;

    // ------ 6. 結構體比較(需自行實作) ------
    std::cout << "【6】結構體比較(自行定義)\n" << std::endl;

    Point a{1.0, 2.0};
    Point b{1.0, 2.0};
    Point c{3.0, 4.0};

    // 結構體沒有預設的 == 運算子(C++20 之前)
    // 需自行比較各成員
    auto pointEqual = [](const Point& lhs, const Point& rhs) {
        return lhs.x == rhs.x && lhs.y == rhs.y;
    };

    std::cout << "  a == b? " << (pointEqual(a, b) ? "是" : "否") << std::endl;
    std::cout << "  a == c? " << (pointEqual(a, c) ? "是" : "否") << std::endl;

    std::cout << "\n========================================" << std::endl;
    std::cout << " 範例結束" << std::endl;
    std::cout << "========================================" << std::endl;

    return 0;
}

Artículos relacionados