您的位置:首页 > 编程语言 > C语言/C++

Java和C++数组的比较

2016-03-30 22:26 501 查看
Java一维数组声明,创建和初始化:

public class TestArry {

public static void main(String arg[])
{
System.out.println("############################################");
int a[]=new int[6];//a[6]默认初始化为0;a后面的[]不能加数字
for(int i=0;i<5;i++)
{
a[i]=i;
}

    for(int i=0;i<6;i++)
    {
        System.out.println("a["+i+"]="+a[i]);
    }
System.out.println("动态初始化");
    System.out.println("############################################");
    int b[]={12,34,3,3,8,7};//初始化a[6]数组越界

for(int i=0;i<6;i++)
{
System.out.println("b["+i+"]="+b[i]);
}
System.out.println("静态初始化");
System.out.println("############################################");
}

}


############################################
a[0]=0
a[1]=1
a[2]=2
a[3]=3
a[4]=4
a[5]=0
动态初始化
############################################
b[0]=12
b[1]=34
b[2]=3
b[3]=3
b[4]=8
b[5]=7
静态初始化
############################################

C++一维数组声明,创建和初始化:

#include <iostream>

using namespace std;

int main()
{
int *a=new int[5];
for(int i=0;i<5;i++)
{
a[i]=i;
}

for(int i=0;i<5;i++)
{
cout<<"a["<<i<<"]:"<<a[i]<<endl;
}
cout<<"dynamic"<<endl;
cout<<"****************************"<<endl;

int b[5]={2,4.5,8,4};//int b[]={2,4.5,8,4};等价
for(int i=0;i<5;i++)
{
cout<<"b["<<i<<"]:"<<b[i]<<endl;
}
cout<<"static"<<endl;
cout<<"****************************"<<endl;
    delete a;
    return 0;
}




Java数组的工作原理与它们不同。Java中的数组是对象,这就意味着与C++中的数组的根本不同.

1、数组不是集合,它只能保存同种类型的多个原始类型或者对象的引用。数组保存的仅仅是对象的引用,而不是对象本身。数组声明的两种形式:一、int[]
arr; 二、int
arr[];  推荐使用前者,这是一个int数组对象,而不是一个int原始类型。

2、数组本身就是对象,Java中对象是在堆中的,因此数组无论保存原始类型还是其他对象类型,数组对象本身是在堆中的。

3、在数组声明中包含数组长度永远是不合法的!如:int[5]
arr; 。因为,声明的时候并没有实例化任何对象,只有在实例化数组对象时,JVM才分配空间,这时才与长度有关。

4、在数组构造的时候必须指定长度,因为JVM要知道需要在堆上分配多少空间。例:int[]
arr = new int[5];

5、一维数组的构造。形如:String[]
sa = new String[5];  或者分成两句:String[]
sa;  sa = new String[5];

6、对象类型的数组虽然被默认初始化了,但是并没有调用其构造函数。也就是说:Car[]
myCar = new Car[10];只创建了一个myCar数组对象!并没有创建Car对象的任何实例!
7、多维数组的构造。float[][]
ratings = new float[9][]; 第一维的长度必须给出,其余的可以不写,因为JVM只需要知道赋给变量ratings的对象的长度。

8、数组索引的范围。数组中各个元素的索引是从0开始的,到length-1。每个数组对象都有一个length属性,它保存了该数组对象的长度。(注意和String对象的length()方法区分开来)
9、Java有数组下标检查,当访问超出索引范围时,将产生ArrayIndexOutOfBoundsException运行时异常。注意,这种下标检查不是在编译时刻进行的,而是在运行时!也就是说int[]
arr = new int[10];  arr[100] = 100; 这么明显的错误可以通过编译,但在运行时抛出!

10、原始类型数组元素的默认值。对于原始类型数组,在用new构造完成而没有初始化时,JVM自动对其进行初始化。默认值:byte、short、 int、long--0  float--0.0f
double--0.0  boolean--false  char--'"u0000'。(无论该数组是成员变量还是局部变量)

