黑马程序员技术交流社区

标题: foreach语句二维数组嵌套问题 [打印本页]

作者: 杨贺阳    时间: 2012-7-17 12:02
标题: foreach语句二维数组嵌套问题
本帖最后由 杨贺阳 于 2012-7-17 13:33 编辑

关于foreach语句,我在论坛里搜了一下帖子,感觉没有解决我的疑惑,所以发帖求助~
请看下面这个例子。

               我知道foreach语句是遍历数组的元素的,但是我不理解这个遍历二维数组的for嵌套,无法理解我就记不住。
疑问一、第一个for里面为什么是 int  x[] 而不是int  x  ,别跟我说因为把 int x[]看成是元素变量,如果是这样,那怎么把 int x[]看成是元素变量,能不能讲讲计算机运行这个语句的时候,
       内部如何一步一步的执行的。
疑问二、 第二个for中if语句有一句e==x.length   ,按照教材上的注释,这句是表示判断e是否是数组的最后一个变量,

x.length不是数组的长度的具体数值吗?把e的值和数组长度的值比较,会得出e是数组最后一个变量的结论吗?

如果这句if 语句的运行,跟第二个for有关联,运行受for的影响,那么这个if (e==x.length  )怎么就判断e是否是数组最后一个变量了。

我是思考是e是什么,是元素变量,二维数组的,那么e和x.length比较,好像就没有意义,除非e是一个元素变量标号,而这个标号还是从1开始的,跟数组不同!
是这样吗?这只是我的推论猜想,有没有知道真相的大神啊!?

      三、麻烦大家了,还希望能详细讲讲,尤其是想大神帮我梳理一下计算机内部如何运行foreach语句,很迷惑~

大家有人说要帖出代码,复制粘贴代码如下,不过不知道为什么代码的空格没有了,显得没有结构
class Demo
{
public static void main(String[] args)
{
  int arr[][]={{8,32},{211,27}};
  for(int x[]:arr)
  {
   for(int e:x)
   {
    if(e==x.length){System.out.println(e);}
    else System.out.println(e+"、");
   }
   
  }
  
}
}


作者: 党巾水    时间: 2012-7-17 12:06
本帖最后由 刘馨琪 于 2012-7-17 12:14 编辑

第一个for里面为什么是 int  x[] 而不是int  x
因为一个遍历的时里面的数组。数组要有[]标明。

把e的值和数组长度的值比较,会得出e是数组最后一个变量的结论吗?
会,题目中最后一个元素是2,恰好是数组长度,前面的三个元素都不等于数组长度,所以有else里面的打印格式。打印到最后一个元素时末尾不加逗号。

这个也就只能在这里用,特别让数组元素和数组长度相等才能这样~~呵呵
作者: 杨贺阳    时间: 2012-7-17 12:12
刘馨琪 发表于 2012-7-17 12:06
第一个for里面为什么是 int  x[] 而不是int  x ,因为一个遍历的时里面的数组

这个我知道,第一个for是遍历一维数组的,但是计算机如何遍历了一维数组,我是想问下这个计算机的详细过程,因为不明白这个,就造成了我第二个疑问,请认真思考对待一下我的问题啊。,,
作者: 党巾水    时间: 2012-7-17 12:12
杨贺阳 发表于 2012-7-17 12:12
这个我知道,第一个for是遍历一维数组的,但是计算机如何遍历了一维数组,我是想问下这个计算机的详细过 ...

我更新了答案,你看下
作者: 杨贺阳    时间: 2012-7-17 12:20
刘馨琪 发表于 2012-7-17 12:06
第一个for里面为什么是 int  x[] 而不是int  x
因为一个遍历的时里面的数组。数组要有[]标明。
这个也就只能在这里用,特别让数组元素和数组长度相等才能这样~~呵呵


你是意思是这是个巧合?。。。。。不会吧,那改变这个例子的数组元素值就不能用了?
作者: 程潇    时间: 2012-7-17 12:27
本帖最后由 程潇 于 2012-7-17 12:29 编辑

要解答你的疑问,首先要分析清楚这个二维数组
int arr[][]={{4,3},{1,2}};
二维数组又可以看成是数组的数组,我们对它进行拆分,就可以拆成:arr[0][]和arr[1][]两个一维数组,他们对应的值分别为:
arr[0][]={4,3}
arr[1][]={1,2}
分析到此,我们再来看通过foreach来遍历数组的元素。
我们要遍历数组arr[][],通过以上分析,可以先遍历arr[0][]和arr[1][],然后再对这两个数组进行遍历
因此就有了foreach的两层循环
第一层:for(int x[]:arr),这里的x[]就是指的arr[0][]和arr[1][], arr指的是二维数组arr[][]
第二层:for(int e:x),e表示x[]的元素,即arr[0][]或arr[1][]中的元素,x表示arr[0]或arr[1]

希望对你有帮助
作者: 党巾水    时间: 2012-7-17 12:31
杨贺阳 发表于 2012-7-17 12:20
你是意思是这是个巧合?。。。。。不会吧,那改变这个例子的数组元素值就不能用了? ...


