C++ 结构体:struct 的定义与结构体数组

C++ 结构体(struct):定义、用法与结构体数组
(从零基础到能写出常见场景,带完整示例 + 对比 + 常见坑)

结构体是 C++ 中非常重要的用户自定义复合类型,它让你能把不同类型的数据捆绑成一个整体,非常适合表示“实体”(学生、图书、坐标、员工等)。

1. struct 的基本定义方式(3 种常见写法)

写法代码示例特点推荐场景
方式1:最规范、最常用“`cpp
方式2:定义时顺便声明变量(C 风格遗留)cpp<br>struct Student {<br> int id;<br> // ...<br>} stu1, stu2;<br>定义类型的同时创建变量快速测试、小脚本
方式3:匿名结构体(极少用)cpp<br>struct {<br> int x, y;<br>} point;<br>没有类型名,只能用一次临时小结构

现代 C++ 推荐:方式1 + 使用 std::string 而不是 char[](更安全)。

2. 如何创建结构体变量 & 访问成员

#include <iostream>
#include <string>

struct Student {
    int id;
    std::string name;
    char gender;     // 'M' 或 'F'
    int age;
    double score;
};

int main() {
    // 创建方式1:定义后声明
    Student s1;

    // 创建方式2:定义时初始化(最推荐)
    Student s2 = {1001, "张三", 'M', 20, 88.5};

    // C++11 统一初始化(推荐)
    Student s3{1002, "李四", 'F', 19, 92.0};

    // 访问成员:用 . 点运算符
    s1.id     = 1003;
    s1.name   = "王五";
    s1.gender = 'M';
    s1.age    = 21;
    s1.score  = 76.5;

    // 输出
    std::cout << "学号:" << s1.id << "\n"
              << "姓名:" << s1.name << "\n"
              << "性别:" << s1.gender << "\n"
              << "年龄:" << s1.age << "\n"
              << "分数:" << s1.score << "\n";

    return 0;
}

3. 结构体数组(超级常用!)

结构体数组 = 每个元素都是一个结构体,适合存储一批同类对象(比如一个班的所有学生)。

3.1 三种常见声明方式

// 方式1:固定大小(最常见)
Student class1[5];                  // 5 个学生

// 方式2:初始化(C++11 统一初始化语法最清晰)
Student class2[4] = {
    {1001, "小明", 'M', 20, 85.0},
    {1002, "小红", 'F', 19, 92.5},
    {1003, "小刚", 'M', 21, 78.0},
    {1004, "小丽", 'F', 20, 88.5}
};

// 方式3:C++11 统一初始化(推荐,可省略部分成员,默认 0/空)
Student class3[3] {
    {1005, "张伟"},
    {},                               // 全部默认初始化
    {1007, "刘洋", 'M', 20, 90.0}
};

3.2 遍历 & 操作结构体数组(三种写法对比)

#include <iostream>
#include <string>

struct Student { /* 同上 */ };

int main() {
    Student students[5] = {
        {1001, "Alice", 'F', 20, 88.5},
        {1002, "Bob",   'M', 21, 76.0},
        {1003, "Carol", 'F', 19, 95.0},
        {1004, "David", 'M', 20, 82.5},
        {1005, "Eve",   'F', 22, 90.0}
    };

    // 写法1:普通 for 循环(最直观)
    std::cout << "普通 for 循环:\n";
    for(int i = 0; i < 5; i++) {
        std::cout << students[i].id << "\t" 
                  << students[i].name << "\t"
                  << students[i].score << "\n";
    }

    // 写法2:范围 for(C++11+,最现代、最推荐)
    std::cout << "\n范围 for(只读):\n";
    for(const auto& stu : students) {   // const & 防止拷贝
        std::cout << stu.id << "\t" << stu.name << "\t" << stu.score << "\n";
    }

    // 写法3:范围 for + 可修改
    std::cout << "\n范围 for + 修改分数+5:\n";
    for(auto& stu : students) {
        stu.score += 5;
        std::cout << stu.name << " 新分数:" << stu.score << "\n";
    }

    return 0;
}

4. 结构体数组 vs 普通数组 对比(为什么用 struct)

项目普通数组(二维)结构体数组优势说明
数据含义students[30][5]Student stu[30]语义清晰(.name vs [1])
可读性差(全是数字下标)好(.id .name .score)代码维护性大幅提升
类型安全容易越界或错位编译器检查成员类型减少 bug
扩展性加一列要改所有代码加成员只需改 struct 定义后期维护友好

5. 常见坑 & 注意事项(面试/实际开发高频)

  1. 结构体大小 & 内存对齐
   struct A { char c; int i; };   // 大小通常 8 字节(不是 5)

建议:把大成员放前面,或用 #pragma pack(1) 强制 1 字节对齐(但慎用)。

  1. 不要在结构体里放大数组
    错:char buf[8192];(栈容易爆)
    改:用 std::stringstd::vector<char>
  2. 初始化顺序
    C++11 前:必须按声明顺序初始化
    C++11 后:支持指定成员初始化( designated initializers,C++20 更完善)
   Student s{.id=1001, .name="Tom", .score=99.0};  // C++20
  1. 结构体数组传参
  • 推荐:void print(const Student arr[], int n)void print(const std::vector<Student>& v)
  • 不推荐直接传大数组(栈开销大)
  1. C++ vs C 的 struct 区别
  • C++ 的 struct 默认 public,可以有成员函数、构造函数
  • 可以写:
    cpp struct Point { int x, y; double distance() const { return std::sqrt(x*x + y*y); } };

6. 小练习(建议你敲一遍)

  1. 定义一个 struct Book {std::string title; std::string author; double price; int stock;};
  2. 创建包含 3 本书的结构体数组
  3. 写函数:找出最贵的书,并打印
  4. 写函数:把所有库存 < 5 的书价格打 8 折

希望这篇把 struct 和结构体数组的核心用法讲透了!
有哪部分还不太清楚?想看带成员函数的 struct、vector 版本、还是排序/查找示例?直接告诉我~ 😄

文章已创建 4237

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

相关文章

开始在上面输入您的搜索词,然后按回车进行搜索。按ESC取消。

返回顶部