C++: 结构体基础

最后更新:2026-08-26

数组能存多个同类型的数据,但如果要存一个学生的姓名(字符串)、年龄(整数)、成绩(浮点数)呢?

这就需要结构体——把多个不同类型的变量组合成一个整体。


1. 什么是结构体?

(1) 1.1 生活中的结构体

生活场景 程序中的对应
一张名片(姓名、电话、邮箱) 结构体
一本书(书名、作者、价格) 结构体
一个学生(姓名、年龄、成绩) 结构体

结构体的特点:

  1. 成员类型可以不同
  2. 内存连续(和数组一样)
  3. 是"类"的前奏(后面会学类)

(2) 1.2 为什么需要结构体?

不用结构体(麻烦):

▶ 示例 2:代码示例(难度⭐)

CPP
#include <iostream>
#include <string>

int main() {
 std::string name1 = "Alice";
 int age1 = 20;
 double score1 = 92.5;
 
 std::string name2 = "Bob";
 int age2 = 21;
 double score2 = 88.0;
 // ... 要声明 3 × 100 个变量!
 
 return 0;
}
▶ 试一试

输出:

TEXT 📖 仅展示
(程序输出)

用结构体(简洁):

CPP
#include <iostream>
#include <string>

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

int main() {
 Student s1 = {"Alice", 20, 92.5};
 Student s2 = {"Bob", 21, 88.0};
 // ... 简洁多了!
 
 return 0;
}


2. 结构体的声明与定义

(1) 2.1 声明结构体

语法:

TEXT 📖 仅展示
struct StructName {
 memberType1 memberName1;
 memberType2 memberName2;
 ...
};

示例:

CPP
#include <iostream>
#include <string>

// 声明结构体
struct Student {
 std::string name;
 int age;
 double score;
}; // ⚠️ 注意:分号不能少!

int main() {
 // ...
 return 0;
}

💡 重点: 结构体声明以分号结尾!这是新手常犯的错误。



3. 结构体变量的创建与初始化

(1) 3.1 创建结构体变量

CPP
Student s1; // 创建一个 Student 类型的变量 s1

(2) 3.2 初始化结构体变量

方法一:按声明顺序初始化

CPP
Student s1 = {"Alice", 20, 92.5};

方法二:指定成员初始化(C++20,推荐)

CPP
Student s1 = {.name = "Alice", .age = 20, .score = 92.5};

方法三:逐个赋值

CPP
Student s1;
s1.name = "Alice";
s1.age = 20;
s1.score = 92.5;

💡 提示: 推荐用方法一或方法二,更简洁。



4. 访问结构体成员

(1) 4.1 读取成员

语法:

TEXT 📖 仅展示
structName.memberName

示例:

CPP
#include <iostream>
#include <string>

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

int main() {
 Student s1 = {"Alice", 20, 92.5};
 
 std::cout << "姓名:" << s1.name << std::endl; // Alice
 std::cout << "年龄:" << s1.age << std::endl; // 20
 std::cout << "成绩:" << s1.score << std::endl; // 92.5
 
 return 0;
}

(2) 4.2 修改成员

CPP
Student s1 = {"Alice", 20, 92.5};
s1.score = 95.0; // 修改成绩
std::cout << "新成绩:" << s1.score << std::endl; // 95.0


5. 结构体作为参数传递

(1) 5.1 传值(不推荐)

CPP
void printStudent(Student s) { // ❌ 传值:复制整个结构体,开销大
 std::cout << "姓名:" << s.name << std::endl;
}

(2) 5.2 传引用(推荐)

CPP
void printStudent(const Student& s) { // ✅ 传引用:不复制,且不能修改
 std::cout << "姓名:" << s.name << std::endl;
 std::cout << "年龄:" << s.age << std::endl;
 std::cout << "成绩:" << s.score << std::endl;
}

💡 黄金法则: 结构体作为参数时,优先用 const 引用——既避免复制开销,又防止误修改。



6. 结构体数组

结构体也可以组成数组!

示例:学生数组(难度⭐⭐)

CPP
#include <iostream>
#include <string>

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

int main() {
 Student students[3] = {
 {"Alice", 20, 92.5},
 {"Bob", 21, 88.0},
 {"Charlie", 19, 95.0}
 };
 
 // 遍历结构体数组
 for (int i = 0; i < 3; i++) {
 std::cout << "========== 学生 " << i + 1 << " ==========" << std::endl;
 std::cout << "姓名:" << students[i].name << std::endl;
 std::cout << "年龄:" << students[i].age << std::endl;
 std::cout << "成绩:" << students[i].score << std::endl;
 std::cout << std::endl;
 }
 
 return 0;
}


7. 实战:学生成绩管理(结构体版)

▶ 示例 1:完整的学生成绩管理(难度⭐⭐⭐)

CPP 📖 仅展示
#include <iostream>
#include <string>
#include <vector> // 后面会学 vector,这里先用数组

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

// 函数声明
void addStudent(Student students, int& count);
void printStudents(const Student students, int count);
double calculateAverage(const Student students, int count);

