进一步理解函数
admin
2024-02-24 18:47:08
0次

函数的定义和基本调用应该是比较容易理解的,但有很多细节可能令初学者困惑,包括参数传递、返回、函数命名、调用过程等,我们逐个介绍。

1.参数传递
有两类特殊类型的参数:数组和可变长度的参数。
(1)数组
数组作为参数与基本类型是不一样的,基本类型不会对调用者中的变量造成任何影响,但数组不是,在函数内修改数组中的元素会修改调用者中的数组内容。我们看个例子:
public static void reset(int[] arr){
    for(int i=0;i
        arr[i] = i;
    }
}
public static void main(String[] args) {
    int[] arr = {10,20,30,40};
    reset(arr);
    for(int i=0;i
        System.out.println(arr[i]);
    }
}
在reset函数内给参数数组元素赋值,在main函数中数组arr的值也会变。
这个其实也容易理解,我们在1.2节介绍过,一个数组变量有两块空间,一块用于存储数组内容本身,另一块用于存储内容的位置,给数组变量赋值不会影响原有的数组内容本身,而只会让数组变量指向一个不同的数组内容空间。
在上例中,函数参数中的数组变量arr和main函数中的数组变量arr存储的都是相同的位置,而数组内容本身只有一份数据,所以,在reset中修改数组元素内容和在main中修改是完全一样的。
(2)可变长度的参数
前面介绍的函数,参数个数都是固定的,但有时候可能希望参数个数不是固定的,比如求若干个数的最大值,可能是两个,也可能是多个。Java支持可变长度的参数,如下例所示:
public static int max(int min, int ... a){
    int max = min;
    for(int i=0;i
        if(max
            max = a[i];
        }
    }
    return max;
}
public static void main(String[] args) {
    System.out.println(max(0));
    System.out.println(max(0,2));
    System.out.println(max(0,2,4));
    System.out.println(max(0,2,4,5));
}这个max函数接受一个最小值,以及可变长度的若干参数,返回其中的最大值。可变长度参数的语法是在数据类型后面加三个点“...”,在函数内,可变长度参数可以看作是数组。可变长度参数必须是参数列表中的最后一个,一个函数也只能有一个可变长度的参数。
可变长度参数实际上会转换为数组参数,也就是说,函数声明max(int min,int...a)实际上会转换为max(int min,int[]a),在main函数调用max(0,2,4,5)的时候,实际上会转换为调用max(0,new int[]{2,4,5}),使用可变长度参数主要是简化了代码书写。

2.理解返回
对初学者,我们强调下return的含义。函数返回值类型为void时,return不是必需的,在没有return的情况下,会执行到函数结尾自动返回。return用于显式结束函数执行,返回调用方。
return可以用于函数内的任意地方,可以在函数结尾,也可以在中间,可以在if语句内,可以在for循环内,用于提前结束函数执行,返回调用方。
函数返回值类型为void也可以使用return,即“return;”,不用带值,含义是返回调用方,只是没有返回值而已。
函数的返回值最多只能有一个,那如果实际情况需要多个返回值呢?比如,计算一个整数数组中的最大的前三个数,需要返回三个结果。这个可以用数组作为返回值,在函数内创建一个包含三个元素的数组,然后将前三个结果赋给对应的数组元素。
如果实际情况需要的返回值是一种复合结果呢?比如,查找一个字符数组中所有重复出现的字符以及重复出现的次数。这个可以用对象作为返回值,我们在第3章介绍类和对象。虽然返回值最多只能有一个,但其实一个也够了。

3.重复的命名
每个函数都有一个名字,这个名字表示这个函数的意义,名字可以重复吗?在不同的类里,答案是肯定的,在同一个类里,要看情况。
同一个类里,函数可以重名,但是参数不能完全一样,即要么参数个数不同,要么参数个数相同但至少有一个参数类型不一样。
同一个类中函数名相同但参数不同的现象,一般称为函数重载
 。为什么需要函数重载呢?一般是因为函数想表达的意义是一样的,但参数个数或类型不一样。比如,求两个数的最大值,在Java的Math库中就定义了4个函数,如下所示:
public static double max(double a, double b)
public static float max(float a, float b)
public static int max(int a, int b)
public static long max(long a, long b)

4.调用的匹配过程
在之前介绍函数调用的时候,我们没有特别说明参数的类型。这里说明一下,参数传递实际上是给参数赋值,调用者传递的数据需要与函数声明的参数类型是匹配的,但不要求完全一样。什么意思呢?Java编译器会自动进行类型转换,并寻找最匹配的函数,比如:
char a = 'a';
char b = 'b';
System.out.println(Math.max(a,b));

参数是字符类型的,但Math并没有定义针对字符类型的max函数,这是因为char其实是一个整数(我们在2.4节会说明),Java会自动将char转换为int,然后调用Math.max(int a,int b),屏幕会输出整数结果98。
如果Math中没有定义针对int类型的max函数呢?调用也会成功,会调用long类型的max函数。如果long也没有呢?会调用float型的max函数。如果float也没有,会调用double型的。Java编译器会自动寻找最匹配的。
在只有一个函数的情况下,即没有重载,只要可以进行类型转换,就会调用该函数,在有函数重载的情况下,会调用最匹配的函数。

5.递归函数
函数大部分情况下都是被别的函数调用的,但其实函数也可以调用它自己,调用自己的函数就叫递归函数
 。为什么需要自己调用自己呢?我们来看一个例子,求一个数的阶乘,数学中一个数n的阶乘,表示为n!,它的值定义是这样的:
