✨前言✨
🎓作者:【 教主 】
📜文章推荐:
☕博主水平有限,如有错误,恳请斧正。
📌机会总是留给有准备的人,越努力,越幸运!
💦导航助手💦
目录
函数是什么?
通俗来讲,函数就像是一个加工厂,这个加工厂独立于其他部分,这个加工厂会完成你交给他的任务,得到你需要的结果。
按照定义来讲:函数是完成特定任务的独立程序代码单元。
函数的组成和调用
函数由 返回类型 函数名 参数 以及代码体组成。
函数调用时需要用到函数调用操作符,即在函数名后面加上()。
举个例子,现在我需要一个实现一个add函数来计算两个整数相加,并且得到最终的结果。
代码如下:
#include<stdio.h>
int add(int x, int y)
{
return x + y;
}
int main()
{
int a = 1;
int b = 3;
int result = add(a, b);
printf("%d", result);
return 0;
}
下面我们来分析一下:
这部分就是函数的定义部分
因为我需要实现两个数相加并且返回结果,所以我需要把这两个数传给这个函数,函数完成工作后要把结果返回给我。通俗来说,我需要加工厂把这些零件加工成我需要的产品,最后把产品给我。
返回类型是int 类型,因为我需要相加两个整数,最后返回结果,而结果是int 类型,所以返回类型就是int 类型
形式参数要声明类型并且和实际参数要做到一一对应,实际参数第一个参数传过去了a,那么形式参数第一个就要接收a,因为a的类型是整形,所以要在形式参数表里声明类型,这里x的值就是a的值,y的值就是b的值。
return 后面的就是最终需要返回的结果,而在主函数中,我创建了一个int 类型的result 来接收结果,最终打印出结果。
运行结果如下:
返回类型和参数表为空的函数:
#include<stdio.h>
void print()
{
printf("调用该函数\n");
}
int main()
{
print();
return 0;
}
这里的void 就是空的意思,意思就是不需要函数返回。
在print函数中,既没有给它传参,也不需要它返回什么,只需要它打印一下,可能你在有些代码中见过在函数定义时形参表里写void ,就像这样void print(void),这样写和上述代码效果是一样的。
函数只有调用时才会起作用,如果不调用函数就不会起作用。
举个例子,代码如下:
#include<stdio.h>
void print()
{
printf("调用print()函数\n");
}
void test()
{
printf("调用test()函数\n");
}
int main()
{
print();
return 0;
}
main()函数是程序的入口和出口,main()函数里面用到什么就会运行什么,如果没有用就不会调用。上述代码中main()函数里面只调用了print()函数,并没有调用test()函数,所以test()函数是不会执行的。
运行结果如下:
函数的声明
函数一定要满足:先声明,后使用.
什么意思呢?就拿上面这段代码举个例子,如果我把print()函数和main()函数换个位置,让print()函数在main()函数的下面,结果还会是这样吗?
代码如下:
#include<stdio.h>
int main()
{
print();
return 0;
}
void print()
{
printf("调用print()函数\n");
}
有人可能会想,这有什么区别?
到底会是什么样的结果呢?我们运行一下来看
嘶~好像出错了,编译器报了个错误,错误如下:
未定义?可是我们不是把这个函数原原本本的写出来了吗?为什么会这样?
函数的调用一定要满足:先声明,后使用
在main()函数调用print()函数之前,一直没有出现过print()函数的影子,突然冒出来一个print()函数,编译器也反应不过来,不知道怎么办,编译器必须见过函数后,函数才可以使用,怎么实现呢?
有两种解决方法,一种就像原来一样,把print()函数放在main()函数之前,只要编译器见过它,就可以使用,否则不认账。
还有一种方法就像这样写,但是在main()函数之前要声明一下。
代码如下:
#include<stdio.h>
void print();
int main()
{
print();
return 0;
}
void print()
{
printf("调用print()函数\n");
}
运行结果如下
这是没有参数的函数,我们来看看有参数的函数有哪些写法。
代码如下:
#include<stdio.h>
int add(int x, int y);
int main()
{
int a = 3;
int b = 5;
int result = add(a, b);
printf("%d", result);
}
int add(int x, int y)
{
return x + y;
}
运行结果如下:
这里函数的声明部分int add(int x,int y);有很多种写法
可以写成 int add(int ,int);只需要声明参数的类型
还可以写成int add(int a,int b);声明部分的参数名和函数实现部分的参数名可以不一样。
传值调用和传址调用
- 传值调用:形参只是实参的拷贝,形参的变化不会对实参产生影响。
- 传值调用:通过地址找到实参,直接对实参进行操作。
举个例子,如果我想实现两个整数的交换,怎么设计一个函数来实现呢?
我们可以这样,再创建第三个变量,把第一个变量的值赋给第三个变量,再把第二个变量的值赋给第一个变量,再把第三个变量的值赋给第二个变量,就可以实现交换。
代码如下:
#include<stdio.h>
void swap(int x, int y)
{
int temp = x;
x = y;
y = temp;
}
int main()
{
int a = 3;
int b = 5;
swap(a, b);
printf("%d %d", a, b);
return 0;
}
如果可以实现,那么a=5,b=3。结果是不是这样呢?
运行结果如下:
好像并没有交换,这就是因为采用的是传值调用,实参a和b根本没有变化。如果想实现这个功能,就要采用传址调用,直接对a,b进行操作。
代码如下:
#include<stdio.h>
void swap(int* pa, int* pb)
{
int temp = *pa;
*pa = *pb;
*pb = temp;
}
int main()
{
int a = 3;
int b = 5;
swap(&a, &b);
printf("%d %d", a, b);
return 0;
}
运行结果如下:
递归
递归就是函数自己调用自己。
讲个故事什么是递归:从前有座山,山里有座庙,庙里老和尚给小和尚讲了个故事:从前有座山,山里有座庙,庙里老和尚给小和尚讲了个故事:从前有座山,山里有座庙,庙里老和尚给小和尚讲了个故事:从前有座山……
这个故事什么时候可以讲完,谁也不知道,递归和这个类似,但是递归必须有故事讲完的一次。这就是递归不再进行的条件。
递归分为为两个部分,可以从名字来理解:递出去,归回来。
举个递归的例子:我想要打印一个整数的各位上的数,比如说1234,打印出来就是1 2 3 4 ,如何实现呢?
递归代码如下:
#include<stdio.h>
void print(int num)
{
if (num > 10)
print(num / 10);
printf("%d ", num%10);
}
int main()
{
print(1234);
return 0;
}
递归如下图:
递归递归,先递后归。绿色箭头是递,红色箭头是归。
过程:1234>10,满足条件,进入print(),后面的打印还没有开始执行,123>10,满足条件,进入print(),如此循环,一直到传进去的是1的时候,不满足再递归的条件,这时候就执行下面的printf()函数,打印出1,调用完成这一次的print()函数,哪里回来的回哪去,回到上一次的print()函数,上一次的print()函数的num是12,打印出2,再回到上一次的print()函数,直至回到第一个print()函数,递归完成。
//递归对于一些问题能够提供非常简单的解决办法,但是递归回占用大量的内存,执行效率很低,不建议使用,而且递归代码的可读性非常低,令人费解,还是少用为妙。
欢迎关注,码字不易,希望多多点赞、收藏哦!抱拳了。