C语言之函数章

对于函数的初步认识

在c语言的学习中,我们认识到了一个新的知识——函数。在数学中有过对函数的定义,我想大家都知道,但是在C语言中,函数的概念和数学中定义的函数概念一样吗?
其实本质上是一样的,我们知道数学中引入函数是为了解决一系列含有一对一或多对一的映射问题,而C语言中也是一样,我们所写的函数,则是解决我们需要解决的问题。当然,大家肯定也都知道C语言中有函数库,里面为我们提供大量的常用函数,不过值得了解的是,在早期的c语言中,是没有函数库的,当时人们对于某个尝用问题所写的函数不一样,为了统一,这才有了函数库,像我们知道的printf,scanf等都是函数库中的函数。由此看来,我们所写的函数对于解决我们要解决的问题则起着决定性作用,那么接下来我们走进对函数的了解吧

函数的基本定义

首先,想要了解函数,就先需要知道如何用C语言去定义函数,为此我写了一个较为简单的函数如下。

#include<stdio.h>
void Print(int Number)
{
  printf("%d\n",Number);
}
int main()
{
  int Num = 0;
  scanf("%d",&Num);
  printf("%d\n",Num);
  Print(Num);
  return 0;
}

如果我输入20则运行结果如下图

对此,大家是不已经有些许自己对函数的初步想法。
首先在主函数中输入20后,第一条printf语句打印出20,接下来遇到了语句print(Num),然后又打印出一个20,有的人可能就有疑惑了,明明只有一个printf语句,怎么会再打印出20?这是我们再看主函数上方有一个void print(int Number),在这个大括号中包含一句printf的语句,看样子应该是这句话再打印出一个20.
在此,我告诉大家,void print(int Number)这就是一个函数。它包含了参数类型,函数名字以及是否有返回值这三个主要的东西。
这也就不难知道,主函数调用函数的时候,我们需要写入函数名,并在函数名后的小括号中写入需要向这个函数传入的参数,例如上面这个代码,我们就向函数Print中传入了一个名为Num的参数,则在我们所写的函数中就会接收到这个参数,并且执行函数中的语句,最后打印出20。

实参与形参

在C语言中,函数的参数可出现在两个地方,分别为函数定义处和函数调用处,但是这两个地方的参数是有不同的区别的。
在函数定义时,我们在后面定义的一个或多个参数,就是形式,参数简称形参,而在函数调用时,我们在所调用的函数名后的括号中,写入的一个或多个参数,是实实在在存在的参数,则叫做实际参数,简称实参。如下展示代码

#include<stdio.h>
void Print(int Number) //Number为形式参数
{
  printf("%d\n",Number);
}
int main()
{
  int Num = 0;
  scanf("%d",&Num);
  printf("%d\n",Num);
  Print(Num);//Numw为实际参数
  return 0;
}

通过定义便可知,主函数中在函数print调用处的Num为实际参数,是我们实实在在输入进去的参数,而在上面函数定义处的Number则为形式参数。形参和实参的功能是传递数据,发生函数调用时,实参的值会传递给形参。可以理解为形参是实参拷贝的一份。为使大家更好理解我们看以下代码

#include<stdio.h>
void My_Swap(int Number1,int Number2)
{
  int Temp = 0;
  Temp = Number1;
  Number1 = Number2;
  Number2 = Temp;
}
int main()
{
  int Num1=10,Num2=20;
  printf("Num1=%d,Num2=%d\n",Num1,Num2);
  My_Swap(Num1,Num2);
  printf("Num1=%d,Num2=%d\n",Num1,Num2);
  return 0;
}

大家不难看出所写的是一个交换寒素,想要把主函数中的Num1的值和Num2的值进行交换,但是运行结果如下

并没有将这两个值进行交换,是因为在所写的交换函数中,传入的是形式参数,并不是实际参数本身,形式参数的值与实际参数的值一模一样,但是他们的地址却不一样,如果想要将上述的两个值进行改变,则需要用到指针,代码,运行结果如下

