JAVA - 数组的定义与使用

1. 数组基本用法

1.1 什么是数组

数组本质上就是让我们能 “批量” 创建相同类型的变量.
例如:
如果需要表示两个数据, 那么直接创建两个变量即可 int a; int b
如果需要表示五个数据, 那么可以创建五个变量 int a1; int a2; int a3; int a4; int a5;
但是如果需要表示一万个数据, 那么就不能创建一万个变量了. 这时候就需要使用数组, 帮我们批量创建.
注意事项: 在 Java 中, 数组中包含的变量必须是 相同类型.

1.2 创建数组

基本语法

// 动态初始化
数据类型[] 数组名称 = new 数据类型 [] {
    
     初始化数据 };
//初始化给定长度的数组
int[] arr = new arr[arr.length]; 
// 静态初始化
数据类型[] 数组名称 = {
    
     初始化数据 };

代码示例

int[] arr = new int[]{
    
    1, 2, 3};
int[] arr = {
    
    1, 2, 3};

注意事项: 静态初始化的时候, 数组元素个数和初始化数据的格式是一致的.

1.3 数组的使用

代码示例: 获取长度 & 访问元素

int[] arr = {
    
    1, 2, 3};
// 获取数组长度
System.out.println("length: " + arr.length); // 执行结果: 3
// 访问数组中的元素
System.out.println(arr[1]); // 执行结果: 2
System.out.println(arr[0]); // 执行结果: 1
arr[2] = 100;
System.out.println(arr[2]); // 执行结果: 100

注意事项

  1. 使用 arr.length 能够获取到数组的长度. . 这个操作为成员访问操作符. 后面在面向对象中会经常用到.
  2. 使用 [ ] 按下标取数组元素. 需要注意, 下标从 0 开始计数
  3. 使用 [ ] 操作既能读取数据, 也能修改数据.
  4. 下标访问操作不能超出有效范围 [0, length - 1] , 如果超出有效范围, 会出现下标越界异常
    代码示例: 遍历数组
    所谓 “遍历” 是指将数组中的所有元素都访问一遍, 不重不漏. 通常需要搭配循环语句.
int[] arr = {
    
    1, 2, 3};
for (int i = 0; i < arr.length; i++) {
    
    
    System.out.println(arr[i]);
}
// 执行结果
1
2
3

代码示例: 使用 for-each 遍历数组

int[] arr = {
    
    1, 2, 3};
for (int x : arr) {
    
    
    System.out.println(x);
}
// 执行结果
1
2
3

for-each 是 for 循环的另外一种使用方式. 能够更方便的完成对数组的遍历. 可以避免循环条件和更新语句写错.
注意:for循环 和 for each循环的区别?

  • for循环是可以拿到下标的;
  • for each是拿不到下标的,只拿元素(多用于后面会学到的集合中);

2. 数组作为方法的参数

2.1 基本用法

代码示例: 打印数组内容

public static void main(String[] args) {
    
    
    int[] arr = {
    
    1, 2, 3};
    printArray(arr);
}
public static void printArray(int[] a) {
    
    
    for (int x : a) {
    
    
        System.out.println(x);
    }
}
// 执行结果
1
2
3

在这个代码中

  • int[] a 是函数的形参, int[] arr 是函数实参.
  • 如果需要获取到数组长度, 同样可以使用 a.length

2.2 理解引用类型(重点/难点)

我们尝试以下代码
代码示例1 参数传内置类型

public static void main(String[] args) {
    
    
    int num = 0;
    func(num);
    System.out.println("num = " + num);
}
public static void func(int x) {
    
    
    x = 10;
    System.out.println("x = " + x);
}
// 执行结果
x = 10
num = 0

我们发现, 修改形参 x 的值, 不影响实参的 num 值.
在这里插入图片描述
代码示例2 参数传数组类型

public static void main(String[] args) {
    
    
    int[] arr = {
    
    1, 2, 3};
    func(arr);
    System.out.println("arr[0] = " + arr[0]);
}
public static void func(int[] a) {
    
    
    a[0] = 10;
    System.out.println("a[0] = " + a[0]);
}
// 执行结果
a[0] = 10
arr[0] = 10

我们发现, 在函数内部修改数组内容, 函数外部也发生改变.
此时数组名 arr 是一个 “引用” . 当传参的时候, 是按照引用传参.

