C++ 第一阶段总结:从零基础到 ROS2 前置语法

以后我们每完成一个阶段,我都会先做一次这种"阶段性总结":覆盖核心知识、配代表代码、不过度展开,然后再继续答案与下一课。

C++ 第一阶段总结:从零基础到 ROS2 前置语法

你目前已经完成的内容,大致可以分成 5 组。


一、变量、数据类型、运算和流程控制

1. 变量

复制代码
int a = 5;
double angle = 30.5;
bool enabled = true;
char c = 'A';

理解:

复制代码
int     整数
double  小数
bool    true / false
char    单个字符

= 是赋值:

复制代码
a = 10;

表示把 10 放进 a。


2. 运算

复制代码
int c = a + b;
double error = target - current;

常见:

复制代码
+  -  *  /

整数除法:

复制代码
5 / 2

结果是:

复制代码
2

3. 比较和逻辑

复制代码
a == b
a != b
a > b
a <= b

逻辑:

复制代码
&&   并且
||   或者
!    取反

机器人例子:

复制代码
if (angle >= -90.0 && angle <= 90.0)
{
    // 角度合法
}

4. if / else

复制代码
if (error < 1.0)
{
    std::cout << "Reached";
}
else
{
    std::cout << "Moving";
}

表示:

根据条件选择执行哪一段代码。


5. switch

适合固定状态:

复制代码
switch (state)
{
case 0:
    break;

case 1:
    break;

default:
    break;
}

机器人状态机里很常见。


6. 循环

while:

复制代码
while (running)
{
    // 持续控制
}

for:

复制代码
for (int i = 0; i < 6; i++)
{
    std::cout << i;
}

六轴机械臂里:

复制代码
i = 0 ~ 5

分别对应 6 个关节。


7. break / continue

复制代码
break;

直接退出当前循环。

复制代码
continue;

跳过本轮,进入下一轮。


二、函数、引用、指针和内存

1. 函数

复制代码
double calculateError(double target, double current)
{
    return target - current;
}

调用:

复制代码
double error = calculateError(50, 20);

结果:

复制代码
30

函数的意义:

把一段功能封装起来反复使用。


2. 局部变量

复制代码
void test()
{
    int a = 5;
}

a 只能在 test() 里面使用。

这涉及:

复制代码
作用域 scope
生命周期 lifetime

3. 值传递

复制代码
void change(int a)
{
    a = 100;
}

调用:

复制代码
int x = 5;
change(x);

最终:

复制代码
x = 5

因为:

a 是 x 的副本。

口诀:

复制代码
值传递 = 副本

4. 引用

复制代码
void change(int& a)
{
    a = 100;
}

调用:

复制代码
int x = 5;
change(x);

最终:

复制代码
x = 100

因为:

a 是 x 的别名。

口诀:

复制代码
引用 = 别名

5. 指针

复制代码
int x = 5;

int* p = &x;

关系:

复制代码
x    → 值 5
&x   → x 的地址
p    → 保存 x 的地址
*p   → 访问该地址里的值

所以:

复制代码
*p = 100;

会让:

复制代码
x = 100

口诀:

复制代码
指针 = 地址

6. 对象指针

普通对象:

复制代码
robot.stop();

指针:

复制代码
Robot* p = &robot;

p->stop();

记住:

复制代码
对象      用 .
对象指针  用 ->

而:

复制代码
p->stop();

基本等价于:

复制代码
(*p).stop();

三、数组、vector、string、struct

1. 数组

复制代码
double joint[6] =
{
    10, 20, 30, 40, 50, 60
};

访问:

复制代码
joint[0]
joint[5]

下标从:

复制代码
0

开始。

必须防止越界:

复制代码
for (int i = 0; i < 6; i++)

不能写:

复制代码
i <= 6

2. 数组和指针

复制代码
int a[4] = {10, 20, 30, 40};

int* p = a;

重要关系:

复制代码
*p        = a[0]

*(p + 1) = a[1]

a[i]     ≈ *(a + i)

这是理解底层数组、缓冲区、CAN 数据的重要基础。


3. std::vector

动态数组:

复制代码
std::vector<double> data;

添加:

复制代码
data.push_back(10.0);

数量:

复制代码
data.size();

访问:

复制代码
data[0];

适合:

复制代码
轨迹点
传感器数据
视觉结果
可变长度数据

4. std::string

复制代码
std::string state = "ERROR";

区别:

复制代码
'A'

是一个 char。

复制代码
"A"

是字符串。

字符串可以:

复制代码
state == "ERROR"

比较,也可以:

复制代码
name.size()

查看长度。


5. struct

把相关数据打包:

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

创建:

复制代码
Joint joint1;

访问:

复制代码
joint1.angle = 30.0;

六轴:

复制代码
Joint joints[6];

访问第三轴:

复制代码
joints[2].angle;

四、class 和面向对象基础

1. class

复制代码
class Joint
{
public:
    void setAngle(double angle)
    {
        this->angle = angle;
    }

private:
    double angle;
};

可以理解成:

