数组介绍及其内存图

Java学习笔记(新手纯小白向)

第一章 JAVA基础概念

第二章 JAVA安装和环境配置

第三章 IntelliJ IDEA安装

第四章 运算符

第五章 运算符联系

第六章 判断与循环

第七章 判断与循环练习

第八章 循环高级综合

第九章 数组介绍及其内存图


目录

前言

数组介绍

一、数组的定义与静态初始化

        1.数组的定义

        2.数组的静态初始化

        3.演示

二、数组元素访问

        1.数组的地址值 

        2.索引

        3.利用索引对数组中的元素进行访问

        4.把数据存储到数组中

        5.演示

三、数组遍历

        1.数组的长度的调用方式

        2.IDEA提供的自动快速生成数组的通用方式

        3.演示

        4.练习

四、数组的动态初始化

        1.数组动态初始化

        2.数组默认初始化值的规律

        3.数组动态初始化与静态初始化的区别

        4.演示

五、数组常见问题

        only one:当访问了数组中不存在的索引,就会引发索引越界异常

六、数组常见操作

        1.求最值

        2.求和

        3.交换数据

        4.打乱数据

数组练习

一、求最值

        1.需求

        2.参考答案

二、遍历数组求和

        1.需求

        2.参考答案

三、交换数组中的数据

        1.需求

        2.参考答案 

四、打乱数组中的数据

        1. 需求

        2.参考答案

数组的内存图

一、Java内存分配

        1.栈

        2.堆

        3.方法区

        4.本地方法栈

        5.寄存器

        6.注意

二、数组的内存图

总结


前言

本篇章主要介绍了数组的一些基础概念及其使用方法与场景


数组介绍

数组:是一种容器,可以用来存储同种数据类型的多个值

数组容器在存储数据的时候,需要结合隐式转换考虑。如:int类型的数组容器(boolean,不可以;byte,可以;short,可以;int,可以;double,不可以) ,double类型的数组容器(byte,可以;short,可以;int,可以;long,可以;float,可以;double,可以)。

建议:容器的类型,和存储的数据类型保持一致

一、数组的定义与静态初始化

        1.数组的定义

格式一:数据类型[] 数组名
范例:int[] array
格式二:数据类型 数组名[]
范例:int array []

        2.数组的静态初始化

                初始化:就是在内存中,为数组容器开辟空间,并将数据存入容器中的过程

完整格式:数据类型[] 数组名 = new 数据类型[]{元素1,元素2,元素3...};
范例:int[] array = new int[]{11,22,33};
范例:double[] array2 = new double[]{11.1,22.2,33.3};
简化格式:数据类型[] 数组名 = {元素1,元素2,元素3...};
范例:int[] array = {11,22,33};
范例:double[] array2 = {11.1,22.2,33.3};

        3.演示

    public static void main(String[] args) {
        //静态初始化
        //完整格式与简化格式
        //定义数组存储5个学生的年龄
        int[] age1 = new int[]{16, 17, 18, 19, 20};
        int[] age2 = {16, 17, 18, 19, 20};

        //定义数组存储3个学生的姓名
        String[] name1 = new String[]{"张三", "李四", "王五"};
        String[] name2 = {"张三", "李四", "王五"};

        //定义数组存储4个学生的身高
        double[] height1 = new double[]{179.8, 179.9, 180.0, 180.1};
        double[] height2 = {179.8, 179.9, 180.0, 180.1};
    }

