0 / 5 页已完成

函数:把动作打包Functions: Packaging Actions

4.1 为什么需要函数?4.1 Why Do We Need Functions?

想象一下,你的机器人要做这些动作:前进 → 右转 → 前进 → 右转 → 前进。不用函数的话:Imagine your robot needs to do: forward → turn right → forward → turn right → forward. Without functions:

C++ (VEXcode)
// 前进
LeftMotor.spin(forward, 50, percent);
RightMotor.spin(forward, 50, percent);
wait(1000, msec);
LeftMotor.stop();
RightMotor.stop();

// 右转
LeftMotor.spin(forward, 30, percent);
RightMotor.spin(reverse, 30, percent);
wait(500, msec);
LeftMotor.stop();
RightMotor.stop();

// 又前进...(再写一遍同样的 5 行)
LeftMotor.spin(forward, 50, percent);
RightMotor.spin(forward, 50, percent);
wait(1000, msec);
LeftMotor.stop();
RightMotor.stop();

// 又右转...(又写一遍)
// ...
C++ (VS Code)
// 前进
LeftMotor.spin(forward, 50, percent);
RightMotor.spin(forward, 50, percent);
wait(1000, msec);
LeftMotor.stop();
RightMotor.stop();

// 右转
LeftMotor.spin(forward, 30, percent);
RightMotor.spin(reverse, 30, percent);
wait(500, msec);
LeftMotor.stop();
RightMotor.stop();

// 又前进...(再写一遍同样的 5 行)
LeftMotor.spin(forward, 50, percent);
RightMotor.spin(forward, 50, percent);
wait(1000, msec);
LeftMotor.stop();
RightMotor.stop();

// 又右转...(又写一遍)
// ...
C++ (PROS)
// 前进
left_motor.move(50);
right_motor.move(50);
pros::delay(1000);
left_motor.brake();
right_motor.brake();

// 右转
left_motor.move(30);
right_motor.move(-30);
pros::delay(500);
left_motor.brake();
right_motor.brake();

// 又前进...(再写一遍同样的 5 行)
left_motor.move(50);
right_motor.move(50);
pros::delay(1000);
left_motor.brake();
right_motor.brake();

// 又右转...(又写一遍)
// ...

同样的代码复制粘贴了好几遍。如果你想把速度从 50 改成 60,要改好多地方,漏改一个就出 bug。The same code is copy-pasted multiple times. If you want to change the speed from 50 to 60, you have to change it everywhere — miss one and you've got a bug.

函数的作用What Functions Do

把重复使用的代码打包成一个名字。以后用到这段代码时,只要叫它的名字就行。改一次函数,所有用到它的地方都跟着改。Package frequently used code under one name. When you need that code, just call its name. Change the function once, and everywhere it's used gets updated.

4.2 函数长什么样?4.2 What Does a Function Look Like?

一个函数有三个要素:A function has three key parts:

  1. 返回类型 — 函数做完后给你什么结果?不给结果就写 voidReturn type — what result does the function give you? If none, write void
  2. 函数名 — 你给这段代码起的名字Function name — the name you give this piece of code
  3. 参数 — 函数需要你告诉它什么信息Parameters — what information the function needs from you
C++ (通用)
// 返回类型  函数名      参数列表
//   ↓        ↓           ↓
   void   moveForward(int speed, int ms) {
       // 函数体:具体做什么
   }

4.3 void 函数:做事不回报4.3 Void Functions: Do Something, Return Nothing

大多数机器人动作函数都是 void 类型——它们执行一个动作,但不需要返回什么值。Most robot action functions are void type — they perform an action but don't need to return any value.

C++ (VEXcode)
// 定义函数
void moveForward(int speed, int ms) {
    LeftMotor.spin(forward, speed, percent);
    RightMotor.spin(forward, speed, percent);
    wait(ms, msec);
    LeftMotor.stop();
    RightMotor.stop();
}

// 使用函数(调用)
int main() {
    moveForward(50, 1000);  // 50% 速度前进 1 秒
    moveForward(80, 500);   // 80% 速度前进 0.5 秒
    return 0;
}
C++ (VS Code)
// 定义函数
void moveForward(int speed, int ms) {
    LeftMotor.spin(forward, speed, percent);
    RightMotor.spin(forward, speed, percent);
    wait(ms, msec);
    LeftMotor.stop();
    RightMotor.stop();
}

