(三)Java的基本程序结构(二)---数据输入、控制流、大数、数组

Java的基本程序结构(二)—数据输入、控制流、大数、数组


前言

提示:以下是本篇文章正文内容,下面案例可供参考


一、数据输入

前面已经了解到,将输出打印到控制台是一件非常容易的事情,只需要调用System.out.println()即可。然而读取就没有那么简单了。要想通过控制台进行输入,首先要构造一个与“标准输入流”System.in关联的Scanner对象。

我们可以通过 Scanner 类来获取用户的输入。使用步骤如下:
1、导包。Scanner 类在java.util包下,所以需要将该类导入。导包的语句需要定义在类的上面。

import java.util.Scanner;

2、创建Scanner对象。

Scanner sc = new Scanner(System.in);

3、接收数据

int text = sc.nextInt(); // 表示将键盘录入的值作为int数返回。

例如:

//创建对象
Scanner sc = new Scanner(System.in);
//接收数据 
int text = sc.nextInt(); 
//输出数据 
System.out.println("text:" + text);

补充:
1、Scanner(InputStream in)
用给定的输入流创建一个Scanner对象
2、String nextLine()
读取用户输入的下一行内容
3、String next()
读取输入的下一个单词(以空格作为分隔符)
4、double nextDouble()
读取并转换下一个表示整数或浮点数的字符序列
5、boolean hasNext()
检测输入中是否还有其他单词


二、控制流

在一个程序执行的过程中,各条语句的执行顺序对程序的结果是有直接影响的。所以,我们必须清楚每条语句的执行流程。而且,很多时候要通过控制语句的执行顺序来实现我们想要的功能。

1、块作用域

在深入学习控制结构之前,需要了解块(block)的概念。
块(即复合语句)是指若干条Java语句组成的语句,并用一对大括号括起来。块确定了变量的作用域。一个块可以嵌套在另一个块中。
例如:

public static void main(String[] args) {
	int n;
	//若干语句
	{
		int k;
		//若干语句
	}
}

但是,嵌套的块中不能声明同名的变量。例如下面代码就有错误,并无法通过编译。

public static void main(String[] args) {
	int n;
	//若干语句
	{
		int k;
		int n;
		//若干语句
	}
}

2、流程控制语句分类

1、顺序结构
2、分支结构(if, switch)
3、循环结构(for, while, do…while)

3、顺序结构

顺序结构是程序中最简单最基本的流程控制,没有特定的语法结构,按照代码的先后顺序,依次执行,程序中大多数的代码都是这样执行的。

4、分支结构

1、if语句

if语句格式1:

if (关系表达式) { 
	语句体; 
}

执行流程:
①首先计算关系表达式的值
②如果关系表达式的值为true就执行语句体
③如果关系表达式的值为false就不执行语句体
④继续执行后面的语句内容

示例:

System.out.println("开始"); // 定义两个变量 
int a = 10; 
int b = 20;
//需求:判断a和b的值是否相等,如果相等,就在控制台输出:a等于b 
if(a== b) { 
	System.out.println("a等于b");
}
//需求:判断a和c的值是否相等,如果相等,就在控制台输出:a等于c 
int c = 10; 
if(a == c) {
	System.out.println("a等于c");
}
System.out.println("结束");

if语句格式2:

if (关系表达式) { 
	语句体1; 
} 
else { 
	语句体2; 
}

执行流程:
①首先计算关系表达式的值
②如果关系表达式的值为true就执行语句体1
③如果关系表达式的值为false就执行语句体2
④继续执行后面的语句内容

System.out.println("开始"); 
//定义两个变量 
int a = 10; 
int b = 20; 
b = 5; 
//需求:判断a是否大于b,如果是,在控制台输出:a的值大于b,否则,在控制台输出:a的值不大于b 
if(a > b) { 
	System.out.println("a的值大于b"); 
} 
else 
{ 
	System.out.println("a的值不大于b"); 
}
System.out.println("结束");

实例:

