- C
C语言函数教程01
- 2025-6-6 7:27:29 @
C语言函数详解
函数是C语言程序的基本组成单元,它可以将复杂任务分解为小模块,提高代码复用性和可维护性。本教程适合零基础学习者,通过示例和注释详细讲解函数的使用。
1. 函数的基本概念
函数是一段完成特定任务的独立代码块,有输入参数和返回值(可选)。类似于数学中的函数 y = f(x)
,C语言函数接收输入(参数),执行操作,返回结果。
函数的优点:
- 代码复用
- 模块化设计
- 便于调试和维护
2. 函数的定义与调用
2.1 函数定义的语法
返回类型 函数名(参数列表) {
// 函数体(代码逻辑)
return 返回值; // 与返回类型匹配
}
- 返回类型:函数返回值的数据类型(如
int
,float
,void
等)。 - 函数名:自定义标识符,命名规则与变量相同。
- 参数列表:输入参数的类型和名称,多个参数用逗号分隔。
- 函数体:实现具体功能的代码块。
- return语句:结束函数并返回值(返回类型为
void
时可省略)。
2.2 示例:定义一个简单的函数
// 定义一个函数:计算两数之和
int add(int a, int b) { // 接收两个整数参数
int sum = a + b; // 计算和
return sum; // 返回结果
}
2.3 函数调用
定义后的函数需要被调用才能执行。调用时需提供参数(如果有),并可以接收返回值。
#include <stdio.h>
int main() {
int result;
// 调用add函数,传入参数5和3,并将返回值赋给result
result = add(5, 3);
printf("5 + 3 = %d\n", result); // 输出:5 + 3 = 8
return 0;
}
3. 函数参数
3.1 形式参数(形参)与实际参数(实参)
- 形参:函数定义时声明的参数,用于接收外部传入的值。
- 实参:函数调用时传递给函数的实际值。
// 形参:a和b
int multiply(int a, int b) {
return a * b;
}
int main() {
int x = 4, y = 5;
// 实参:x和y(或直接用常量4和5)
int result = multiply(x, y);
return 0;
}
3.2 参数传递方式
C语言通过值传递方式传递参数,即传递的是实参的副本,而非实参本身。因此,函数内部修改形参不会影响实参。
// 尝试交换两个数(错误示例)
void swap(int a, int b) {
int temp = a;
a = b;
b = temp;
// 仅交换了形参a和b的副本,实参不受影响
}
int main() {
int x = 10, y = 20;
swap(x, y); // 调用后x和y的值不变
printf("x = %d, y = %d\n", x, y); // 输出:x = 10, y = 20
return 0;
}
4. 返回值与返回类型
4.1 返回类型
函数可以返回各种数据类型的值,如 int
, float
, char
等。如果不需要返回值,使用 void
类型。
// 返回浮点数的函数
float divide(float a, float b) {
if (b != 0) {
return a / b;
} else {
printf("Error: division by zero!\n");
return 0.0; // 错误处理
}
}
// 无返回值的函数
void printHello() {
printf("Hello, World!\n");
// 无需return语句
}
4.2 return语句
- 终止函数执行并返回值。
- 返回值的类型必须与函数定义的返回类型一致。
- 一个函数可以有多个return语句,但只能执行其中一个。
int max(int a, int b) {
if (a > b) {
return a; // 条件满足时执行此return
} else {
return b; // 条件不满足时执行此return
}
}
5. 函数声明与头文件
5.1 函数声明
如果函数定义在调用之后,需要在调用前进行函数声明(原型声明)。声明告诉编译器函数的返回类型、名称和参数类型。
#include <stdio.h>
// 函数声明(原型)
int subtract(int a, int b); // 声明但不实现
int main() {
int result = subtract(10, 5); // 调用在定义前
printf("10 - 5 = %d\n", result);
return 0;
}
// 函数定义(实现)
int subtract(int a, int b) {
return a - b;
}
5.2 头文件的使用
将函数声明放在头文件(.h
)中,函数定义放在源文件(.c
)中,可以提高代码组织性。
示例:
-
创建
math_operations.h
头文件:// math_operations.h #ifndef MATH_OPERATIONS_H #define MATH_OPERATIONS_H // 函数声明 int add(int a, int b); int subtract(int a, int b); #endif
-
创建
math_operations.c
源文件:// math_operations.c #include "math_operations.h" // 函数定义 int add(int a, int b) { return a + b; } int subtract(int a, int b) { return a - b; }
-
在主程序中使用:
// main.c #include <stdio.h> #include "math_operations.h" // 包含自定义头文件 int main() { int sum = add(3, 4); int diff = subtract(10, 5); printf("Sum: %d, Difference: %d\n", sum, diff); return 0; }
6. 递归函数
递归是指函数调用自身的编程技术。递归函数通常包含两个部分:
- 基线条件(终止条件):停止递归的条件。
- 递归条件:函数调用自身的条件。
示例:计算阶乘
// 递归计算n的阶乘
int factorial(int n) {
if (n == 0 || n == 1) { // 基线条件
return 1;
} else { // 递归条件
return n * factorial(n - 1); // 调用自身
}
}
递归执行过程(以 factorial(3)
为例):
factorial(3) → 3 * factorial(2)
→ 2 * factorial(1)
→ 1 (基线条件,返回1)
→ 2 * 1 = 2
→ 3 * 2 = 6
7. 变量的作用域
变量的作用域决定了它的可见性和生命周期。在函数中,变量分为:
- 局部变量:在函数内部定义,只能在函数内访问,函数结束后销毁。
- 全局变量:在所有函数外部定义,整个程序都能访问,生命周期为程序运行期间。
#include <stdio.h>
int global = 10; // 全局变量
void test() {
int local = 20; // 局部变量
printf("Global: %d, Local: %d\n", global, local);
}
int main() {
test(); // 输出:Global: 10, Local: 20
printf("Global: %d\n", global); // 可以访问全局变量
// printf("Local: %d\n", local); // 错误:无法访问局部变量
return 0;
}
8. 实践案例:计算数组平均值
#include <stdio.h>
// 计算数组元素的平均值
float average(int arr[], int size) {
int sum = 0;
for (int i = 0; i < size; i++) {
sum += arr[i];
}
return (float)sum / size; // 转换为浮点数避免整数除法
}
int main() {
int numbers[] = {10, 20, 30, 40, 50};
int n = sizeof(numbers) / sizeof(numbers[0]); // 计算数组长度
float avg = average(numbers, n);
printf("Average: %.2f\n", avg); // 输出:Average: 30.00
return 0;
}
9. 常见错误与注意事项
- 忘记声明或定义函数:编译器会报错“隐式声明”。
- 返回类型不匹配:确保return语句的类型与函数声明一致。
- 无限递归:忘记基线条件会导致栈溢出。
- 修改值传递的参数:函数内无法直接修改实参(需用指针,后续教程介绍)。
10. 练习题目
- 编写函数
isPrime(int n)
,判断一个数是否为素数。 - 编写函数
reverse(int n)
,反转一个整数(例如:输入123,输出321)。 - 编写函数
maxElement(int arr[], int size)
,返回数组中的最大值。
通过掌握函数,你可以将复杂程序分解为小模块,使代码更易读、易维护。多练习不同类型的函数,逐步掌握参数传递、返回值和递归等核心概念。
0 条评论
目前还没有评论...