我有以下代码:
public class Book {
private static int sample1(int i) {
return i++;
}
private static int sample2(int j) {
return ++j;
}
public static void main(String[] arguments){
int i = 0;
int j = 0;
System.out.println(sample1(i++)); //0
System.out.println(sample1(++i)); //1
System.out.println(sample2(j++));//1
System.out.println(sample2(++j));//2
System.out.println(i);//2
System.out.println(j);//2
}
}
我的预期输出在评论中。实际输出如下:
0
2
1
3
2
2
我对函数调用和incemental运算符感到困惑。有人可以解释实际结果吗?
答案 0 :(得分:15)
由于sample1
和sample2
只是修改自己的局部变量i
和j
(不是调用方法的变量),所以如果我们更清楚在没有这些修改的情况下重写它们:
private static int sample1(int i) {
return i; // was 'i++', which evaluates to the old i
}
private static int sample2(int j) {
return j + 1; // was '++j', which evaluates to j after incrementing
}
在这一点上直接替换它们是直截了当的 - sample1(...)
变为...
,而sample2(...)
变为... + 1
:
int i = 0;
int j = 0;
System.out.println(i++);
System.out.println(++i);
System.out.println((j++) + 1);
System.out.println((++j) + 1);
System.out.println(i);
System.out.println(j);
我们可以通过将增量分成它们自己的命令来使这一点更加清晰。 i++
评估i
的原始值,因此在运行周围命令后递增i
;相比之下,++i
就像在运行周围命令之前递增i
。所以我们得到:
int i = 0;
int j = 0;
System.out.println(i);
i++;
++i;
System.out.println(i);
System.out.println(j + 1);
j++;
++j;
System.out.println(j + 1);
System.out.println(i);
System.out.println(j);
。 。 。在这一点上,应该直截了当地查看它将会输出什么。
这一切都有意义吗?
答案 1 :(得分:11)
首先,您需要了解x++
和++X
;
如果是x++
:
首先使用当前值,然后将增加当前值。
这意味着您将获得操作的x
的当前值以及您是否
下次使用x将获得递增的值;
如果是++x
:
首先,当前值将递增,然后将使用它(递增值),这意味着您将获得递增的值 在此操作和此操作后的其他操作。
现在让我们分开代码并单独讨论
方法:sample1():
private static int sample1(int i) {
return i++;
}
此方法将采用int并首先返回它然后尝试递增但是在返回后变量i
将超出范围,因此它将永远不会
完全递增。 exp in: 10-> out 10
方法:sample2():
private static int sample2(int j) {
return ++j;
}
此方法将获取一个int并首先递增它然后返回它。 exp in: 10-> out 11
在这两种情况下,只有变量会在本地更改,这意味着如果从main方法调用,main方法的变量将不受更改的影响 (因为sample1()和sample2()正在复制变量)
现在为主要方法的代码
System.out.println(sample1(i++)); // it's giving sample1() `i=0` then making `i=1`
// so sample1() will return 0 too;
System.out.println(sample1(++i)); // it's making `i=2` and then giving sample1() `i=2`
// so sample1() will return 2;
System.out.println(sample2(j++)); // it's giving sample2() `j=0` then making `j=1`
// so sample2() will return 1;
System.out.println(sample2(++j)); // it's making `j=2` giving sample2() `j=2` then
// so sample2() will return 3;
答案 2 :(得分:8)
您正在体验前缀和后缀运算符的乐趣。
前缀运算符++i
将变量i
增加一个,然后在表达式中使用它,其中后缀运算符(i++
)使用{{在递增之前的表达式中的1}}。
这意味着你的方法i
没有做任何事情;它会计算包含sample1
的表达式,但由于该表达式是一个return语句,因此局部变量i
超出范围,我们不能再修改它了。
i
会在返回之前递增sample2
的本地副本,这就是您打印的j
值高于预期的原因。
答案 3 :(得分:2)
易于:
1)第一次通话:
a)向sample1()提供i(== 0),返回0(然后递增参数i,然后丢弃)。
b)因i ++而增加i。 我现在是1
c)打印功能结果:0。
2)第二次通话:
a)因为++ i而增加i。 我现在2
b)向sample1()提供i(== 2),返回2(然后递增参数i,然后丢弃)
c)打印功能结果:2。
3)第三次电话:
a)向sample2()提供j(== 0),使参数递增,因此返回1.
b)因为j ++而增加j。 j现在为1
c)打印功能结果:1。
4)第四次电话:
a)因为++ j而增加j。 j现在为2
b)将j(== 2)提供给sample2(),使参数递增,因此返回3.
c)打印功能结果:3。
5& 6)第五和第六电话:
a)打印j的值:2。
这里要记住的关键是i ++在将变量作为参数传递之后递增变量,而++ i在将变量作为参数传递之前递增变量。
希望这有帮助
答案 4 :(得分:2)
第一次印刷
呼叫前:i = 0
通话后递增
调用sample1,值为0
样本1返回0,丢弃增量
电话后:i = 1
第二次印刷
呼叫前:i = 1
呼叫前递增
调用sample1,值为2
sample1返回2,丢弃增量
电话后:i = 2
第3次印刷
呼叫前:j = 0
通话后递增
调用sample2,值为0
sample2增量0到1,返回
打印1
将j增加到1
电话后:j = 1
第4次印刷
呼叫前:j = 1
呼叫前递增
将j增加到2
调用sample2,值为2
sample2增量2到3,返回
打印3
电话后:j = 2
第5次印刷
打印我
打印2
第6次印刷
打印j
打印2
答案 5 :(得分:2)
它们都将变量i增加一个,如i = i + 1;
区别在于:
++ i首先递增值然后返回
i ++首先返回值,然后递增
这种行为差异在for循环中无关紧要。
如果你想知道差异,试试这个:
int x = 0;
int y = x++;
int x = 0;
int y = ++x;
此处x++
返回值然后递增它,但++x
首先递增该值然后返回该值
答案 6 :(得分:2)
形成你的榜样,
private static int sample1(int i) {
return i++;
}
private static int sample2(int j) {
return ++j;
}
public static void main(String[] arguments)
{
int i = 0;
int j = 0;
System.out.println(sample1(i++)); //0
System.out.println(sample1(++i)); //1
System.out.println(sample2(j++));//1
System.out.println(sample2(++j));//2
System.out.println(j);//2
System.out.println(j);//2
}