Scanner sc = new Scanner(System.in);
System.out.println("输入一个数字:");
int num = sc.nextInt();
if (num % 2 == 0) {
	System.out.println(num+"是一个偶数");
} else {
	System.out.println(num+"是一个奇数");
}

else子句总是与最邻近未配对的 if 构成一组。

if语句格式3

if (关系表达式1) { 
	语句体1; 
} 
else if (关系表达式2) { 
	语句体2; 
}else {
	语句体n+1; 
}

执行流程:
①首先计算关系表达式1的值
②如果值为true就执行语句体1;如果值为false就计算关系表达式2的值
③如果值为true就执行语句体2;如果值为false就计算关系表达式3的值
④…
⑤如果没有任何关系表达式为true,就执行语句体n+1。

示例:
键盘录入一个星期数(1,2,…7),输出对应的星期一,星期二,…星期日

Scanner sc = new Scanner(System.in);
System.out.println("请输入星期几数字:");
int num = sc.nextInt();
if (num==1) {
	System.out.println("今天周一");
}
else if (num==2) {
	System.out.println("今天周二");
}
else if (num==3) {
	System.out.println("今天周三");
}
else if (num==4) {
	System.out.println("今天周四");
}
else if (num==5) {
	System.out.println("今天周五");
}
else if (num==6) {
	System.out.println("今天周六");
}
else if (num==7) {
	System.out.println("今天周日");
}
else {
	System.out.println("输入错误");
}

2、switch语句(多重选择)

格式:

switch (表达式) { 
	case 1: 语句体1; break; 
	case 2: 语句体2; break; 
	... 
	default: 语句体n+1; break; 
}

执行流程:
1、首先计算出表达式的值
2、其次,和case依次比较,一旦有对应的值,就会执行相应的语句,在执行的过程中,遇到break就会结束。
3、最后,如果所有的case都和表达式的值不匹配,就会执行default语句体部分,然后程序结束掉。

case标签可以是:
1、类型为char、byte、short或int的常量表达式
2、枚举常量
3、从Java7开始,cse标签还可以是字符串字面量

例如:

case "yes": ...;break;

示例:春夏秋冬

//键盘录入月份数据,使用变量接收
Scanner sc = new Scanner(System.in); 
System.out.println("请输入一个月份:"); 
int month = sc.nextInt(); 
//case穿透
switch(month) { 
	case 1:
	case 2: 
	case 12: System.out.println("冬季"); break; 
	case 3: 
	case 4: 
	case 5: System.out.println("春季"); break; 
	case 6: 
	case 7: 
	case 8: System.out.println("夏季"); break; 
	case 9: 
	case 10: 
	case 11: System.out.println("秋季"); break; 
	default: System.out.println("你输入的月份有误");break;
}

注意:如果switch中得case,没有对应break的话,则会出现case穿透的现象。

5、循环结构

1、for循环结构

循环语句可以在满足循环条件的情况下,反复执行某一段代码,这段被重复执行的代码被称为循环体语句,当反复执行这个循环体时,需要在合适的时候把循环判断条件修改为false,从而结束循环,否则循环将一直执行下去,形成死循环。

for循环格式:

for (初始化语句;条件判断语句;条件控制语句) { 
	循环体语句; 
}

格式解释:
1、初始化语句: 用于表示循环开启时的起始状态,简单说就是循环开始的时候什么样
2、条件判断语句:用于表示循环反复执行的条件,简单说就是判断循环是否能一直执行下去
3、循环体语句: 用于表示循环反复执行的内容,简单说就是循环反复执行的事情
4、条件控制语句:用于表示循环执行中每次变化的内容,简单说就是控制循环是否能执行下去

执行流程:
①执行初始化语句
②执行条件判断语句,看其结果是true还是false
如果是false,循环结束
如果是true,继续执行
③执行循环体语句
④执行条件控制语句
⑤回到②继续