0!=1
n!=(n-1)!×n
0的阶乘是1,n的阶乘的值是n-1的阶乘的值乘以n,这个定义是一个递归的定义,为求n的值,需先求n-1的值,直到0,然后依次往回退。用递归表达的计算用递归函数容易实现,代码如下:
public static long factorial(int n){
    if(n==0){
        return 1;
    }else{
        return n*factorial(n-1);
    }
}
看上去应该是比较容易理解的,和数学定义类似。递归函数形式上往往比较简单,但递归其实是有开销的,而且使用不当,可能会出现意外的结果,比如说这个调用:
System.out.println(factorial(100000));

系统并不会给出任何结果,而会抛出异常。异常我们在第6章介绍,此处理解为系统错误就可以了。异常类型为java.lang.StackOverflowError,这是什么意思呢?这表示栈溢出错误,要理解这个错误,我们需要理解函数调用的实现原理,我们1.7节介绍。
那递归不可行的情况下怎么办呢?递归函数经常可以转换为非递归的形式,通过循环实现。比如,求阶乘的例子,其非递归形式的定义是:
n!=1×2×3×…×n
这个可以用循环来实现,代码如下:
public static long factorial(int n){
    long result = 1;
    for(int i=1; i<=n; i++){
        result=result*i;
    }
    return result;
}

想要了解更多Java基础知识,可以点击评论区链接和小编一起学习java吧,此视频教程为初学者而著,零基础入门篇!给同学们带来全新的Java300集课程啦!java零基础小白自学Java必备优质教程_手把手图解学习Java,让学习成为一种享受_哔哩哔哩_bilibili

相关内容

热门资讯

蜻蜓订购APP贵金属订购非法期...   蜻蜓订购APP以"投资平台"名义对外宣传,主打贵金属期货(订购)交易。该平台一方面强调自身"正规...
悟空订购APP非法期货交易欺骗...   近期,有投资者反映,“悟空订购APP”等平台以白银、贵金属订购为名,宣传所谓“高收益”“低门槛”...
小赢淘金APP期货投资骗局,平...   “小赢淘金”之流,最擅长的就是用“注册送现金”、“充值返券”的糖衣炮弹来引流。别天真地以为那是福...
八方淘金APP非法期货交易欺骗...   警惕!八方生财、每日淘金、小赢淘金、悟空订购、蜻蜓订购、斗金订购等APP均涉嫌非法期货交易!  ...
智易购APP贵金属订购交易骗局...   很多人看到“3元起投”“充值送福利”“操作简单”“随时提现”这类宣传,很容易把智易购APP当成普...
喜玛银庄APP商品订购投资骗局...   喜玛银庄APP白银、铂金“现货订购”骗局警示:无资质平台涉嫌非法期货交易,投资者爆仓后如何维权?...
吉鑫乐享APP炒贵金属订购交易...   近期,多名投资者反映在“吉鑫乐享APP”进行贵金属投资时遭遇严重亏损,甚至血本无归。看似正规的“...
易掘金APP虚假期货投资骗局,...   “易掘金”的APP它打着“高收益、灵活投资”的旗号,宣称通过“商品订购”就能轻松赚钱,吸引了不少...
在大吉订购APP订购交易亏损被...   近期,不少投资者反映在“大吉订购App”上投资白银、铂金等商品遭遇严重亏损。该平台宣称提供现货订...
铂银壹号APP商品订购交易亏损...   许多中小投资者误以为网上的“商品现货订购”是合规合法的理财渠道,殊不知这背后隐藏着巨大的合规风险...
兴鑫淘金APP贵金属订购交易亏...   白银、贵金属或其他商品类投资,除国家批准的正规期货交易场所及持牌期货公司外,市面上大量第三方交易...
铂银掘金APP无资质的违规平台...   铂银掘金等平台的投资者,往往是被“注册送现金”“充值返现券”“首单免亏”等广告话术吸引,进而下载...
八方淘金APP订购交易不合规,...   “八方淘金APP”“铂银掘金APP”“铂银壹号APP”等软件被指以“现货订购”为名,实际采用高杠...
在指尖订购APP订购商品亏损被...   指尖订购APP这类平台,表面是“订购交易”,实则是披着电商外衣的非法期货陷阱。绝大多数投资者被蒙...
在犀贝易购APP做商品订购交易...   市面上打着“现货投资”“贵金属交易”旗号的APP并不少,但真正合规、受监管的平台并不多。犀贝易购...
易达淘金APP虚假商品订购交易...   易达淘金APP存在严重的虚假宣传与违规交易行为。该平台打着“商品订购”的旗号,实则通过不合规的交...
大浪淘金APP白银订购亏损被骗...   大浪淘金APP最隐蔽的套路,在于其完全封闭的内盘交易系统。表面上,它宣称与国际贵金属市场接轨;实...
一品好购APP上订购白银出现亏...   一品好购APP原名“一品订购”,运营方为上海宝智未来信息技术有限公司。近期不少投资者反映在该平台...
九州订购APP贵金属订购投资骗...   九州订购APP正通过抖.音、快手、今日头条等平台大量投放投资广告,用“5元起投”“充值返现”“0...
坚锅淘金APP交易软件并不正规...   当前,市面上大量所谓的“现货商城订购”交易软件,早已偏离了正常的实物商品买卖,演变为高杠杆、高手...