函数是可重复使用的代码块。本课将学习如何编写和使用函数。
想象你要做 10 次同样的计算。你会复制粘贴代码 10 次吗?❌
函数的好处:
返回类型 函数名 (参数列表) {
// 函数体
// 执行的代码
return 返回值; // 如果返回类型不是 void
}
// 函数定义
int square(int x) {
return x * x;
}
// 函数调用
int result = square(5); // result = 25
int add (int a, int b)
↓ ↓ ↓
返回类型 函数名 参数列表
{
return a + b; // 函数体
}
| 部分 | 说明 | 示例 |
|---|---|---|
| 返回类型 | 函数返回值的类型 | int, float, void |
| 函数名 | 函数的名字 | calculate_score |
| 参数列表 | 传入函数的值 | (int x, int y) |
| 函数体 | 实际执行的代码 | { ... } |
| 返回值 | 函数执行的结果 | return result; |
// snake.h
int snake_get_length(snake_t* snake);
void snake_move(snake_t* snake);
// snake.c
#include "snake.h"
int snake_get_length(snake_t* snake) {
return snake->length;
}
void snake_move(snake_t* snake) {
// 移动蛇的逻辑
}
void clear_screen(void) {
printf("\033[2J\033[H"); // 清屏转义序列
}
void draw_char(int x, int y, char ch) {
printf("\033[%d;%dH%c", y, x, ch);
}
int calculate_score(int food_eaten, int level) {
return food_eaten * 10 * level;
}
bool check_collision(int snake_x, int snake_y,
int wall_x, int wall_y) {
return (snake_x == wall_x && snake_y == wall_y);
}
// 1. 直接使用返回值
int result = square(5);
// 2. 作为其他函数的参数
printf("结果是:%d\n", square(5));
// 3. 忽略返回值(void 函数)
clear_screen();
// 4. 在条件语句中
if (check_collision(x, y, wall_x, wall_y)) {
game_over();
}
int global_var = 100; // 全局变量,任何地方都能访问
void function1(void) {
int local_var = 50; // 局部变量,只在函数内有效
printf("%d\n", global_var); // ✅ 可以访问
printf("%d\n", local_var); // ✅ 可以访问
}
void function2(void) {
printf("%d\n", global_var); // ✅ 可以访问
printf("%d\n", local_var); // ❌ 错误!local_var 不存在于此
}
┌─────────────────────────────────────┐
│ 全局作用域 │
│ int global_var; │
│ ┌─────────────────────────────┐ │
│ │ 函数 1 局部作用域 │ │
│ │ int local1; │ │
│ └─────────────────────────────┘ │
│ ┌─────────────────────────────┐ │
│ │ 函数 2 局部作用域 │ │
│ │ int local2; │ │
│ └─────────────────────────────┘ │
└─────────────────────────────────────┘
函数可以调用自己,这叫递归:
// 计算阶乘:5! = 5 × 4 × 3 × 2 × 1 = 120
int factorial(int n) {
if (n <= 1) {
return 1; // 基础情况
}
return n * factorial(n - 1); // 递归调用
}
int main(void) {
int result = factorial(5); // result = 120
printf("5! = %d\n", result);
return 0;
}
int main(void) {
// 初始化
int score = 0;
int snake_x = 10, snake_y = 10;
// 游戏循环
while (1) {
// 处理输入
// 更新蛇位置
snake_x += 1;
// 检查碰撞
if (snake_x >= 80) {
printf("Game Over!\n");
break;
}
// 绘制
printf("Snake at (%d, %d)\n", snake_x, snake_y);
}
return 0;
}
void init_game(game_t* game) {
game->score = 0;
game->snake_x = 10;
game->snake_y = 10;
}
void update_snake(snake_t* snake) {
snake->x += 1;
}
bool check_wall_collision(snake_t* snake, int width) {
return snake->x >= width;
}
void render_game(game_t* game) {
printf("Snake at (%d, %d)\n", game->snake_x, game->snake_y);
}
int main(void) {
game_t game;
init_game(&game);
while (1) {
update_snake(&game.snake);
if (check_wall_collision(&game.snake, 80)) {
printf("Game Over!\n");
break;
}
render_game(&game);
}
return 0;
}
编写一个函数 int max(int a, int b),返回两个数中的较大值
编写一个函数 void print_box(int width, int height),打印指定大小的矩形框
将你的贪吃蛇代码中的功能分解成函数:
init_game() - 初始化游戏handle_input() - 处理输入update_game() - 更新游戏状态render_game() - 绘制画面下一课:结构体