我们在程序设计中,需要经常用到数组和字符串这两种数据结构,无论是面向对象,还是面向过程,这是由于我们需要处理大量的数据
一维数组
我们先来看看最简单的数组------一维数组,其逻辑结构为线性表
定义方式为
int [] grade = new int[100];
double[] averages = new double[200];
即
数据类型 [] 数组名;
数组名 = new 数据类型 [个数];
注意:
元素个数必须为整数
元素个数必须给出
元素个数可以是变量
比如:
可以由用户来确定我们的数组的大小
int count;
count = in.nextInt();
int[] x = new int [count];
有效的下标
而如果我们确定了一个数组之后,我们就需要知道其下标从而得到不同元素的位置,从而进行各种操作
- 最小的下标为0,最大的下标是数组的元素个数-1
- 编译器不会检查看你是否用了有效的下标
- 但是运行的时候出现了无效的下标,可能会导致程序终止
length
我们在确定数组的长度时可以直接使用Length,这样后续在修改代码时,循环语句不会由于变量的改变而改变大量的篇幅
for (i=0; i<100; ++i)
sum + grade[i];
最好是
for (i=0; i<grade.length; ++i)
sum + grade[i];
写循环我们还可以用foreach
格式如下
for(type element: array)
{
System.out.println(element);
}
实际就是输出array这个数组里的每一个元素element
注意:
定义了一个数组之后,Java会自动帮助我们填充0,故我们不需要自动初始化
直接初始化数组
new 创建的数组会得到默认值0
int[] scores = {1,2,3,4,5,6,7,7};
直接用大括号给出数组的所有元素的初始值
不需要给出数组的大小,编译器会自动数数
int[] scores = {1,2,3,4,5,6,7,8};
System.out.println(scores.length);
#输出为8
数组变量赋值
int[] a = new int[10];
a[0] = 5;
int[] b = a;
b[0] = 16;
System.out.println(a[0]);
我们会得到a[0[输出是16,这可能会和我们的C++不相同,理解起来也比较的困难
这是由于在Java里面int[] b = a;并没有新建数组,而是b也去管理a管理的那一块内存地址,即a和b知识管理者,而不是所有者
下面举一个例子
int[] a1 = {1,2,3,4,5};
int[] a2 = a1;
for (int i=0; i<a2.length; ++i)
{
a2[i]++;
}
for (int i=0; i<a1.length; ++i)
{
System.out.println(a1[i]);
}
用这个图可以很好的理解
总结
- 数组变量是数组的管理者而非数组本身
- 数组必须创建出来然后交给数组变量来管理
- 数组变量之间的赋值是管理权限的赋予
- 数组变量之间的比较是判断是否管理同一数组
那我们如何得到复制过去的数组呢
我们先来看个例子
Scanner in = new Scanner(System.in);
in[] a = {1,2,3,4,5};
int[] b = {1,2,3,4,5};
System.out.println(a==b);
输出为false
而我们使其管理同一块地址的时候是相同的,故可以知道它开辟了两个空间
那如果我们想要复制一个数组的话,我们就需要一个一个复制过去
int[] a = {1,2,3,4,5};
int[] b = new int[a.length];
for (int i=0; i<b.length; i++)
{
b[i] = a[i];
}
System.out.println(a==b);
二维数组
定义为
int[][] a = new int[3][5];
//可看作a为一个3行5列的矩阵
对其如何遍历呢
for (i=0;i<3;i++)
{
for (j=0;j<5;j++)
{ a[i][j] =i*j; }
}
注意:
a[i][j] 是一个int,表示第i行第j列的单元,实际并不存在
初始化问题
int[][] a = {
{1,2,3,4},
{1,2,3},
};
编译器来数数
每一个大括号用逗号来分隔
最后的逗号可以存在
如果省略可以补零