`
喻红叶
  • 浏览: 41113 次
  • 性别: Icon_minigender_1
  • 来自: 哈尔滨
社区版块
存档分类
最新评论

一个表达式中对同一个变量多次赋值(i = i++)

 
阅读更多

问:

int i = 0;
i = ++i;
i的值是多少?毫无疑问,i = 1;但是,i = ++i;这条语句对i进行了两次赋值:第一次,i自增,此时i=1;第二次,将++i的表达式的值(也就是1)赋给i。我们通过字节码来分析一下这段代码的执行过程:

//int i = 0;的字节码
0:iconst_0 //将int型0推送至栈顶
1:istore_1 //将栈顶值(0)存入局部变量表中索引为1的地方(也就是i)

// i = ++i;的字节码
2:innc 1,1  //在局部变量表中索引为1的变量加1,此时i=1;
3:iload_1   //索引为1的变量值存入栈顶
4:istore_1  //将栈顶值存入索引为1的变量中

理解了上面的代码后,再考虑这样两行代码:

int i = 0;
i = i++;
这两条代码执行完成后,i的值是多少?答案是0。稍加思考,就会觉得这个结果并不是太意外,这两句代码的执行过程是这样的:

1))定义整型局部变量i,初始值为0;

2)JVM执行i++计算,该表达式的值为0;

3) i自增,i此时为1;

4)将i++表达式的值赋给i,i++表达式的值是0,所以赋值后,i = 0;

5)计算完毕,i = 0。

上面的每一步都不会让我们感到意外,为了更加清晰的说明问题,上面两行代码的等价代码如下:

int i = 0;

int tmp = 0;  //对应分析中的第(2)步,也就是i++表达式的值
i++;         //分析中的第(3)步
i = tmp;    //分析中的第(4)步

我们也从字节码看看这两条语句的执行过程:

//int i = 0;的字节码

0:iconst_0 //将int型0推送至栈顶,此时栈中的内容:[0]

1:istore_1 //将栈顶值(0)存入局部变量表中索引为1的地方(也就是i),i = 0;栈中的内容:[ ]

// i = i++;的字节码

2:iload_1 //索引为1的变量值存入栈顶,也就是i++表达式的值(0)存入栈顶,此时栈中的内容:[0]

3:innc 1,1 //在局部变量表中索引为1的变量加1,此时i=1;栈中的内容:[0]

4:istore_1 //将栈顶值(0)存入索引为1的变量中,i=0;栈中的内容:[ ]

从字节码中,我们可以看到:JVM首先把i++表达式的值存入到操作数栈中,也就是栈中保存着i = i++右半部的值(表达式i++,也就是0);然后把=右边的表达式计算完毕;最后将表达式i++的值赋给i(栈顶元素出栈,赋给i)。注意,i++是一个表达式,这个表达式的值是0。

这样的讨论其实是没有意义的,不要在一个表达式中,对同一个变量多次赋值!

参考资料:http://www.ticmy.com/?p=43(写这篇博客主要是为了加深自己的理解)


分享到:
评论

相关推荐

    java中for(int i= 0; i<=10;i=i++)System.out.print(i);为什么无限输出0

    因此,如果我们在一个表达式中直接使用`i++`,那么这个表达式的值就是`i`的原始值。例如,如果`i`的初始值为0,那么`i++`表达式的值也为0,尽管之后`i`的值变为1。 #### 循环中的`i = i++`操作 当我们把这个表达式...

    变量与赋值PPT学习教案.pptx

    当程序中多次对同一个变量进行赋值时,变量的最终值将是最后一次赋值的值。例如,如果有一个程序段: ``` x = 1 x = x + 2 x = 4 ``` 在执行完这些语句后,变量`x`的最终值将会是4。 赋值语句有一些使用规则: 1. ...

    整数运算表达式及赋值语句翻译

    赋值语句是将一个值(如运算表达式的结果)赋给变量的指令。在大多数编程语言中,赋值操作符是 `=`。例如,`x = 5` 将整数 5 赋给变量 x。当我们有整数运算表达式时,可以将其结果赋给变量,如 `y = x + 3`,这会将 ...

    变量与赋值 PPT学习教案.pptx

    4. 变量可以接受多次赋值,其最终值取决于最后一次赋值。 5. 赋值语句中的“=”不同于数学中的等号,如`i=i+1`表示增加`i`的值,而在数学中这表示两者相等。 6. 多个“=”连用,如`a=b=2`是错误的,应分别进行赋值。...

    java常量变量表达式

    // 声明一个整型变量x并赋值为5 x = 10; // 改变x的值 ``` 3. 数据类型: Java有两类数据类型:基本数据类型(如int、char、float、double等)和引用数据类型(如类、接口和数组)。基本数据类型具有固定大小和值...

    编译型复数表达式计算器

    由于在最近的一个项目中需要用到复数表达式的计算,计算的特点是:对于同一个公式需要进行重复多次的计算,每次计算时只需要变换公式中的某些变量的值。于是花了点时间写了个编译型的复数表达式计算器,该计算器的...

    C语言变量及赋值共2页.pdf.zip

    C语言是一种广泛应用于系统编程、应用编程、嵌入式开发等领域的高级编程...在项目中,不仅要关注变量和赋值,还要注意控制流程(如条件语句、循环)、函数、文件操作、错误处理等多个方面,以实现完整且健壮的程序。

    2019_2020学年高中数学第二章算法初步2.2变量与赋值练习含解析北师大版必修3

    输入语句可以一次为多个变量赋值,而赋值语句每次只能赋值给一个变量。 编写程序的步骤通常包括:理解问题,构思算法,绘制程序流程图,最后将流程图转换成程序代码。 在提供的练习题中,涉及了正确使用赋值语句和...

    C语言中的运算符和表达式

    5. **赋值运算符**:用于赋值操作,不仅包括简单的赋值(=),还包括复合赋值如加赋值(+=)、减赋值(-=)、乘赋值(*=)、除赋值(/=)、取模赋值(%=)、位与赋值(&=)、位或赋值(|=)、位异或赋值(^=)、左移...

    2019_2020学年高中数学第2章算法初步2_2_2变量与赋值课件北师大版必修3202004290693

    赋值操作遵循特定规则:赋值符号左边只能是变量,右边可以是数据、常量或表达式,但一次只能给一个变量赋值,且不能出现多个“=”号。 理解变量与赋值的运用,有助于培养学生的数学应用意识。在实际编程中,赋值...

    2019_2020学年高中数学课时作业13变量与赋值北师大版必修3202004290638

    - 问题3指出,一次赋值操作只能给一个变量赋值,选项A是正确的。 2. **变量交换**: - 问题4涉及如何正确地交换两个变量的值。在选项A和B中,简单的赋值会导致两个变量最终都等于最后一个值。选项C中,变量c的值...

    C语言中自增自减表达式的未定义行为.pdf

    例如,当一个表达式中对同一个变量多次自增或自减时,编译器可能在不同的序列点对变量进行操作,这就产生了未定义行为。 未定义行为也是计算机编程中的一个微妙话题,它涉及许多看似合理却具有不确定性行为的计算机...

    2020学年高中数学 第2章 2.2变量与赋值课时作业(含解析)北师大版必修3.doc

    在选择题的例子里,变量a的值可以被多次赋值,如`a=3`后又有`a=5`,最后输出a的值为5。 3. **赋值语句的格式**: - 赋值语句的左边必须是变量名,右边可以是常量、变量或者表达式,但不能是表达式的运算结果。...

    C语言中++和--运算的一些问题

    - 应尽量避免在一个表达式中多次使用这些运算符。 2. **兼容性问题**: - 不同的编译器可能对自加/自减运算符的处理方式略有不同。 - 在编写代码时,应考虑跨平台的兼容性问题。 通过上述讨论可以看出,自加(`++...

    C语言 实验四 计数型循环结构及其测试.doc

    我们对程序进行了多次测试,分别测试了不同的循环次数: * 外循环1次,i=20,j=4 * 外循环1次,i=20,j=3 * 外循环1次,i=19,j=3 * 外循环2次,i=19,j=2 * 外循环19次,i=19,j=1 * 外循环20次,i=1,j=2 * 外...

    赋值语句实用PPT学习教案.pptx

    6. **变量的多次赋值**:一个变量可以被多次赋值,每次赋值都会覆盖之前的价值,如`a=5`,`a=7`,最后a的值是7。变量间的辗转赋值,如`N=N+1`,表示将N的当前值加1再赋给N。 7. **赋值与等式的区别**:赋值语句中的...

    基于分治思想的表达式运算系统C#源码+项目说明+sln解决方案.zip

    可以处理一个表达式,当表达式中的变量已经创建时,使用已经创建的变量的值,如果还没创建,就随机化生成一个值带进去运算。如 x+y-sin(x)中x=1,y随机初始化 可以改变已经创建的变量的值。 如 x=4

    输入输出赋值语句PPT学习教案.pptx

    7. 对于一个变量可以多次赋值,每次赋值将“原值”冲掉,留下“新值”。 二、输入语句 输入语句是一种基本的编程语句,用于从用户那里获取输入信息。其一般格式为:INPUT “提示内容”;变量。 输入语句的功能: ...

    U67I6ERQR43Q5

    此外,当在一个表达式中多次使用同一变量的自增操作符时,如`i++++i`,这种写法在C/C++中是未定义行为(undefined behavior),因此应避免使用。 ### 结论 通过对这部分内容的分析,我们学习了C/C++中`for`循环与`...

    SQL中SET和SELECT赋值的区别

    SET 是一种基本的赋值方式,它可以将一个值赋给一个变量,但是它一次只能对一个变量进行赋值。如果需要对多个变量赋值,需要使用多个 SET 语句。SELECT 则不同,它可以在一条语句中对多个变量同时赋值。 例如,假定...

Global site tag (gtag.js) - Google Analytics