CC++ & Algorithm

结构体的定义与使用

中等9
语言版本:C++
概述:用结构体可以把不同类型的数据打包在一起,就像文具盒里可以放笔、橡皮、尺子。

结构体:把数据装进一个“文具盒”

你有没有遇到过这种情况?要记录一个同学的信息,得分开写好几个变量:string name; int age; int score;。这些数据明明都属于同一个人,却散落在不同地方,就像把铅笔、橡皮、尺子乱扔在桌子上,用的时候要找半天。C++ 里的结构体就像是一个文具盒,可以把不同类型的数据打包在一起,变成一个整体,拿起来方便,整理起来也清晰。

下面我们就一起来学习结构体怎么定义、怎么用,以及有哪些容易掉进去的坑。


什么是结构体?

结构体(struct)是一种自定义的数据类型,它允许你把多个不同类型的数据“捆”在一起,形成一个新类型。比如你要描述一个学生,需要姓名(字符串)、年龄(整数)、分数(整数),用结构体就可以这样声明:

struct Student {
    string name;   // 姓名
    int age;       // 年龄
    int score;     // 分数
};

这样一来,Student 就成了一个“新物种”,就像文具盒一样,里面装着三个小部件。以后每次用到学生信息,只需要定义一个 Student 变量,就能同时拥有姓名、年龄、分数。


如何定义和使用结构体?

定义结构体用关键字 struct,后面跟上结构体的名字,然后在大括号里列出成员(成员就是里面每个数据),最后别忘了分号。这是新手最容易漏掉的地方。

1. 定义结构体类型

#include <iostream>
#include <string>
using namespace std;

// 定义一个结构体叫 Student,包含姓名、年龄、分数
struct Student {
    string name;   // 姓名
    int age;       // 年龄
    int score;     // 分数
};   // ← 这个分号千万不能少!

2. 创建结构体变量(两种方式)

方式一:定义时直接初始化(推荐)

Student stu1 = {"小明", 10, 95};

大括号里的值按成员顺序依次赋值:name 得到 "小明",age 得到 10,score 得到 95。

方式二:先定义,再逐个赋值

Student stu2;
stu2.name = "小红";
stu2.age = 11;
stu2.score = 88;

注意:方式二必须保证成员先存在,不能直接写 Student stu2 = {"小红", 11, 88}; 再修改,这样会覆盖。

3. 访问和修改成员

用**点号(.)**就能拿到里面的数据,就像从文具盒里拿出铅笔一样简单。

int main() {
    Student stu1 = {"小明", 10, 95};
    
    // 访问成员
    cout << "姓名:" << stu1.name << endl;   // 输出:小明
    cout << "年龄:" << stu1.age << endl;    // 输出:10
    cout << "分数:" << stu1.score << endl;  // 输出:95
    
    // 修改成员
    stu1.score = 100;   // 小明考了满分,修改分数
    cout << "修改后分数:" << stu1.score << endl;  // 输出:100
    
    return 0;
}

结构体的生活化例子:图书信息

再来一个贴近生活的例子——图书。每本书都有书名、作者、价格,用结构体来装:

#include <iostream>
#include <string>
using namespace std;

struct Book {
    string title;   // 书名
    string author;  // 作者
    double price;   // 价格(元)
};

int main() {
    // 创建一本《哈利·波特》的书
    Book myBook = {"哈利·波特与魔法石", "J.K.罗琳", 39.9};
    
    cout << "书名:" << myBook.title << endl;
    cout << "作者:" << myBook.author << endl;
    cout << "价格:" << myBook.price << " 元" << endl;
    
    // 降价促销,修改价格
    myBook.price = 29.9;
    cout << "现价:" << myBook.price << " 元" << endl;
    
    return 0;
}

结构体数组:处理多个同学的数据

假设班级里有 40 个学生,每个学生都有姓名、年龄、分数。如果不用结构体,你需要三个分开的数组,维护起来非常痛苦。有了结构体,只需要一个结构体数组:

Student class[40];  // 创建一个可以装40个学生的数组

// 给第一个学生赋值
class[0].name = "小刚";
class[0].age = 10;
class[0].score = 92;

// 给第二个学生赋值
class[1].name = "小丽";
class[1].age = 11;
class[1].score = 97;

// 也可以用初始化列表创造整班数据(这里只演示两个)
Student class[2] = {
    {"小刚", 10, 92},
    {"小丽", 11, 97}
};

这样全班的信息就整整齐齐地装在一个数组里了,遍历、排序、统计平均分都非常方便。


结构体作为函数参数

你可以把结构体直接传给函数,一次传入所有信息。比如写一个函数来打印学生信息:

