- 函数的嵌套调用和链式访问
- 函数的声明和定义
- 函数递归
1. 函数的嵌套调用和链式访问
函数和函数之间可以根据实际的需求进行组合的,也就是互相调用的。
1.1嵌套调用
int main()
{
int num = 0;
//调用函数,使得num每次增加1
return 0;
}
#include <stdio.h>
void new_line()
{
printf("hehe\n");
}
void three_line()
{
int i = 0;
for(i=0; i<3; i++)
{
new_line();
}
}
int main()
{
three_line();
return 0;
}
函数可以嵌套调用,但是不能嵌套定义。
函数的返回类型不写的时候,默认是返回的是int类型
test(void)
{
printf("hehe\n");
}
1.2 链式访问
把一个函数的返回值作为另外一个函数的参数。
代码1:
int main()
{
int len = strlen("abcdef");
printf("%d\n", strlen("abcdef"));//链式访问
return 0;
}
代码2:
int main()
{
printf("%d", printf("%d", printf("%d", 43)));//链式访问
return 0;
}
printf函数返回的是打印在屏幕上字符的个数。
结果为:4 3 2 1
2.函数的声明和定义
2.1 函数声明:
- 告诉编译器有一个函数叫什么,参数是什么,返回类型是什么。但是具体是不是存在,函数
声明决定不了。 - 函数的声明一般出现在函数的使用之前。要满足先声明后使用。
- 函数的声明一般要放在头文件中的。
//函数的声明
int Add(int x, int y);
int main()
{
int a = 0;
int b = 0;
scanf("%d %d", &a, &b);
//求和
int ret = Add(a, b);
printf("%d\n", ret);
return 0;
}
//函数的定义
//函数的定义也是一种特殊的声明
int Add(int x, int y)
{
return x + y;
}
2.2 函数定义:
函数的定义是指函数的具体实现,交待函数的功能实现。
变量的声明:
//变量的声明
int g_val;
int main()
{
printf("g_val = %d\n", g_val);
return 0;
}
变量的定义:
//变量的定义
int g_val = 2022;
int g_val;
int main()
{
printf("g_val = %d\n", g_val);
return 0;
}
定义
int val;
全局变量不初始化的时候,默认是0
int main()
{
printf("%d\n", val);
return 0;
}
3. 函数递归
3.1 什么是递归?
程序调用自身的编程技巧称为递归( recursion)。
递归做为一种算法在程序设计语言中广泛应用。 一个过程或函数在其定义或说明中有直接或间接
调用自身的
一种方法,它通常把一个大型复杂的问题层层转化为一个与原问题相似的规模较小的问题来求解,
递归策略
只需少量的程序就可描述出解题过程所需要的多次重复计算,大大地减少了程序的代码量。
递归的主要思考方式在于:把大事化小
简单的递归程序:
int main()
{
printf("hehe\n");
main();
return 0;
}
3.2 递归的两个必要条件
存在限制条件,当满足这个限制条件的时候,递归便不再继续。
每次递归调用之后越来越接近这个限制条件。
3.2.1 练习1:(画图讲解)
接受一个整型值(无符号),按照顺序打印它的每一位。
例如:
输入:1234,输出 1 2 3 4
//正常解答:
void Print(unsigned int n)
{
while (n)
{
printf("%d ", n % 10);
n = n / 10;
}
}
int main()
{
unsigned int num = 0;
scanf("%u", &num);
//写一个函数打印num的每一位
Print(num);
return 0;
}
//递归方法:
void Print(unsigned int n)
{
if (n > 9)
{
Print(n/10);
}
printf("%d ", n % 10);
}
int main()
{
unsigned int num = 0;
scanf("%u", &num);
//写一个函数打印num的每一位
Print(num);
return 0;
}
3.2.2 练习2:(画图讲解)
编写函数不允许创建临时变量,求字符串的长度。
#include <string.h>
模拟实现strlen
//正常解答:
int my_strlen(char* str)
{
int count = 0;
while (*str != '\0')
{
count++;
str++;//字符指针+1,向后跳1个字符
}
return count;
}
//递归方法:
int my_strlen(char* str)
{
if (*str != '\0')
return 1 + my_strlen(str + 1);
else
return 0;
}
int main()
{
char arr[] = "bit";
//[b i t \0]
//数组名其实是数组首元素的地址
//
int len = my_strlen(arr);
printf("%d\n", len);
return 0;
}
3.2.3练习3:(画图讲解)
求n的阶乘。(不考虑溢出)
参考代码:
阶乘的概念及背景:
概念:
一个正整数的阶乘(factorial)是所有小于及等于该数的正整数的积,并且0的阶乘为1。自然数n的阶乘写作n!。
阶乘的计算方法:
任何大于等于1 的自然数n 阶乘表示方法:
n!=1×2×3×…×(n-1)×n 或 n!=n×(n-1)!
注意:0的阶乘为1,即 0!=1。
1! = 1
2! = 2 * 1 = 2
3! = 3 * 2 * 1 = 6
…
n! = n * (n-1) *… * 2 * 1
//非递归
#include<stdio.h>
int main()
{
int n;
scanf("%d", &n);
int fact = 1;
int i;
for (i = 1; i <= n; i++)
{
fact *= i;
}
printf("%d\n", fact);
return 0;
}
//递归
#include <stdio.h>
int Fact(int n) //递归函数
{
int res = n;
if (n > 1)
res = res * Fact(n - 1);
return res;
}
int main() //主函数
{
int n, cnt;
scanf("%d", &n);
cnt = Fact(n);
printf("%d\n", cnt);
return 0;
}
3.3.4 练习4:
求第n个斐波那契数。(不考虑溢出)
参考代码:
#include<stdio.h>
int myt(int n)
{
if (n <= 2)
return 1;
else
return myt(n - 1) + myt(n - 2);
}
int main()
{
int n = 0;
scanf("%d", &n);
int ret=myt(n);
printf("%d\n", ret);
return 0;
}
斐波那契数列是一组第一位和第二位为1,从第三位开始,后一位是前两位和的一组递增数列,
像这样的:1、1、2、3、5、8、13、21、34、55…