每天进步一点点,希望的火苗不熄灭。
目录
一、函数的概念
函数是由一个或多个语句块组成的,负责完成某种特定的功能,是一段可以重复使用的代码,相较于其他的代码具有一定的独立性。
二、函数的分类
从定义的角度看:将C语言函数分为库函数(可以直接调用的函数)和自定义函数(程序员自己编写的函数)
三、库函数的使用
1.使用库函数的必备工具:
法一:我们可以在下方网站上进行库函数的学习https://cplusplus.com/reference/
法二:下载MSDN软件
2.使用库函数的方法:
我们在使用一个库函数之前首先要知道它的功能,下面我将带着大家一起来学习使用库函数的方法。
eg:以MSDN工具为例,假如我们要使用的是strlen函数
我们首先打开MSDN工具,然后点击标号1的索引处,最后在标号2的搜索框里输入我们要学习的“strlen”,回车后我们就可以看到标号3处strlen的具体实现。
下面我们一起来分析下这个库函数:
- 标号1处表示的这个函数的返回类型size_t表示的是字节数,不同于这个函数其他函数的返回类型有(int 、void、char*等)int表返回的类型为一个int型数据、void表示没有返回值、char*表返回值为一个char*类型的指针,关于这个问题大家下去可以慢慢研究;
- 标号2处表示这个函数的参数,(const char* string)表示这边传入的是一个不可被修改的字符串,如果是()则表示无参;
- 标号3处表示使用这个库函数需要在文件开头加上对应的头文件 #include <xxxxx>;
- return value:是对这个函数返回内容的具体说明;
- parameter:是对这个函数的参数的具体说明。
四、自定义函数的使用
1.自定义函数的组成:
ret_type fun_name(para1, para2 )
{
statement;//语句项
}
ret_type 返回类型
fun_name 函数名
para1 函数参数
注意:我们的返回类型可以是void、int、char、char*等,参数类型也可以是void、int、char*等等任意类型,参数不止两个可以是多个。
五、函数的参数:
函数的参数分为实际参数(实参)和形式参数(形参);
实际参数(实参):真实传给函数的参数,叫实参。实参可以是:常量、变量、表达式、函数等。无论实参是何种类型的量,在进行函数调用时,它们都必须有确定的值,以便把这些值传送给形参。形式参数(形参):形式参数是指函数名后括号中的变量,因为形式参数只有在函数被调用的过程中才实例化(分配 内存单元),所以叫形式参数。形式参数当函数调用完成之后就自动销毁了。因此形式参数只在函数中有效。
eg:在下面这个代码中a、b是实参,x、y是形参
#include <stdio.h>
int add(int x,int y)
{
return x+y;
}
int main()
{
int a=5;
int b=3;
int c=add(a,b);
return 0;
}
六、函数的调用:
函数的调用分为传值调用和传址调用;
传值调用 : 函数的形参和实参分别占有不同内存块,对形参的修改不会影响实参。传址调用 : 传址调用是把函数外部创建变量的内存地址传递给函数参数的一种调用函数的方式。这种传参方式可以让函数和函数外边的变量建立起正真的联系,也就是函数内部可以直接操 作函数外部的变量。
七、函数的嵌套调用和链式访问 :
1.嵌套调用:在一个函数内部调用另一个函数;
eg:下方一个程序从main()函数进入,然后调用three_line()函数,在three_lline()函数内部通过循环调用new_line()函数,完成屏幕上打印三行hehe的功能。
#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;
}
2.链式访问:把一个函数的返回值作为另外一个函数的参数。
eg:在下面程序中我们首先利用strcat()函数完成了在arr数组后面(hello后面)添加“word”的功能,然后将其返回值作为strlen()的参数完成计算总字符(helloword)个数的功能形成了函数的链式访问。
#include <stdio.h>
#include <string.h>
int main()
{
char arr[20] = "hello";
int ret=strlen(strcat(arr,"word"));
printf("%d\n", ret);
return0;
}
八、函数的声明和定义:
1.函数声明:
- 告诉编译器有一个函数叫什么,参数是什么,返回类型是什么。但是具体是不是存在,无关紧要。
- 函数的声明一般出现在函数的使用之前。要满足先声明后使用。
- 函数的声明一般要放在头文件中的。
2.函数定义:
- 函数的定义是指函数的具体实现,交待函数的功能实现。
//函数声明
int add(int x,int y);
//函数定义
int add(int x,int y)
{
int c=x+y;
return c;
}
3.文件的书写形式:
在上述函数声明和函数定义中,我们若把函数声明部分放在创建的一个头文件中(test.h),函数定义放在创建的一个源文件中(test.c),并且在(test.c)文件的顶部加上一行 #include "test.h" 的代码那就可以在(test.c)文件中使用此函数,这种书写方式称为分文件的书写形式。
九、函数递归:
1.递归的定义
程序调用自身的编程技巧称为递归( recursion)。通常把一个大型复杂的问题层层转化为一个与原问题相似的规模较小的问题来求解,只需少量的程序就可描述出解题过程所需要的多次重复计算,大大地减少了程序的代码量。递归的主要思考方式在于:把大事化小
2. 递归的两个必要条件
- 存在限制条件,当满足这个限制条件的时候,递归便不再继续。
- 每次递归调用之后越来越接近这个限制条件。
3.递归的缺点
递归思想能够帮助我们将一个大的问题分解为小的问题,有利于我们对问题的解决,但它也存在一定的弊端。
eg:我们要完成计算6!
在此过程中我们很容易看到有很多数其实完成了多次计算,造成了计算的冗余。在遇到大规模问题要用递归求解的话,那么肯定是需要大量时间的。