目录
今天我们来谈一下在C语言中函数的知识点
函数
-
库函数
C语言中常用的库函数有:IO函数,字符串操作函数,内存操作函数,时间函数,日期函数,数学函数,其他库函数,这里就不多赘述,我前面的的博客也模拟实现了很多库函数,有兴趣可以自行观看。
-
自定义函数
在自定义函数里面我们要注意,当实参传递给形参的时候,形参是实参的一份临时拷贝,对形参的操作不能改变实参。
int add(int x, int y)
{
return x + y;
}
int main()
{
int i = add(10, 20);
printf("%d\n", i);
return 0;
}
-
函数参数
实参:真是传递给函数的参数,叫做实参。实参可以是常量,变量,表达式,函数等,无论实参是何种类型的量,在进行函数调用时,他们都必须有确定的值,以便把这些值传给形参。
形参:指函数名后面括号中的变量,因为形参只有在函数被调用的过程中才实例化(分配在内存单元中),形参当函数调用完成之后就自动销毁了,因此函数只在函数中有效。
注意:实参 和 形参的名字可以相同,也可以不同。
int c = add(a+3,b);//表达式
int c = add(add(2,3),b);//函数
//这里只举较难理解的例子
-
函数传参
函数调用分为传值调用和传址调用,传址调用就是传一个地址,传值调用就是传一个值。
上面说过,形参是实参的一份临时拷贝,对形参的改变不能改变实参,但是这是针对传值调用来说的,而传址调用这种方式可以让函数和函数外边的变量建立起联系,也就是函数内部可以直接操作函数外部的变量。
int add(int *x, int y)
{
return x + y;
}
int main()
{
int a = 10;
int i = add(&a, 20);
printf("%d\n", i);
return 0;
}
我们肯定学习过数组这个概念了,(没学过的可以自己去学学)我们知道函数的传参也可以传数组,数组传参实际上传递的是数组首元素的地址,而不是整个函数的地址,所以在函数内部计算一个函数参数部分的数组的元素个数是不可行的。
int add(int* x, int y,int arr[])
{
return x + y;
}
int main()
{
int a = 10;
int arr[5] = { 0 };
int i = add(&a, 20,arr);
printf("%d\n", i);
return 0;
}
-
函数的链式访问和嵌套调用
函数可以嵌套调用(就是函数内部也可以调用函数),也可以链式访问(一个函数的返回值作为另一个函数的参数,就是链式访问),但是函数不能嵌套定义。
-
函数的声明
函数的声明就是告诉编译器有一个函数叫什么,返回类型是什么,函数的声明一般会放在头文件中(以.h为结尾) ,在实现比较大的项目时,我们一般习惯将头文件单独放在一个.h的头文件中
这样我们直接在.c文件中包含该头文件即可:#include"game.h"(这里要注意包含的格式,不是<>,而是"".)
-
函数递归
函数的递归就是程序调用自身,在于把大事化小
整体思路:在函数的内部自己调用自己(同一个函数),当不满足条件时,就在不满足条件的函数停止调用,然后执行剩下语句,执行完又回到上一次调用,直到回到第一次,然后调用结束。
条件:1 . 存在限制条件,当满足这个限制条件就停止递归。
2 . 每次递归调用之后越来越接近这个限制条件。
void unfold(char mine[ROWS][COLS], char show[ROWS][COLS], int x, int y, int* count)
{
//这里展开功能的解释:扫雷展开是要当前坐标前后左右八个坐标都没有雷时才展开,所以这里写成了if,else结构,如果当前位置附近没有雷时,才进行递归展开
int i = 0;
int j = 0;
if (1 <= x && x <= ROW && 1 <= y && y <= COL && mine[x][y] == '0' && show[x][y] == '*')//坐标合法性判断
{
if (getminecount(mine, x, y))
{
//getmincount获取坐标附近雷的个数
show[x][y] = getminecount(mine, x, y) + '0';//因为上面初始化数组时第一行第一列已经被用来打印数字了,所以就从1开始就可以
(*count)--;
//这里count也要减减
}
else
{
show[x][y] = ' ';//这里周围八个坐标都不是雷,才变成空格
(*count)--;//这里没进来一次count都要--
for (i = -1; i <= 1; i++)
{
for (j = -1; j <= 1; j++)//附近的八个坐标无非就是不变加一和减一,所以这样写递归即可
{
unfold(mine, show, x + i, y + j, count);//递归
}
}
}
}
}
这里以unfold函数递归实现扫雷展开一片的功能开展示,就不详解了,详解在之前我那个C语言实现扫雷的文章里有详细的解释,有兴趣的或者不懂的可以移步观看。