[上一篇](https://blog.csdn.net/CHiN_951/article/details/134720821?spm=1001.2014.3001.5502)
bug:臭虫,系统漏洞,程序故障
debug:解决系统故障
步骤:
1.添加断点,双击某段代码
2.使用F11启动debug执行
3.
F5进入方法之内,有下一步的作用
F6不进入到方法内,有下一步的作用
F7结束当前执行的方法
F8整体结束
4.取消断点
什么是递归?
解决具有既定规律的问题时,在方法内部调用自身方法的一种编程形式(写法)
何时使用递归?
当需要解决的问题可以拆分为若干个小问题,大小问题的解决方式相同,方法中自调用自己
使用循环解决的常规问题,都可以替换为递归
如何正确使用递归?
设置有效的出口条件,可以让调用的链式的方法(递归方法)可以正常结束,避免无休止的递归
public class Demo10 {
// 求某个数阶乘
// n!=n*(n-1)*(n-2)*(n-3)*.....
// 5! = 5 * 4!
// 4! = 4 * 3!
// 求n的阶乘
public int jc(int n) {
// 设置程序出口 1! == 1;
if(n == 1) {
return 1;
}
return n * jc(n-1);
}
public static void main(String[] args) {
Demo10 demo10 = new Demo10();
System.out.println(demo10.jc(5));
}
}
public class Demo11 {
// 使用递归完成斐波那契数列
// 每三个数字中,前两个数字相加的和为第三个数字
public int fb(int n) {
if(n == 1 || n == 2) {
return 1;
}
return fb(n - 1) + fb(n - 2);
}
public static void main(String[] args) {
Demo11 demo11 = new Demo11();
System.out.println(demo11.fb(12));
}
}
public class Demo12 {
// 输出每个位置上的值
public void cfs(int num) {
if(num == 0) {
return;
}
// 输出个位数
System.out.println(num % 10);
// 缩小10倍
cfs(num / 10);
}
public static void main(String[] args) {
Demo12 demo12 = new Demo12();
demo12.cfs(123456);
}
}
如何存储100名学生的成绩?
方案:使用100个变量,每个变量都代表一个学生的成绩
缺点:非常麻烦
优化方案:使用数组
数组是内存中,一块连续的空间,可以保存相同类型的多个数据的容器
特定:
类型相同,数组中必须保存相同数据类型的数据
长度固定,数组一旦创建了长度不可以改变
初始化:进行创建和赋值的过程
动态初始化:先创建数组,在后续的程序中对数据进行赋值的过程
语法1:
数据类型[] 数组名 = new 数据类型[长度];//数据类型前后一致,数据类型可以为任意的类型
语法2:
数据类型 数组名[] = new 数据类型[长度];
推荐使用语法1,可读性更高
public class Demo01 {
// 数组的动态初始化
public static void main(String[] args) {
// int 和 int[]是两个东西
// 定义一个长度为3的int类型数组
// 1.初始化
int[] arr = new int[3];
// 2.存储数据:使用下标的形式访问数据,数组下标从0开始
arr[0] = 1;
arr[1] = 2;
arr[2] = 3;
// 3.取值使用
System.out.println("下标为0的元素:"+arr[0]);
System.out.println("下标为1的元素:"+arr[1]);
System.out.println("下标为2的元素:"+arr[2]);
// 获取数组的长度
System.out.println(arr.length);//arr数组的长度
// 错误:数据下标越界异常 ArrayIndexOutOfBoundsException
// 异常之下的代码,默认是无法执行的
// 总长度为3没有下标为3的元素了
System.out.println(arr[3]);
// 初始化的另一种语法,可读性差
int arr1[] = new int[3];
// System.out.println("嘿嘿嘿,让我执行");
}
}
静态初始化:数组创建的同时对数组的各个位置进行赋值
语法:
1.数据类型[] 数组名 = new 数据类型[]{数据1,数据2…};
2.数据类型 数组名[] = new 数据类型[]{数据1,数据2…};
3.数据类型[] 数组名 = {数据1,数据2…};//简化写法,必须在同一条语句中完成创建和赋值
4.数据类型 数组名[] = {数据1,数据2…};
public class Demo02 {
// 静态初始化
public static void main(String[] args) {
// 静态初始化,创建的同时赋值
int[] arr = new int[]{1,2,3,4,6,7};
// 获取数组长度
System.out.println(arr.length);
// 获取数组数据
System.out.println(arr[0]);
// 改变数组数据
arr[1] = 100;
System.out.println(arr[1]);
System.out.println("-----------------------");
// arr = {1,2,3,5,5};//不能使用{}字面量的写法去改值
arr = new int[] {1,2,3,5,5};
// 该写法为简化写法,特殊要求是只能在同一条语句中进行创建和赋值
int[] arr1 = {1,2,3,5,5};
}
}
数组中的每个数据被称为数组的元素
数组中的每个元素都有一个对应的下标
数组下标为int类型的变量
数组下标范围:0~长度-1
数组的长度获取:数组名.length
数组下标不在指定的范围内时,会抛出数组下标越界异常(ArrayIndexOutOfBoundsException)
数组变量本身可以被输出,但结果是内存的显示形式
例如:[I@7852e922
public static void main(String[] args) {
int[] arr = new int[] {1,2,3,4,5};
// 直接输出数据变量
// [I@7852e922 地址显示形式
System.out.println(arr);
}
遍历:获取/保存数组中的每一个元素(循环)
1.使用for循环
for(int i = 0;i<数组名.length;i++){
使用数组元素:数组名[i];
}
2.使用foreach循环 jdk1.5后引入的
将数组中的每个位置的值,都赋值给变量,然后对变量进行输出等操作
for(数组中存储的类型 变量名:数组名){
使用变量名;
}
// 遍历数组:获取数组中的每个元素
public static void main(String[] args) {
int[] arr = {1,2,3,5,6,76,7,8,1};
// 1.for循环
for(int i = 0;i<arr.length;i++) {
System.out.println(arr[i]);
}
System.out.println("--------------------");
// 2.foreach循环 将arr中的每个变量都赋值给i,然后进行显示
// foreach中没有下标
// foreach就是为了遍历而生的
for(int i:arr) {
System.out.println(i);
}
}
和基本类型不一样,数据创建的同时可以为各个位置添加默认值
整数型:0
浮点型:0.0
布尔型:false
字符型:‘\u0000’ 或者 ‘’ 或者 0
引用类型:null
null是一种特殊的值,表示当前对象在内存中没有任何的地址
""表示空字符串,在内存中有对应的地址
// 数组默认值
public static void main(String[] args) {
int[] arr = new int[10];
System.out.println(arr[0]);
double[] ds = new double[10];
System.out.println(ds[0]);
boolean[] bs = new boolean[10];
System.out.println(bs[0]);
char[] cs = new char[10];
System.out.println(cs[0]);
// 引用类型代表
String[] ss = new String[10];
System.out.println(ss[0]);
}