合抱之木,生于毫末;九层之台,起于累土;千里之行,始于足下。💪🏻
【一】、调用有参函数 ⭐️
有参函数:调用函数时,需要
传对应参数
。
一、实现步骤 🌸
实现步骤:💐
- (一)、申明函数
- (二)、定义/封装函数
- (三)、调用函数
(一)、申明函数 🍭
1、一般形式 🎠
函数结果类型
函数名
(参数类型1
参数名1
,参数类型2
参数名2
, … ,参数类型n
参数名n
);
2、example1:🎈
float
max
(float
x
,float
y
); // 申明函数max
:有两个形参x
、y
(均为单精度浮点型),函数结果也是单精度浮点型
3、example2:🎈
void
max
(float
x
,float
y
); // 申明函数max
:有两个形参x
、y
(均为单精度浮点型),函数无返回值
(函数结果类型为void
)
(二)、定义/封装有参函数 🍭
1、一般形式 🎠
函数结果类型 函数名(参数类型1 参数名1, 参数类型2 参数名2, ..., 参数类型n 参数名n)
{
声明部分 ------ 声明各种变量、常量、函数等
语句部分 ------ 各表达式
(返回值) ------ 可有可无,应需求而定【无返回值时,函数结果类型为void】
}
2、注意事项 👁
- 定义/封装函数 时,必须指定
函数结果类型
(无返回值
时,类型是void
)和各形参类型
;
(三)、调用函数 🍭
1、一般形式 🎠
函数名
(参数值1
,参数值2
, … ,参数值n
);
2、注意事项 👁
- 调用函数 时,
传入的实参
需与定义/封装函数时的形参
在个数
、类型
、顺序
上保持一致; - 调用函数
传数组
时只用写数组名
就相当于把数组传过去了。
二、举例 🌸
example1:🎈
需求:有两个小组,分别有5名学生和10名学生。请编程输入这些学生的成绩,并调用一个aver函数求这两个小组的平均分。
/**
* 需求:有两个小组,分别有5名学生和10名学生。请编程输入这些学生的成绩,并调用一个aver函数求这两个小组的平均分。
*/
#include <stdio.h>
int main()
{
/** 使用变量/常量/函数前必须先声明 */
float aver(float a[], int n); // 声明函数aver:有两个形参a[](数组,数组元素为单精度浮点型)、n(数组个数,整数型),函数结果是单精度浮点型
float arr1[5], arr2[10]; // 声明两个一维数组arr1、arr2
int i;
/** 引导用户输入学生成绩 */
printf("请输入第1组的学生成绩:\n"); // 提示信息
for (i = 0; i < 5; i++)
scanf("%f", &arr1[i]); // for语句依次输入第1组学生的成绩
printf("请输入第2组的学生成绩:\n"); // 提示信息
for (i = 0; i < 10; i++)
scanf("%f", &arr2[i]); // for语句依次输入第2组学生的成绩
/** 输出结果 —— 调用函数获取到平均分 */
printf("第1组平均分是%f\n", aver(arr1, 5)); // 传数组时只用写数组名就相当于把数组传过去了
printf("第2组平均分是%f\n", aver(arr2, 10)); // 传数组时只用写数组名就相当于把数组传过去了
/** 程序正常运行结束 */
return 0;
}
/**
* 定义/封装函数:求数组元素的平均值
* @param {a[]} a[] 数组
* @param {int} n 数组个数
* @return 平均值
* */
float aver(float a[], int n)
{
/** 声明部分 */
float sum = a[0], average;
int i;
/** 语句部分 */
for (i = 1; i < n; i++) // i初始值为1:因为sum的初始值是a[0](数组里的第一个元素),所以第一个元素没必要再遍历一次了
sum += a[i];
average = sum / n; // 获取到平均值
/** 返回值 */
return (average);
}
example2:🎈
需求:请编程输入10个整数,并将这10个数由小到大排序。
/**
* 需求:请编程输入10个整数,并将这10个数由小到大排序。
*/
#include <stdio.h>
int main()
{
/** 使用变量/常量/函数前必须先声明 */
void sort(int a[], int n); // 声明函数sort:有两个形参a[](数组,数组元素为单精度浮点型)、n(数组个数,整数型),函数结果是单精度浮点型
int a[10], i;
/** 引导用户输入10个整数 */
printf("请输入10个整数:\n"); // 提示信息
for (i = 0; i < 10; i++)
scanf("%d", &a[i]); // 用户输入
/** 调用函数 —— 升序 */
sort(a, 10); // 传数组时只用写数组名就相当于把数组传过去了
/** 输出结果 */
printf("排序后的整数依次是:\n"); // 提示信息
for (i = 0; i < 10; i++)
printf("%d\t", a[i]);
printf("\n"); // 最后一个输出语句,一定要记得加上换行符(\n)
/** 程序正常运行结束 */
return 0;
}
/**
* 定义/封装函数:选择法实现升序
* @param {a[]} a[] 数组
* @param {int} n 数组个数
* @return 无返回值
* */
void sort(int a[], int n)
{
/** 声明部分 */
int i, j, t;
/** 语句部分 */
for (i = 0; i < n - 1; i++) // i初始值为1:因为sum的初始值是a[0](数组里的第一个元素),所以第一个元素没必要再遍历一次了
for (j = i + 1; j < n; j++)
if (a[i] > a[j])
{
t = a[i];
a[i] = a[j];
a[j] = t;
}
}
【二】、调用无参函数 ⭐️
无参函数:调用函数时,
不需要传对应参数
。
一、实现步骤 🌸
实现步骤:💐
- (一)、申明函数
- (二)、定义/封装函数
- (三)、调用函数
(一)、申明函数 🍭
1、一般形式 🎠
函数结果类型
函数名
();
2、example1:🎈
float
sort
(); // 申明函数sort
:不含参数,函数结果是单精度浮点型
3、example2:🎈
void
sort
(); // 申明函数sort
:不含参数,函数无返回值
(函数结果类型为void
)
(二)、定义/封装无参函数 🍭
1、一般形式 🎠
函数结果类型 函数名()
{
声明部分 ------ 声明各种变量、常量、函数等
语句部分 ------ 各表达式
(返回值) ------ 可有可无,应需求而定【无返回值时,函数结果类型为void】
}
2、注意事项 👁
- 定义/封装函数 时,必须指定
函数结果类型
(无返回值
时,类型是void
);
(三)、调用函数 🍭
1、一般形式 🎠
函数名
();
2、注意事项 👁
- 调用函数
传数组
时只用写数组名
就相当于把数组传过去了。
二、举例 🌸
下面声明 一个无返回值的无参函数 和 一个有返回值(返回值类型为字符型)的无参函数为例:
#include <stdio.h>
int main()
{
/** 使用变量/常量/函数前必须先声明 */
void output(); // 声明一个无返回值的无参函数
char get(); // 声明一个有返回值(返回值类型为字符型)的无参函数
/** 调用函数 */
output();
printf("得到一个字符:%c\n", get()); // 记得加换行符
/** 程序正常运行结束 */
return 0;
}
/**
* 定义/封装函数
*/
// 输出一句话
void output()
{
printf("冲冲冲哇~\n"); // 记得加换行符
}
// 返回一个字符
char get()
{
return 'a';
}
【三】、函数的嵌套 ⭐️
(一)、含义 🌸
函数的嵌套:
函数里面再嵌套函数
。
(二)、举例 🌸
需求:请编程输入4个整数,并找出其中最大的数。
/**
* 需求:请编程输入4个整数,并找出其中最大的数。
*/
#include <stdio.h>
int main()
{
/** 使用变量/常量/函数前必须先声明 */
int max4(int a, int b, int c, int d); // 声明函数max4:有4个形参a、b、c、d,均为整数型,函数结果也是整数型
int a, b, c, d, max;
/** 引导用户输入10个整数 */
printf("请输入4个整数(以空格隔开):\n"); // 提示信息
scanf("%d %d %d %d", &a, &b, &c, &d); // 用户输入
/** 调用函数 —— 获取4个整数里的最大值 */
max = max4(a, b, c, d);
/** 输出结果 */
printf("最大数为%d\n", max);
/** 程序正常运行结束 */
return 0;
}
/**
* 定义/封装函数:获取4个整数里的最大值
* @return 4个整数里的最大值
* */
int max4(int a, int b, int c, int d)
{
/** 声明部分 */
int max2(int a, int b); // 函数使用前必须声明
/** 返回值 */
return (max2(max2(max2(a, b), c), d)); // 函数嵌套
}
/**
* 定义/封装函数:获取2个整数里的最大值
* @return 2个整数里的最大值
* */
int max2(int a, int b)
{
/** 返回值 */
return (a > b ? a : b);
}
【四】、函数的递归 ⭐️
(一)、含义 🌸
函数的递归:
函数里面调用函数自己
。
(二)、举例 🌸
example1:🎈
#include <stdio.h>
int main()
{
/** 使用变量/常量/函数前必须先声明 */
int ageFun(int n); // 声明函数
/** 输出结果 */
printf("第5个学生的年龄为%d\n", ageFun(5));
/** 程序正常运行结束 */
return 0;
}
/**
* 定义/封装函数:计算年龄
* @param {int} n 整数
* @return 年龄
* */
int ageFun(int n)
{
int age; // 年龄
age = n == 1 ? 10 : ageFun(n - 1) + 2;
return age;
}
example2:🎈【重要】
需求 🌈:
用递归方法求n!(n的阶乘)
。
分析 📚:
- 1、
负数没有阶乘
;- 2、
0和1的阶乘为1
;
- 1! = 1 = 0! * 1;
0! = 1; 【1! = 1 = 0! * 1 👉🏻 0! = 1】- 3、
大于等于2的阶乘:
2! = 1 * 2= 1! * 2;(2)
3! = 1 * 2 * 3 = 2! * 3;(6)
4! = 1 * 2 * 3 * 4 = 3! * 4;(24)
。。。
n! = 1 * 2 * 3 * 4 * … * n-1 * n = (n-1)! * n;
规律为:n! = (n-1)! * n;
/**
* 需求:用递归方法求n!(n的阶乘)。
*/
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
int main()
{
/** 使用变量/常量/函数前必须先声明 */
unsigned long long factorial(int n); // 声明函数
int n;
/** 引导用户输入 */
printf("请输入一个正整数n:"); // 提示信息
scanf("%d", &n); // 用户输入
n < 0 ? printf("输入错误!\n") : printf("%d! = %llu\n", n, factorial(n)); // 负数没有阶乘
return 0;
}
/**
* 定义/封装函数:获取n的阶乘
* @param {int} n 整数
* @return n的阶乘
* */
unsigned long long factorial(int n)
{
if (n == 0 || n == 1)
{ // 阶乘0和1都为1
return 1;
}
else
{
unsigned long long res = factorial(n - 1); // 递归求解n-1的阶乘
// 防止溢出
// ULLONG_MAX常量是在limits标头中定义的宏常量,用于获取无符号long long int对象的最大值,它返回一个无符号long long int对象可以存储的最大值,即18446744073709551615 (在32位编译器)。
if (res > ULLONG_MAX / n)
{
printf("Error: 哦豁!我只能求%d以下滴阶乘哦~\n", n);
/**
* EXIT_FAILURE作为exit()的参数来使用,表示没有成功地执行一个程序;
* EXIT_SUCCESS作为exit()的参数来使用,表示成功地执行一个程序。
* 二者对应需引入的头文件是:#include <stdlib.h>
*/
exit(EXIT_FAILURE);
}
return res * n; // 返回n的阶乘
}
}