对,你试试改成{{2,6},{3,4}},看看还能不能全遍历出来
作者: 党巾水    时间: 2012-7-17 12:36
杨贺阳 发表于 2012-7-17 12:20
你是意思是这是个巧合?。。。。。不会吧,那改变这个例子的数组元素值就不能用了? ...

等下,好像我错了。
作者: 党巾水    时间: 2012-7-17 12:38
本帖最后由 刘馨琪 于 2012-7-17 12:54 编辑
杨贺阳 发表于 2012-7-17 12:20
你是意思是这是个巧合?。。。。。不会吧,那改变这个例子的数组元素值就不能用了? ...


数字可以遍历出来,只是里面的逗号,那个标点打印位置就会有问题,所以这个东西只能应用在这个2结尾的数组中


你确定标点也是正确的吗?
作者: 杨贺阳    时间: 2012-7-17 12:41
程潇 发表于 2012-7-17 12:27
要解答你的疑问,首先要分析清楚这个二维数组
int arr[][]={{4,3},{1,2}};
二维数组又可以看成是数组的数组 ...

感谢回答,有心了~

第二层:for(int e:x),e表示x[]的元素,即arr[0][]或arr[1][]中的元素


如果e表示x[]的元素,那么我的第二个疑问,if(e==x.length)中表达的内容,
按照你的解释就应该表达如下: 把x[]的元素 跟它 x[]二维数组的长度比较,这不是很难说通吗?
作者: 党巾水    时间: 2012-7-17 12:55
杨贺阳 发表于 2012-7-17 12:20
你是意思是这是个巧合?。。。。。不会吧,那改变这个例子的数组元素值就不能用了? ...

你确定标点也是正确的吗?
作者: 王飞    时间: 2012-7-17 13:07

个么,下次发代码可以吗  这样我们就可以复制代码,然后在相应位置上给你改正说明。


你第一个 for(int x[] : arry)----------------这里的意思是把一个二维数组的-----第一维----传递给int x,又因为arr 的第一维是个数组类型的,所以这里要用int[] x,这个数组来接收


for(e : x)-----你把一个int[] x数组中的每一个变量都用e接收,那么下面的e就是你x数组中的每一项值咯-----e是你int[] x数组中的的数值

if(e==x.length)----因为e是x数组中的数值,那么x.length返回的也是一个数值,此时就可以判断了
作者: 程潇    时间: 2012-7-17 13:08
杨贺阳 发表于 2012-7-17 12:41
感谢回答,有心了~

这个例子是为了凑出在打印最后一个元素时不打印标点符号,硬凑的一句if(e==e.length)
按照你说的if(e==x.length)这句的目的是判断e是否是数组的最后一个变量,在这个数组中只有最后一个元素值是2,而数组的长度也是2。

作者: 杨贺阳    时间: 2012-7-17 13:21
程潇 发表于 2012-7-17 13:08
这个例子是为了凑出在打印最后一个元素时不打印标点符号,硬凑的一句if(e==e.length)
按照你说的if(e==x. ...

我晕死,这代码也太坑爹了,原来果然是巧合,故意硬凑的。。。
作者: 党巾水    时间: 2012-7-17 13:26
刘馨琪 发表于 2012-7-17 12:55
你确定标点也是正确的吗?

我觉得在已知有这样的数组的情况下,这个办法还是很巧妙的,避免了写标点那个复杂的过程。值得借鉴,感谢分享。
作者: 张世威    时间: 2012-7-17 13:41
1、数组是一个容器,多维数组就是容器里面装容器,这个题里面的数组int arr[][]={{4,3},{1,2}};
       是1个大数组里面装了2个小数组,①第一个小数组里面装了4和3
                                                    ②第二个小数组里面装了1和2
2、就像一个大盒子里面装了i个盒子,每个盒子里面又装了j个苹果,你要吃苹果,必须打开大盒子,在打开小盒子,即两次循环,才可以吃完所有的苹果。如图


3、你这样想,你第一次循环,拿出一个小盒子,这个小盒子是一维数组,你遍历完它。
                       你第二次循环,拿出第二个盒子,这个小盒子也是一维数组,你遍历完它。
                       你第三次循环,拿出第三个盒子, 这个小盒子也是一维数组,你遍历完它。
                                                 。。。。。。

      这里面涉及要一层关系了,一层层的剥皮,就可以把最里层的数据拿出来了。
        
4、你的疑问:① int[] x 的x指的就是小盒子,是个一维数组,
                       ②int e  的e指的就是苹果了,是一个int数据
                      ③if (e==x.length  ) 如果e和小盒子的长度相等,则输出 小盒子长度
                                                          否则输出 e值
                         这一句好像没有什么意义。。判断小盒子里面的元素值和盒子长度?
                       把内层循环里面的fi判读去掉,直接写出System.out.println("e"+"、”);
                    这样就会把所有的数都遍历出来了







欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2