A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© hejinzhong 中级黑马   /  2014-7-6 09:58  /  1878 人查看  /  8 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

今天学习了java中的数组,觉得和C有不少差别,各位大神们,请看下面这些疑问,求验证(给图给真相)。
(1)二维数组的地址是否是数组第一行(arr[0])和第一个元素(arr[0][0])地址相同?
(2)int[][] arr=new int[12],这12个元素在内存中的空间是否连续的?
(3)二维数组中,每行元素可以不同吗?是否可以这么定义 int[][] arr=new int[][4]{{1},{2},{3}}; ?

8 个回复

倒序浏览
(1)第一个问题的C语言数组验证
        #include<stdio.h>
        int main()
        {
              int arr[2][3];
              printf("%p\n%p\n%p\n",arr,arr[0],&arr[0][0]);
              //分别输出三个数组、第一行、首元素的地址
              return 0;
         }


评分

参与人数 1技术分 +1 收起 理由
李小然 + 1

查看全部评分

回复 使用道具 举报

运行结果,在C中表明这三个的地址是相同的。

1.jpg (22.74 KB, 下载次数: 14)

1.jpg
回复 使用道具 举报
问题1,java中验证(求指导错误)

class Demo
{
        public static void main(String[] args)
        {
                int[][] arr = new int[2][3];
                System.out.println(arr);//输出数组地址
                System.out.println(arr[0]);//第一行地址
                System.out.println(&arr[0][0]);//第一个元素地址
        }
        return 0;
}
回复 使用道具 举报
本帖最后由 OCTSJimmy 于 2014-7-6 10:46 编辑
hejinzhong 发表于 2014-7-6 10:28
问题1,java中验证(求指导错误)

class Demo


首先,System.out.println(&arr[0][0]);出错,JAVA中没有指针地址的概念。



其次,我找到一篇达文,果然是达人的杰作:
原帖地址:http://blog.sina.com.cn/s/blog_74924f2401017uqb.html
PS:多谢达人!

数组Array:java中的数组与C中的完全不一样。  相同类型的数据的集合叫做数组
如何定义数组:type[] 变量名 = new type[数组中元素的个数]   或者  int[] a = {1,2,3};     或者 int[] a = new int[]{1, 2, 3, 4};
int[] a = new int[4]{1, 2, 3, 4};的书写格式是错的
int[] a = new int[4];  表示我定义了一个int类型的数组,名字叫做a,这个数组的长度是4,开辟了16个字节的地址空间
Java中的每个数组都有一个名为length的属性,表示数组的长度。length属性是public,final,int的。数组长度一旦确定,就不能改变大小(例int[] a = new int[100]; a.length = 200;出错)

int[] a = {1, 2, 3};
int[] b = {1, 2, 3};
System.out.println(a.equals(b));//结果为false,因为数组对象并没有对Object类中的equals方法进行重写,所以对象数组引用了Object类中的equals方法,比较两者的地址,两个数组对象,地址肯定不同
int[] a = new int[10]; 其中a是一个引用,它指向了生成的数组对象的首地址,数组中每个元素都是int类型,其中仅存放数据值本身。
  1. public class Array
  2. {
  3. public static void main(String[] args)
  4. {
  5. Person[] p = new Person[10]; //内存中生成0个person对象,因为仅仅声明了数组本身,没有生成对象。数组中存放的是对象的引用,不是对象本身,我们只能通过引用来操纵对象。所以说这里的new有点欺骗的作用,实际没有创建对象
  6. System.out.println(p[0]);
  7. }
  8. }

  9. class Person
  10. {
  11. int age;
  12. public Person(int age)
  13. {
  14. this.age = age;
  15. }
  16. }
复制代码

