3.2 习题解析
一、选择题
1. 以下选项中,合法的赋值语句是______。
A. ++m!=n--; B. ++ m; C. m=m + 1= 5; D. m = = 1;
答案:B
解析:在上述四个选项中,选项A和D为逻辑表达式而非赋值语句;选项C中的m+1=5的表示是错误的;选项B中实现的功能等同于m=m+1。
2. 下列语句序列执行后,ch1变量中的值为______。
char ch1='A', ch2='B';
if (ch1 + 2 < ch2) ++ch1 ;
A. 'A' B. 'B' C. A D. B
答案:A
解析:Java的字符比较运算遵循原则:首先将字符转换为Unicode代码(Unicode代码最前面的128个字符与ASCII代码相同),然后再比较其大小。当前ch1为'A',其Unicode代码值为65,ch2为'B',其Unicode代码值为66,65+2大于66,故表达式(ch1 + 2 < ch2)的值为false,根据单分支结构语句的运行规则,此时并不进行++ch1的运算,因此ch1的值仍旧为'A',而字符常量的表示规则为该字符两端必须加上单引号,故答案A正确。
3. 下列语句序列执行后,c变量的值为______。
int a=2, b=4, c=5;
if (a<--b) c*=a;
A. 5 B. 20 C. 15 D. 10
答案:D
解析:在表达式(a<--b)中先进行--b的运算,由于b的值为4,经运算后b的值为3,故表达式的值为真,因而将进行c=a的运算,其运算的结果等同于c=ca,在a=2,c=5的前提下,显然经运算后c的值为10,故选项D是正确的。
4. 下列语句序列执行后,c 的值是______。
int a=6, b=3, c=5;
if (a==b) c+=a; else c=++a*c;
A. 15 B. 25 C. 35 D. 45
答案:C
解析:根据双分支结构语句的运行规则,当关系表达式(a==b)的值非真时,执行else后面的语句“c=++a*c;”,由于此时a为6,++a后a的值为7,而c为5,故相乘后值为35,选项C是正确的。
5. 下列语句序列执行后,c的值是______。
int a=4,b=5,c=9,d=6;
if (a>b||c
A. 6 B. 10 C. 8 D. 9
答案:B
解析:根据变量初始化后所赋的值,可知表达式(a>b| |c
6. 设a、b为int类型变量,c、d为float类型变量,ch为char类型变量,且所有变量均已赋值,则下列正确的switch语句是______。
A. switch (a + b); {...} B. switch (ch + 1) {...}
C. switch ch {...} D. switch (c + d) {...}
答案:B
解析:根据switch语句的使用规则,switch后面的表达式不允许是float类型的数据,故答案D错;表达式必须用括号括起,故答案C错;表达式后面应紧跟复合语句,不允许出现分号,故答案A错;程序运行时,会自动将ch + 1转换为整型数据并完成运算,故选项B是正确的。
7. 下列语句序列执行后,c的值是______。
int a=10, b=18, c=30;
switch (b-a) {
case 8 : c++;
case 9 : c+=2;
case 10: c+=3;
default :c/=b;
}
A. 31 B. 32 C. 2 D. 33
答案:C
解析:根据switch语句的运行规则,当b–a的值为8时执行“case 8 :”行的语句,执行结果为c取值31,由于没有break语句,故程序将继续执行“case 9 :”行语句以及下面的所有语句,当执行到“case 10 :”行语句时,c取值36,故执行“default :”行语句时,36除以18得商为2,故选项C正确。
8. 下列语句序列执行后,a的值为______。
int a=1;
for ( int i=5; i>0; i-=2 ) a*=i;
A. 0 B. 1 C. 15 D. 60
答案:C
解析:在当前的循环语句中,由于循环变量的增值步长为-2,故循环将被执行3次,分别是当i为5、3和1时;由于a的初值为1,故连续乘以5、3和1之后其值应为15,故选项C正确。
9. 下列语句序列执行后,c的值为______。
int a=3, b=4, c=0;
while ((a++)<(-- b)) ++c;
A. 0 B. 1 C. 2 D. 3
答案:A
解析:在表达式(a++) < (--b)的运算过程中,变量a是与变量b先比较而后自加,而变量b则反之:先自减而后与变量a比较。数值代入后的表达式为:3<3,表达式显然非真,故本循环其实一次也没有执行,当然c还是维持原来的值:0,故选项A正确。
10. 下面关于数组定义语句不正确的是______。
A. float f[]=new {2.4f,3.5f,5.7f,7.9f}; B. int a1[]={1,2,3,4,5};
C. double[] d=new double[10]; D. int[] a2;
答案:A
解析:对于Java一维数组的声明,可以有两种形式。标准的声明格式为:
type <数组名>[ ];//声明一维数组
数组名=new type [<元素个数>];//分配内存给数组
而
type <数组名>[ ]=new type [<元素个数>];
可以理解为上面两个语句的缩写形式。
第二种形式是在声明时直接赋值,格式为:
type <数组名>[ ]={<数值1>,<数值2>,…,<数值n>};
两种形式不可混淆使用,故选项A的定义方式是不正确的。
11. 设有定义语句int a[ ]={36,72,99},则以下对此语句叙述错误的是______。
A. 该语句定义了一个名为a的一维数组 B. a数组有3个元素
C. 数组中的每个元素是整型 D. a数组的元素的下标为1~3
答案:D
解析:Java的数组一旦声明,下标自动从0开始编号,所以a数组的元素的下标为0~2,选项D的叙述是错误的。
12. 在一个应用程序中定义了数组a:int[ ] a={1,2,3,4,5,6,7,8,9,10},为了打印输出数组a的最后一个数组元素,下面正确的代码是______。
A. System.out.println(a[10]); B. System.out.println(a[9]);
C. System.out.println(a[8]); D. System.out.println(a[a.length]);
答案:B
解析:由于当前数组a中有10个元素,而Java的数组下标自动从0开始编号,因此最后一个元素应为a[9],a[10]在内存中是不存在的,而a.length中返回的是该数组的元素个数,其值为10,故选项B是正确的。
13. 执行下列语句
int[] lx = {2,3,4,5};
lx[3] = lx[3] == --lx[0]?++lx[1]:lx[2]--;
后,数组lx的元素值分别为______。
A. 1,2,3,4 B. 1,3,3,3 C. 1,2,3,3 D. 1,3,3,4
答案:D
解析:当数组lx中的元素被分别赋值之后,对于表达式:lx[3] == ––lx[0]?++lx[1]:lx[2]––,由于此时lx[0]取值为2,lx[3]取值为5,因此显然lx[3] == ––lx[0]取值非真,根据多元运算符“?:”的运算规则:应将冒号后面的表达式的值(lx[2]––)赋值给lx[3],由于此时lx[2]取值为4,系统先将该值赋予lx[3],然后对lx[2]进行自减;由于整个过程中lx[1]并未被引用,因此也不会进行自增的操作。
14. 语句
String s1 = new String("Hello");
String s2 = new String("Hello");
System.out.println(s1 == s2);
System.out.println(s1.equals(s2));
执行后的输出结果是______。
A. Hello B. Hello C. Hello D. false
false true Hello true
答案:D
解析:String类型数据并非Java的基本数据类型,s1和s2是从java.lang中的字符串类中创建的实例对象,对于实例对象而言,“==”所比较的是两者的内存地址而非它们的具体内容,若要比较两者的具体内容是否相同,必须使用其所对应的方法“equals()”,“==”与“equals()”比较的结果均为逻辑值,故答案D正确。
15. 设有如下定义语句:
String s1="My cat";
int m=s1.compareTo("My a cat");
语句被执行后m的值为______。
A. 2 B. 1 C. 0 D. –2
答案:A
解析:Java语言处理系统对于字符串的比较基于字符串中各个字符的Unicode值。将此 String变量表示的字符序列与参数字符串所表示的字符序列进行逐个比较。如果按字典顺序此String变量在参数字符串之前,则比较结果为一个负整数;如果按字典顺序此String变量位于参数字符串之后,则比较结果为一个正整数。当前String变量s1按字典顺序显然在参数字符串"My a cat"之后,因此比较结果为正值,且c的Unicode代码比a的Unicode代码大2,故选项A正确。
16. 下列方法定义中,正确的是______。
A. double me(int a, int b) { int r; r=a–b; }
B. double me(a, b ) { return b; }
C. int me(int a, int b) { return a–b; }
D. int me(int a, b) { return (a–b); }
答案:C
解析:对于有返回值的方法的定义,一般都使用return语句将计算值返回至主调程序,故答案A的定义不正确;方法的返回值类型必须与方法声明类型一致,答案B中的变量b没有声明其类型,故该定义也不正确;方法中若有参数,该方法声明时参数必须逐个明确声明,答案D中参数a虽然经过了声明,但参数b却没有声明,故该定义也不正确;显然只有答案C是符合要求的。
17. 下列方法定义中,不正确的是______。
A. float x( int a,int b ) { return (a–b); }
B. int x( int a,int b) { return a–b; }
C. int x( int a,int b ) { return ab; }
D. int x(int a,int b) { return 1.2(a+b); }
答案:D
解析:根据上题所述理由:方法的返回值类型必须与方法声明类型一致,而1.2*(a+b)显然不是整型数值,故答案D的方法定义不正确。
18. 在Java程序中所提到的“递归”的基本概念,其基本思想是______。
A. 让别人反复调用自己 B. 自己反复调用别人
C. 自己反复调用自己 D. 以上说法都不对
答案:C
解析:Java程序中的方法须经过调用方能得以运行(主方法除外),根据不同的具体需求,Java中的方法一可以调用方法二,方法二可以调用方法三(称为嵌套调用),方法一也可以调用方法一本身(称为递归调用),故答案C正确。
二、程序填空
1. 下面程序的功能是:由键盘输入一个小于“100”的数字字符串(例如“38”),将它转换成整数,然后计算并输出从该整数到100之间所有整数的累加和。请将程序补充完整。
import (1) ;
public class NumJa1{
public static void main(String args[]) throws IOException{
int num1,s;
String str;
BufferedReader buf;
buf=new BufferedReader(new InputStreamReader(System.in));
System.out.print("请输入整数:");
str= (2) ;
num1= (3) ;
if (num1>=100)
System.out.print("输入的数已超出范围");
else {
(4) ;
for ( (5) )
s=s+i;
System.out.println("The sum is "+s);
}
}
}
答案:
(1)java.io.*
(2)buf.readLine();
(3)Integer.parseInt(str);
(4)s=0
(5)int i=num1;i<=100;i++
解析:本程序中使用了键盘输入语句,处理该语句的工具BufferedReader类与InputStreamReader类都被封装于java.io包中,故在程序开始时,必须首先引入这个包以及这个包中所有的类。readLine()是BufferedReader类中封装的方法,用于接收用户从键盘输入的数据,该方法必须由对象加以调用。因此程序首先声明了buf对象,然后通过该对象调用其方法。因为此程序从键盘获得的数据是字符串,因而数据一旦被读入,应立即将其转换为整型数才能对变量num1赋值。当程序开始累加操作时,累加器(此处为变量s)清零是一个必需的过程。按照题目的要求,要设置从num1(键盘输入的数值)开始到100为止、每次循环变量增值为1的循环。
2. 下面Java应用程序接收用户输入的10个整数,将这10个数按从大到小的方式排序并输出,请将程序补充完整。
import java.io.* ;
public class cxtc2{
public static void main(String args[ ])throws IOException{
int arr[]=new (1) , i ;
BufferedReader br;
br =new BufferedReader(new InputStreamReader(System.in));
(2) {
arr[i] = Integer.parseInt(br.readLine() );
}
for (i = 0 ; i < 9 ; i ++)
for ( (3) ;j<10;j++)
if(arr[i] (4) arr[j]){
int t=arr[i];arr[i]=arr[j]; (5) ;
}
System.out.println("排序结果为:");
for ( i = 0 ; i < 10 ; i ++ )
System.out.print(arr[i]+"\t");
}
}
答案:
(1)int[10]
(2)for ( i = 0 ; i < 10 ; i ++ )
(3)int j=i+1
(4)<
(5)arr[j]=t
解析:声明数组的标准语法格式在new的后面应该是该数组的数据类型及其长度。一旦数组与变量声明完毕,后面就是逐个处理由用户从键盘输入的数据,既然是逐个处理,显然该处应使用循环语句,且其循环的次数应该与数组的长度相同、循环变量每次增值为1。由于排序要求为从大到小,故本程序采用的方法是:第一次(也就是第一轮循环),取定数组的第一个元素,把它与后面的元素逐个相比较,凡有比该数(即第一个元素)的数值大的,立刻将这两个元素的数值进行交换,此时值较大的元素换到了第一个元素的位置。交换结束后,将第一个元素再继续与刚才交换位置元素后面的元素进行逐个比较,凡有比该数的数值大的,再将这两个元素的数值进行交换,以此类推,当处理完了最后一个元素之后(即第一轮循环结束),第一个元素的数值自然变成了该数组中的最大值元素了;第二次,取定数组的第二个元素,进行与第一次同样的比较操作,当第二轮循环结束时,第二个元素的数值就是该数组中除了第一个元素之外最大的了。如此进行9次循环之后,数组的元素从大到小就依次排好了。抽象地考虑:当进行第i轮循环时,首先应该取定数组的第i个元素,为了与后面的元素比较,因此必须声明与i类型相同的变量(此处为j),作为循环变量进行操作,且该循环变量的初值显然应该是i+1。每一轮的循环中arr[i]是被取定的元素,arr[j]是与之相比较的元素,比较规则是一旦arr[i]< arr[j],两元素的数值被交换。两个元素数值交换的常用方法是:先把第一个元素的值放到临时变量中暂存(int t=arr[i];),将第二个元素的值赋予第一个元素(arr[i]=arr[j];),再将临时变量中的值赋予第二个元素(arr[j] =t;)。
3. 本程序的功能是:首先建立一个有序数组{18,16,14,12,10,8,6,4,2},然后将整数13插入该数组中并使数组仍然有序,即插入后的数组为{18,16,14,13,12,10,8,6,4,2}。请将程序补充完整。
public class InsertIn{
public static void main(String args[]) {
int i,q=13;
(1)
System.out.println("Before Insert:");
for (i=0;i<=8;i++) {
(2)
System.out.print(n[i]+" ");
}
System.out.println();
System.out.print("After Insert:");
for (i=8;i>=0;i--) {
if (n[i]<=q) {
(3)
if (i==0)
(4)
}
else {
(5)
break;
}
}
System.out.println();
for (i=0;i<=9;i++)
System.out.print(n[i]+" ");
}
}
答案:
(1)int n[]=new int[10];
(2)n[i]=18-2*i;
(3)n[i+1]=n[i];
(4)n[i]=q;
(5)n[i+1]=q;
解析:按照题目的要求首先应该声明数组,数组名应通过仔细观察程序后面所使用到的数组的名称而获得。根据题目要求,数组元素所获得的数值应从递推公式n[i]=18-2*i中产生。当前插入法排序的思想是:将原数组从最后一个元素起,逐个与要插入的数据(此处为q)进行比较,若最后一个元素比q小,则将该元素后移一位(即将n[8]的值赋予n[9]);然后将倒数第二个元素与q进行比较,若该元素仍然小于q,则同样将该元素后移一位(即将n[7]的值赋予n[8]);以此类推到倒数第i个元素,若该元素仍然小于q,则同样将该元素后移一位(即将n[i]的值赋予n[i+1]);若判断下来所有的元素都小于q(此时所有的元素都被后移了一位),则将q的值赋予第一个元素;若判断下来所有的元素都不小于q,则将q的值赋予最后一个元素。事实上,由于原数组本来有序,所以只要将原数组中的最后一个元素与q进行比较,若该元素的值比q大,则前面的元素都不会比q小,所以直接将q的数值赋予最后一个元素即可。
4. 下面程序的运行功能为实现字符串中字符的删除:现有字符串为“zyzmmmazza”,要从中删除字符“z”,程序运行后结果显示为“ymmmaa”。请将程序补充完整。
class TestString{
static String strip(String s,char c){
int n= (1) ;
char[] a= new char[n];
int i=0;
int j=0;
while( (2) ) {
char sn= (3) ;
if (sn==c) j++;
else a[ (4) ]=sn;
}
return new String(a,0,i);
}
public static void main(String[] args){
String s=new String("zyzmmmazza");
System.out.println(s);
s= (5) ;
System.out.println(s);
}
}
答案:
(1)s.length()
(2)i+j<n
(3)s.charAt(i+j)
(4)i++
(5)strip(s,'z')
解析:本程序的TestString类中除了主方法之外,还包含另外一个类方法strip(),其中strip()方法含有两个参数,这个方法显然应该在主方法中被调用,而当前主方法中除了该填的空之外没有任何调用方法的语句,因此第5个空应填入含有实参的调用方法表达式;在strip()方法中,n的值用于声明字符数组的长度,在这里,字符数组用于存放被删除所指定字符(此处为'z')之后所剩的字符串,它的最大长度应等同于主方法中传入的字符串的长度,故在第1个空中应填入“s.length();”,从“if (sn==c) j++”语句可知,变量j用于统计字符串中要删除的字符(此处为'z')的个数,则变量i显然用于统计原字符串中所有不为'z'的字符的个数,本程序的基本思想是:从原字符串中逐个取字符进行判别,若当前取得的字符为'z',则变量j增1;若当前取得的字符不为'z',则将该字符放入a数组中,同时数组下标变量增1,以此类推,直到进行到原字符串的最后一个字符为止,当处理完最后一个字符,此时i+j应等于n,故在第2个空中应填入:i+j<n,只有当字符串没被处理完才有继续循环的必要。第3个空所在的语句的作用是逐个从原字符串中取得字符,我们知道要从字符串的指定位置中取得字符,可以调用字符串对象所支持的charAt()方法,在循环过程执行到该语句时,由于前面的字符不是被舍弃,就是被存放到a数组中了,所以当前取得字符的位置应该是i+j,故在第3个空中应填入:s.charAt(i+j)。将需保存的字符放入a数组中时,数组下标变量需自动增1,以便后面的字符可以被继续存放,故在第4个空中应填入:i++。