#include<stdio.h>
void My_Swap(int *Number1,int *Number2)//用指针接收
{
  int Temp = 0;
  Temp = *Number1;
  *Number1 = *Number2;
  *Number2 = Temp;
}
int main()
{
  int Num1=10,Num2=20;
  printf("Num1=%d,Num2=%d\n",Num1,Num2);
  My_Swap(&Num1,&Num2);//传入地址
  printf("Num1=%d,Num2=%d\n",Num1,Num2);
  return 0;
}

函数的返回值

在上述的函数中,我们看到都是在所写的函数中执行语句并且输出。那么问题来了,如果用所写的函数计算得到一个结果,想要让主函数收到这个结果,该怎么实现呢?这就需要用到函数的返回值,首先,举个例子,我想要计算15+30的值,则代码如下

#include<stdio.h>
int Add(int Number1,int Number2)
{
  int Sum = Number1 + Number2;
  return Sum;
}
int main()
{
  int Num1 = 15,Num2 = 30,sum = 0;
  sum = Add(Num1,Num2);
  printf("%d + %d = %d\n",Num1,Num2,sum);
  return 0;
}

运行结果如下图

我们发现得出正确答案。那么是怎么实现的呢?
看到与之前写的函数不同的是,void变成了int,而这便是函数的返回类型,因为我们得到的答案是一个整型,所以这里需要用int,那是怎么返回的呢,可以看到函数中最后一句我为return Sum,这句话便把函数所计算的结果返回给主函数,这时,主函数中需要有个一变量接收这个参数,不难发现也需要用整型进行接收,在此我们知道,主函数的接收类型和函数的返回类型要一置。
当然,返回值可以时变量也可以时一条语句也可以是一个常数,也可以是函数。
比如上述代码可以把部分语句做如下替换

  return Sum;//替换如下
  return Number1 + Number2;
  printf("%d + %d = %d\n",Num1,Num2,sum);//替换如下
  printf("%d + %d = %d\n",Num1,Num2,Add(Num1,Num2));

函数的递归

接下来,就要给大家讲一讲函数的递归。什么是递归?刚才我说函数的返回值除了可以是变量,常数,一条语句,也可以是函数。其中如果这个返回值是函数的话并且是函数它本身,那么就可以理解为自己调用自己,而这就是递归。
递归需要有条件限制,不能无限制递归下去,这样就成了死递归,并且还要有跳出递归的条件,每次递归的时候需要接近这个跳出条件。
为了方便理解,现有如下计算n的阶乘代码

#include<stdio.h>
int Jie_Cheng(int Number)
{
  if(Number==1) return 1;
  else{
    return Number*Jie_Cheng(Number-1);
  }
}
int main()
{
  int Num=0;
  scanf("%d",&Num);
  printf("%d!= %d\n",Num,Jie_Cheng(Num));
  return 0;
}

输入5后运行结果如下图

那么,这是怎么计算的呢?首先5作为形式参数传入函数后,付给Number,因为5>1所以第一条if语句没有进去,走else语句,我们发现号后面便是函数自己,于是又进入该函数,此时新的形式参数值变为了4,因为4>1于是又走else语句,再号后面又是函数本生,如此循环,直到Number=1时进入if条件句,此时return 1,则开始逐层跳出,因为刚才该函数调用了自己很多次,当遇到该跳出递归的条件时,便需要一层一层跳出,最后返回的结果实际上就是54321。
同样的如下递归求字符串长度代码

#include<stdio.h>
int My_Strlen(char *Str)
{
  if(*Str!='\0')
  return My_Strlen(Str+1)+1;
}
int main()
{
  char St[100];
  scanf("%s",&St);
  printf("%d\n",My_Strlen(St));
  return 0;
}

输入abcdef后运行结果如下

同理,也是通过递归跳出条件进行判定,如果其不为’\0’则表示长度加一,使Str+1即地址加一继续判定,当读到’\0’时,满足跳出递归条件,则一层一层的跳出,最后计算结果为7。
至此,递归的讲解就到这里,如果大家对递归感兴趣的话,可以了解以下汉诺塔问题等,谢谢大家的阅读

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值