1、C语言中函数的分类
1.1 库函数
使用库函数,必须包含 #include 对应的头文件。
在哪里查?:
Reference - C++ Reference (cplusplus.com)
1.2 自定义函数
2、函数的嵌套调用和链式访问
2.1 嵌套调用
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;
}
函数可以嵌套调用,但是不能嵌套定义。
2.2 链式访问
把一个函数的返回值作为另外一个函数的参数。
#include <stdio.h>
#include <string.h>
int main()
{
int len = strlen("abcdef");
printf("%d\n", len);
//链式访问
printf("%d\n", strlen("abcdef"));
return 0;
}
#include <stdio.h>
int main()
{
printf("%d", printf("%d", printf("%d", 43)));//输出结果:4321
printf("%d ", printf("%d ", printf("%d ", 43)));//输出结果:43 3 2
//注:printf函数的返回值是打印在屏幕上字符的个数,
//printf函数作为printf函数的参数时自己也会打印
return 0;
}
3、函数的声明和定义
3.1 函数声明
告诉编译器有一个函数叫什么,参数是什么,返回类型是什么。但是具体是不是存在,函数声明决定不了。
函数的声明一般出现在函数的使用之前。要满足先声明后使用。
函数的声明一般要放在头文件中的
3.2 函数定义
//函数声明
//int Add(int, int);
int Add(int x, int y);
int main()
{
int a = 0;
int b = 0;
scanf("%d %d", &a, &b);
int c = Add(a, b);//函数调用
printf("%d\n", c);
return 0;
}
//函数的定义
int Add(int x, int y)
{
return x + y;
}
4、函数递归
4.1 函数递归的两个必要条件
-
存在限制条件,当满足这个限制条件的时候,递归便不再继续
-
每次递归调用之后越来越接近这个限制条件
4.2 练习
4.2.1 接受一个整型值(无符号),按照顺序打印它的每一位。
例如:输入:1234,输出:1 2 3 4
void print(int n)
{
if (n == 0)
return;
print(n / 10);
printf("%d ", n % 10);
}
int main()
{
int num = 1234;
print(num);
return 0;
}
4.2.2 编写函数不允许创建临时变量,求字符串的长度。
int Strlen(char* s)
{
if (*s == '\0')
return 0;
else
return 1 + Strlen(s + 1);
}
int main()
{
char* str = "abcdef";
int ret = Strlen(str);
printf("%d\n", ret);
return 0;
}
4.3 递归与迭代
4.3.1 求n的阶乘。(不考虑溢出)
//迭代(循环)
//int Fac(int n)
//{
// int ret = 1;
// for (int i = 1; i <= n; i++)
// {
// ret *= i;
// }
// return ret;
//}
//递归
int Fac(int n)
{
if (n <= 1)
return 1;
else
return n * Fac(n - 1);
}
int main()
{
int n = 5;
int ret = Fac(n);
printf("%d\n", ret);
return 0;
}
4.3.2 求第n个斐波那契数。(不考虑溢出)
//递归
int count = 0;
int Fib(int n)
{
if (n == 3)
count++;
if (n <= 2)
return 1;
else
return Fib(n - 1) + Fib(n - 2);
}
int main()
{
int n = 0;
scanf("%d", &n);
int ret = Fib(n);
printf("%d\n", ret);
printf("count = %d\n", count);
return 0;
}
-
使用 fib 这个函数的时候如果我们要计算第50个斐波那契数字的时候特别耗费时间。
那我们如何改进呢?
-
系统分配给程序的栈空间是有限的,但是如果出现了死循环,或者(死递归),这样有可能导致一直开辟栈空间,最终产生栈空间耗尽的情况,这样的现象我们称为栈溢出。
那如何解决上述的问题:
将递归改写成非递归
//迭代
int Fib(int n)
{
int a = 1;
int b = 1;
int c = 1;
while (n >= 3)
{
c = a + b;
a = b;
b = c;
n--;
}
return c;
}
int main()
{
int n = 0;
scanf("%d", &n);
int ret = Fib(n);
printf("%d\n", ret);
//printf("count = %d\n", count);
return 0;
}