如何理解内存?
内存就是指我们熟悉的 “内存”. 内存可以直观的理解成一个宿舍楼. 有一个长长的大走廊, 上面有很多房间.
每个房间的大小是 1 Byte (如果计算机有 8G 内存, 则相当于有 80亿 个这样的房间).
每个房间上面又有一个门牌号, 这个门牌号就称为 地址
什么是引用?
引用相当于一个 “别名”, 也可以理解成一个指针.
创建一个引用只是相当于创建了一个很小的变量, 这个变量保存了一个整数, 这个整数表示内存中的一个地址.
针对 int[] arr = new int[]{1, 2, 3} 这样的代码, 内存布局如图:
a) 当我们创建 new int[]{1, 2, 3} 的时候, 相当于创建了一块内存空间保存三个 int
b) 接下来执行 int[] arr = new int[]{1, 2, 3} 相当于又创建了一个 int[] 变量, 这个变量是一个引用类型, 里面只保存了一个整数(数组的起始内存地址)
在这里插入图片描述
c) 接下来我们进行传参相当于 int[] a = arr , 内存布局如图
在这里插入图片描述
d) 接下来我们修改 a[0] , 此时是根据 0x100 这样的地址找到对应的内存位置, 将值改成 100
在这里插入图片描述
此时已经将 0x100 地址的数据改成了 100 . 那么根据实参 arr 来获取数组内容 arr[0] , 本质上也是获取 0x100地址上的数据, 也是 100.

总结: 所谓的 “引用” 本质上只是存了一个地址. Java 将数组设定成引用类型, 这样的话后续进行数组参数传参, 其实只是将数组的地址传入到函数形参中. 这样可以避免对整个数组的拷贝(数组可能比较长, 那么拷贝开销就会很大).
容易犯错误的知识点:
1.实参和形参
在这里插入图片描述
func1 结果为
1,2,3,4,5,6
1,2,3,4,5,6
原因分析:实参指向对象,形参指向另一个对象,打印出的实参结果不变。
在这里插入图片描述
func2 结果为
1,2,3,4,5,6
899,2,3,4,5,6
原因分析:实参指向对象,形参也指向对象。
2.一个引用不能同时指向多个对象,一个引用只能保存一个对象的地址。
3.引用一定是在栈上吗?不一定:一个变量在不在栈上,是变量的性质决定的。如果是一个局部变量,就在栈上。如果是实例成员变量,那就不一定再栈上了。
一个例子:https://www.zhihu.com/question/300519939/answer/1617705726
扩展:
1.类的成员变量的引用是在栈上还是在堆上?
答:堆上,随着对象实例放在堆当中。
2.类的静态方法在main方法中被引用是在栈上还是堆上?
答:栈上,所有方法都是在栈内存中执行。

2.3 认识 null

null 在 Java 中表示 “空引用” , 也就是一个无效的引用

int[] arr = null;
System.out.println(arr[0]);
// 执行结果
Exception in thread "main" java.lang.NullPointerException
at Test.main(Test.java:6)

null 的作用类似于 C 语言中的 NULL (空指针), 都是表示一个无效的内存位置. 因此不能对这个内存进行任何读写操作. 一旦尝试读写, 就会抛出 NullPointerException.
注意: Java 中并没有约定 null 和 0 号地址的内存有任何关联.

2.4 初识 JVM 内存区域划分(重点)

JVM 的内存被划分成了几个区域, 如图所示:
在这里插入图片描述

  • 程序计数器 (PC Register): 只是一个很小的空间, 保存下一条执行的指令的地址.
  • 虚拟机栈(JVM Stack): 重点是存储局部变量表(当然也有其他信息). 我们刚才创建的 int[] arr这样的存储地址的引用就是在这里保存.
  • 本地方法栈(Native Method Stack): 本地方法栈与虚拟机栈的作用类似. 只不过保存的内容是Native方法的局部变量.在有些版本的 JVM 实现中(例如HotSpot), 本地方法栈和虚拟机栈是一起的.
  • 堆(Heap): JVM所管理的最大内存区域. 使用 new 创建的对象都是在堆上保存 (例如前面的 new int[]{1, 2, 3})
  • 方法区(Method Area): 用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据.方法编译出的的字节码就是保存在这个区域.
  • 运行时常量池(Runtime Constant Pool): 是方法区的一部分, 存放字面量(字符串常量)与符号引用. (注意 从JDK1.7 开始, 运行时常量池在堆上)