//定义变量count,用于保存“水仙花数”的数量,初始值为0 int count = 0; 
//输出所有的水仙花数必然要使用到循环,遍历所有的三位数,三位数从100开始,到999结束 
for(int i=100; i<1000; i++) { 
	//在计算之前获取三位数中每个位上的值 
	int ge = i%10; 
	int shi = i/10%10; 
	int bai = i/100; 
	//在判定水仙花数的过程中,满足条件不再输出,更改为修改count的值,使count+1 
	if(ge*ge*ge + shi*shi*shi + bai*bai*bai == i) { 
	count++; 
	} 
}
//打印输出最终结果 
System.out.println("水仙花共有:" + count + "个");

2、while循环

while循环完整格式:

初始化语句; 
while (条件判断语句) { 
	循环体语句; 
	条件控制语句; 
}

while循环执行流程:
①执行初始化语句
②执行条件判断语句,看其结果是true还是false
如果是false,循环结束
如果是true,继续执行
③执行循环体语句
④执行条件控制语句
⑤回到②继续

示例(珠穆朗玛峰):
世界最高山峰是珠穆朗玛峰(8844.43米=8844430毫米),假如我有一张足够大的纸,它的厚度是0.1毫米。请问,我折叠多少次,可以折成珠穆朗玛峰的高度?

// 定义一个计数器,初始值为0 
int count = 0; 
//定义纸张厚度 
double paper = 0.1;
//定义珠穆朗玛峰的高度
int zf = 8844430; 
//因为要反复折叠,所以要使用循环,但是不知道折叠多少次,这种情况下更适合使用while循环 
//折叠的过程中当纸张厚度大于珠峰就停止了,因此继续执行的要求是纸张厚度小于珠峰高度
while(paper <= zf) { 
	//循环的执行过程中每次纸张折叠,纸张的厚度要加倍 
	paper *= 2; 
	//在循环中执行累加,对应折叠了多少次 
	count++; 
}
//打印计数器的值 
System.out.println("需要折叠:" + count + "次");

3、 do…while循环结构

完整格式:

初始化语句; do {
	循环体语句; 
	条件控制语句; 
}while(条件判断语句);

执行流程:
① 执行初始化语句
② 执行循环体语句
③ 执行条件控制语句
④ 执行条件判断语句,看其结果是true还是false
如果是false,循环结束
如果是true,继续执行
⑤ 回到②继续

int j = 1; 
do {
	System.out.println("HelloWorld"); 
	j++; 
}while(j<=5);

4、三种循环的区别

三种循环的区别
1、for循环和while循环先判断条件是否成立,然后决定是否执行循环体(先判断后执行)。
2、do…while循环先执行一次循环体,然后判断条件是否成立,是否继续执行循环体(先执行后判断)。

for循环和while的区别
1、条件控制语句所控制的自增变量,因为归属for循环的语法结构中,在for循环结束后,就不能再次被访问到了。
2、条件控制语句所控制的自增变量,对于while循环来说不归属其语法结构中,在while循环结束后,该变量还可以继续使用。

死循环(无限循环)的三种格式

  1. for( ; ; ) {}
  2. while(true){}
  3. do {} while(true);

5、跳转控制语句

1、跳转控制语句(break)
跳出循环,结束循环

2、跳转控制语句(continue)
跳过本次循环,继续下次循环

注意: continue只能在循环中进行使用!

6、循环嵌套

循环嵌套概述:在循环中,继续定义循环。

for (int hour = 0; hour < 24; hour++) { 
	for (int minute = 0; minute < 60; minute++) { 
		System.out.println(hour + "时" + minute + "分"); 
	}
	System.out.println("--------"); 
}

请反复理解这句话(整个内循环,就是外循环的一个循环体,内部循环体没有执行完毕,外循环是不会继续向下执行的)。

结论:外循环执行一次,内循环执行一圈

6、Random

Random产生随机数。
Random类似Scanner,也是Java提供好的API,内部提供了产生随机数的功能。
使用步骤:

  1. 导入包
    import java.util.Random;
  2. 创建对象
    Random r = new Random();
  3. 产生随机数
    int num = r.nextInt(10);
    解释: 10代表的是一个范围,如果括号写10,产生的随机数就是0-9,括号写20,参数的随机数则是0-19
