1. 函数的基本概念与用途
- 函数是 C 语言程序的基本构建块。它将一个大型程序分解为较小的、可管理的部分,每个部分负责特定的任务,这样可以提高代码的可读性、可维护性和可复用性。例如,在一个涉及数学计算、输入输出处理和数据存储的复杂程序中,可以分别使用不同的函数来处理这些任务。
- 从程序执行的角度看,函数是一段独立的代码序列,当被调用时,程序的控制权转移到函数内部,函数执行完其任务后,控制权又返回给调用它的位置。
2. 函数的定义
语法格式:
返回类型 函数名(参数列表) {函数体(变量定义、语句等);return 返回值;
}
- 返回类型:可以是基本数据类型(如int、float、char等),也可以是指针类型、结构体类型或void(表示无返回值)。例如,int表示函数返回一个整数,void表示函数不返回任何有意义的值。
- 函数名:是一个标识符,用于在程序中唯一标识这个函数,命名规则遵循 C 语言标识符的命名规则(以字母或下划线开头,后面可以跟字母、数字或下划线)。
- 参数列表:包含零个或多个参数,参数之间用逗号分隔。参数由参数类型和参数名组成,例如(int a, int b),表示函数接受两个整数类型的参数a和b。参数的作用是向函数内部传递数据。
- 函数体:是花括号内的部分,用于实现函数的具体功能。函数体中可以包含变量定义、表达式语句、控制流语句(如if - else、for、while等)等。
- 返回值:如果函数的返回类型不是void,则函数体中必须包含return语句来返回一个与返回类型匹配的值。例如,对于返回类型为int的函数,return语句后应该跟一个整数表达式。return语句的作用是将函数的执行结果传递回调用者,并结束函数的执行。
3. 函数的参数传递机制
- 值传递:
这是 C 语言中最基本的参数传递方式。当函数被调用时,实参的值被复制一份传递给形参。例如:
void swap(int a, int b) {int temp = a;a = b;b = temp;
}
int main() {int x = 3, y = 5;swap(x, y);printf("x = %d, y = %d\n", x, y);return 0;
}
在这个例子中,swap函数试图交换a和b的值,但由于是值传递,swap函数内部的a和b是x和y的副本,所以在swap函数执行完后,x和y的值并没有改变。
- 指针传递:
通过传递变量的地址来实现参数传递。这样,函数内部可以通过指针间接访问和修改调用者传入的变量的值。例如:
void swap(int *a, int *b) {int temp = *a;*a = *b;*b = temp;
}
int main() {int x = 3, y = 5;swap(&x, &y);printf("x = %d, y = %d\n", x, y);return 0;
}
这里swap函数的参数是指针类型,在调用swap函数时,传入x和y的地址(&x和&y)。函数内部通过解引用指针(a和b)来访问和交换x和y的值。
4. 函数的调用
- 调用方式:在 C 语言中,函数调用是通过函数名和实参列表来实现的。例如,对于一个已定义的函数
int add(int a, int b),可以在另一个函数(如main函数)中这样调用:
int result = add(3, 4);
这里3和4是实参,它们按照参数列表的顺序传递给add函数的形参a和b。
- 调用顺序:函数调用的执行顺序是先计算实参表达式的值,然后将这些值传递给被调用函数的形参,接着执行被调用函数的函数体,最后根据函数的返回类型返回结果(如果返回类型是void,则直接返回,不返回具体的值)。
- 嵌套调用:C 语言允许函数的嵌套调用,即一个函数在其函数体内部可以调用其他函数。例如:
int square(int x) {return x * x;
}
int cube(int x) {return square(x) * x;
}
int main() {int num = 3;int result = cube(num);printf("结果是:%d\n", result);return 0;
}
在这个例子中,cube函数内部调用了square函数,这种嵌套调用可以构建复杂的程序逻辑。
5. 函数声明与原型
- 函数声明:
函数声明用于向编译器提供函数的基本信息,包括函数名、返回类型和参数列表等,以便编译器在遇到函数调用时能够正确地处理。函数声明的语法格式与函数头相似,但末尾需要加上分号。例如:
int add(int a, int b);
函数声明的主要作用是让编译器在编译程序时知道函数的参数和返回类型,从而进行类型检查等操作。如果没有函数声明,编译器可能会发出警告或错误,尤其是在隐式函数声明的情况下(这种情况可能导致程序运行时出现意外的结果)。
- 函数原型:
函数原型是一种完整的函数声明形式,它包括函数的返回类型、函数名和参数列表。函数原型通常放在头文件中,供多个源文件引用。例如,假设有一个名为math_functions.h的头文件,其中包含函数原型:
#ifndef MATH_FUNCTIONS_H
#define MATH_FUNCTIONS_H
int add(int a, int b);
int subtract(int a, int b);
#endif
然后在其他源文件中可以通过
#include "math_functions.h"
来引用这些函数原型,从而正确地调用相关函数。
6. 函数的递归
- 定义与原理:函数递归是指一个函数在其函数体内部直接或间接地调用自身。递归函数通常有一个或多个递归终止条件,当满足这些条件时,递归停止。例如,计算阶乘的函数可以用递归实现:
int factorial(int n) {if (n == 0 || n == 1) {return 1;} else {return n * factorial(n - 1);}
}
在这个例子中,factorial函数计算n的阶乘。当n为 0 或 1 时,函数返回 1(这是递归终止条件);当n大于 1 时,函数通过调用自身factorial(n - 1)来计算n的阶乘。
- 注意事项:在使用递归时,需要注意递归深度,因为每次递归调用都会在栈上分配空间。如果递归深度过深,可能会导致栈溢出(Stack Overflow)错误。同时,递归函数的效率可能不如循环实现的相同功能的函数,因为递归涉及函数调用的开销。
7.案例
以下是一个案例,展示如何使用函数实现一个简单的学生成绩管理系统,包括录入成绩、计算平均分、查找最高分和最低分等功能。
#include <stdio.h>
#include <windows.h>// 函数声明
void inputScores(int scores[], int size);
void displayScores(int scores[], int size);
float calculateAverage(int scores[], int size);
int findMaxScore(int scores[], int size);
int findMinScore(int scores[], int size);int main() {int n;int scores[n]; // 用于存储学生成绩SetConsoleOutputCP(65001);// 输入学生人数printf("请输入学生人数:");scanf("%d", &n);if (n <= 0) {printf("学生人数必须大于0!\n");return 1;}// 调用函数实现功能inputScores(scores, n); // 输入成绩displayScores(scores, n); // 显示成绩printf("平均成绩:%.2f\n", calculateAverage(scores, n)); // 计算平均分printf("最高成绩:%d\n", findMaxScore(scores, n)); // 查找最高分printf("最低成绩:%d\n", findMinScore(scores, n)); // 查找最低分return 0;
}// 函数定义// 输入学生成绩
void inputScores(int scores[], int size) {for (int i = 0; i < size; i++) {printf("请输入第 %d 位学生的成绩:", i + 1);scanf("%d", &scores[i]);}
}// 显示学生成绩
void displayScores(int scores[], int size) {printf("学生成绩为:");for (int i = 0; i < size; i++) {printf("%d ", scores[i]);}printf("\n");
}// 计算平均分
float calculateAverage(int scores[], int size) {int sum = 0;for (int i = 0; i < size; i++) {sum += scores[i];}return (float)sum / size;
}// 查找最高分
int findMaxScore(int scores[], int size) {int max = scores[0];for (int i = 1; i < size; i++) {if (scores[i] > max) {max = scores[i];}}return max;
}// 查找最低分
int findMinScore(int scores[], int size) {int min = scores[0];for (int i = 1; i < size; i++) {if (scores[i] < min) {min = scores[i];}}return min;
}
-
功能说明
- 录入成绩:
用户输入每位学生的成绩并存储在数组中。 - 显示成绩:
输出所有学生的成绩。 - 计算平均分:
求出所有学生成绩的平均值。 - 查找最高分:
遍历数组找到最高的成绩。 - 查找最低分:
遍历数组找到最低的成绩。
- 录入成绩:
-
编译并运行