数据 + 操作数据的函数。


2. public / private

复制代码
public:

外部可以访问。

复制代码
private:

只能类内部访问。

这样可以防止外部乱改数据。


3. 构造函数

复制代码
class Motor
{
public:
    Motor(int id)
        : id(id)
    {
    }

private:
    int id;
};

创建:

复制代码
Motor motor(1);

会自动调用构造函数。

构造函数:

复制代码
名字和类名一样
没有返回类型
对象创建时自动执行

4. getter / setter

修改:

复制代码
void setAngle(double angle)
{
    this->angle = angle;
}

读取:

复制代码
double getAngle() const
{
    return angle;
}

5. this

复制代码
this->angle

表示:

当前这个对象自己的 angle。

this 本身是指向当前对象的指针。


6. const

常量:

复制代码
const int JOINT_COUNT = 6;

不能修改。

只读引用:

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

表示:

不复制 joint,也不允许通过这个引用修改它。

成员函数:

复制代码
double getAngle() const

表示:

这个函数承诺不会修改当前对象。


五、开始进入 ROS2 所需的现代 C++

1. auto

复制代码
auto x = 10;

编译器自动判断类型。

ROS2 里很常见:

复制代码
auto node = std::make_shared<MyNode>();

2. shared_ptr

复制代码
auto robot =
    std::make_shared<Robot>();

robot 的类型大致是:

复制代码
std::shared_ptr<Robot>

它不是直接的 Robot,而是:

管理 Robot 对象生命周期的智能指针。

使用:

复制代码
robot->run();

多个 shared_ptr 可以管理同一个对象:

复制代码
auto p1 = std::make_shared<Robot>();
auto p2 = p1;

这里:

复制代码
p1
p2

指向同一个 Robot。


3. lambda

最简单:

复制代码
auto f = []()
{
    std::cout << "Hello";
};

执行:

复制代码
f();

可以理解成:

没有名字的小函数。

参数:

复制代码
auto f = [](int x)
{
    std::cout << x;
};

4. lambda 捕获

复制代码
[x]

按值捕获。

复制代码
[&x]

按引用捕获。

复制代码
[this]

捕获当前对象。

ROS2 里特别重要:

复制代码
[this](const Msg::SharedPtr msg)
{
    current_angle = msg->angle;
}

你现在已经能初步拆成:

复制代码
[this]
↓
可以使用当前对象

msg
↓
收到的消息

msg->angle
↓
通过智能指针读取消息里的 angle

到目前为止,你已经建立的核心思维

现在看一段:

复制代码
class Robot
{
public:
    void update(const Msg::SharedPtr msg)
    {
        current_angle = msg->angle;
    }

private:
    double current_angle = 0.0;
};

你已经可以拆出:

复制代码
class
对象
成员函数
private
double
智能指针
->
消息数据

这已经是进入 ROS2 C++ 的基础了。


上一课练习答案

第 1 题

复制代码
auto f = []()
{
    std::cout << "Hi";
};

这里只是:

定义了 lambda。

还没有执行。

必须:

复制代码
f();

才执行。


第 2 题

复制代码
int x = 10;

auto f = [x]()
{
    std::cout << x;
};

x = 20;

f();

通常输出:

复制代码
10

因为:

复制代码
[x]

是按值捕获,相当于保存了当时 x = 10 的一份副本。


第 3 题

复制代码
int x = 10;

auto f = [&x]()
{
    x = 50;
};

f();

最后:

复制代码
x = 50

因为:

复制代码
[&x]

是按引用捕获。


第 4 题

复制代码
[this]()
{
    speed = 100;
}

[this] 表示:

这个 lambda 可以访问当前对象的成员。

所以:

复制代码
speed = 100;

实际上是在操作当前对象自己的 speed。


第 5 题

复制代码
msg->data

如果 msg 是智能指针,就是:

通过 msg 找到它管理的消息对象,然后访问这个消息对象里的 data 成员。

相关推荐
朝朝辞暮i1 小时前
C++ 第 25 课:getter / setter + this
java·javascript·c++
2601_962885721 小时前
如何用 Python 回测定投策略(定期定额 DCA)?(和一次性买入对比)
开发语言·人工智能·python
H.莓飛1 小时前
【数据结构】链表_OJ题
linux·数据结构·算法·链表
周杰偷奶茶1 小时前
【JavaSE】类和对象基础
java·开发语言
All for pursuit.1 小时前
【回溯-4】46.全排列
数据结构·c++·算法·leetcode
小鱼~~1 小时前
Recall@K、Precision@K、MRR、nDCG@K简介
人工智能·算法·机器学习
在所不辞兄1 小时前
【零基础学智能仿真-38】从规则矩形到带孔薄板:Gmsh 网格与 FEniCSx 联合求解
人工智能·深度学习·算法·机器学习·工程仿真
大圣编蚕1 小时前
C语言核心知识复习:预处理、头文件、强制类型转换、错误处理、递归与内存管理
c语言·开发语言
虎大猫猫1 小时前
Python教程——按位取反的原理
开发语言·python