//创建对象
Random random = new Random();
//用for循环或许3个随机数
for (int i = 1; i <= 3; i++) {
	int num = random.nextInt(10)+1;
	System.out.println("num:"+num);
}
System.out.println("--------");
//获取一个1-100之间的随机数
int x = random.nextInt(100) + 1;
System.out.println(x);

示例(猜数字游戏):

程序自动生成一个1-100之间的数字,使用程序实现猜出这个数字是多少?
当猜错的时候根据不同情况给出相应的提示:
A. 如果猜的数字比真实数字大,提示你猜的数据大了
B. 如果猜的数字比真实数字小,提示你猜的数据小了
C. 如果猜的数字与真实数字相等,提示恭喜你猜中了

//要完成猜数字的游戏,首先需要有一个要猜的数字,使用随机数生成该数字,范围1到100
Random random = new Random();
int number = random.nextInt(100)+1;
while (true) {
	//使用程序实现猜数字,每次均要输入猜测的数字值,需要使用键盘录入实现
	Scanner sc = new Scanner(System.in);
			
	System.out.println("请输入要猜的数字");
	int guessnum = sc.nextInt();
			
	//比较输入的数字和系统产生的数据,需要使用分支语句。 
	//这里使用if..else..if..格式,根据不同情况进行猜测结果显示
	if (guessnum > number) {
		System.out.println("您输入的数字"+guessnum+"大了");
	}
	else if (guessnum < number) {
		System.out.println("您输入的数字"+guessnum+"小了");
	}
	else {
		System.out.println("恭喜您猜对了");
		break;
	}
}

三、大数

如果基本的整数和浮点数精度不能够满足需求,那么可以使用java.math包中两个很有用的类:BigInteger和BigDecimal。这两个类可以处理包含任意长度数字序列的数值。
BigInteger类实现任意精度的整数运算。
BigDecimal类实现任意精度的浮点数运算。

使用:
可以用静态的valueOf方法将普通的数值转换为大数:

BigInteger aBigInteger = BigInteger.valueOf(100);

对于更大的数,可以使用一个带字符串参数的构造器;

BigInteger aBigInteger = BigInteger.valueOf(100);

注意:

但是不能使用我们熟悉的算术运算符(如:+和*)处理大数,需要使用大数类中的add和multiply方法。

BigInteger a = BigInteger.valueOf(4);
BigInteger b = BigInteger.valueOf(6);

BigInteger c = a.add(b);  //c=a+b
BigInteger d = c.multiply(b.add(BigInteger.valueOf(2))); //d=c*(b+2)
		
System.out.println(a); //4
System.out.println(b); //6
System.out.println(c); //10
System.out.println(d); //80

四、数组

1、什么是数组

概念:数组就是存储数据长度固定的容器,存储多个数据的数据类型要一致。

2、数组定义格式

第一种
数据类型[] 数组名

int[] arr; 
double[] arr; 
char[] arr;

第二种
数据类型 数组名[]

int arr[]; 
double arr[]; 
char arr[];

3、数组动态初始化

数组动态初始化就是只给定数组的长度,由系统给出默认初始化值。

动态初始化格式

数据类型[] 数组名 = new 数据类型[数组长度];
int arr[] = new int[3];

等号左边:
1、int : 数组的数据类型
2、[] : 代表这是一个数组
3、arr : 代表数组的名称

等号右边:
1、new : 为数组开辟内存空间
2、int : 数组的数据类型
3、[] : 代表这是一个数组
4、5 : 代表数组的长度

4、数组元素访问

每一个存储到数组的元素,都会自动的拥有一个编号,从0开始。
这个自动编号称为数组索引(index),可以通过数组的索引访问到数组中的元素。

访问数组元素格式
数组名[索引];

示例:

//定义一个长度为3的整形数组
int arr[] = new int[3];
		
//输出数组名
System.out.println(arr);
		
//输出数组中的元素 
System.out.println(arr[0]); 
System.out.println(arr[1]); 
System.out.println(arr[2]);

5、内存分配

内存概述
内存是计算机中的重要原件,临时存储区域,作用是运行程序。
我们编写的程序是存放在硬盘中的,在硬盘中的程序是不会运行的。
必须放进内存中才能运行,运行完毕后会清空内存。
Java虚拟机要运行程序,必须要对内存进行空间的分配和管理。

