函数:把动作打包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:
// 前进
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();
// 又右转...(又写一遍)
// ...
// 前进
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();
// 又右转...(又写一遍)
// ...
// 前进
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.
把重复使用的代码打包成一个名字。以后用到这段代码时,只要叫它的名字就行。改一次函数,所有用到它的地方都跟着改。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:
- 返回类型 — 函数做完后给你什么结果?不给结果就写
voidReturn type — what result does the function give you? If none, writevoid - 函数名 — 你给这段代码起的名字Function name — the name you give this piece of code
- 参数 — 函数需要你告诉它什么信息Parameters — what information the function needs from you
// 返回类型 函数名 参数列表
// ↓ ↓ ↓
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.
// 定义函数
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;
}
// 定义函数
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;
}
// 定义函数
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 秒
}
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:
// 计算两个电机的平均速度
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:做事不给结果。例:让电机转、让机器人前进void: does something, returns nothing. Example: spin a motor, drive the robot- 有返回值(
int、double等):做完事给你一个值。例:读传感器、做计算With return value (int,double, etc.): does something and gives you a value. Example: read a sensor, do a calculation
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:
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;
}
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;
}
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.
moveForward(100, 500);
turnRight(30, 300);
moveForward(50, 2000);
4.6 写代码练习4.6 Coding Exercise
写一个函数 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.