二、数组元素访问

        1.数组的地址值 

                数组的地址值表示数组在内存中的位置

        int[] age1 = new int[]{16, 17, 18, 19, 20};
        //地址值的格式含义
        System.out.println(age1);//[I@b4c966a -> 地址值
        //[:表示当前是一个数组
        //I:表示当前数组里面的元素都是int类型的
        //@:表示一个间隔符号(固定格式)
        //b4c966a:数组真正的地址值(十六进制),但平时我们习惯性地把整体叫做数组的地址值

        2.索引

                (1)索引:也叫下标,角标

                (2)索引的特点:从0开始,逐个+1增长,连续不间断

        3.利用索引对数组中的元素进行访问

                格式:数组名[索引]

        4.把数据存储到数组中

                格式:数组名[索引] = 具体数据/变量

        5.演示

    public static void main(String[] args) {
        //利用索引对数组中的元素进行访问
        //获取数组中的元素
        //格式:数组名[索引]

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

        //获取数组中的第一个元素
        int number = arr[0];
        System.out.println(number);

        //把数据存储到数组之中
        //格式:数组名[索引] = 具体数据/变量;
        //一旦覆盖之后,原来的数据就不存在了
        arr[0] = 100;
        System.out.println(arr[0]);
    }

三、数组遍历

        1.数组的长度的调用方式

                格式:数组名.length

        2.IDEA提供的自动快速生成数组的通用方式

                格式:数组名.fori

        3.演示

    public static void main(String[] args) {
        //定义一个数组
        int[] arr = {1, 2, 3, 4, 5};

        //获取数组里面所有的元素
        /*for (int i = 0; i < 5; i++) {
            System.out.println(arr[i]);
        }*/

        //在Java当中,关于数组的一个长度属性,length
        //调用方式:数组名.length
        System.out.println(arr.length);
        for (int i = 0; i < arr.length; i++) {
            System.out.println(arr[i]);
        }

        //自动快速生成数组的通用方式
        //idea提供
        //数组名.fori
        for (int i = 0; i < arr.length; i++) {
            System.out.println(arr[i]);
        }
    }

        4.练习

    public static void main(String[] args) {
        //定义一个数组,存储1,2,3,4,5
        //遍历数组得到每一个元素,求数组里面所有的数据和

        //定义数组number
        int[] number = {1, 2, 3, 4, 5};

        //遍历数组并求和
        int sum = 0;
        for (int i = 0; i < number.length; i++) {
            System.out.println(number[i]);
            sum = sum + number[i];
        }
        System.out.println(sum);
    }
    public static void main(String[] args) {
        //定义一个数组,存储1,2,3,4,5,6,7,8,9,10
        //遍历数组得到每一个元素,统计数组里面一共有多少个能被3整除的数字

        //定义数组number
        int[] number = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};

        //统计数组里面能被3整除的数字及其个数
        int count = 0;
        System.out.println("数组里面能被3整除的数字为:");
        for (int i = 0; i < number.length; i++) {
            if (number[i]%3==0){
                count++;
                System.out.println(number[i]);
            }
        }
        System.out.println("数组里面能被3整除的数字的个数为:"+count);
    }
    public static void main(String[] args) {
        //定义一个数组,存储1,2,3,4,5,6,7,8,9,10
        //遍历数组得到每一个元素
        /*如果是奇数,则将当前数字扩大两倍
          如果是偶数,则将当前数字变成1/2
        */

        //定义数组number
        int[] number = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};

        //遍历数组
        for (int i = 0; i < number.length; i++) {
            if (number[i] % 2 == 0) {
                number[i] = number[i] / 2;
            } else {
                number[i] = number[i] * 2;
            }
        }

        //一个循环尽量只做一件事情
        for (int i = 0; i < number.length; i++) {
            System.out.println(number[i]);
        }
    }

四、数组的动态初始化

        1.数组动态初始化

                动态初始化:初始化时只能指定数组的长度,由系统为数组分配初始值。

格式:数据类型[] 数组名 = new 数据类型[数组长度];
范例:int[] arr = new[3];

        2.数组默认初始化值的规律

                (1)整数类型:默认初始化值为0

                (2)小数类型:默认初始化值为0.0

                (3)字符类型:默认初始化值为'/u0000',即空格

                (4)布尔类型:默认初始化值为false

                (5)引用数据类型:默认初始化值为null

        3.数组动态初始化与静态初始化的区别

                (1)动态初始化:手动指定数组长度,由系统给出默认初始化值

                                只明确元素个数,不明确具体数值,推荐使用动态初始化

