Java 带“的变长参数列表”;“用户定义类型”;弄乱论点

Java 带“的变长参数列表”;“用户定义类型”;弄乱论点,java,variadic-functions,Java,Variadic Functions,自从提出第一个问题以来,在过去的两周里,我已经走了很长的路。我已经编写了一个TictoE游戏,使用网格布局和按钮按下来生成x和o,并宣布胜利者,以及一个执行复数运算(例如,z1=-3-4i加上z2=7+I,通过cAdd(z1,z2))和计算(例如,sin(z1)和log(z2))的类。(由名为派生的CAS确认并通过其帮助实施) 到目前为止没有问题 因此,我决定增强cAdd以接受两个以上的复数(例如,cAdd(z1,z2,z3)),并发现以下用于变长参数列表的语法: public ComplexN

自从提出第一个问题以来,在过去的两周里,我已经走了很长的路。我已经编写了一个TictoE游戏,使用网格布局和按钮按下来生成x和o,并宣布胜利者,以及一个执行复数运算(例如,z1=-3-4i加上z2=7+I,通过cAdd(z1,z2))和计算(例如,sin(z1)和log(z2))的类。(由名为派生的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);
    }
  }
无法在后续计算中使用第一个参数,因为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;
  }
公共静态复合编号cAdd(复合编号…a){
ComplexNumber z=新的ComplexNumber();
for(int i=0;i

======================在
cAdd
中创建变量
z
时,将其引用到
a[0]
。现在
z
a[0]
都引用同一对象。然后更改它

您应该做的是为
z
制作第一个元素的副本,这样当您修改
z
时,您就不会修改
a[0]
。类似于这样:

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

嗯:
ComplexNumber z=a[0];…z.real=z.real+a[i]。real;
噢,天哪。我明白了。多谢奥利C:ComplexNumber z=new ComplexNumber(a[0]。real,a[0]。real;//传递引用,更新引用。z.real=z.real+a[i]。real;//这里您正在更改它z.imag=z.imag+a[i]。imag;我的修复,感谢奥利C:ComplexNumber z=new ComplexNumber(a[0]。real,a[0]。imag);我真的很感激你的暗示,而不是“来吧,做这个…”,真的!我是个老师,很多孩子讨厌暗示,有些孩子只想要“来吧,做这个…”这让我大吃一惊!!!!!!!!!谢谢,谢谢,谢谢,奥利。如果你删除默认的构造函数,使
成为real
imag
最终版
你可以肯定这不会再发生了是的……我只是做了一个更好的修复,不得不编辑我的原始帖子,因为我是一个新手,无法“回答自己的问题”8个小时!谢谢大家。我会在这个网站上呆很久的!也许有一天我会成为帮助者而不是被帮助者。
ComplexNumber z = new ComplexNumber(a[0].real, a[0].imag);