C++ 第 21 课:struct —— 把一组相关数据打包在一起

答案与下一课

上一课标准答案:

复制代码
'A'

是 char,表示单个字符。

复制代码
"A"

是字符串,通常配合 std::string 使用。

name[0] = 'R' name[2] = 'b' name.size() = 5

因为:

R o b o t 0 1 2 3 4

  1. 输出:

1

因为:

复制代码
state == "ERROR"

成立。

  1. 最后:

c = "Joint Ready"

因为 std::string 可以使用 + 进行字符串拼接。


第 21 课:struct ------ 把一组相关数据打包在一起

现在开始进入一个非常重要的新阶段。

前面我们保存机械臂关节信息,可能会写:

复制代码
double angle = 30.0;
double speed = 10.0;
double temperature = 45.0;
bool enabled = true;

这些变量都在描述:

同一个关节。

问题来了:

如果有 6 个关节怎么办?

可能变成:

复制代码
double joint1_angle;
double joint1_speed;
double joint1_temperature;
bool joint1_enabled;

double joint2_angle;
double joint2_speed;
double joint2_temperature;
bool joint2_enabled;

// ...

很快就会乱。

这时候我们需要:

struct

也就是:

结构体


1. struct 最直觉的理解

你可以把 struct 理解成:

自己设计一种新的"数据盒子"。

以前:

复制代码
int
double
bool

都是 C++ 已经提供的数据类型。

比如:

复制代码
double angle = 30.0;

但现在我们想定义一种新的类型:

Joint

这个类型里面同时拥有:

角度 速度 温度 是否使能

于是:

复制代码
struct Joint
{
    double angle;
    double speed;
    double temperature;
    bool enabled;
};

这就是我们自己定义的:

Joint 类型。


2. 先不要把 struct 想得太复杂

以前:

复制代码
double angle;

一个变量只能直接代表一个数据。

而现在:

复制代码
Joint joint1;

这个变量里面可以装很多相关数据:

joint1 ┌────────────────────┐ │ angle │ │ speed │ │ temperature │ │ enabled │ └────────────────────┘

所以:

struct = 把多个相关变量打包到一起。


3. 逐行解释

看:

复制代码
struct Joint
{
    double angle;
    double speed;
    bool enabled;
};

第一行:

复制代码
struct Joint

意思是:

我要定义一种新的结构体类型,名字叫 Joint。


然后:

复制代码
{

表示这个结构体内部有哪些成员。


复制代码
double angle;

表示:

每一个 Joint 都有一个 double 类型的 angle。


复制代码
double speed;

表示:

每个 Joint 都有一个 speed。


复制代码
bool enabled;

表示:

每个 Joint 都有一个真假状态 enabled。


最后:

复制代码
};

特别注意:

struct 定义结束的 } 后面还有一个分号 ;

也就是:

复制代码
};

这和普通函数:

复制代码
void test()
{
}

不一样。


4. 定义完 Joint 后怎么用?

定义:

复制代码
struct Joint
{
    double angle;
    double speed;
    bool enabled;
};

然后可以:

复制代码
Joint joint1;

这和:

复制代码
int a;

非常像。

只不过:

复制代码
int

是 C++ 自带类型。

而:

复制代码
Joint

是我们刚才自己定义的类型。


5. 怎么访问里面的数据?

需要使用:

复制代码
.

这个点号。

例如:

复制代码
joint1.angle = 30.0;
joint1.speed = 10.0;
joint1.enabled = true;

你可以读成:

joint1 的 angle joint1 的 speed joint1 的 enabled

所以:

复制代码
.

你现在可以先理解成:

"里面的"


6. 和之前的 std::vector 联系起来

你之前看过:

复制代码
data.push_back(10);

这里也有:

复制代码
.

其实:

复制代码
data.push_back(...)

也可以粗略读成:

data 里面的 push_back() 功能。

而:

复制代码
joint1.angle

就是:

joint1 里面的 angle。

后面学 class 时,我们会正式解释这个点号。


7. 一个完整例子

复制代码
#include <iostream>

struct Joint
{
    double angle;
    double speed;
    bool enabled;
};

int main()
{
    Joint joint1;

    joint1.angle = 30.0;
    joint1.speed = 5.0;
    joint1.enabled = true;

    std::cout << joint1.angle << std::endl;
    std::cout << joint1.speed << std::endl;

    return 0;
}

输出:

30 5


8. 内存思维

可以把:

复制代码
Joint joint1;

想成一个大盒子:

