第六章:函数与模块化编程
6.1 函数定义与声明
函数定义
函数是完成特定任务的代码块,语法如下:
返回类型 函数名(参数列表) {
// 函数体
return 表达式; // 若返回类型非void
}
函数声明(原型)
在调用函数前需声明其存在,语法:
返回类型 函数名(参数类型列表);
示例:计算两数之和
#include <stdio.h>
// 函数声明(可省略参数名)
int add(int, int);
int main() {
int result = add(3, 5); // 调用函数
printf("Sum: %d\n", result); // 输出:Sum: 8
return 0;
}
// 函数定义
int add(int a, int b) {
return a + b;
}
注意事项:
• 若函数定义在调用前,可省略声明。
• void
表示无返回值或无参数,如 void func(void);
。
6.2 参数传递:值传递与地址传递
传递方式 | 描述 | 示例 | 特点 |
值传递 | 传递参数的副本 | void swap(int a, int b) | 函数内修改不影响原始变量 |
地址传递 | 传递指针(内存地址) | void swap(int *a, int *b) | 函数内可通过指针修改原始变量 |
示例:交换两个变量的值
// 值传递(无法交换)
void swap_val(int a, int b) {
int temp = a;
a = b;
b = temp;
}
// 地址传递(成功交换)
void swap_ptr(int *a, int *b) {
int temp = *a;
*a = *b;
*b = temp;
}
int main() {
int x = 10, y = 20;
swap_val(x, y); // x=10, y=20(未交换)
swap_ptr(&x, &y); // x=20, y=10(成功交换)
return 0;
}
数组参数传递:
数组名作为指针传递,需指定大小(或使用指针):
void printArray(int arr[], int size) { // 等价于 int *arr
for (int i=0; i<size; i++) {
printf("%d ", arr[i]);
}
}
6.3 递归函数设计
递归:函数直接或间接调用自身,需满足:
- 基准条件(终止条件)。
- 递归步骤(向基准条件推进)。
示例:计算阶乘
int factorial(int n) {
if (n <= 1) { // 基准条件
return 1;
}
return n * factorial(n-1); // 递归调用
}
// factorial(5) = 5*4*3*2*1 = 120
递归缺陷:
• 栈溢出风险(如递归深度过大)。
• 效率低于迭代(重复计算,如斐波那契数列)。
6.4 变量作用域与存储类别
作用域规则
- 局部变量:函数内部定义,仅在函数内有效。
- 全局变量:函数外部定义,整个文件有效(慎用,易引发耦合)。
存储类别关键字
关键字 | 描述 | 示例 |
auto | 默认,局部变量自动分配/释放(通常省略) | auto int x = 10; |
static | 静态变量,生命周期持续到程序结束 | static int count = 0; |
register | 建议编译器将变量存储在寄存器(现代编译器自动优化,极少手动指定) | register int i; |
extern | 声明外部全局变量(用于多文件共享) | extern int globalVar; |
示例:静态局部变量
void counter() {
static int count = 0; // 仅初始化一次
count++;
printf("Count: %d\n", count);
}
int main() {
counter(); // 输出:Count: 1
counter(); // 输出:Count: 2
return 0;
}
6.5 头文件与多文件编程
头文件(.h)
• 包含函数声明、宏定义、类型定义等。
• 使用 #ifndef
防止重复包含:
// example.h
#ifndef EXAMPLE_H
#define EXAMPLE_H
extern int globalVar; // 声明全局变量
void printMessage(); // 声明函数
#endif
多文件编程
主文件(main.c):
#include "example.h"
int globalVar = 100; // 定义全局变量
int main() {
printMessage(); // 调用其他文件的函数
return 0;
}
功能文件(utils.c):
#include <stdio.h>
#include "example.h"
void printMessage() {
printf("GlobalVar: %d\n", globalVar); // 使用全局变量
}
编译与链接:
gcc main.c utils.c -o program
./program
总结
- 函数封装:提升代码复用性和可维护性。
- 模块化设计:通过头文件和多文件组织代码,降低耦合。
- 递归谨慎使用:优先考虑迭代,避免栈溢出。
- 变量作用域:合理使用
static
和 extern
控制可见性。
模块化编程是构建大型项目的基石,遵循高内聚、低耦合原则!