C语言函数详解(入门到进阶)
Posted 攻城狮白玉
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C语言函数详解(入门到进阶)相关的知识,希望对你有一定的参考价值。
目录
前言
最近帮家里的小朋友整理一些学习C语言的知识点
有整体入门基础文章——【C语言】拯救新手,半小时从零到一认识C语言基础
C语言数据类型的详解——【C语言】数据类型一文详解
变量和赋值的详解——【C语言】变量及赋值
指针和数组关系——【C语言】小妹不懂指针和数组的关系?那就安排指针数组关系详解
问了小妹她C语言还有哪些不懂得,提到了函数的应用,那么就安排函数的详解。
一、什么是函数
函数是由一系列语句组合而成的,是一组语句的封装。函数的使用可以让我们避免重复的代码编写,让我们的程序更加的模块化。
其实,咱们从接触C语言开始的时候,就已经接触了函数了。每个C语言程序至少会有一个函数,那就是main()函数。main()函数是C语言程序的入口。除了main()函数,咱们在输出的控制台信息的时候用到的printf()也是一个函数。
函数还有很多叫法,比如方法、子例程或程序,等等。
二、函数的构成
函数是由函数类型,函数名,形参列表,函数主体这几部分构成的。
函数类型 函数名(形参列表){
函数主体;
}
- 函数类型,决定了函数最后return的返回值类型,比如是int型函数,那么在函数体里面要用return返回int型的值,如果是char型函数,则返回char型的值。如果不需要返回值的话,则函数类型写为void
- 函数名,是我们在调用函数时使用的,就跟变量名一个道理
- 参数列表,咱们在调用函数时,往函数里面传入的参数,这里的参数是可有可无的,写在函数定义的参数列表的参数叫做形式参数(形参),当我们调用函数的时候,填入的叫实际参数(实参)
- 函数主体,用花括弧{}括起来的,包含所有组成函数的语句。如果函数不是void型的,则函数主体里面要有return语句返回对应类型的值
三、函数的调用和声明
函数的调用方式:
函数名(实参列表);
这里的实参列表,可以是变量(包括普通变量和指针变量),常量,表达式,函数等。实参列表里多个实参之间用逗号【,】来隔开。当定义函数时没有形参列表,则在调用函数的时候也不用传入实参。
在咱们最熟悉的输出语句printf()就是函数的调用,例如
char str[] = "Hello Baiyu";
printf("%s\\n",str);//调用printf()函数,里面的"%s\\n",str就是实际参数
- “%s\\n”这个是常量
- str这个是字符串变量
下面用代码演示一下函数的定义、以及几种函数的调用形式:
#include<stdio.h>
//此处定义一个比较两个数取最大值函数
int max(int x, int y) {
if (x > y) {
return x;
}
else {
return y;
}
}
//定义一个无返回值类型的函数,用于调用max()函数输出最大值
void output(){
int i_baiyu = 10;
int i_zhh = 20;
// 函数作为表达式的一部分
int i_max = max(i_baiyu, i_zhh);
int i_max2 = max(i_zhh, i_baiyu) + 100;
// 函数作为自身函数的实参,同时函数也作为表达式的一部分
int i_max3 = max(max(i_zhh, i_baiyu), i_max2);
// 函数作为一个单独语句
printf("i_max的值为:%d\\n", i_max);
printf("i_max3的值为:%d\\n", i_max3);
//函数作为调用另一个函数时的实参
printf("函数作为调用另一个函数时的实参:%d\\n", max(max(i_zhh, i_baiyu), i_max2));
}
//主函数
int main() {
output();
return 0;
}
由于C语言代码是从上往下依次执行的,所以对于函数的调用,咱们有两种方式
- 函数定义在函数调用之前,函数可以直接调用。
- 函数定义在函数调用之后,则需要在函数调用之前先声明被调用的函数之后再调用。
上面这两句话可能看起来有点绕。不能理解,那我们把上面这个比较大小的代码稍微调整一下,把函数定义放在main()函数后面
#include<stdio.h>
//主函数
int main() {
output();
return 0;
}
//输出最大值
void output(){
int i_baiyu = 10;
int i_zhh = 20;
// 函数作为表达式的一部分
int i_max = max(i_baiyu, i_zhh);
int i_max2 = max(i_zhh, i_baiyu) + 100;
// 函数作为自身函数的实参,同时函数也作为表达式的一部分
int i_max3 = max(max(i_zhh, i_baiyu), i_max2);
// 函数作为一个单独语句
printf("i_max的值为:%d\\n", i_max);
printf("i_max3的值为:%d\\n", i_max3);
//函数作为调用另一个函数时的实参
printf("函数作为调用另一个函数时的实参:%d\\n", max(max(i_zhh, i_baiyu), i_max2));
}
//此处定义一个比较两个数取最大值函数
int max(int x, int y) {
if (x > y) {
return x;
}
else {
return y;
}
}
这个时候,我们执行程序可能会发现其编译时会有告警,这是因为我们的函数定义放在了函数调用之后。函数在调用的时候找不到函数的定义。
因此,我们只需要在函数调用之前,对函数进行声明,这样子的话,函数定义就可以放在程序的任意位置了。
函数的声明格式如下:
函数类型 函数名(形参列表);
我们发现,函数声明跟函数定义差不多,只是把函数定义时的函数体去掉。
修改后的代码如下:
#include<stdio.h>
void output(); //这里增加output函数的声明
int max(int x, int y);//这里增加max函数的声明
//主函数
int main() {
output();
return 0;
}
//输出最大值
void output(){
int i_baiyu = 10;
int i_zhh = 20;
// 函数作为表达式的一部分
int i_max = max(i_baiyu, i_zhh);
int i_max2 = max(i_zhh, i_baiyu) + 100;
// 函数作为自身函数的实参,同时函数也作为表达式的一部分
int i_max3 = max(max(i_zhh, i_baiyu), i_max2);
// 函数作为一个单独语句
printf("i_max的值为:%d\\n", i_max);
printf("i_max3的值为:%d\\n", i_max3);
//函数作为调用另一个函数时的实参
printf("函数作为调用另一个函数时的实参:%d\\n", max(max(i_zhh, i_baiyu), i_max2));
}
//此处定义一个比较两个数取最大值函数
int max(int x, int y) {
if (x > y) {
return x;
}
else {
return y;
}
}
四、函数的参数
前面咱们说过,函数的形式参数列表,可以是变量(包括普通变量和指针变量),常量,表达式,函数等。实参列表里多个实参之间用逗号【,】来隔开
这里单独要再强调一下,就是形参就像是函数内其他的局部变量一样。在函数调用结束之后,会进行销毁。我们在向函数传递变量时,会有两种传递参数形式。这也是为啥前面我在变量那里会强调指出有普通变量跟指针变量
- 传值调用:该方法会把实际参数的值复制到函数的形式参数,此时,修改函数内形式参数的值并不会影响实际参数的值
- 引用调用:通过指针变量来传递,形参会指向实参地址的指针,当对形参指向的值进行操作时,就相当于对实参本身进行操作
上面这样子讲可能不太好理解,还是上代码
这里咱们举一个例子就是来写一个函数,用于交换两个变量的值。
#include <stdio.h>
// 通过普通变量,进行值传递
void swap(int x, int y) {
printf("交换前x的值为:%d,y的值为:%d\\n", x, y);
int temp = x;
x = y;
y = temp;
printf("交换后x的值为:%d,y的值为:%d\\n", x, y);
}
// 通过指针变量,进行引用传递
void swap_p(int* x, int* y) {
printf("交换前x的值为:%d,y的值为:%d\\n", *x, *y);
int temp = *x;
*x = *y;
*y = temp;
printf("交换后x的值为:%d,y的值为:%d\\n", *x, *y);
}
int main() {
int i_baiyu = 66;
int i_zhh = 77;
printf("swap交换前i_baiyu的值为:%d,i_zhh的值为:%d\\n", i_baiyu,i_zhh);
swap(i_baiyu, i_zhh);
printf("swap交换后i_baiyu的值为:%d,i_zhh的值为:%d\\n", i_baiyu,i_zhh);
printf("-------------------------------------------\\n");
printf("swap_p交换前i_baiyu的值为:%d,i_zhh的值为:%d\\n", i_baiyu, i_zhh);
swap_p(&i_baiyu, &i_zhh);
printf("swap_p交换后i_baiyu的值为:%d,i_zhh的值为:%d\\n", i_baiyu, i_zhh);
return 0;
}
五、函数的递归
在开始讲函数的递归之前,给大家将一个耳熟能详的故事
从前有座山,山里有座庙,庙里有个老和尚给一个小和尚讲故事,讲什么呢?老和尚说
从前有座山,山里有座庙,庙里有个老和尚给一个小和尚讲故事,讲什么呢?老和尚说
从前有座山,山里有座庙,庙里有个老和尚给一个小和尚讲故事,讲什么呢?老和尚说
......
在C语言中,当函数直接或者间接调用函数本身,就叫做函数的递归。
在使用函数递归的时候,我们要注意设置好一个从函数退出的条件,否则就会进入一个死循环,就像老和尚给小和尚讲故事一样,是无限循环的。
函数的递归,这样子讲可能不太容易懂,下面举几个例子,让大家一起熟悉一下
通过递归求n的阶乘
我们从数学公式可知
n! = n *(n-1)!
#include <stdio.h>
double factorial(unsigned int i)
{
if (i <= 1)//这里就是结束递归的判断条件
{
return 1;
}
return i * factorial(i - 1);
}
int main()
{
int i_baiyu = 6;// 这里我们计算6的阶乘。
printf("%d 的阶乘为 %f\\n", i_baiyu, factorial(i_baiyu));
return 0;
}
6!= 6 * 5 * 4 * 3 * 2 * 1 = 720
总结
本文讲述了C语言函数的定义、基本使用,和函数的递归。从零到一带各位同学熟悉C语言中函数的使用。
写在后面
如果觉得有用的话,麻烦动动各位发财的小手指,给个一键三连支持一下攻城狮白玉,并把本文分享给更多的小伙伴。你的简单支持,我的无限创作动力
如果有想看的内容,也可以在博文底部评论,我会整理出来给到大家~
以上是关于C语言函数详解(入门到进阶)的主要内容,如果未能解决你的问题,请参考以下文章