joint1 ┌─────────────────┐ │ angle │ → 30.0 ├─────────────────┤ │ speed │ → 5.0 ├─────────────────┤ │ enabled │ → true └─────────────────┘

所以 joint1 不是单纯保存一个数。

它是一整组数据。


9. 为什么这对机器人特别重要?

因为现实中的"关节"本来就是一个整体对象。

一个机械臂关节可能有:

关节角度 目标角度 速度 电流 温度 故障状态 是否使能

这些数据本来就属于同一个关节。

所以可以写:

复制代码
struct Joint
{
    double current_angle;
    double target_angle;
    double speed;
    double current;
    double temperature;
    bool enabled;
    bool error;
};

这样比定义一堆散乱变量清晰得多。


10. 创建多个关节

定义一次:

复制代码
struct Joint
{
    double angle;
    double speed;
};

以后可以创建:

复制代码
Joint joint1;
Joint joint2;
Joint joint3;

每个都是独立的数据。

例如:

复制代码
joint1.angle = 10.0;
joint2.angle = 20.0;
joint3.angle = 30.0;

它们互不影响。


11. 就像设计了一个"模板"

你可以把:

复制代码
struct Joint
{
    double angle;
    double speed;
};

理解成:

Joint 的设计图纸。

而:

复制代码
Joint joint1;
Joint joint2;

就是按照这个设计图纸造了两个实际对象。

类似:

Joint 图纸 ┌─────────────┐ │ angle │ │ speed │ └─────────────┘ 制造: joint1 ┌─────────────┐ │ angle = 10 │ │ speed = 5 │ └─────────────┘ joint2 ┌─────────────┐ │ angle = 20 │ │ speed = 8 │ └─────────────┘


12. 创建时直接赋值

也可以写:

复制代码
Joint joint1 = {30.0, 5.0, true};

如果结构体定义是:

复制代码
struct Joint
{
    double angle;
    double speed;
    bool enabled;
};

那么按照顺序:

30.0 → angle 5.0 → speed true → enabled

所以:

复制代码
Joint joint1 = {30.0, 5.0, true};

就相当于:

复制代码
joint1.angle = 30.0;
joint1.speed = 5.0;
joint1.enabled = true;

13. 顺序一定要注意

假设:

复制代码
struct Joint
{
    double angle;
    double speed;
    bool enabled;
};

那么:

复制代码
Joint joint1 = {30.0, 5.0, true};

是按结构体成员定义顺序对应的。

所以如果成员很多,这种写法可能不如逐个赋值直观。

初学阶段建议你优先看懂:

复制代码
joint1.angle = 30.0;
joint1.speed = 5.0;

14. struct 里面可以有 std::string

例如:

复制代码
#include <string>

struct Joint
{
    std::string name;
    double angle;
    bool enabled;
};

然后:

复制代码
Joint joint1;

joint1.name = "Joint1";
joint1.angle = 30.0;
joint1.enabled = true;

于是一个关节同时拥有:

名字 角度 状态


15. 完整机器人例子

复制代码
#include <iostream>
#include <string>

struct Joint
{
    std::string name;
    double angle;
    double speed;
    bool enabled;
};

int main()
{
    Joint joint1;

    joint1.name = "Joint1";
    joint1.angle = 30.0;
    joint1.speed = 5.0;
    joint1.enabled = true;

    std::cout << joint1.name << std::endl;
    std::cout << joint1.angle << std::endl;
    std::cout << joint1.speed << std::endl;

    return 0;
}

输出:

Joint1 30 5


16. struct + 数组 非常适合六轴机械臂

现在开始真正结合起来。

我们已经定义:

复制代码
struct Joint
{
    double angle;
    double speed;
    bool enabled;
};

然后可以创建:

复制代码
Joint joints[6];

这是什么意思?

不是:

6 个 double

而是:

6 个 Joint

可以画成:

joints [0] [1] [2] ... ┌─────────┐ ┌─────────┐ ┌─────────┐ │ angle │ │ angle │ │ angle │ │ speed │ │ speed │ │ speed │ │ enabled │ │ enabled │ │ enabled │ └─────────┘ └─────────┘ └─────────┘

这已经很像真实六自由度机械臂的数据结构了。


17. 怎么访问?

例如:

复制代码
joints[0].angle = 10.0;

拆开:

复制代码
joints[0]

表示:

第 1 个 Joint。

然后:

复制代码
.angle

表示:

这个 Joint 里面的 angle。

所以:

复制代码
joints[0].angle

就是:

第 1 个关节的角度。


18. 六轴机械臂例子

复制代码
Joint joints[6];