java中的内存分配
目前我们只需要记住两个内存,分别是:栈内存和堆内存。

区域名称作用
寄存器给CPU使用,和我们开发无关。
本地方法栈JVM在使用操作系统功能的时候使用,和我们开发无关。
方法区存储可以运行的class文件。
堆内存存储对象或者数组,new来创建的,都存储在堆内存。
方法栈方法运行时使用的内存,比如main方法运行,进入方法栈中执行。

6、数组静态初始化

在创建数组时,直接将元素确定。

静态初始化格式

1、完整版格式

数据类型[] 数组名 = new 数据类型[]{元素1,元素2,...};

2、简化版格式

数据类型[] 数组名 = {元素1,元素2,...};

示例:

int arr[] = {1,2,3,4,5,6};
//输出数组中的元素 
System.out.println(arr[0]); //1
System.out.println(arr[1]); //2
System.out.println(arr[2]); //3

7、数组操作的两个常见小问题

1、索引越界异常

出现原因:

int[] arr = new int[3]; 
System.out.println(arr[3]);

1、数组长度为3,索引范围是0~2,但是我们却访问了一个3的索引。
2、程序运行后,将会抛出ArrayIndexOutOfBoundsException 数组越界异常。在开发中,数组的越界异常是不能出现的,一旦出现了,就必须要修改我们编写的代码。

解决方案:
将错误的索引修改为正确的索引范围即可!

2、空指针异常

出现原因:

int[] arr = new int[3]; 

//把null赋值给数组 
arr = null; 
System.out.println(arr[0]);

arr = null 这行代码,意味着变量arr将不会在保存数组的内存地址,也就不允许再操作数组了,因此运行的时候会抛出 NullPointerException 空指针异常。在开发中,数组的越界异常是不能出现的,一旦出现了,就必须要修改我们编写的代码。

解决方案:
给数组一个真正的堆内存空间引用即可!

8、数组遍历

数组遍历:就是将数组中的每个元素分别获取出来,就是遍历。遍历也是数组操作中的基石。

int[] arr = { 1, 2, 3, 4, 5 }; 
System.out.println(arr[0]); 
System.out.println(arr[1]); 
System.out.println(arr[2]); 
System.out.println(arr[3]); 
System.out.println(arr[4]);

以上代码是可以将数组中每个元素全部遍历出来,但是如果数组元素非常多,这种写法肯定不行,因此我们需要改造成循环的写法。数组的索引是 0 到 lenght-1 ,可以作为循环的条件出现。

//定义数组 
int[] arr = {11, 22, 33, 44, 55}; 
//使用通用的遍历格式 
for(int x=0; x<arr.length; x++) { 
	System.out.println(arr[x]); 
}

1、for each遍历

可以用来依次处理数组(或者其他元素集合)中的每一个元素,而不考虑指定下标值。

String[] string = {"","abc","defg","hij","lmn"};
for (String element : string) {
	System.out.println(element);
}

for each循环语句的循环变量将会遍历数组中的每个元素,而不是下标值。然而很多时候还是需要使用传统的for循环。

2、Arrays类

使用Arrays类的toString方法。调用Arrays.toString(a),返回一个包含数组元素的字符串,这些元素包围在中括号内,而不是用逗号隔开。
例如:

String[] string = {"","abc","defg","hij","lmn"};
//Arrays.toString(a)打印数组中所有值
System.out.println(Arrays.toString(string)); //[, abc, defg, hij, lmn]

3、数组拷贝

在Java中,允许将一个数组变量拷贝到另一个数组变量。这是两个数组将引用同一个数组:

int[] arrA = {1,2,3,4,5};
int[] arrB = arrA;
arrB[3] = 12;
System.out.println(Arrays.toString(arrA)); //[1, 2, 3, 12, 5]
System.out.println(Arrays.toString(arrB)); //[1, 2, 3, 12, 5]

如果希望将一个数组的所有值拷贝到一个新的数组中,就要使用Arrays类中的copyOf方法:

