函数
文章目录
一、函数的分类
1.库函数
- 简单的总结: C语言常用的库函数有:
IO函数
字符串操作函数
字符操作函数
内存操作函数
时间/日期函数
数学函数
其他库函数 - 学会查询工具的使用:
MSDN(Microsoft Developer Network)
www.cplusplus.com
http://en.cppreference.com(英文版)
http://zh.cppreference.com(中文版)
英文很重要。最起码得看懂文献。
2.自定义函数
- 自定义函数和库函数一样,有函数名,返回值类型和函数参数
- 易错点(参数是值传递还是值传递)
二、函数的参数, 调用,
1.函数的参数
1.1实参
- 实参可以是:常量、变量、表达式、函数等
- 无论实参是何种类型的量,在进行函数调用时,它们都必须有确定的值,以便把这些值传送给形
参
1.2形参
- 形式参数当函数调用完成之后就自动销毁了。因此形式参数只在函数中有效
- 形参实例化之后其实相当于实参的一份临时拷贝
2.函数的调用
2.1传值
- 函数的形参和实参分别占有不同内存块,对形参的修改不会影响实参
2.2传址
- 对同一个空间进行操作,
四、函数的嵌套调用和链式访问
1.嵌套调用
- 完成调用之后, 返回到函数调用处
- 函数可以嵌套调用,但是不能嵌套定义
2.链式访问
把一个函数的返回值作为另外一个函数的参数。
代码演示运行结果是什么
#include <stdio.h>
int main()
{
printf("%d", printf("%d", printf("%d", 43)));
//结果是啥?
//注:printf函数的返回值是打印在屏幕上字符的个数
return 0;
}
注意: int printf ( const char * format, ... );
表明printf的返回的是字符的个数, 类型是int
运行结果为:4321
五、函数递归(难点)
1.递归的两个必要条件
- 存在限制条件,当满足这个限制条件的时候,递归便不再继续
- 每次递归调用之后越来越接近这个限制条件
2.典例
2.1代码演示利用递归将输入的数字依次打印出来
#include <stdio.h>
print(int n)
{
int ge = n % 10;
if (n > 9)
{
print(n / 10);
}
printf("%d ", ge);
}
int main()
{
int num = 0;
scanf("%d", &num);
print(num);
}
分析:
//12345
//1234 (5)
//123 (4 5)
//12 (3 4 5)
//1 (2 3 4 5)
关键是要理解函数一层一层的进去,进去执行完会继续执行剩下来的代码,
最后回到原来的函数调用处
2.2代码演示求字符串的长度 ( 模拟实现 strlen (不创建临时变量) )->利用递归
- 创建临时变量的常规做法
#include <stdio.h>
int my_strlen(char* str)
{
//1.创建一个count作为计数器
int count = 0;
//2.当str指向的字符串中的'\0'为结束标志
while (*str != '\0') //*str 表示的是数组里面的元素内容,小细节
{
str++;
count++;
}
return count;
}
int main()
{
char arr[] = "myblueoffer";
int len = my_strlen(arr);
printf("%d\n", len);
return 0;
}
- 利用递归实现strlen
#include <stdio.h>
int my_strlen(char* str)
{
//对传过来的指针进行解引用,得到的是指针所指向地址的内容
//字符串是以'\0'结尾的,如果解引用后不是'\0',说明字符串还没有结束
if (*str != '\0')
{
return 1 + my_strlen(str + 1);
}
else
{
return 0;
}
}
int main()
{
char arr[] = "abc";
int len = my_strlen(arr);//1.把要求的字符串传过去
printf("%d\n", len);
return 0;
}
//递归的思路
//1+(bc)
//1 + 1 + (c)
//1 + 1 + 1 + (\0)
//1 + 1 + 1 + 0
2.3代码演示利用递归求n的阶乘
(不考虑溢出)
#include <stdio.h>
int fun(int num)
{
if (num <= 1)
{
return 1;
}
else
{
return num * fun(num - 1);
}
}
//假设传进来的num是5,那么进入到这个函数里面就会走
//5*fun(4)
//5*4*fun(3)
//5*4*3*fun(2)
//5*4*3*2*fun(1)
//5*4*3*2*1
//120
//最后这个fun传进来的num是1,所以走了if(num == 1)这一条分支语句,那么就直接返回了1,最后的结果就返回到了main函数里的函数调用处了
int main()
{
int num = 0;
//1.输入一个整数
printf("请输入一个整数num: \n");
scanf("%d", &num);
//2.调用函数fun,用sum接收最后的结果
int sum = fun(num);
printf("%d", sum);
}
提示:
- 许多问题是以递归的形式进行解释的,这只是因为它比非递归的形式更为清晰。
- 但是这些问题的迭代实现往往比递归实现效率更高,虽然代码的可读性稍微差些。
- 当一个问题相当复杂,难以用迭代实现时,此时递归实现的简洁性便可以补偿它所带来的运行时开
销。
总结
以上内容是对函数的简单介绍,主要是这部分的关键内容进行讲解,上述讲解的几个例题可以去试着练习一下,希望阅读完的码友能够有所收获!如果存在不足,欢迎在评论区指正!