Native 方法:
JVM 是一个基于 C++ 实现的程序. 在 Java 程序执行过程中, 本质上也需要调用 C++ 提供的一些函数进行和操作系统底层进行一些交互. 因此在 Java 开发中也会调用到一些 C++ 实现的函数.这里的 Native 方法就是指这些 C++ 实现的, 再由 Java 来调用的函数.

我们发现, 在上面的图中, 程序计数器, 虚拟机栈, 本地方法栈被很多个原谅色的, 名叫 Thread(线程) 的方框圈起来了,并且存在很多份. 而 堆, 方法区, 运行时常量池, 只有一份. (关于线程, 这是我们后面重点讲解的内容).关于上面的划分方式, 我们随着后面的学习慢慢理解. 此处我们重点理解 虚拟机栈 和 堆
在这里插入图片描述

  • 局部变量和引用保存在栈上, new 出的对象保存在堆上.
  • 堆的空间非常大, 栈的空间比较小.
  • 堆是整个 JVM 共享一个, 而栈每个线程具有一份(一个 Java 程序中可能存在多个栈).

线程共享区:Java堆 、方法区
线程私有内存区: 虚拟机栈、本地方法栈、程序计数器

在这里插入图片描述

3. 数组作为方法的返回值

代码示例: 写一个方法, 将数组中的每个元素都 * 2

// 直接修改原数组
class Test {
    
    
    public static void main(String[] args) {
    
    
        int[] arr = {
    
    1, 2, 3};
        transform(arr);
        printArray(arr);
    }
    public static void printArray(int[] arr) {
    
    
        for (int i = 0; i < arr.length; i++) {
    
    
        System.out.println(arr[i]);
    }
}
    public static void transform(int[] arr) {
    
    
        for (int i = 0; i < arr.length; i++) {
    
    
        arr[i] = arr[i] * 2;
        }
    }
}

这个代码固然可行, 但是破坏了原有数组. 有时候我们不希望破坏原数组, 就需要在方法内部创建一个新的数组, 并由方法返回出来.

// 返回一个新的数组
class Test {
    
    
    public static void main(String[] args) {
    
    
        int[] arr = {
    
    1, 2, 3};
        int[] output = transform(arr);
        printArray(output);
    }
    public static void printArray(int[] arr) {
    
    
        for (int i = 0; i < arr.length; i++) {
    
    
        System.out.println(arr[i]);
        }
    }
    public static int[] transform(int[] arr) {
    
    
        int[] ret = new int[arr.length];
        for (int i = 0; i < arr.length; i++) {
    
    
            ret[i] = arr[i] * 2;
        }
        return ret;
    }
}

这样的话就不会破坏原有数组了.
另外由于数组是引用类型, 返回的时候只是将这个数组的首地址返回给函数调用者, 没有拷贝数组内容, 从而比较高效.

4. 数组练习

4.1 数组转字符串

代码示例

import java.util.Arrays
int[] arr = {
    
    1,2,3,4,5,6};
String newArr = Arrays.toString(arr);
System.out.println(newArr);
// 执行结果
[1, 2, 3, 4, 5, 6]

使用这个方法后续打印数组就更方便一些.
Java 中提供了 java.util.Arrays 包, 其中包含了一些操作数组的常用方法.

4.2 数组拷贝

一共有五种方法
代码示例
第一种:利用for循环,此种方法创建了新对象,为深拷贝。

public static int[] copyArray(int[]a){
    
    
    int[] ret = new int[a.length];
    for(int i = 0; i<ret.length; i++){
    
    
        ret[i]=a[i];
    }//利用for循环
    return ret;//返回数组
}

第二种:Arrays.copyOf(arr, arr.length)(默认浅拷贝)
第三种:Arrays.copyOfRange(arr, 2, 4)(默认浅拷贝)

import java.util.Arrays
int[] arr = {
    
    1,2,3,4,5,6};
int[] newArr = Arrays.copyOf(arr, arr.length);
System.out.println("newArr: " + Arrays.toString(newArr));
arr[0] = 10;
System.out.println("arr: " + Arrays.toString(arr));
System.out.println("newArr: " + Arrays.toString(newArr));
// 拷贝某个范围.
int[] newArr = Arrays.copyOfRange(arr, 2, 4);
System.out.println("newArr2: " + Arrays.toString(newArr2));

第四种:System.arraycopy是native方法,使用c/c++写的内置库。(默认浅拷贝)

int[] copy = new int[array.length];
System.arraycopy(array,0,copy,0,array.length);
System.out.println(Arrays.toString(copy));