int main() {
 const int MAX_STUDENTS = 100;
 Student students[MAX_STUDENTS];
 int count = 0;
 
 int choice;
 do {
 std::cout << "========== 学生成绩管理 ==========" << std::endl;
 std::cout << "1. 添加学生" << std::endl;
 std::cout << "2. 显示所有学生" << std::endl;
 std::cout << "3. 计算平均分" << std::endl;
 std::cout << "4. 退出" << std::endl;
 std::cout << "请选择(1-4):";
 std::cin >> choice;
 
 if (choice == 1) {
 addStudent(students, count);
 } else if (choice == 2) {
 printStudents(students, count);
 } else if (choice == 3) {
 if (count == 0) {
 std::cout << "没有学生数据!" << std::endl;
 } else {
 std::cout << "平均分:" << calculateAverage(students, count) << std::endl;
 }
 } else if (choice == 4) {
 std::cout << "再见!" << std::endl;
 } else {
 std::cout << "错误:请输入 1-4 之间的数字!" << std::endl;
 }
 
 std::cout << std::endl;
 
 } while (choice != 4);
 
 return 0;
}

// 函数定义
void addStudent(Student students, int& count) {
 if (count >= 100) {
 std::cout << "学生数量已达上限!" << std::endl;
 return;
 }
 
 std::cout << "请输入姓名:";
 std::cin.ignore();
 std::getline(std::cin, students[count].name);
 
 std::cout << "请输入年龄:";
 std::cin >> students[count].age;
 
 std::cout << "请输入成绩:";
 std::cin >> students[count].score;
 
 count++;
 std::cout << "添加成功!" << std::endl;
}

void printStudents(const Student students, int count) {
 if (count == 0) {
 std::cout << "没有学生数据!" << std::endl;
 return;
 }
 
 std::cout << "\n========== 学生列表 ==========" << std::endl;
 for (int i = 0; i < count; i++) {
 std::cout << i + 1 << ". 姓名:" << students[i].name 
 << ",年龄:" << students[i].age 
 << ",成绩:" << students[i].score << std::endl;
 }
 std::cout << "================================\n\n";
}

double calculateAverage(const Student students, int count) {
 if (count == 0) {
 return 0.0;
 }
 
 double sum = 0.0;
 for (int i = 0; i < count; i++) {
 sum += students[i].score;
 }
 
 return sum / count;
}
逻辑代码 78 行(超过 40 行限制,仅展示)

输出:

TEXT 📖 仅展示
========== 学生成绩管理 ==========
1. 添加学生
2. 显示所有学生
3. 计算平均分
4. 退出
请选择(1-4):
没有学生数据!
平均分:
再见!
错误:请输入 1-4 之间的数字!
学生数量已达上限!
请输入姓名:
请输入年龄:
请输入成绩:
添加成功!
没有学生数据!

========== 学生列表 ==========
. 姓名:
================================




▶ 示例 3:结构体作为函数返回值(难度⭐)

CPP
#include <iostream>
#include <string>

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

// 返回结构体的函数
Student createStudent(std::string n, int a, double s) {
    Student stu;
    stu.name = n;
    stu.age = a;
    stu.score = s;
    return stu;
}

int main() {
    Student s1 = createStudent("张三", 20, 92.5);
    
    std::cout << "姓名:" << s1.name << std::endl;
    std::cout << "年龄:" << s1.age << std::endl;
    std::cout << "成绩:" << s1.score << std::endl;
    
    return 0;
}
▶ 试一试

输出:

TEXT 📖 仅展示
姓名:
年龄:
成绩:
💡 提示:结构体可以作为函数返回值,用于创建和初始化结构体对象。


8. 常见错误

(1) 8.1 忘记写分号

错误示例:

CPP
struct Student { // ❌ 忘记写分号
 std::string name;
 int age;
} // ❌ 这里应该有分号

int main() {
 // ...
}

编译错误信息:

TEXT 📖 仅展示
error: expected ';' after struct definition

(2) 8.2 访问不存在的成员

错误示例:

CPP
struct Student {
 std::string name;
 int age;
};

int main() {
 Student s1;
 s1.score = 92.5; // ❌ 错误:Student 没有 score 成员
 return 0;
}

❓ 常见问题

Q 结构体和类(class)有什么区别?
A 后面会详细讲类,这里先简单说: > - struct 的默认访问权限是 public(公有) > - class 的默认访问权限是 private(私有)

Q:关于structs basics最重要的是什么? A:先理解核心概念,再通过实践例子来巩固。

📖 小节


📝 作业

  1. 基础题 (Difficulty ⭐): 定义一个 Book 结构体,包含书名、作者、价格三个成员。创建两个 Book 变量并输出。

  2. 进阶题 (Difficulty ⭐⭐): 定义一个 Rectangle 结构体,包含宽度和高度两个成员。

  3. 写一个函数 double calculateArea(const Rectangle& r) 计算面积

  4. 写一个函数 double calculatePerimeter(const Rectangle& r) 计算周长

  5. main 里测试

  6. 挑战题 (Difficulty ⭐⭐⭐): 定义一个 Date 结构体(年、月、日),写一个函数判断一个日期是否合法(如 2024-02-29 合法,2023-02-29 不合法)。


9. 🚀 下一步

学会了结构体,接下来我们进入 Phase 4(指针与引用)——这是 C++ 最核心也最难的部分,但掌握后能写出更高效的代码!

Web-Tutorial.com

Web-Tutorial 技术团队

由多位开发者共同维护的编程教程平台。每篇教程由对应领域的开发者编写和审核,确保内容准确可靠。如发现任何问题,欢迎向我们反馈。

100%

🙏 帮我们做得更好

我们是刚上线的编程教程站,几个人的小团队,精力有限。页面虽经检查,难免还有疏漏——链接失效、排版错乱、内容有误、语言生硬……

如果您发现了,麻烦告诉我们,我们会在收到反馈后第一时间进行修复,再次感谢您的光临 🙏