举例:使用数组容器来存储键盘录入的5个整数
int[] arr = {?,?,?,?,?};
int[] arr = new int[5];

                 (2)静态初始化:手动指定数组元素,系统会根据元素个数,计算出数组的长度。

                                需求中已明确了要操作的具体数据,直接静态初始化即可

举例:将全班的学生成绩存入数组中 11,22,33
int[] arr = {11,22,33};

        4.演示

    public static void main(String[] args) {
        /*
        定义一个数组,用来存储班级中50个学生的姓名
        姓名未知,等学生报道之后,在进行添加
         */

        //定义姓名数组,长度为50
        String[] name = new String[50];

        //添加学生
        name[0]="zhangsan";
        name[1]="lisi";

        //获取
        System.out.println(name[0]);
        System.out.println(name[1]);
        System.out.println(name[2]);

        //数组默认初始化值的规律
        //整数类型:默认初始化值为0
        //小数类型:默认初始化值为0.0
        //字符类型:默认初始化值为'/u0000',即空格
        //布尔类型:默认初始化值为false
        //引用数据类型:默认初始化值为null
    }

五、数组常见问题

        only one:当访问了数组中不存在的索引,就会引发索引越界异常

六、数组常见操作

        1.求最值

        2.求和

        3.交换数据

        4.打乱数据

数组练习

一、求最值

        1.需求

                已知数组元素为{33,5,22,44,55},请找出数组中最大值并打印在控制台

        2.参考答案

    public static void main(String[] args) {
        //需求已知数组元素为{33,5,22,44,55}
        //请找出数组中最大值并打印在控制台

        //定义数组
        int[] array = {33, 5, 22, 44, 55};

        //找出数组中的最大值
        //定义变量max存储临时最大值
        //max记录为array[0],不能为0。因为若数组中均为负值,则输出结果为0,但数组中未存储0
        //max的初始化值一定要是数组中的值
        int max = array[0];
        
        //遍历数组
        //循环开始条件若为0,则第一次循环是自己与自己比较,对结果无影响,但效率偏低
        //为提高效率,减少一次循环次数,循环开始条件可以为1
        for (int i = 0; i < array.length; i++) {
            if (array[i] > max) {
                max = array[i];
            }
        }
        System.out.println("该数组中的最大值为" + max);
    }

二、遍历数组求和

        1.需求

                生成10个1~100之间的随机数存入数组。

                (1)求出所有数据的和

                (2)求所有数据的平均数

                (3)统计有多少个数据比平均值小

        2.参考答案

    public static void main(String[] args) {
        /*生成10个1~100之间的随机数存入数组。
        求出所有数据的和
        求所有数据的平均数
        统计有多少个数据比平均值小*/

        //定义一个数组存储10个随机数
        int[] number = new int[10];

        //生成10个1~100之间的随机数,并存入数组
        Random r = new Random();
        for (int i = 0; i < number.length; i++) {
            number[i] = r.nextInt(100) + 1;
        }

        //求数组中所有数的和
        //定义变量sum存储和
        int sum = 0;
        for (int i = 0; i < number.length; i++) {
            sum = sum + number[i];
        }
        System.out.println("所有数据的和为:" + sum);

        //求数组中所有数的平均数
        double mean = (double) sum / number.length;
        System.out.println("所有数据的平均数为:" + mean);

        //统计有多少个数据比平均值小
        //定义变量count存储数据个数
        int count = 0;
        for (int i = 0; i < number.length; i++) {
            if (number[i] < mean) {
                count++;
            }
        }
        System.out.println("数据比平均值小的个数为:" + count);

        //遍历数组,验证答案
        for (int i = 0; i < number.length; i++) {
            System.out.print(number[i]+" ");
        }
    }

三、交换数组中的数据

        1.需求

                定义一个数组,存入1,2,3,4,5。按照要求交换索引对应的元素。

                交换前:1,2,3,4,5

                交换后:5,4,3,2,1

        2.参考答案 

    public static void main(String[] args) {
        /*
        定义一个数组,存入1,2,3,4,5。按照要求交换索引对应的元素。
        交换前:1,2,3,4,5
        交换后:5,4,3,2,1
        */

        //定义数据数组
        int[] number = {1, 2, 3, 4, 5};

        //交换元素
        for (int i = 0, j = number.length - 1; i < j; i++, j--) {
            //定义临时变量存储要交换的元素值
            int temp = number[i];
            number[i] = number[j];
            number[j] = temp;
        }
        for (int i = 0; i < number.length; i++) {
            System.out.print(number[i] + " ");
        }
    }

