C语言函数,函数,递归,递归

目录

一,函数

1,什么是函数

2,为什么使用函数

二,简单函数

1,创建函数

 2,函数的类型 

 3,函数的参数

三,函数的调用 

1,实际参数

2.传值与传址调用

   2.1传值调用

   2.2 传址调用

3.使用return

     3.1 从函数中返回值

 3.2 终止函数

四,递归

    1.基本原理

    1.1递归是如何工作的

  1.2 图解

2.递归的一点总结

总结


一,函数

1,什么是函数

函数是完成特点任务的独立程序代码单元,不同的函数完成的操作也不一样。

2,为什么使用函数

使用函数可以避免编写一些重复性的代码

使程序更加模块化,从而提高程序代码的可读性,也方便后期修改。

二,简单函数

函数包含 返回类型,函数名和参数 

1,创建函数

想要完成一项操作,比如说两个数相加,可以通过函数来完成:

int ADD(int,int) ; //声明
int main()
{
int a =10 ;
int b =20 ;
int c =ADD(a,b); //调用
printf("%d\n",c);
return 0;
}

int ADD(int a,int b) //函数
{
 return a+b ;
}
  1. 函数和变量一样,有很多种类,在使用函数之前都要声明函数的类型,所以出了                  int ADD(int,int) ; int 是函数的类型,表示返回值是int类型; ADD 表示函数名 ;(int,int)表示函数的参数是两个 int 类型的变量;结尾的分号说明这是在声明函数,不是定义;
  2. 如果这个函数出现在main() 函数之后,那么在main()函数里调用这个函数时需要声明,如果这个函数出现在main()函数之前,那么在main()函数里调用这个函数时可以不声明;在别的函数调用时也与之一样。
  3. 在main()函数里调用ADD函数,把变量ab的值传给 ADD(int ,int)函数中的两个int ,然后返回一个值给到c  ,这时候c的值就是 a+b:

 2,函数的类型 

  声明函数时必须声明函数的类型,带返回值的函数类型应该与返回值类型相同,没有返回值的函数为void类型。

  特别要注意函数的类型是返回值的类型,不是函数参数的类型。

int sum(int a,int b) ;//函数声明

上述函数声明中,sum()函数的返回类型是int 为sum左边的int 。

 3,函数的参数

函数分为库函数和自定义函数,库函数的参数可以通过一些工具查询,自定义函数的参数是由自己决定。比如说上述的ADD(int ,int )函数的两个int类型的参数是由自己定义的。我们根据函数是需要什么类型的参数去给函数传递值。

int ADD(int a,int b)   //()内为参数类型,接受两个int类型的参数

{                               //函数体

    return a+b ;         //返回值,返回一个int类型的结果
}

上述函数的定义,告诉编译器 ADD()使用两个参数,两个都是int 类型,这两个变量都被称为形式参数,简称形参。该参数是局部变量,也就是说离开这个函数之后就会被销毁,属于该函数私有,所以不会和别的函数中的同名变量产生冲突。

在定义函数参数时,应该注意每个变量都应该在其前声明类型,不然无效。

void add(int a,b,c) //无效的函数头
void add(int a,int b,int c) //有效的函数头

除去这种方式以外还有一种有效定义函数头的方式

void add(x,y,z)
int x,y,z ;
//这种方式也是有效的,不过不建议使用

三,函数的调用 

调用函数时,应根据函数定义时需要的参数来传递参数,如果没有定义参数则不需要传参。

1,实际参数

       函数调用时传递的参数,如上述的ADD()函数调用时,传递两个值,两个值之间用逗号隔开。

       实际参数可以是常量、变量,或者时更复杂的表达式,不管用哪种方式,实际参数都要被求值,然后将值考贝给被调函数相应的形式参数。

      注:如何区分实际参数和形式参数

             形式参数时被调函数中的变量,实际参数时主调函数赋给被调函数的具体值。