第五种:array.clone()(默认是浅拷贝,深拷贝需要重写)

int[] array = {
    
    1,2,3,4,5,6};
int[] copy = array.clone();
System.out.println(Arrays.toString(copy));

注意事项:

  1. 相比于 newArr = arr 这样的赋值, copyOf 是将数组进行了 深拷贝, 即又创建了一个数组对象,拷贝原有数组中的所有元素到新数组中. 因此, 修改原数组, 不会影响到新数组.
    深拷贝:拷贝对象 B复制A,A变,B不变
    浅拷贝:拷贝地址 B复制A,A变,B变
    深拷贝和浅拷贝是一种概念,具体需要看代码是怎样拷贝的。
    看拷贝的是基本类型,还是引用类型,是否创建新对象。
    深拷贝和浅拷贝的知识链接:
    Java深入理解深拷贝和浅拷贝区别,超链接点击查看
  2. int[] newArr = Arrays.copyOfRange(arr, 2, 4); //此处实际上拷贝到下表2到3,最后一位下标4所在元素不拷贝.

在这里插入图片描述

4.3 找数组中的最大元素

给定一个整型数组, 找到其中的最大元素 (找最小元素同理)

4.4 求数组中元素的平均值

给定一个整型数组, 求平均值

4.5 查找数组中指定元素(顺序查找)

给定一个数组, 再给定一个元素, 找出该元素在数组中的位置.

4.6 查找数组中指定元素(二分查找)

针对有序数组, 可以使用更高效的二分查找.
以升序数组为例, 二分查找的思路是先取中间位置的元素, 看要找的值比中间元素大还是小. 如果小, 就去左边找; 否则就去右边找.
代码示例

public static void main(String[] args) {
    
    
    int[] arr = {
    
    1,2,3,4,5,6};
    System.out.println(binarySearch(arr, 6));
}
public static int binarySearch(int[] arr, int toFind) {
    
    
    int left = 0;
    int right = arr.length - 1;
    while (left <= right) {
    
    
        int mid = (left + right) / 2;
        if (toFind < arr[mid]) {
    
    
        // 去左侧区间找
        right = mid - 1;
        } else if (toFind > arr[mid]) {
    
    
        // 去右侧区间找
        left = mid + 1;
        } else {
    
    
        // 相等, 说明找到了
               return mid;
        }
    }
    // 循环结束, 说明没找到
    return -1;
}
// 执行结果
5

4.7 检查数组的有序性

给定一个整型数组, 判断是否该数组是有序的(升序)

public static void main(String[] args) {
    
    
    int[] arr = {
    
    1,2,3,10,5,6};
    System.out.println(isSorted(arr));
}
public static boolean isSorted(int[] arr) {
    
    
    for (int i = 0; i < arr.length - 1; i++) {
    
    
        if (arr[i] > arr[i + 1]) {
    
    
            return false;
        }
    }
return true;
}

4.8 数组排序(冒泡排序)

给定一个数组, 让数组升序 (降序) 排序.
算法思路
每次尝试找到当前待排序区间中最小(或最大)的元素, 放到数组最前面(或最后面).
在这里插入图片描述

代码示例1

// [bound, length) 构成了一个前闭后开区间, 表示已排序区间
// [0, bound)构成了一个前闭后开区间, 表示待排序区间
// 每循环一次, 就找到一个合适大小的元素, 已排序区间就增大1.
public static void main(String[] args) {
    
    
    int[] arr = {
    
    9, 5, 2, 7};
    bubbleSort(arr);
    System.out.println(Arrays.toString(arr));
}
private static void bubbleSort(int[] arr) {
    
    
    for (int bound = arr.length; bound > 0; bound--) {
    
    
        for (int cur = 0; cur < bound - 1; cur++) {
    
    
            if (arr[cur] > arr[cur + 1]) {
    
    
                int tmp = arr[cur];
                arr[cur] = arr[cur + 1];
                arr[cur + 1] = tmp;
            }
        }
    }
}
// 执行结果
[2, 5, 7, 9]

代码示例2
思路和上面一样,只是边界Bound从左向右开始循环。
其中,如何循环到i次恰好没有互换元素,就说明已经有序了,就直接break即可(使用Boolean判断是否互换过元素)

