自问我的第一个问题以来,过去两周我走了很长一段路,已经编写了一个使用网格布局和按钮按钮制作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]
。现在,z
和a[0]
都引用相同的对象。然后您更改它。
您应该做的是为z
创建第一个元素的副本,以便在修改z
时不必修改a[0]
。像这样:
ComplexNumber z = new ComplexNumber(a[0].real, a[0].imag);