Java中的数组中既可以存储基本的值类型,也可以存储对象。对象数组和原始数据类型数组在使用方法上几乎是完全一致的,唯一的差别在于对象数组容纳的是引用而原始数据类型数组容纳的是具体的数值。在讨论关于数组的问题时,一定要先确定数组中存储的是基本值类型还是对象。特别是在调试程序时,要注意这方面。在C/C++中,我们定义的变量所需的空间都是分配在栈上的,而new所需的空间都是分配在堆上的在栈上的变量必须在代码中明确指出大小,所以在C/C++中定义数组必须指定大小而JAVA中所有的变量都是引用,换个角度理解就是C++中的指针,所以在JAVA中的变量都是后期分配的,所以不需要在定义的时候就指定大小。

当执行AnimApp[] array = new AnimApp[3];时并不会调用构造函数,仅仅申请了空间。构造对象的时候才会调用构造函数。
Java中,定义一个数组, new[]时,并没有执行构造函数,
只是申请了一段内存空间,与C++中的allocator<T>.allocate(size)(因为allocator<T>的类型在运行时确定, 所以不是指定空间的字节数, 而是用元素个数,
每个元素的大小allocator中有记录)相似. 然后在构造一个对象的时候, 即如上new AnimApp(3)时, 才真正的构造对象, 似allocator<T>.construct(param).
C++中, new[]操作符(默认的)就会去先申请空间, 接着执行构造函数,
申请了多少个对象的空间, 执行多少次(每个对象一次), 所以想为无无参构造函数的类使用默认的new[]来定义一个数组是不行的, 这点与Java不同, 他是即申请空间, 同时也要构造对象, Java只是申请一段空间, 对于空间中的每个对象, 得自己显示的用new ClassName(param)来构造.

对于Java这种与C++不同之处的原因要归为它们之间的实现不同。

1)Java的数组不是集合,它只能保存同种类型的多个原始类型或者对象的引用。数组保存的仅仅是对象的引用,而不是对象本身。

2)数组本身就是对象,Java中对象是在堆中的,因此数组无论保存原始类型还是其他对象类型,数组对象本身是在堆中的。

3)在Java中,官方推荐的声明方式是Object []array,并且不能指定长度,只有new的时候才指定长度。

4)对象类型数组中的引用被默认初始化为null。如:Object [] myobj= new Object [10]; 相当于从myobj[0]到myobj[9]都这样被自动初始化为myCar[i] = null;并没有调用构造函数。在myobj[1] = new Object的时候才调用。至于Java为什么要选择这种方式,则是其刻意避免指针(容易犯错),符号都是引用类型。几乎所有的程序设计语言都支持数组。在C和C++中使用数组是很危险的。因为C和C++中的数组就是内存块。如果一个程序要访问其自身内存块之外的数组,或者在数组初始化之前使用它,都会产生难以预料的后果。

     java的主要目标之一就是安全性。java确保数组会被初始化,而且不能在它的范围之外被访问。这种范围检查,是以每个数组上少量的内存开销以及运行时的下标检查为代价的。但是由此换来的安全性和效率的提高,也是值得的。

     当java创建一个数组对象时,实际上就是创建了一个引用数组,并且每个引用都会被自动初始化一个特殊值。该值拥有自己的关键字null,一旦java看见了null,就知道这个引用还没有指向某个对象。如果使用某个指向null的引用,就会在运行时报错。

C++多维数组声明,创建和初始化

#include <iostream>
#include <math.h>
#include <stdlib.h>

using namespace std;

int main()
{
int **c=new int*[3];//二维数组c[3][4]
for(int i=0;i<3;i++)//申请内存
{
c[i]=new int[4];
}
srand(unsigned(time(NULL)));
for(int i=0;i<3;i++)//动态初始化
{
for(int j=0;j<4;j++)
{
c[i][j]=rand()%100;
cout<<c[i][j]<<endl;
}
}

for(int i=0;i<3;i++)
{
cout<<endl;
for(int j=0;j<4;j++)
{
cout<<c[i][j]<<"  ";
}
}

for(int i=0;i<3;i++)//delete堆中内存
{
delete[] c[i];
}
delete[] c;
cout<<"****************************"<<endl;

int*** d=new int** [3];//三维数组d[3][2][4]
for(int i=0;i<3;i++)
{
d[i]=new int*[2];
for(int j=0;j<2;j++)
{
d[i][j]=new int[4];
}
}

for(int i=0;i<3;i++)
{

for(int j=0;j<2;j++)
{
for(int k=0;k<4;k++)
{
d[i][j][k]=rand()%100;
}
}
}

for(int i=0;i<3;i++)
{
for(int j=0;j<2;j++)
{
for(int k=0;k<4;k++)
{
cout<< d[i][j][k]<<"   ";
}
}
cout<<endl;
}

for(int i=0;i<3;i++)
{
for(int j=0;j<2;j++)
{
delete[] d[i][j];
}
delete[] d[i];
}
delete[] d;
cout<<"########################";

return 0;
}