joints[0].angle = 10.0;
joints[1].angle = 20.0;
joints[2].angle = 30.0;
joints[3].angle = 40.0;
joints[4].angle = 50.0;
joints[5].angle = 60.0;

然后可以配合:

复制代码
for

统一输出:

复制代码
for (int i = 0; i < 6; i++)
{
    std::cout << joints[i].angle << std::endl;
}

输出:

10 20 30 40 50 60


19. 现在你已经把很多知识串起来了

看这一句:

复制代码
std::cout << joints[i].angle << std::endl;

你现在可以一层层拆:

joints ↓ 一个 Joint 数组 [i] ↓ 取第 i 个 Joint .angle ↓ 取这个 Joint 里面的 angle std::cout ↓ 输出它

这就是阅读复杂 C++ 代码的正确方法:

一层一层拆,而不是整句硬看。


20. struct 也能传进函数

例如:

复制代码
void printJoint(Joint joint)
{
    std::cout << joint.angle << std::endl;
}

然后:

复制代码
Joint j;
j.angle = 30.0;

printJoint(j);

输出:

30

不过这里:

复制代码
Joint joint

仍然是:

值传递。

也就是说,会复制一个 Joint。


21. 又和引用连起来了

如果结构体比较大,我们可能不希望复制。

就可能写:

复制代码
void printJoint(const Joint& joint)
{
    std::cout << joint.angle << std::endl;
}

这里出现了:

复制代码
const Joint& joint

你已经认识:

复制代码
&

表示引用。

但:

复制代码
const

我们还没正式学。

所以现在不要硬啃这一句。

你只需要知道:

以后大型结构体经常通过引用传入函数,避免复制。

下一阶段会讲 const。


22. struct 和 class 有什么关系?

你目标里还有:

class 面向对象

其实:

复制代码
struct

和:

复制代码
class

关系非常近。

现在我们先把 struct 理解成:

打包数据。

以后 class 会进一步变成:

数据 + 操作这些数据的函数

例如:

复制代码
class Robot
{
    // 机器人数据
    // 机器人功能
};

所以 struct 是学习类非常好的过渡。


23. 本课核心

以前:

复制代码
double angle;
double speed;
bool enabled;

是三个散乱变量。

现在:

复制代码
struct Joint
{
    double angle;
    double speed;
    bool enabled;
};

把它们打包成一种新类型:

复制代码
Joint

然后:

复制代码
Joint joint1;

创建一个具体关节。

使用:

复制代码
joint1.angle
joint1.speed
joint1.enabled

本课小练习

第 1 题

复制代码
struct Motor
{
    double speed;
    bool enabled;
};

那么:

复制代码
Motor m;
m.speed = 100.0;
m.enabled = true;

m.speed 是多少?


第 2 题

下面:

复制代码
struct Joint
{
    double angle;
    double speed;
};

Joint 是变量名还是我们自己定义的新类型?


第 3 题

复制代码
Joint joints[6];

是什么意思?


第 4 题

复制代码
joints[2].angle = 45.0;

用自己的话解释这句话。


下一课我们讲:

第 22 课:const ------ "这个值不允许被修改"

你会开始理解:

复制代码
const double PI = 3.14159;

以及为什么真实工程里经常写:

复制代码
void printJoint(const Joint& joint)

这会把你之前学过的变量、引用、函数参数、struct真正连起来。

相关推荐
青梅橘子皮1 小时前
Blue---二分算法(二分查找与二分答案)
算法
长河1 小时前
Java的GC(垃圾回收)中,标记无用对象的核心方法是可达性分析算法
java·jvm·算法
月光船幽幽2 小时前
加性偏移外推提升参数识别可靠性
python·算法
SHARK_pssm2 小时前
【C++——类和对象(下)】
开发语言·c++·经验分享·笔记
凯哥Java2 小时前
写代码怎么避免逻辑漏洞?
java·开发语言·人工智能·自动化
汉克老师2 小时前
GESP2026年9月认证C++二级( 第一部分选择题(1~7题)精讲
c++·gesp·小学生·学c++编程
Ivanqhz2 小时前
层归一化、残差、前馈网络与激活函数简述
服务器·数据库·人工智能·深度学习·算法
Ai-_Man2 小时前
您您这可以把Dola的多个会话比如说。左侧的多个会话一次性导出吗?不是单条会话里面的多次会对话。用AI导出鸭,答案是可以的
开发语言·前端·人工智能·小程序
Java后端的Ai之路2 小时前
Python进阶探索23 - Python中的Time与Datetime模块
开发语言·数据库·python·datetime·time