函数的调用及重载

半世苍凉 提交于 2020-02-15 02:21:12

函数的调用

1.格式: 函数(参数1,参数2,…)
2.函数不调用不调用是不会执行的
3.函数调用的三种格式

  • 如果调用函数没有返回值, 直接调用即可
  • 如果调用函数有返回值
  • 如果结果要在其他位置使用,使用变量存储方法调用的返回值
  • 如果只想输出函数的返回值, 直接把方法的调用写在输出语句中的小括号中函数执行内存

调用:通过函数名和参数列表共同确定一个函数;

好处:让开发者需要记忆的函数名大大降低,提高开发效率。

递归调用:

人用迭代,神用递归

什么是递归

方法自身调用自身即为递归

递归:先递,后归。我们可以把递归分成三个部分,即:

前进段:指的就是讲问题从大化小

结束段:问题无法再继续化小,则处理当前的问题

返回段:将小问题处理完毕之后,向上返回(有些问题是不需要返回的)

递归和循环编写必须的三个部分:

  • 初始值
  • 终止条件
  • 前进步长

递归主要解决的问题:

  • 阶乘
/** 
 * 计算5的阶乘(result = 5*4*3*2*1) 
 * @author Champion.Wong 
 *  
 * 
 */  
public class Jiecheng {  
    public static void main(String[] args) {  
        System.out.println(f(5));  
    }  
      
    public static int f(int n) {  
        if (1 == n)   
            return 1;  
        else   
            return n*f(n-1);  
    }  
}  
  • 数列
/** 
 * 求数列:1,1,2,3,5,8......第40位的数 
 * @author Champion.Wong 
 *  
 */  
public class Shulie {  
    public static void main(String[] args) {  
        System.out.println(f(6));  
    }  
      
    public static int f(int n ) {  
        if (1== n || 2 == n)   
            return 1;  
        else  
            return f(n-1) + f(n-2);  
    }  
}  
  • 斐波那契数列

 斐波那契数列第一位和第二位的数值都是1,之后的每一位都是前两位的和;

迭代:

迭代:利用变量的原理推算出变量的一个新值。如果说递归时自己调用自己,那么迭代就是A不断的调用B

递归和迭代的区别:

  • 一般而言,但凡能够被迭代(循环)解决的问题,递归都可以;而递归解决的问题,迭代就不一定了
  • 递归就是函数在进栈,进栈的次数多了,势必会占内存,无法避免的

在某些问题上,递归所写的代码要比迭代写的代码少

在某些问题上,迭代是写不出来的,所以只能用递归

  • 递归其实是分治法的一种实现方式(一种实现思路)

分治法是一种算法思想,分治法主要解决的问题是将大问题,进行拆分,拆分成若干个小的问题进行求解,最终将每个小问题的解进行合并。

其实,分治法就是一种暴力破解法(穷举),也是一种搜索最优答案的算法

接下来,我们分别用迭代和递归的思想来求斐波那契数列的前10项和。

思想分析:

前10项:1 1 2 3 5 8 13 21 34 55 ......
        f(n)指的是斐波那契的第n项
        f(n)=f(n-1)+f(n-2) f(1)=1 f(2)=1
                    f(5)
                f(4)        f(3)
            f(3)    f(2) f(2)   f(1)
        f(2)    f(1)
 

public class Feibo {
    public static void main(String[] args) {
        System.out.println(fab_recursion(10));
        System.out.println(fab_iteration(10));
    }
    //迭代实现斐波那契
    private static long fab_iteration(int index) {
        if (index ==1 || index == 2) {
            return 1;
        }
        else {
            long f1 = 1l;
            long f2 = 1l;
            long f3 = 0;
            for ( int i = 0; i < index-2; i++) {
                f3 = f1 + f2;//利用变量的原值推算出变量的一个新值
                f1 = f2;
                f2 = f3;
            }
            return f3;
        }
    }
    //递归实现斐波那契
    private static long fab_recursion(int index) {
        if (index ==1 || index == 2) {
            return 1;
        }
        else {
            return fab_recursion(index-1) + fab_recursion(index - 2);//递归求值
        }
    }
}
    

递归其实是方便了程序员难为了机器,递归可以通过数学公式很方便的转换为程序。其优点就是易理解,容易编程。但递归是用栈机制实现的,每深入一层,都要占去一块栈数据区域,对嵌套层数深的一些算法,递归会力不从心,空间上会以内存崩溃而告终,而且递归也带来了大量的函数调用,这也有许多额外的时间开销。所以在深度大时,它的时空性就不好了。(会占用大量的内存空间。

而迭代虽然效率高,运行时间只因循环次数增加而增加,没什么额外开销,空间上也没有什么增加,但缺点就是不容易理解,编写复杂问题时困难。

重载:

概念:在同一个类中,可以定义多个名称相同,参数列表不同的函数,这种情况较做函数的重载;

public static int sum(int a,int b)
{    
    return a + b;
}
public static float sum(float a,float b)
{    
    return a + b;
}

特点:

  • 与返回值类型无关,只看方法名和参数列表
  • 在调用时,虚拟机通过参数列表的不同来区分同名方法

好处:在于我们可以扩展函数的功能(函数重名,但是参数类型不一样,执行内容也可以不一样)

寻找适当函数的流程

1.看是否有确切的参数定义 int+int 查看是否有(int,int)

2.看是否有可兼容的参数定义 int+int 查看是否有(double,double)

3.如果可兼容的参数定义有多个int+int,(double,int)或(int,double) 此时报错 引用不明确

 


 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!