int[] arrA = { 1, 2, 3, 4, 5 };
int[] arrB = Arrays.copyOf(arrA, arrA.length);
int[] arrC = Arrays.copyOf(arrA, arrA.length*2);
		
System.out.println(Arrays.toString(arrA)); //[1, 2, 3, 4, 5]
System.out.println(Arrays.toString(arrB)); //[1, 2, 3, 4, 5]
System.out.println(Arrays.toString(arrC)); //[1, 2, 3, 4, 5, 0, 0, 0, 0, 0]

第二个参数是新数组的长度。这个方法通常用来增加数组的大小。如果数组元素是数值型,那么额外的元素将被赋值为0,。如果数组元素是布尔型,则会被赋值为false。
相反,如果数组长度小于原始数组长度,则只拷贝前面的值。

4、数组排序

要想对数值型数组排序,可以使用Arrays类中的sort方法:

int[] a = {12,432,654,3,756,43,86};
System.out.println(Arrays.toString(a)); //[12, 432, 654, 3, 756, 43, 86]
Arrays.sort(a);
System.out.println(Arrays.toString(a)); //[3, 12, 43, 86, 432, 654, 756]

5、常用方法

1、toString(xxx[] a)
返回包含a中元素的一个字符串,这些元素用中括号包围,并用逗号分隔。在这个方法以及后面方法中,数组元素类型xxx可以是int、long、char、byte、boolean、float或double。
2、copyOf(xxx[] a,int end)
3、copyOfRange(xxx[] a, int start, int end)
返回与a类型相同的一个数组,其长度为length或者end-start。数组元素为a的值。如果end大于a.length,结果会填充0或false的值。
4、sort(xxx[] a)
使用优化的快速排序算法对数组进行排序。
5、fill(xxx[] a,xxx v)
将数组的所有数据元素设置为v。
6、equals(xxx[] a,xxx[] b)
如果两个数组大小相同,并且下标相同的元素都对应相等,返回true。
7、binarySearch(xxx[] a,xxx v)
8、binarySearch(xxx[] a, int start, int end, xxx v)
使用二分查找法在有序数组a中查找值v。如果找到,则返回相应的下标;否则,返回一个负数值r。-r-1是v应插入的位置(为保持a有序)。

int[] a = {12,432,654,3,756,43,86};
int[] b = {22, 22, 22, 22, 22, 22, 22};
int[] c = {1,2,3,4,5,6,7,8,9,10};
		
//Arrays.toString()
System.out.println(Arrays.toString(a)); //[12, 432, 654, 3, 756, 43, 86]
		
//Arrays.sort()
Arrays.sort(a);
System.out.println(Arrays.toString(a)); //[3, 12, 43, 86, 432, 654, 756]
		
//Arrays.fill()
Arrays.fill(a, 22);
System.out.println(Arrays.toString(a)); //[22, 22, 22, 22, 22, 22, 22]
		
//Arrays.equals(a, b)
System.out.println(Arrays.equals(a, b)); //true
		
//binarySearch(c, v)
System.out.println(Arrays.binarySearch(c, 5)); //4
System.out.println(Arrays.binarySearch(c, 5, 8, 5)); //-6

9、数组最值

最大值获取:从数组的所有元素中找出最大值。

实现思路:
1、定义变量,保存数组0索引上的元素。
2、遍历数组,获取出数组中的每个元素。
3、将遍历到的元素和保存数组0索引上值的变量进行比较。
4、如果数组元素的值大于了变量的值,变量记录住新的值。
5、数组循环遍历结束,变量保存的就是数组中的最大值。

//定义数组 
int[] arr = {12, 45, 98, 73, 60};
//定义一个变量,用于保存最大值 
//取数组中第一个数据作为变量的初始值 
int max = arr[0];
//与数组中剩余的数据逐个比对,每次比对将最大值保存到变量中
for (int i = 0; i < arr.length; i++) {
	if (max<arr[i]) {
		max=arr[i];
	}
}
System.out.println("max:"+max);

总结

一步一个脚印,lyy加油!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值