void printStudent(Student s) {
    cout << s.name << ",年龄" << s.age << ",分数" << s.score << endl;
}

int main() {
    Student stu = {"王同学", 12, 88};
    printStudent(stu);   // 输出:王同学,年龄12,分数88
    return 0;
}

如果函数要修改结构体里面的值,记得用引用传参,否则修改的是副本:

void addBonus(Student &s, int bonus) {
    s.score += bonus;   // 给这个学生加分
}

新手最容易犯的 3 个错误

错误 1:定义结构体末尾忘记分号

struct Student {
    string name;
    int age;
    int score;
}   // ❌ 这里少了分号,编译会报错

正确:大括号后面一定要加 ;

错误 2:用点号访问成员时写错变量名

Student stu;
cout << stu.Name;   // ❌ 成员名是 name,不是 Name(大小写敏感)

错误 3:试图直接给整个结构体赋值,但没有使用大括号

Student stu;
stu = {"小明", 10, 95};   // ✅ 编译通过(C++11起支持)
// 但旧版本可能会报错,建议在定义时初始化,或者逐个成员赋值。

完整示例:学生成绩小统计

下面是一个完整的程序,包含结构体定义、结构体数组、打印函数、求平均分。你可以直接复制运行。

#include <iostream>
#include <string>
using namespace std;

struct Student {
    string name;   // 姓名
    int age;       // 年龄
    int score;     // 分数
};

// 打印一个学生的信息
void printStudent(Student s) {
    cout << "姓名:" << s.name << ",年龄:" << s.age << ",分数:" << s.score << endl;
}

// 计算全班平均分
double averageScore(Student cls[], int n) {
    int sum = 0;
    for (int i = 0; i < n; i++) {
        sum += cls[i].score;
    }
    return (double)sum / n;
}

int main() {
    // 定义全班学生(假设有3个同学)
    Student class3[3] = {
        {"小明", 10, 95},
        {"小红", 11, 88},
        {"小刚", 10, 92}
    };
    
    // 打印每个人的信息
    cout << "=== 班级成绩 ===" << endl;
    for (int i = 0; i < 3; i++) {
        printStudent(class3[i]);
    }
    
    // 计算并输出平均分
    double avg = averageScore(class3, 3);
    cout << "全班平均分:" << avg << endl;
    
    // 给小红加分(引用传参)
    auto addBonus = [](Student &s, int bonus) { s.score += bonus; };
    addBonus(class3[1], 5);   // 小红加5分
    cout << "\n加分后小红的信息:";
    printStudent(class3[1]);
    
    return 0;
}

输出结果

=== 班级成绩 ===
姓名:小明,年龄:10,分数:95
姓名:小红,年龄:11,分数:88
姓名:小刚,年龄:10,分数:92
全班平均分:91.6667

加分后小红的信息:姓名:小红,年龄:11,分数:93

学了结构体,接下来学什么?

  • 指针与结构体:用指针访问结构体成员时要用 -> 号,比如 ptr->name
  • 结构体排序:结合 sort 函数,可以按分数排序全班同学。
  • 类(class):结构体的“升级版”,可以包含函数(成员方法),是面向对象编程的基础。

结构体就像是数据世界的“小盒子”,把零散的东西装在一起,代码变得清晰又好用。下次遇到一群相关的数据,别犹豫,先写一个结构体吧!

例题精讲

1单选题

以下关于C++结构体定义的说法,正确的是?

A定义结构体时,成员之间必须用分号分隔,最后一个成员后不需要分号
B定义结构体时,struct关键字后面必须紧跟结构体名称,不能省略
C定义结构体时,大括号后面必须加分号,否则编译报错
D结构体成员不能是相同类型的结构体变量(嵌套定义)
2判断题

在C++中,结构体(struct)的成员默认访问权限是public,而类(class)的成员默认访问权限是private。

3填空题
以下代码定义了一个表示学生信息的结构体,并创建了一个变量s,使用初始化列表赋初值。请补充完整代码。

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

int main() {
    ___;
    cout << s.name << endl;
    return 0;
}
4单选题

定义如下结构体,计算 sizeof(Point) 的结果是多少?(假设 int 占4字节,char 占1字节,不考虑对齐补齐) struct Point { int x; char y; int z; };

A9
B12
C13
D8
5填空题
以下函数接收一个结构体变量作为参数,输出其信息。请补充函数定义。

struct Book {
    string title;
    double price;
};

void printBook(___ book) {
    cout << "书名: " << book.title << ", 价格: " << book.price << endl;
}

int main() {
    Book b = {"C++编程", 45.5};
    printBook(b);
    return 0;
}