C语言---函数
文章目录
- 一、函数的概念与作用
- 二、函数的组成部分
- 三、函数的分类
- 四、函数的三要素:声明、定义、调用
- 五、参数传递:传值调用
- 六、递归函数
函数是C语言的基本构建模块,也是结构化编程的核心。它是一段为了完成特定任务而编写的、可重复使用的代码块。每个 C 程序都至少有一个函数,即主函数 main() 。
一、函数的概念与作用
1、代码复用:将一段常用的功能封装成函数,在需要的地方直接调用,避免编写重复的代码。
2、模块化:将一个复杂的大程序分解成若干个功能单一、结构清晰的小模块(函数),使得程序更易于理解、编写和维护。
3、提高可读性:通过给函数起一个见名知意的名字,可以使程序的逻辑更加清晰。
4、分工协作:在大型项目中,不同程序员可以负责编写不同的函数,从而提高开发效率。
二、函数的组成部分
一个C语言函数主要由以下几个部分构成:
// 1. 返回类型
// 2. 函数名
// 3. 参数列表
// 4. 函数体返回类型 函数名(参数列表) {// 函数体:执行具体任务的代码// ...return 返回值; // 如果返回类型不是void,则需要return语句
}
具体示例与分析
#include <stdio.h>// 函数声明(函数原型)
int add(int a, int b);// 主函数 - 程序的入口
int main() {int num1 = 5, num2 = 3;int sum;// 函数调用sum = add(num1, num2);printf("两数之和为:%d\n", sum);return 0;
}// 函数定义
// 功能:计算两个整数的和
// 返回类型:int
// 函数名:add
// 参数:两个int类型的参数 a 和 b
// 函数体:包含具体的加法运算和返回语句
int add(int a, int b) {int result;result = a + b;return result; // 将结果返回给调用者
}
三、函数的分类
- 从定义角度分
库函数:由C语言标准库(如 stdio.h, math.h, string.h)提供的,可以直接调用的函数。例如 printf(), scanf(), sqrt()。
用户自定义函数:由程序员根据需求自己编写的函数。例如上面例子中的 add() 函数。
2. 从参数和返回值分
无参数无返回值
void sayHello() {printf("Hello, World!\n");// 无return语句,或使用 return; (不返回任何值)
}
有参数无返回值
void printStar(int n) {for(int i = 0; i < n; i++) {printf("*");}printf("\n");
}
无参数有返回值
int getNumber() {int num;printf("请输入一个数字:");scanf("%d", &num);return num;
}
有参数有返回值
int findMax(int x, int y) {return (x > y) ? x : y; // 使用条件运算符
}
四、函数的三要素:声明、定义、调用
1、函数声明(函数原型)
作用:告诉编译器函数的名称、返回类型和参数列表。这样编译器在遇到函数调用时,就知道如何检查调用的正确性。
格式:返回类型 函数名(参数类型列表);
注意:参数名在声明中是可选的,但类型必须写明。int add(int, int); 也是合法的声明。
位置:通常在源文件的开始处或头文件(.h)中。
2、函数定义
作用:包含函数实际的代码实现。
格式:即上面介绍的完整格式,包含函数体。
3、函数调用
作用:在程序中使用函数的功能。
格式:函数名(实际参数);
过程:
程序执行到函数调用时,会暂停当前函数。
将实际参数的值传递给函数定义中的形式参数。
执行被调用函数的函数体。
遇到 return 语句或函数体执行完毕后,将返回值(如果有)交还给调用者,并回到调用处继续执行。
五、参数传递:传值调用
C语言默认采用的是传值调用。
核心思想:将实际参数的值复制一份传递给函数的形式参数。
重要影响:在函数内部修改形式参数的值,不会影响函数外部的实际参数。
#include <stdio.h>void swap(int x, int y) { // x和y是形式参数int temp;temp = x;x = y;y = temp;printf("函数内交换后:x = %d, y = %d\n", x, y);
}int main() {int a = 10, b = 20;printf("交换前:a = %d, b = %d\n", a, b);swap(a, b); // a和b是实际参数printf("交换后:a = %d, b = %d\n", a, b); // a和b的值并未改变!return 0;
}
输出:
交换前:a = 10, b = 20
函数内交换后:x = 20, y = 10
交换后:a = 10, b = 20
解释:swap 函数交换的只是它自己内部的副本 x 和 y,而原始的 a 和 b 保持不变。
六、递归函数
一个函数在它的函数体内直接或间接地调用它自身,称为递归调用。
核心思想:将一个大问题分解为一个或多个与原问题相似但规模更小的子问题。
必要条件:
- 递归出口:必须有一个明确的结束条件,防止无限递归。
- 递归体:递归调用语句,并且每次调用都应向递归出口靠近。
经典例子:计算阶乘 n!
#include <stdio.h>long factorial(int n) {if (n == 0 || n == 1) { // 1. 递归出口return 1;} else {return n * factorial(n - 1); // 2. 递归体,问题规模n在减小}
}int main() {int num = 5;printf("%d的阶乘是%ld\n", num, factorial(num));return 0;
}
输出:
5的阶乘是120