自问我的第一个问题以来,过去两周我走了很长一段路,已经编写了一个使用网格布局和按钮按钮制作x和o并声明获胜者和一个执行复数算术(例如z1)的类的tictactoe游戏。 = -3-4i加z2 = 7 + i通过cAdd(z1,z2))和计算(例如sin(z1)和log(z2))正确。 (由称为Derive的CAS确认并通过其实施)。

到目前为止没有问题。

因此,我决定增强cAdd以接受两个以上的复数(例如cAdd(z1,z2,z3)),并发现以下用于变长参数列表的语法:

public ComplexNumber cAdd ( ComplexNumber ... a);


但是,尽管cAdd(z1,z2)的两参数版本工作正常,但“ varargs”版本(例如cAdd(z1,z2,z3))却给出了正确的结果,但是改变了参数值,因此,如果将z1用于后来的计算,它不是开始的样子。

这是代码,然后是输出。

  class ComplexNumber {

    double real, imag;

    public ComplexNumber() {                // default constructor
    }

    public ComplexNumber(double a, double b) {    // initializer constructor
        real = a;
        imag = b;
    }

  public class CBug {

    public static void cPrint(String s, ComplexNumber z) {
        System.out.println(s + z.real + " + " + z.imag + "i");
    }

    public static void dump(int n, ComplexNumber z, ComplexNumber [] a){
        System.out.print("Dump " + n + "; sum so far is " );
        cPrint("z = ", z);
        for (int i = 0; i < a.length; i++)
            cPrint("" + i + ": " ,a[i]);
        System.out.println("");
    }

    public static ComplexNumber cAdd(ComplexNumber ... a) {
        ComplexNumber z = a[0];
        for (int i = 1; i < a.length; i++){
            dump(i,z,a);
            z.real = z.real + a[i].real;
            z.imag = z.imag + a[i].imag;
        }
        dump(99,z,a);
        return z;
    }

    public static void main(String[] args) {
        ComplexNumber sum = new ComplexNumber();
        ComplexNumber z1 = new ComplexNumber(1000,500);
        ComplexNumber z2 = new ComplexNumber(7, 1);
        ComplexNumber z3 = new ComplexNumber(100,100);
        cPrint("z1 = ", z1);
        cPrint("z2 = ", z2);
        cPrint("z3 = ", z3);

        System.out.println("");

        System.out.println("++++++++++++++++++++++");
        sum = cAdd(z1,    z2,    z3) ;
        cPrint     ("z1 + z2 + z3 = " , sum);
        System.out.println("--------------------");

        cPrint("z1 = ", z1);
        cPrint("z2 = ", z2);
        cPrint("z3 = ", z3);
    }
  }


输出:

run:
z1 = 1000.0 + 500.0i
z2 = 7.0 + 1.0i
z3 = 100.0 + 100.0i

++++++++++++++++++++++
Dump 1; sum so far is z = 1000.0 + 500.0i   [correct]
0: 1000.0 + 500.0i
1: 7.0 + 1.0i
2: 100.0 + 100.0i

Dump 2; sum so far is z = 1007.0 + 501.0i     [correct]
0: 1007.0 + 501.0i        [but WHY DID ARG[0] CHANGE to "z so far"?]
1: 7.0 + 1.0i
2: 100.0 + 100.0i

Dump 99; sum so far is z = 1107.0 + 601.0i   [correct]
0: 1107.0 + 601.0i         [WHY DID ARG[0] CHANGE AGAIN to new "z so far"?]
1: 7.0 + 1.0i
2: 100.0 + 100.0i

z1 + z2 + z3 = 1107.0 + 601.0i                [correct]
--------------------
z1 = 1107.0 + 601.0i          [WHY DID z1 (a.k.a. arg[0]) CHANGE?]
z2 = 7.0 + 1.0i
z3 = 100.0 + 100.0i
BUILD SUCCESSFUL (total time: 0 seconds)


由于cAdd损坏了它,因此无法在后续计算中使用第一个参数。

============================

这就是我现在对cAdd的要求(因为我的原始“修复”(在下面的评论中描述)有些古怪]:

 public static ComplexNumber cAdd(ComplexNumber ... a) {
    ComplexNumber z = new ComplexNumber();
    for (int i = 0; i < a.length; i++){
      z.real += a[i].real;
      z.imag += a[i].imag;
    }
    return z;
  }


==============================

最佳答案

z中创建变量cAdd时,将其引用为a[0]。现在,za[0]都引用相同的对象。然后您更改它。

您应该做的是为z创建第一个元素的副本,以便在修改z时不必修改a[0]。像这样:

ComplexNumber z = new ComplexNumber(a[0].real, a[0].imag);

07-26 03:19