private static void bubbleSort(int[] arr) {
    
    
    for (int bound = arr.length; bound > 0; bound--) {
    
    
        boolean flg = false;
        for (int cur = 0; cur < bound - 1; cur++) {
    
    
            if (arr[cur] > arr[cur + 1]) {
    
    
                int tmp = arr[cur];
                arr[cur] = arr[cur + 1];
                arr[cur + 1] = tmp;
                flg = true;
            }
        }
        if (flg == false) {
    
    
            break;
        }
    }
}

代码示例3
思路同上

private static void bubbleSort(int[] arr) {
    
    
    for (int i = 0; i < arr.length - 1; i++) {
    
    
        boolean flg = false;
        for (int cur = 0; cur < arr.length - 1 - i; cur++) {
    
    
            if (arr[cur] > arr[cur + 1]) {
    
    
                int tmp = arr[cur];
                arr[cur] = arr[cur + 1];
                arr[cur + 1] = tmp;
                flg = true;
            }
        }
        if (flg == false) {
    
    
            break;
        }
    }
}

冒泡排序性能较低. Java 中内置了更高效的排序算法

public static void main(String[] args) {
    
    
    int[] arr = {
    
    9, 5, 2, 7};
    Arrays.sort(arr);
    System.out.println(Arrays.toString(arr));
}

关于 Arrays.sort 的具体实现算法, 我们在后面的排序算法课上再详细介绍. 到时候我们会介绍很多种常见排序算法.
4.9 数组逆序
给定一个数组, 将里面的元素逆序排列.
思路
设定两个下标, 分别指向第一个元素和最后一个元素. 交换两个位置的元素.然后让前一个下标自增, 后一个下标自减, 循环继续即可.
代码示例

public static void main(String[] args) {
    
    
    int[] arr = {
    
    1, 2, 3, 4};
    reverse(arr);
    System.out.println(Arrays.toString(arr));
}
public static void reverse(int[] arr) {
    
    
    int left = 0;
    int right = arr.length - 1;
    while (left < right) {
    
    
        int tmp = arr[left];
        arr[left] = arr[right];
        arr[right] = tmp;
        left++;
        right--;
    }
}

4.10 数组数字排列

给定一个整型数组, 将所有的偶数放在前半部分, 将所有的奇数放在数组后半部分

例如
{
    
    1, 2, 3, 4}
调整后得到
{
    
    4, 2, 3, 1}

基本思路
设定两个下标分别指向第一个元素和最后一个元素.
用前一个下标从左往右找到第一个奇数, 用后一个下标从右往左找到第一个偶数, 然后交换两个位置的元素.依次循环即可.
代码示例

public static void main(String[] args) {
    
    
    int[] arr = {
    
    1, 2, 3, 4, 5, 6};
    transform(arr);
    System.out.println(Arrays.toString(arr));
}
public static void transform(int[] arr) {
    
    
    int left = 0;
    int right = arr.length - 1;
    while (left < right) {
    
    
    // 该循环结束, left 就指向了一个奇数
    while (left < right && arr[left] % 2 == 0) {
    
    
        left++;
    }
    // 该循环结束, right 就指向了一个偶数
    while (left < right && arr[right] % 2 != 0) {
    
    
        right--;
    }
    // 交换两个位置的元素
    int tmp = arr[left];
    arr[left] = arr[right];
    arr[right] = tmp;
    }
}

5. 二维数组

二维数组本质上也就是一维数组, 只不过每个元素又是一个一维数组.
基本语法

数据类型[][] 数组名称 = new 数据类型 [行数][列数] {
    
     初始化数据 };

代码示例
方法一:for循环打印二维数组

int[][] arr = {
    
    
    {
    
    1, 2, 3, 4},
    {
    
    5, 6, 7, 8},
    {
    
    9, 10, 11, 12}
};
for (int row = 0; row < arr.length; row++) {
    
    
    for (int col = 0; col < arr[row].length; col++) {
    
    
    System.out.printf("%d\t", arr[row][col]);
    }
    System.out.println("");
}
// 执行结果
1 2 3 4
5 6 7 8
9 10 11 12

方法二:使用for each

int[][] array = {
    
    
    {
    
    1,2,3},
    {
    
    4,5,6}
};
for (int[] ret : array) {
    
    
    for (int x :ret) {
    
    
        System.out.print(x +" ");
    }
    System.out.println();
}

方法三:使用Arrays.deepToString(array)

System.out.println(Arrays.deepToString(array));

