Java 具有数组的多个赋值的意外输出
考虑Java 具有数组的多个赋值的意外输出,java,arrays,Java,Arrays,考虑 int b = 2; int[] a = new int[4]; a[a[b]] = a[b] = b = 2; for (int i = 0; i <= 3; i++) { System.out.println(a[i]); } 我希望a[0]为零。因为a[a[b]与a[0]相同,而您正在为此赋值2 b = 2, a[b] = 0 so a[a[b]] = 2 a[a[b]]=a[b]=b=2,从左侧执行 首先 现在, 所以输出是, 2 0 2 0 让我们看看a
int b = 2;
int[] a = new int[4];
a[a[b]] = a[b] = b = 2;
for (int i = 0; i <= 3; i++)
{
System.out.println(a[i]);
}
我希望
a[0]
为零。因为a[a[b]
与a[0]
相同,而您正在为此赋值2
b = 2, a[b] = 0 so a[a[b]] = 2
a[a[b]]=a[b]=b=2
,从左侧执行
首先
现在,
所以输出是,
2 0 2 0
让我们看看
a[a[b]]=a[b]=b=2代码>详细说明:
a[a[b]
:b是2,a[2]
是0,a[a[2]
是a[0]
所以a[a[b]]=a[b]=b=2代码>计算为a[0]=a[b]=b=2代码>
其计算结果为a[0]=a[2]=2所以a[2]
是2,a[0]
等于a[2]
我想你在读
a[a[b]]=a[b]=b=2
从右到左,期望数组和b在每一步都被重新计算,而实际上,a和b在赋值时似乎被冻结了。考虑等效代码:
1) int b = 2;
//array initialized to 0
2) int[] a= new int[4]; // 0 0 0 0
// at this point a[b] is a[2] = 0, therefore below a[a[b]]=2 is equivalent to a[0]=2
3) a[a[b]] = 2 // 2 0 0 0
// the same: a[b] = 2 is equivalent to a[2] = 2 -note that the arrays are zero based
4) a[b]= 2 // 2 0 2 0
5) b=2;
我想这个线程可能会帮助您理解java中的求值顺序:
这个问题最重要的部分是第一个=
是实际的赋值。在java中,索引总是在赋值之前求值,因此a[a[b]]
是求值顺序中的第一个索引。此时,a[b]
是JLS 15.26.1的0
摘录。简单赋值运算符=
如果左侧操作数是数组访问表达式(§15.13),
可能包含在一对或多对括号中,然后:
首先,左边操作数的数组引用子表达式
对数组访问表达式进行求值。如果此评估完成
突然,则赋值表达式为
同样的理由;左操作数数组的索引子表达式
访问表达式)和右侧操作数不求值,且没有
分配发生
这意味着a[a[b]]
在第一次求值时将求值为a[0]
。然后我们简单地按照a[0]=a[b]=b=2
进行,赋值从右到左进行
请参见为什么会有这样的代码?任何有三个作业的陈述都是一个坏主意…@Pshemo:很好的地方,而且复本上被接受的答案也很好。@Bathsheba所有学分都归最后一名。他找到了它并在他的答案中贴出了链接。我只是把它标记为复制品。
a[0]=a[2]=b=2;
2 0 2 0
1) int b = 2;
//array initialized to 0
2) int[] a= new int[4]; // 0 0 0 0
// at this point a[b] is a[2] = 0, therefore below a[a[b]]=2 is equivalent to a[0]=2
3) a[a[b]] = 2 // 2 0 0 0
// the same: a[b] = 2 is equivalent to a[2] = 2 -note that the arrays are zero based
4) a[b]= 2 // 2 0 2 0
5) b=2;