输出结果:null
引用数组中的各个元素都为引用类型,没赋初值的时候为null,表示不指向任何对象
  1. public class Array
  2. {
  3. public static void main(String[] args)
  4. {
  5. Person[] p = new Person[10]; //内存中生成0个person对象,因为仅仅声明了数组本身,没有生成对象。数组中存放的是对象的引用,不是对象本身,我们只能通过引用来操纵对象。
  6. p[0] = new Person(10);//输出的结果为地址
  7. p[1] = new Person(20);
  8. p[3] = new Person(30);
  9. for(int i = 0; i<p.length; i++) //p.length的值为10
  10. {
  11. System.out.println(p[i]);
  12. }
  13. }
  14. }

  15. class Person
  16. {
  17. int age;
  18. public Person(int age)
  19. {
  20. this.age = age;
  21. }
  22. }
复制代码
数组都有一个length属性





还有篇达文,详解了JAVA中“指针”的概念:
原文地址:http://blog.csdn.net/hitxueliang/article/details/7297866
在实际 的编程中,经常有人问我关于两个对象相同,一个改变了对于另一个是否影响的问题,实际中也常遇到这样的问题,有的时候,可能一时发现不了问题,这个问题实际上就是对于Java中和C++中指针的认识没有搞清楚。下面我来阐述我对Java中指针的理解。
尽管java并不使用显示指针而且不允许编程者使用指针,可是访问对象依然以来指针。一个对象占用了从某个位置开始的一段内存空间,指针对于该对象而言只是一个保存了对象地址的变量,并且这个地址是对象的内存起始地址。在很多的语言里,指针是一种变量类型的技术术语,在Java中避免了这个术语而是用引用代替了它。
用例子说明更为明了。
比如定义了一个实体
  1. Class Node{

  2. Stirng name;

  3. int age;

  4. }

复制代码

声明:
  1. Node p=null,q=new Node("asd",10);

  2. p=new Node("asd",10);

  3. System.out.println(p==q);
复制代码

理解了引用就不难理解,输出是假,因为我们比较的是两个不同对象的引用变量,也就是,比较了两个不同的引用(地址),而不是对象。因此为了比较对象的内容,我们必须定义一个方法一次比较各个数据域。
  1. public boolean equals(Node n)
  2. {
  3. return name.equals(n.name)&&age==n.age;
  4. }
复制代码

对象变量是对象的引用,这个现实有助于解释为什么需要谨慎的使用赋值运算符。
声明:Node node1=new Node("abc",20),node2=node1;
目的是创建对象node1,并为他的两个域赋值,然后创建对象node2,并将他的域初始化为相同的值。这些对象应当是独立的实体,因此对于他们中的任何一个的赋值都不会英系那个另一个的值,但是,在下面的赋值语句中:
  1. node2.name="def";
  2. node2.age=10;
复制代码
之后打印
  1. System.out.println(node1.name+" "+node1.age+" "+node2.name+" "+node2.age );
复制代码

结果竟是:

def 10 def 10
这就充分的说明了这些变量名称都是引用,相当于C++中的指针,指向的是同一个地址。
尽管Java中缺少显示指针,但是Java比C/C++更依赖指针。只是这些对于编程者是透明的。
回复 使用道具 举报
上面程序小改动下:
class Demo
{
        public static void main(String[] args)
        {
                int[][] arr = new int[2][3];
                System.out.println(arr);
                System.out.println(arr[0]);
                //System.out.println(Integer.toHexString(arr[0][0].hashCode));
                //不知道怎么获取变量的地址 求支援!
        }
}
回复 使用道具 举报

这个是JAVA中的验证,可惜只有数组地址和第一行地址,但可以看出他们的地址不是一个地方。
求大神告知怎么获取一个变量的地址。
回复 使用道具 举报
OCTSJimmy 发表于 2014-7-6 10:39
首先,System.out.println(&arr[0][0]);出错,JAVA中没有指针地址的概念。

了解了,3Q
回复 使用道具 举报
嗯,关于多维数组,毕老师有更直观的解释了,为什么print出来的内存地址会不一样:




图中的内存地址为示例地址,所以随意写的,实际地址其实是例如:
c中存的是 [[I@xxxxx 这种格式
c[0]中存的是 [I@xxxxx 这种格式


如此可懂?

回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马