2.传值与传址调用

   2.1传值调用

          把实际参数的值传给形参,实参和形参分别占有不同的内存空间,对形参的修改不会影响实        际参数。

   2.2 传址调用

        (1)是把函数外部创建变量的内存地址传递给函数参数的一种调用方式

        (2)这种传递方式使函数内外部的变量联系起来(共用一块地址),也就是说函数内部对形                   式参数的修改可以影响实际参数。

3.使用return

     3.1 从函数中返回值

int add(int x,int y);//声明

int main()
{
   int a =10,b=10 ;
   int c = add(a,b) ;//调用,a,b为实际参数
                     //变量c接收从函数中返回的值
   return 0;
}

int add(int x,int y) //函数定义,x,y为形式参数
{
   return a+b ; //使用return 从函数中返回值
}

  返回值可以是任意表达式的值,

return x>y?x:y ; 

如果返回的类型与函数声明的类型不一样,如:

int div(int a,int b)
{
   double z = a/b ;
   return z; //返回类型与声明的类型不一样
   // z会被强制类型转换为 int -> (int)z ,然后返回
}

 3.2 终止函数

        终止函数并把控制返回给主调函数的下一条语句。

int my_min(int a,int b)
{
   if(a>b)
     return b ;
   else
     return a;
}

   在函数中使用多个return 语句也是没有错误的。

四,递归

         简单来说递归就是函数自己调用自己

    1.基本原理

    使用一个演示:

void my_and (int n);

int main()
{
	my_and (1);
	return 0;
}
void my_and (int n)
{
	printf(" 第 %d 级调用 地址是 %p\n", n, &n); // a语句
	if (n < 4)
		my_and(n + 1);
	printf(" 第 %d 级调用 地址是 %p\n", n, &n);// b语句
}

    1.1递归是如何工作的

  1.    函数首先接受了一个值 1作为初始值进入函数执行,所以a语句打印 第 1 级调用 然后打         印出地址。
  2.   因为1小于4 所以,进入if ,第 1 级调用实际参数为 n+1 (2),然后再次调用my_and()函    数(第2级),并把2传递给函数的n ,然后 a语句打印 第 2 级调用 然后打印地址。
  3.  因为2小于4所以,进入if,第2 级调用实际参数为 n+1 (3),然后再次调用my_and()函数(第  3级),并把 3传递给函数的n ,然后a语句打印出 第3级调用,然后打印地址。
  4.  因为3小于4 所以,进入if,第3级调用实际参数为 n+ 1( 4) ,然后再次调用my_and()函数(第   4级),并把4传递给函数的n,然后a语句打印出 第4级调用,然后打印地址。
  5. 因为 4 不小于4 ,所以不进入if ,函数不再调用自己,第4级接着执行 b语句打印 第4级,然后打印地址,然后返回 第3级 调用。
  6. 第3级调用继续执行后面的代码,也就是b语句打印,然后继续返回第2级调用,直到返回到最开始的 n=1 也就是第1 级调用时,执行完b语句打印之后函数结束。

我们通过观察每一级调用的地址可以看到 ,1-4与4-1的地址都是一样的,每级递归的n 都属于本级递归的,所以回到这一级时,使用同样的地址。

  1.2 图解

 每次调用都会返回一次,当函数执行完毕后,控制权会返回到上一级,必须逐级返回,不能跳级。

2.递归的一点总结

   递归有有点也有缺点,优点是可以为某些编程问题提供了简单的解决方案,缺点是长的递归会快速消耗内存资源,不方便阅读和维护。

  1,许多问题是以递归的形式进行解释,只是因为递归形式相较非递归形式更清晰

  2,迭代方式的实现往往比递归实现效率更高

  3,当一个问题相当复杂难以使用迭代解决时,不妨用递归实现,递归的简洁性便可以补偿它所            带来的运行时间的开销

总结

所有C函数都是平等的,每个函数都可以被自己或者其它函数调用,当然main()函数也可以被自己或者其他函数调用。

  • 4
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值