【Java编程思想】第四版课后习题笔记

版权声明:整理不易,转载请注明出处。 https://blog.csdn.net/linmengmeng_1314/article/details/83831732

2.11练习10:
编写一个程序:打印出从命令行获得的三个参数。为此,需要确定命令行数组中string的下标。
书上的答案是:

public class E10 {
	public static void main(String[] args) {
		System.out.println(args[0]);
		System.out.println(args[1]);
		System.out.println(args[2]);
	}
} /* Output: A B C *///:~ 

但是我在Myeclipse里面编写之后,运行,直接就报错了,提示下表越界了,这让我很费解。。。。。

Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 0
	at chart2.E10.main(E10.java:6)

然后注释掉输出语句,打印args.length发现长度为0????
不应该啊,这么经典的书籍怎么会有这么明显的错误呢?于是我开始百度这道题

然后才意识到,这里需要使用jdk编译运行这个文件,然后才能输入输出。因为这里我使用的是IDE编写的,然后直接编译运行了,根本没有输入参数,所以args的leng是0。找到原因之后,我用记事本文件编写这个类,然后直接在cmd里面使用javac E10.java编译,然后运行java E10 4 5 6,这里4 5 6 三个数是输入的参数,可以看到程序正常输出4 5 6了。

有些时候IDE工具确实方便,但是有时候却无法使我们接触到程序底层的运行过程。想弄懂这些还是需要回归到原始的编码方式,我慢慢的意识到大佬建议初学者使用记事本编写程序的用意了。

这里还可以加一个if语句,用来提示输入三个参数。或者直接使用for循环输出用户输入的参数

public class E10 {

	public static void main(String[] args) {
		if (args.length < 3) {
			System.out.println("Need 3 arguments");
			System.exit(1);
		}
		System.out.println(args[0]);
		System.out.println(args[1]);
		System.out.println(args[2]);
	}
	/*for (int i = 0; i < args.length; i++) {
			System.out.println(args[i]);
		}*/
}

4.9斐波那契数列
斐波那契数列是由数字1、1、2、3、5、8、13、21、34等等组成的,其中每一个数字(从第三个数字起)都是前两个数字的和。创建一个方法,接受一个整数参数,并显示从第一个元素开始总共有该参数所构成的所有的斐波那契数字。例如。如果运行java Fibonacci 5(其中Fibonacci是类名),name输出应该是1、1、2、3、5

public class E09_Fibonacci {
    public static void main(String[] args) {
        int n = Integer.parseInt(args[0]);
        if (n<0){
            System.out.println("cannot use negative numbers");
            return;
        }
        for (int i=1; i <= n; i++){
            System.out.print(fi(i) + ", ");
        }
    }
    static int fi(int n){
        if (n <= 2){
            return 1;
        }
        return fi(n-1) + fi(n-2);
    }
}

4.10 吸血鬼数字
吸血鬼数字是指位数为偶数的数字,可以由一对数字相乘而得到,而这对数字包含乘积的一半位数的数字,其中从最初的数字中选取的数字可以任意排序。以两个0结尾的数字是不允许的,例如,下列数字都是“吸血鬼”数字:
1260 = 21 * 60
1827 = 21 * 87
2187 = 27 * 81
写一个程序,找出4位数的所有的吸血鬼数字(Dan Forhan 推荐)。

public class E10_Vampire {
    public static void main(String[] args) {
        int[] startDigit = new int[4];
        int[] productDigit = new int[4];
        for (int num1 = 10; num1 <= 99; num1++)
            for (int num2 = num1; num2 <= 99; num2++) {
                // Pete Hartley's theoretical result:
                // If x·y is a vampire number then
                // x·y == x+y (mod 9)
                if ((num1 * num2) % 9 != (num1 + num2) % 9)
                    continue;
                int product = num1 * num2;
                startDigit[0] = num1 / 10;
                startDigit[1] = num1 % 10;
                startDigit[2] = num2 / 10;
                startDigit[3] = num2 % 10;
                productDigit[0] = product / 1000;
                productDigit[1] = (product % 1000) / 100;
                productDigit[2] = product % 1000 % 100 / 10;
                productDigit[3] = product % 1000 % 100 % 10;
                int count = 0;
                for (int x = 0; x < 4; x++)
                    for (int y = 0; y < 4; y++) {
                        if (productDigit[x] == startDigit[y]) {
                            count++;
                            productDigit[x] = -1;
                            startDigit[y] = -2;
                            if (count == 4)
                                System.out.println(num1 + " * " + num2 + " : " + product);
                        }
                    }
            }
    }
}
/* Output: 
15 * 93 : 1395
21 * 60 : 1260
21 * 87 : 1827
27 * 81 : 2187
30 * 51 : 1530
35 * 41 : 1435
80 * 86 : 6880
下面这两句我是真的没看懂。。。。。。。。。。。。。。。。。。。。。。
productDigit[x] = -1;
startDigit[y] = -2;
*///:~ 

5.1 无参构造器
创建一个类,它包含一个未初始化的String引用。验证该引用被初始化成了null。

public class E01_StringRefInitialization {
    String s;
    public static void main(String[] args) {
        E01_StringRefInitialization e =  new E01_StringRefInitialization();
        System.out.println("e.s = " + e.s);
    }
}
 /* Output: e.s = = null *///:~

5.1 定义时初始化和构造器初始化的区别
创建一个类,它包含一个在定义时就被初始化了的String域,以及另一个通过构造器初始化的String域。这两种方式有何差异?

public class E02_StringInitialization {
    String s1 = "Initialized at definition";
    String s2;

    public E02_StringInitialization(String s2i) {
        s2 = s2i;
    }

    public static void main(String[] args) {
        E02_StringInitialization si = new E02_StringInitialization("Initialized at construction");
        System.out.println("si.s1 = " + si.s1);
        System.out.println("si.s2 = " + si.s2);
    }
} 
/* Output: 
si.s1 = Initialized at definition 
si.s2 = Initialized at construction 
*///:~

“The s1 field is initialized before the constructor is entered; technically, so is the s2 field, which is set to null as the object is created. The more flexible s2 field lets you choose what value to give it when you call the constructor, whereas s1 always has the same value. ”
其中s1是在创建对象之前就已经初始化了的,而s2则是创建对象时才初始化的,s2是可以随着构造器的创建来设置不同的值,而s1则是初始化之后就不会改变的。

猜你喜欢

转载自blog.csdn.net/linmengmeng_1314/article/details/83831732