C&C++快速入门
14、函数与递归
1、课程目标
- 掌握函数的定义、声明和调用
- 理解参数传递方式(值传递、指针传递)
- 掌握递归函数的实现
- 了解函数指针的使用
2、名词解释
| 术语 | 说明 |
|---|---|
| 函数声明 | 告诉编译器函数的存在(原型) |
| 函数定义 | 函数的实际实现 |
| 形参 | 函数定义中的参数 |
| 实参 | 调用时传入的实际值 |
| 值传递 | 拷贝参数值,不影响原变量 |
| 指针传递 | 传递地址,可修改原变量 |
| 递归 | 函数调用自身 |
| 回调函数 | 通过函数指针调用的函数 |
3、代码实现
1. 函数基础
#include <stdio.h>
// 函数声明(原型)
int Add(int a, int b);
void PrintMessage(const char* msg);
int Factorial(int n);
// 函数定义
int Add(int a, int b) {
return a + b;
}
void PrintMessage(const char* msg) {
printf("[MSG] %s\n", msg);
}
int main() {
printf("=== 函数基础 ===\n\n");
// 函数调用
int sum = Add(10, 20);
printf("10 + 20 = %d\n", sum);
PrintMessage("Hello Function!");
return 0;
}
2. 参数传递方式
#include <stdio.h>
// 值传递: 不能修改原变量
void SwapByValue(int a, int b) {
int temp = a;
a = b;
b = temp;
printf(" 函数内: a=%d, b=%d\n", a, b);
}
// 指针传递: 可以修改原变量
void SwapByPointer(int* a, int* b) {
int temp = *a;
*a = *b;
*b = temp;
}
// 数组参数
void PrintArray(int arr[], int size) {
printf("[");
for (int i = 0; i < size; i++) {
printf("%d", arr[i]);
if (i < size - 1) printf(", ");
}
printf("]\n");
}
// 修改数组
void FillArray(int* arr, int size, int value) {
for (int i = 0; i < size; i++) {
arr[i] = value;
}
}
int main() {
printf("=== 参数传递 ===\n\n");
// 值传递
printf("【值传递】\n");
int x = 10, y = 20;
printf("交换前: x=%d, y=%d\n", x, y);
SwapByValue(x, y);
printf("交换后: x=%d, y=%d (未改变)\n", x, y);
// 指针传递
printf("\n【指针传递】\n");
printf("交换前: x=%d, y=%d\n", x, y);
SwapByPointer(&x, &y);
printf("交换后: x=%d, y=%d (已改变)\n", x, y);
// 数组参数
printf("\n【数组参数】\n");
int arr[5] = {1, 2, 3, 4, 5};
PrintArray(arr, 5);
FillArray(arr, 5, 0);
PrintArray(arr, 5);
return 0;
}
3. 递归函数
#include <stdio.h>
// 阶乘
int Factorial(int n) {
if (n <= 1) return 1;
return n * Factorial(n - 1);
}
// 斐波那契
int Fibonacci(int n) {
if (n <= 1) return n;
return Fibonacci(n - 1) + Fibonacci(n - 2);
}
// 二分查找(递归版)
int BinarySearch(int arr[], int left, int right, int target) {
if (left > right) return -1;
int mid = left + (right - left) / 2;
if (arr[mid] == target) return mid;
if (arr[mid] > target)
return BinarySearch(arr, left, mid - 1, target);
return BinarySearch(arr, mid + 1, right, target);
}
int main() {
printf("=== 递归函数 ===\n\n");
// 阶乘
printf("【阶乘】\n");
for (int i = 0; i <= 10; i++) {
printf("%d! = %d\n", i, Factorial(i));
}
// 斐波那契
printf("\n【斐波那契】\n");
printf("F(10) = %d\n", Fibonacci(10));
// 二分查找
printf("\n【二分查找】\n");
int arr[] = {1, 3, 5, 7, 9, 11, 13};
int idx = BinarySearch(arr, 0, 6, 7);
printf("查找7: 索引=%d\n", idx);
return 0;
}
4. 函数指针
#include <stdio.h>
// 函数原型
int Add(int a, int b) { return a + b; }
int Sub(int a, int b) { return a - b; }
int Mul(int a, int b) { return a * b; }
int Div(int a, int b) { return b ? a / b : 0; }
// 函数指针类型
typedef int (*MathFunc)(int, int);
// 回调函数示例
void ProcessArray(int* arr, int size, int (*callback)(int)) {
for (int i = 0; i < size; i++) {
arr[i] = callback(arr[i]);
}
}
int Double(int x) { return x * 2; }
int Square(int x) { return x * x; }
int main() {
printf("=== 函数指针 ===\n\n");
// 函数指针数组
printf("【函数指针数组】\n");
MathFunc funcs[] = {Add, Sub, Mul, Div};
const char* names[] = {"+", "-", "*", "/"};
int a = 10, b = 3;
for (int i = 0; i < 4; i++) {
printf("%d %s %d = %d\n", a, names[i], b, funcs[i](a, b));
}
// 回调函数
printf("\n【回调函数】\n");
int arr[] = {1, 2, 3, 4, 5};
ProcessArray(arr, 5, Double);
printf("翻倍后: ");
for (int i = 0; i < 5; i++) printf("%d ", arr[i]);
printf("\n");
return 0;
}
5、课后作业
5.1、作业1:实现排序函数
实现冒泡排序,接受函数指针作为比较函数。
5.2、作业2:汉诺塔
用递归实现汉诺塔问题。
5.3、作业3:计算器程序
使用函数指针数组实现简单计算器。