注意:
Java中的二维数组列数可以省略,行数不可以int[][] array2 = new int[2][];不指定列数,则为null,列数需要手动指定。
不规则的二维数组:

int[][] array2 = new int[2][];
array2[0] = new int[3];
array2[1] = new int[2];

练习题:

import java.util.Scanner;

public class works {
    
    
    //8. 编写程序数一下 1到 100 的所有整数中出现多少个数字9。
    public static void main11(String[] args) {
    
    
        int count = 0;
        for (int i = 1;i <= 100;i++){
    
    
            if(i % 10 == 9){
    
    
                count++;
            }
            if (i / 10 == 9){
    
    
                count++;
            }
        }
        System.out.printf("1~100中有%d个数字9",count);
    }
//    public static void main(String[] args) {         这个程序错了
//        int count = 0,a,b;
//        for (int i = 1;i <= 100;i++){
    
    
//            a = i;
//            while(a != 0){
    
    
//                b = i % 10;
//                if (b == 9){
    
    
//                count++;
//                }
//                a /= 10;
//            }
//        }
//        System.out.printf("1~100中有%d个数字9",count);
//    }
    //9. 求出0~999之间的所有“水仙花数”并输出。(“水仙花数”是指一个三位数,其各位数字的立方和确好等于该数本
    //身,如;153=1+5+3?,则153是一个“水仙花数”。)
    public static void main77(String[] args) {
    
    
        Scanner sc = new Scanner(System.in);
        int num = sc.nextInt();
        for (int i = 0;i <= num;i++){
    
    
            int tmp = i;
            int count = 0;
            while (tmp != 0){
    
    
                count++;
                tmp /= 10;
            }
            tmp = i;
            int sum = 0;
            while(tmp != 0){
    
    
                sum += Math.pow(tmp % 10,count);
                tmp /= 10;
            }
            if (sum == i){
    
    
                System.out.printf("水仙花数%d\n",i);
            }
        }
    }
    //10. 编写代码模拟三次密码输入的场景。 最多能输入三次密码,密码正确,提示“登录成功”,密码错误, 可以重新输
    //入,最多输入三次。三次均错,则提示退出程序
    public static void main3(String[] args) {
    
    
        String passWord ="ysb4856939";
        Scanner sc = new Scanner(System.in);
        for (int i = 1;i <= 3;i++){
    
    
            String myGuess = sc.nextLine();
            if(passWord.equals(myGuess)){
    
    
                System.out.println("登陆成功");
                break;
            }else if(i != 3){
    
    
                System.out.println("登陆失败");
            }else{
    
    
                System.out.println("三次均错,退出程序");
                break;
            }
        }
    }

    //11. 写一个函数返回参数二进制中 1 的个数 比如: 15 0000 1111 4 个 1      以下为参考答案:
    public static void main45(String[] args) {
    
    
//        System.out.println(Integer.bitCount(21));
        Scanner sc = new Scanner(System.in);
        int m = sc.nextInt();
        int count =0;
        while(m != 0){
    
    
            count++;
            m = m & (m-1);
        }
        System.out.println(count);
    }
    //另一种方法实现   函数返回参数二进制中 1 的个数
    public static void main66(String[] args) {
    
    
        Scanner sc = new Scanner(System.in);
        int num = sc.nextInt();
        int count = 0;
        while (num != 0) {
    
    
            if ((num & 1) == 1) {
    
           //每次循环都和1相与,只要结果为1就count++
                count++;
            }
            num = num >>> 1;            //然后,数字num右移一位
        }
    }

    //12. 获取一个数二进制序列中所有的偶数位和奇数位, 分别输出二进制序列。        以下为参考答案:
    public static void main6(String[] args) {
    
    
        Scanner sc=new Scanner(System.in);
        int num=sc.nextInt();
        System.out.print("odd sequence:");
        for(int i=30;i>=0;i-=2){
    
                                //奇数位
            System.out.print((num>>i)&1);
        }
        System.out.print("   even sequence:");              //偶数位
        for(int i=31;i>=1;i-=2){
    
    
            System.out.print((num>>i)&1);
        }
        sc.close();
    }
    //13. 输出一个整数的每一位.
    public static void main(String[] args) {
    
    
        Scanner sc=new Scanner(System.in);
        int num = sc.nextInt();
        int a;
        while (num != 0){
    
    
            a = num % 10;
            System.out.println(a);
            num /= 10;
        }
    }

}

猜你喜欢

转载自blog.csdn.net/qq_43398758/article/details/120804427