// 使用函数(调用)
int main() {
    moveForward(50, 1000);  // 50% 速度前进 1 秒
    moveForward(80, 500);   // 80% 速度前进 0.5 秒
    return 0;
}
C++ (PROS)
// 定义函数
void moveForward(int speed, int ms) {
    left_motor.move(speed);
    right_motor.move(speed);
    pros::delay(ms);
    left_motor.brake();
    right_motor.brake();
}

// 使用函数(调用)
void autonomous() {
    moveForward(50, 1000);  // 速度 50 前进 1 秒
    moveForward(80, 500);   // 速度 80 前进 0.5 秒
}
函数定义要写在调用之前Function Definition Must Come Before the Call

C++ 从上往下读代码。如果 main() 里调用了 moveForward(),那 moveForward() 的定义必须写在 main() 前面。否则编译器会说:"我不认识这个函数"。C++ reads code from top to bottom. If main() calls moveForward(), then moveForward() must be defined above main(). Otherwise the compiler will say: "I don't know this function."

4.4 有返回值的函数4.4 Functions with Return Values

有时候函数不只是做事,还要给你一个结果。比如:Sometimes a function doesn't just do something — it also gives you a result. For example:

C++ (通用)
// 计算两个电机的平均速度
int averageSpeed(int left, int right) {
    return (left + right) / 2;
}

// 使用
int avg = averageSpeed(80, 60); // avg = 70

返回类型是 int(整数),所以函数里用 return 返回一个整数。The return type is int (integer), so the function uses return to send back an integer.

void vs 有返回值void vs. Return Value

4.5 重构:把之前的代码变好4.5 Refactoring: Making Old Code Better

现在回头看第一节那个又长又重复的代码,用函数重写:Now look back at that long, repetitive code from the first section. Let's rewrite it with functions:

C++ (VEXcode)
void moveForward(int speed, int ms) {
    LeftMotor.spin(forward, speed, percent);
    RightMotor.spin(forward, speed, percent);
    wait(ms, msec);
    LeftMotor.stop();
    RightMotor.stop();
}

void turnRight(int speed, int ms) {
    LeftMotor.spin(forward, speed, percent);
    RightMotor.spin(reverse, speed, percent);
    wait(ms, msec);
    LeftMotor.stop();
    RightMotor.stop();
}

int main() {
    // 清清楚楚:前进 → 右转 → 前进 → 右转 → 前进
    moveForward(50, 1000);
    turnRight(30, 500);
    moveForward(50, 1000);
    turnRight(30, 500);
    moveForward(50, 1000);
    return 0;
}
C++ (VS Code)
void moveForward(int speed, int ms) {
    LeftMotor.spin(forward, speed, percent);
    RightMotor.spin(forward, speed, percent);
    wait(ms, msec);
    LeftMotor.stop();
    RightMotor.stop();
}

void turnRight(int speed, int ms) {
    LeftMotor.spin(forward, speed, percent);
    RightMotor.spin(reverse, speed, percent);
    wait(ms, msec);
    LeftMotor.stop();
    RightMotor.stop();
}

int main() {
    moveForward(50, 1000);
    turnRight(30, 500);
    moveForward(50, 1000);
    turnRight(30, 500);
    moveForward(50, 1000);
    return 0;
}
C++ (PROS)
void moveForward(int speed, int ms) {
    left_motor.move(speed);
    right_motor.move(speed);
    pros::delay(ms);
    left_motor.brake();
    right_motor.brake();
}

void turnRight(int speed, int ms) {
    left_motor.move(speed);
    right_motor.move(-speed);
    pros::delay(ms);
    left_motor.brake();
    right_motor.brake();
}

void autonomous() {
    moveForward(50, 1000);
    turnRight(30, 500);
    moveForward(50, 1000);
    turnRight(30, 500);
    moveForward(50, 1000);
}

对比一下,是不是清楚多了?想改速度只需要改函数定义里的一行,不用到处找。Compare them — isn't this much clearer? To change the speed, you only need to modify one line in the function definition, no need to search everywhere.

检查点:理解函数Checkpoint: Understanding Functions
下面的函数调用执行后,机器人做了什么?What did the robot do after these function calls were executed?
C++ (通用)
moveForward(100, 500);
turnRight(30, 300);
moveForward(50, 2000);

4.6 写代码练习4.6 Coding Exercise

挑战Challenge

写一个函数 moveBackward(int speed, int ms),让机器人后退指定速度和时间。然后在 main 里调用它。Write a function moveBackward(int speed, int ms) that makes the robot drive backward at a given speed for a given time. Then call it in main.