【问题标题】:Why does a void function return a value?为什么 void 函数返回一个值?
【发布时间】:2014-10-16 00:46:40
【问题描述】:

我是一名编程初学者,我对函数的返回值有疑问。

我正在学习 Java。

我附上了我书中的代码,其中包含经典的选择排序。

现在显然书中的代码有效。但是,主要功能中的这三行是我提出问题的基础:

  1. int []a=new int[]{1,9,2,8,3,7,4,6​​,5};

  2. 排序(a);

  3. if(ascending(a)) System.out.println("Works");

所以我的问题是:

在第 2 行中,如果 sort() 函数无效,我如何检索已排序的 a[]?

这行不应该是:a = sort(a)?

public class SelectionSort
{

    public static void main(String[]args)
    {
        int []a=new int[]{1,9,2,8,3,7,4,6,5};
        sort(a);
        if(ascending(a)) System.out.println("Virðist virka");
        else System.out.println("Virkarekki");
    }

    public static void sort(int[]a)
    {
        if(a.length<2) return;
        int i=0;
        while(i!=a.length)
        {
            int k=i+1;
            while(k!=a.length)
            {
                if(a[k]<a[i])
                {
                    int tmp=a[i];
                    a[i]=a[k];
                    a[k]=tmp;
                }
            k++;
            }
        i++;
        }
    }

    public static boolean ascending(int[]a)
    {
        if(a.length<2) return true;
        int i=1;
        while(i!=a.length)
        {
            if(a[i-1]>a[i]) return false;
            i++;
        }
        return true;
    }
}

【问题讨论】:

  • sort 方法修改了你传递的数组,所以你不需要有返回类型。
  • 正如@August 所指出的,sort 方法更改了原始数组。它与 Java 如何处理参数有关:stackoverflow.com/questions/40480/…

标签: java


【解决方案1】:

由于数组是对象,它们是通过引用传递的(它们在内存中的位置),因此sort()a[] 的更改也会更改 main 中声明的a[]。所以 a 在函数内发生了变化。但是,你不能说

public static void change(int[] a) {
    a = new int[3];
    a = {1, 2};
}

这不会改变a 本身,因为这只会创建参数a 指向的新内存位置,而不会更改参数。

【讨论】:

    【解决方案2】:

    sort() 方法修改作为参数传递的数组;也就是修改了原来的数组。

    假设您有数组a,其值为[ 3, 2 ];你打电话给sort(a);如果您的代码如下所示:

    // printArray is an hypothetical method
    printArray(a);
    sort(a);
    printArray(a);
    

    那么输出将是:

    [3, 2]
    [2, 3]
    

    因此,sort() 根本不需要返回结果。

    但是,您可以修改 sort() 方法以制作数组的副本,对副本进行排序并返回该副本。

    【讨论】:

      【解决方案3】:

      sort(int[] a),一个 void 函数,不返回值

      相反,sort() 会就地修改传递给它的数组。您将一个数组对象传递给sort(),并且您的代码对其进行了修改。

      【讨论】:

        【解决方案4】:

        http://javadude.com/articles/passbyvalue.htm

        java中的char和int等基元在java中是按值传递的。

        java 中的数组只是一个对象容器,可以存放任何类型。

        在 java 中将对象作为参数传递类似于作为引用传递 - 您对通过参数传入的对象所做的任何修改都将保留调用方法中的这些更改。

        【讨论】:

          【解决方案5】:

          您正在触及编程语言中的一个概念,即按引用传递与按值传递。

          当您“按值传递对象”给方法时,会获取该对象的副本并将该副本传递给方法。所以在被调用的方法中,当你修改对象时,修改不会反映在调用者的方法中。

          当您“通过引用传递对象”给方法时,只有指向它所引用的实际对象的指针才会传递给方法。所以在被调用的方法中,当你修改对象时,修改确实会反映在调用者的方法中。

          在 Java 中,所有方法参数都是“按值传递”的。更容易认为它是通过引用传递的,但事实并非如此。

          现在,所有对象变量都是 Java 中的引用。所以在这种情况下,数组是一个引用。 Java按值传递该数组引用,即它获取“引用”的副本并传递它。

          所以你现在可以想象两个指向同一个数组的指针 - 在 main() 中名为“args”的原始指针和在 sort() 中名为“a”的新指针

          由于底层数组是相同的,所以无论你使用main()中的指针“args”还是sort()中的指针“a”来修改数组都没有关系。他们都会看到变化。

          这也是原因 - 为什么交换不会像您预期的那样工作。

          void main()
          {
             badSwap(arr1, arr2); 
             // arr1 and arr2 will still point to same values as the prior line
             // because only the reference pointers are getting swapped
             // however, arr1[0] will be -99
          }
          
          void badSwap(int[] a, int[] b)
          {
             a[0] = -99;
             int[] temp = a;
             a = b;
             b = temp; 
          }
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2011-12-17
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2016-08-28
            • 2023-01-28
            • 2019-09-03
            • 2020-02-07
            相关资源
            最近更新 更多