四、打乱数组中的数据

        1. 需求

                定义一个数组,存入1~5。要求打乱数组中所有数据的顺序

        2.参考答案

    public static void main(String[] args) {
        //定义一个数组,存入1~5。要求打乱数组中所有数据的顺序

        //定义数组
        int[] array = {1, 2, 3, 4, 5};

        //循环遍历数组
        Random r = new Random();
        for (int i = 0; i < array.length; i++) {
            //生成随机索引
            int randomIndex = r.nextInt(array.length);

            //将随机索引指向的元素与i指向的元素交换
            //定义临时变量
            int temp = array[i];
            array[i] = array[randomIndex];
            //将i指向的元素交换给随机索引指向的元素
            //避免了交换后数组中元素值的重复
            array[randomIndex] = temp;
        }
        for (int i = 0; i < array.length; i++) {
            System.out.print(array[i] + " ");
        }
    }

数组的内存图

一、Java内存分配

        1.栈:方法运行时使用的内存,比如main方法运行,进入方法栈中执行

        2.堆:存储对象或数组,new来创建的,都存储在堆内存

        3.方法区:存储可以运行的class文件

        4.本地方法栈:JVM在使用操作系统功能的时候使用

        5.寄存器:给CPU使用

        注意:从JDK8开始,取消方法区,新增元空间。把原来的方法区的多种功能进行拆分,有的功能放到了堆中,有的功能放到了元空间中。

二、数组的内存图

        1.只要是new出来的一定是在堆里面开辟了一个小空间

        2.如果new了多次,那么在堆里面有多个小空间,每个小空间中都有各自的数据

        3.当两个数组指向同一个小空间时,其中一个数组对小空间中的值发生了改变,那么其他数组再次访问的时候都是修改之后的结果了。


总结

在了解了数组的基础知识后,一定要自己独立动手练习代码,为以后的进阶打好基础。并且此篇中数组的内存图板块一定要好好了解以下,科班出身的朋友想必比我更懂它的重要性。

  • 33
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
为了动态分配二维数组内存,有几种方法可以使用。一种方法是通过分配一块存放m个int *类型元素的内存,再分配一块存储m * n个元素数据的内存空间来实现,然后将首地址返回给** arr作为二维数组的索引。具体的实现代码如下所示: int** ArrMalloc2d(int ***arr, const int m, const int n) { *arr = (int **)malloc(m * sizeof(int *)); if(! *arr) { return ERROR; } **arr = (int *)malloc(m * n * sizeof(int)); if(! **arr) { return ERROR; } for (int i = 1; i < m; i++) { *(*arr + i) = *(*arr + i - 1) + n; if(! *(*arr + i)) { return ERROR; } } return *arr; } 这段代码会分配一维数组来存储指向二维数组每一行首元素的指针,然后分配一块连续的内存来存储二维数组的元素。通过这种方式,我们可以按照arr[i][j的方式访问二维数组的元素。为了释放内存,我们可以使用下面的代码: Status ArrFree2d(int ***arr, const int m) { free(*(*arr + 0)); *(*arr + 0) = NULL; if(*(*arr + 0)) { return ERROR; } free(*arr); *arr = NULL; if(*arr) { return ERROR; } return OK; } 这样就能动态地分配和释放二维数组内存了。但需要注意的是,使用这种方式分配的二维数组,在进行整块内存操作时会遇到问题,例如对所有元素清零。因为使用memset进行清零操作会清除连续的m * n个内存单元,而实际的*(arr + i)并不是连续的。因此,在对整块内存进行操作时需要注意。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [二维数组及其动态内存分配](https://blog.csdn.net/weixin_43955214/article/details/104126662)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值