欢迎光临
我们一直在努力

C++ 第 11 课:函数返回值与 return

上一课标准答案:

  • Hi 会输出 2 次
  • 输出:
  • 5

  • 有 2 个参数:
  • int joint
    double angle

    其中 joint 是 int,angle 是 double。
    4.

    moveJoint(2, 30.5);

    表示调用 moveJoint 函数,并把:

    2 → joint
    30.5 → angle

    传进去。


    第 11 课:函数返回值与 return

    上一课我们学的函数主要是:

    void moveJoint()
    {
    }

    这种函数只负责:

    做事情

    但有时候我们希望函数:

    算出一个结果,然后把结果交回来。

    例如机械臂控制里:

    目标角度 = 50°
    当前角度 = 20°

    误差 = ?

    我们可以让一个函数专门计算误差。


    1. 先看第一个有返回值的函数

    double calculateError(double target, double current)
    {
    double error = target – current;

    return error;
    }

    先别急,我们一点点拆。


    2. 为什么这里不是 void?

    上一课:

    void stopRobot()

    void 表示:

    这个函数不需要返回结果。

    现在:

    double calculateError(…)

    前面是:

    double

    意思变成:

    这个函数执行完后,会返回一个 double 类型的结果。

    也就是:

    double calculateError(…)
    ↑
    这个函数最终要交回来一个小数


    3. return 是什么?

    看:

    return error;

    可以理解成:

    把 error 的值作为函数结果交回去。

    例如:

    double calculateError(double target, double current)
    {
    double error = target – current;

    return error;
    }

    如果调用:

    calculateError(50.0, 20.0);

    函数内部:

    target = 50.0
    current = 20.0

    于是:

    double error = target – current;

    就是:

    error = 50 – 20
    = 30

    最后:

    return error;

    相当于:

    把 30.0 交回调用函数的位置。


    4. 返回到哪里?

    这是非常重要的一点。

    看:

    double result = calculateError(50.0, 20.0);

    你可以把右边:

    calculateError(50.0, 20.0)

    想象成最终会变成:

    30.0

    所以整句话最终相当于:

    double result = 30.0;

    于是:

    result
    ┌──────┐
    │ 30.0 │
    └──────┘


    5. 用“机器”理解函数返回值

    你可以把:

    calculateError

    想成一台计算机器。

    输入:

    target = 50
    current = 20

    经过:

    50 – 20

    输出:

    30

    所以:

    50 ─────┐
    ├──→ calculateError ───→ 30
    20 ─────┘

    这就是:

    输入参数 → 函数处理 → 返回结果


    6. 完整程序

    #include <iostream>

    double calculateError(double target, double current)
    {
    double error = target – current;

    return error;
    }

    int main()
    {
    double result = calculateError(50.0, 20.0);

    std::cout << result << std::endl;

    return 0;
    }

    最终输出:

    30


    7. 程序到底怎么跳来跳去?

    这个要理解。

    程序先进入:

    main()

    执行:

    double result = calculateError(50.0, 20.0);

    这时程序发现:

    我要调用 calculateError。

    于是:

    main
    ↓
    调用 calculateError
    ↓
    target = 50
    current = 20
    ↓
    计算 error = 30
    ↓
    return 30
    ↓
    回到 main
    ↓
    result = 30

    然后继续:

    std::cout << result << std::endl;

    输出:

    30


    8. 其实可以直接 return

    刚才写:

    double calculateError(double target, double current)
    {
    double error = target – current;

    return error;
    }

    也可以直接写:

    double calculateError(double target, double current)
    {
    return target – current;
    }

    因为:

    target – current

    本身就已经能算出结果。

    例如:

    50 – 20 = 30

    直接:

    return 30;

    完全可以。


    9. 为什么有时候还要先创建 error?

    因为复杂程序里,中间变量往往更容易看懂。

    例如:

    double error = target – current;
    return error;

    比直接写:

    return target – current;

    稍微长一点,但:

    调试时更容易观察 error 到底是多少。

    初学阶段你可以多用中间变量。


    10. 返回类型必须对应

    比如:

    double calculateError(…)

    说明:

    这个函数承诺返回 double。

    所以:

    return error;

    最好也是一个能表示为 double 的值。

    类似:

    int getJointNumber()
    {
    return 3;
    }

    这里:

    int

    对应:

    return 3;


    11. 再看 bool 返回值

    函数不一定返回数字。

    例如我们想判断机械臂角度是否合法:

    bool isAngleValid(double angle)
    {
    return angle >= -90.0 && angle <= 90.0;
    }

    这里返回类型:

    bool

    所以最后返回:

    true

    或者:

    false

    例如:

    bool valid = isAngleValid(45.0);

    里面判断:

    45 >= -90
    并且
    45 <= 90

    都成立。

    所以:

    valid = true


    12. 这在机器人代码里非常常见

    以后你可能看到:

    bool isConnected()

    意思大概率是:

    检查设备是否连接,并返回 true / false。

    例如:

    if (isConnected())
    {
    std::cout << "Robot connected" << std::endl;
    }

    你现在已经能理解这段代码的核心:

    调用 isConnected()
    ↓
    它返回 true 或 false
    ↓
    if 根据这个结果决定是否进入


    13. 函数返回值可以直接参加运算

    比如:

    double getAngle()
    {
    return 30.0;
    }

    那么:

    double result = getAngle() + 10.0;

    相当于:

    double result = 30.0 + 10.0;

    所以:

    result = 40.0

    这点以后非常重要。

    因为函数调用看起来是一串文字:

    calculateIK(…)

    但它最终可能代表一个计算结果。


    14. return 后面的代码通常不会再执行

    看:

    int test()
    {
    return 5;

    std::cout << "Hello" << std::endl;
    }

    执行到:

    return 5;

    时,函数已经结束并返回了。

    所以下面的:

    std::cout << "Hello" << std::endl;

    不会执行。

    可以理解成:

    return
    =
    交出结果 + 离开当前函数


    15. 所以 return 有两个作用

    例如:

    return error;

    可以理解为:

  • 把 error 作为结果交回去
  • 当前函数执行结束
  • 这点很重要。


    16. void 里能不能有 return?

    可以出现:

    return;

    但后面没有返回值。

    例如:

    void checkAngle(double angle)
    {
    if (angle > 90.0)
    {
    return;
    }

    std::cout << "Angle OK" << std::endl;
    }

    如果:

    angle > 90

    就:

    return;

    直接结束函数。

    但因为这是:

    void

    函数,所以不返回具体数据。

    这个现在先认识即可。


    17. 一个机械臂 PID 雏形

    以后 PID 会反复使用:

    误差 = 目标值 – 当前值

    现在我们已经可以封装成函数:

    double calculateError(double target, double current)
    {
    return target – current;
    }

    然后:

    int main()
    {
    double target = 90.0;
    double current = 65.0;

    double error = calculateError(target, current);

    std::cout << error << std::endl;

    return 0;
    }

    结果:

    25

    你以后学 PID 时可能会看到:

    double error = target – current;
    double output = kp * error;

    现在这些基础已经开始接上了。


    18. 再进一步:函数调用函数

    函数里面还可以调用其他函数。

    例如:

    double calculateError(double target, double current)
    {
    return target – current;
    }

    void controlJoint(double target, double current)
    {
    double error = calculateError(target, current);

    std::cout << error << std::endl;
    }

    然后:

    int main()
    {
    controlJoint(50.0, 20.0);

    return 0;
    }

    逻辑是:

    main
    ↓
    controlJoint
    ↓
    calculateError
    ↓
    返回30
    ↓
    controlJoint得到error=30
    ↓
    输出30
    ↓
    回到main

    真实机器人程序就是这样一层一层组织起来的。


    19. 现在总结函数的三个部分

    例如:

    double calculateError(double target, double current)
    {
    return target – current;
    }

    可以拆成:

    double
    ↓
    返回值类型

    calculateError
    ↓
    函数名字

    (double target, double current)
    ↓
    参数

    return target – current;
    ↓
    返回结果

    所以一个函数可以想象成:

    返回类型 函数名(输入参数)
    {
    处理过程

    return 结果;
    }


    本课小练习

    第 1 题

    int add(int a, int b)
    {
    return a + b;
    }

    调用:

    int result = add(3, 4);

    result 是多少?


    第 2 题

    double getAngle()
    {
    return 45.5;
    }

    这里函数:

    • 返回值类型是什么?
    • 返回的值是多少?

    第 3 题

    bool isPositive(int number)
    {
    return number > 0;
    }

    调用:

    bool result = isPositive(-3);

    最后 result 是 true 还是 false?


    第 4 题

    用自己的话解释:

    double error = calculateError(80.0, 50.0);

    下一课我们继续函数,但会讲一个以后非常容易混淆、也非常关键的问题:

    赞(0)
    未经允许不得转载:171主机测评 » C++ 第 11 课:函数返回值与 return
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址