C++数组和指针:

一、关于数组名

假设有数组:

1.数组名代表数组第一个元素的地址,注意,不是数组地址(虽然值相等),是数组第一个元素地址,a 等同于 &a[0];a+1是第二个元素的地址。比第一个元素地址a(或者&a[0])超出了一个整型指针的大小,在这里是4个字节(byte)

2.取址符号&.

&a是数组的地址,注意是数组的地址,表示数组这个整体的地址。不是数组第一个元素的地址(虽然他们的值相同)

&a+1比数组的地址&a超出了一个数组的地址大小,在这里是3*4个字节

int * p = &a;这条语句是不成立的。左边指针变量p时指向整型的指针,而右边是数组(类型是数组)的地址,不是数组元素(类型是整型)的地址,所以不能赋值。
应该赋值给数组指针(下面会讲到)。

关于数组名,切记以上两点。

二、关于指针数组

1.定义

指针数组,就是存放指针的数组,数组里的元素是指针(对比于整型数组,整型数组就是存放整型的数组,数组里的元素是整型)int *ptr[3];如何理解?按照运算符优先级,[]优先级较大,所以ptr先与[3]结合,表示ptr是一个数组,必然要明确数组的元素类型,所以数组里的元素类型是整型指针(int*),数组的大小不一定需要(定义数组时可以根据初始化的元素个数确定)ptr[0]就是数组的第零个元素,它是一个整型指针。

示例如下:

2.如何使用?

像一般指针一样使用。*ptr[0]就是第零个元素(一个指针)所指向元素的值,这里是 5。

三、关于数组指针

1.定义

数组指针,就是指向数组的指针,它是一个指针,指向一个数组(对比于整型指针,就是指向整型的指针,它是一个指针,指向一个整型)

int (*ptr)[3]; 如何理解?先看小括号里面,*ptr说明ptr是一个指针,然后跟[]结合表明这个指针指向一个数组,数组的元素是int

右边a是数组名,还记得上面说的吗,数组名代表数组第一个元素的地址,就是&a[0],数组名的类型相当于整型指针(不知道事实上是不是)int *,因为它指向了第一个元素,第一个元素是int,左边ptr的类型是int(*)[],是数组指针,指向数组的指针,不是指向整型的指针,不能赋值。

因为a是一个数组,&a就是数组的地址,还记得上面说的吗?

2.如何使用

这里有一点难以理解。不防对比一下一下代码。

p是一个指向整型的指针,*p就是所指向的变量(整型x)的值。同理ptr是指向数组的指针,*ptr就是所指向的变量(数组a)的值。(*ptr)[0]就是数组的第零个元素。

四、关于二维数组

1.二维数组是一个数组,它的元素是一维数组。谨记这一点,然后把上面的套进来就行了。

数组名

a是数组第一个(或者说第零个更好)元素的地址,第一个元素是一维数组,a[0] ------> {1, 2, 3}。a+1是第二个元素的地址,就是第二个一维数组的地址,超出了3*4个字节,&a是数组的地址,&a+1 就是超出了一个二维数组的大小,超出了3 * 4 * 3 个字节。

数组指针

因为a表示第一个元素的地址,第一个元素是一个一维数组,所以a表示一个一维数组的地址,一个数组的地址赋值给数组指针,成立。

五、总结:

1.数组名表示数组的第一个元素的地址。

2.&a(a是一个数组)是数组的地址。

3.指针数组是一个数组,它的元素是指针。

4.数组指针是一个指针,它指向一个数组。

5.二维数组的元素是一维数组。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: