代码可以正常编译吗?为什么?
___________________________________________________________ 程序可以正常执行吗?为什么?
___________________________________________________________
实验5.4.3: (I)查找最大数
GreatestNumber.java(范例5-3)将对话框输入的3个数字保存在数组中,计算出其中的最大值。
程序清单5-3:GreatestNumber.java
import javax.swing.JOptionPane;
public class GreatestNumber { public static void main(String[] args) { int[] num = new int[10]; int counter; int max = 0; int totalnumber = 3; // Prompt a user to enter numbers for(counter = 0; counter < totalnumber; counter++) { num[counter] = Integer.parseInt ( JOptionPane.showInputDialog (
\
// Compute the greatest number up to this point if((counter == 0)||(num[counter] > max)) max = num[counter]; } // Display the greatest number. JOptionPane.showMessageDialog(null,
\
} }
现在,参照GreatestNumber.java写一个新的程序SmallestNumber.java, 找出3个数中的最小值。
实验5.4.4: (W)练习使用数组
写一个类似于ExamScores1.java的程序ExamScores2.java,从命令行参数输入学生成绩,没有输入命令行参数时,程序会显示提示信息。要求程序输出成绩列表,以及成绩的最高分和最低分。程序
6
中不使用Math类的max和min方法。
实验5.4.5: (P)用数组实现斐波纳契函数
编写程序FibonacciArray.java,用数组实现斐波纳契函数。由键盘读入n值(参见实验1.4.15)。程序将在控制台输出此斐波纳契序列f(0),f(1),…… f(n)。
斐波纳契序列的定义如下:
如果n = 0 或者 n = 1 , 则 f(n) = 1
如果n是一个整数并且n > 1 , 则f(n)= f(n-1) + f(n-2)
实验5.4.6: (I)字符串和字符数组
在Java库文件中查看String类的toCharArray方法。我们提到过String包含一串字符,更准确地讲,包含了一个字符数组以及操作这些字符的大量方法。
String类的toCharArray方法将字符串转换为Character数组。toCharArray是一个实例方法还是类方法,查看Java文档,写下结果:
_______________________________________________________
范例5-3使用toCharArray方法实现字符串反转。
程序清单5-3:StringReverse.java
public class StringReverse { public static void main(String[] args) { System.out.println(reverse(args[0])); } public static String reverse( String inputString) { if (inputString == null) return null; else { char[] charArray = inputString.toCharArray(); //string to char array for (int i = 0; i < charArray.length / 2; i++) { char temp = charArray [i]; charArray [i] = charArray [charArray.length - i - 1]; charArray [charArray.length - i - 1] = temp; } String re = new String(charArray); //char array to string return re; } } // method reverse }
7
以上程序的算法如下图所示,程序进行1/2数组长度次的循环,每次调换头尾两个位置中的元素。在第一次循环中,先将位置0上的元素存放在temp变量,然后将位置9上的元素赋值到位置0,最后将temp中元素存入位置9。在第二次循环时,先将位置1上的元素存放在temp变量,然后将位置8上的元素赋值到位置1,最后将temp中元素存入位置8。依次类推,最后一次循环,将位置4和位置5中的元素交换。
图5.2 字符串反转算法描述
实验5.4.7: (I)传递数组参数
用简单类型数据做参数时,Java遵循值传递的原则。实质上,就是将参数值先拷贝一份,然后将拷贝传递给方法。因此,在方法内部修改参数对原来的变量没有影响(因为只是对拷贝的修改),而且,方法返回时,方法调用的空间回收,拷贝的参数空间也被收回。
Java中,不能把对象传递给方法,只能传递对象的引用(Reference,即对象的内存地址)。引用本身也是采用值调用。当一个方法接受对象的引用后,它就可以直接操纵对象。
尽管数组在语法上有别于其他一般意义上的对象,但数组被Java看作是对象。数组以引用调用的方式传递给方法,数组的引用变量包含一个指针,指向数组在存储器中的实际存储位置。
编译并运行程序ValueVsReference.java。
程序清单5-4:ValueVsReference.java
public class ValueVsReference {
public static void main(String[] args) { short[] a = { 0, 2, 4, 6, 8 };
System.out.println(\ for ( int i = 0; i < a.length; i++ ) System.out.print(\ \ System.out.println();
System.out.println(\
modifyPrimitive(a[0]);
for ( int i = 0; i < a.length; i++ ) System.out.print(\ \
System.out.println(\ Method tried to modify primitive element.\
modifyArray(a);
8
for ( int i = 0; i < a.length; i++ ) System.out.print(\ \
System.out.println(\ Method modified array.\
modifyArrayReference(a);
for ( int i = 0; i < a.length; i++ ) System.out.print(\ \
System.out.println(\ Method modified its own reference to array.\ } // method main
public static void modifyPrimitive(short p) { p = 20;
} // method methodA
public static void modifyArray(short[] b) { for ( int j = 0; j < b.length; j++ ) b[j] = (short) (j*(-3)); } // method modifyArray
public static void modifyArrayReference(short[] b) { b = new short[5];
for ( int j = 0; j < b.length; j++ ) b[j] = (short) (j*3);
} // method modifyArrayReference } // class ValueVsReference
范例5-4定义了main和其他三个方法modifyPrimitive,、modifyArray和modifyArrayReference。
(1) modifyPrimitive 方法修改参数p的值,p是short原始数据类型。因此,此方法的参数转递为值传递。main方法中调用modifyPrimitive方法,传递的实际参数是数组的一个元素a[0],此元素的类型也是short原始数据类型。
(2) modifyArray方法的参数为数组引用变量b,而不是单独的某个数组元素。方法的头部定义如下:
public static void modifyArray(short[] b)
通过引用变量b,可以操纵b指向的数组对象。main方法中调用modifyArray方法,传递的实际参数是数组引用变量a,此时a和b的实际值都是一个指向同一数组对象的指针。modifyArray方法中,对b引用的数组对象的修改,就是对a引用的数组对象的修改。方法调用完成后,变量b的空间被回收,a引用的数组对象被修改。
(3) modifyArrayReference 方法内,数组引用变量b 被重新赋值,指向一个新创建的数组: b = new short[5];
main方法中调用modifyArrayReference方法,传递的实际参数是数组引用变量a。但由于上面的这个赋值语句,形式参数b指向了一个新的数组,而不再指向a引用的数组。对变量b引用
9
的数组对象的任何修改都不会改变变量a引用的数组对象。
现在,请写下程序执行后的结果,并认真思考为什么是这样的结果。
___________________________________________________________________________________
___________________________________________________________________________________
___________________________________________________________________________________
___________________________________________________________________________________
实验5.4.8: (W)写一个带有数组参数的方法
在MathUtility.java(见程序清单4-6)中,写一个静态方法average,此方法用一个双精度浮点数(double)数组作为参数,并返回此数组中元素的平均值。如果数组长度为0,方法返回值为0,并打印一个标准错误输出流消息。回顾如何定义一个指向double类型数组的指针,并在方法的参数列表中声明。
以如下方式定义average方法的方法头:
public static double average (double[] doubleArray) 运行AverageTest.java程序测试average方法。
程序清单5-5:AverageTest
public class AverageTest {
public static void main(String[] args) { if (args.length == 0) {
System.out.println(\
+ \ System.out.println(\
+ \ Result should be zero\ System.out.println(\ } // if
double[] numbers = new double[args.length];
for ( int i = 0; i < args.length; i++ )
numbers[i] = new Double(args[i]).doubleValue();
System.out.println(\ } // method main } // class AverageTest
10