问:
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(写这篇博客主要是为了加深自己的理解)
分享到:
相关推荐
因此,如果我们在一个表达式中直接使用`i++`,那么这个表达式的值就是`i`的原始值。例如,如果`i`的初始值为0,那么`i++`表达式的值也为0,尽管之后`i`的值变为1。 #### 循环中的`i = i++`操作 当我们把这个表达式...
当程序中多次对同一个变量进行赋值时,变量的最终值将是最后一次赋值的值。例如,如果有一个程序段: ``` x = 1 x = x + 2 x = 4 ``` 在执行完这些语句后,变量`x`的最终值将会是4。 赋值语句有一些使用规则: 1. ...
赋值语句是将一个值(如运算表达式的结果)赋给变量的指令。在大多数编程语言中,赋值操作符是 `=`。例如,`x = 5` 将整数 5 赋给变量 x。当我们有整数运算表达式时,可以将其结果赋给变量,如 `y = x + 3`,这会将 ...
4. 变量可以接受多次赋值,其最终值取决于最后一次赋值。 5. 赋值语句中的“=”不同于数学中的等号,如`i=i+1`表示增加`i`的值,而在数学中这表示两者相等。 6. 多个“=”连用,如`a=b=2`是错误的,应分别进行赋值。...
// 声明一个整型变量x并赋值为5 x = 10; // 改变x的值 ``` 3. 数据类型: Java有两类数据类型:基本数据类型(如int、char、float、double等)和引用数据类型(如类、接口和数组)。基本数据类型具有固定大小和值...
由于在最近的一个项目中需要用到复数表达式的计算,计算的特点是:对于同一个公式需要进行重复多次的计算,每次计算时只需要变换公式中的某些变量的值。于是花了点时间写了个编译型的复数表达式计算器,该计算器的...
C语言是一种广泛应用于系统编程、应用编程、嵌入式开发等领域的高级编程...在项目中,不仅要关注变量和赋值,还要注意控制流程(如条件语句、循环)、函数、文件操作、错误处理等多个方面,以实现完整且健壮的程序。
输入语句可以一次为多个变量赋值,而赋值语句每次只能赋值给一个变量。 编写程序的步骤通常包括:理解问题,构思算法,绘制程序流程图,最后将流程图转换成程序代码。 在提供的练习题中,涉及了正确使用赋值语句和...
5. **赋值运算符**:用于赋值操作,不仅包括简单的赋值(=),还包括复合赋值如加赋值(+=)、减赋值(-=)、乘赋值(*=)、除赋值(/=)、取模赋值(%=)、位与赋值(&=)、位或赋值(|=)、位异或赋值(^=)、左移...
赋值操作遵循特定规则:赋值符号左边只能是变量,右边可以是数据、常量或表达式,但一次只能给一个变量赋值,且不能出现多个“=”号。 理解变量与赋值的运用,有助于培养学生的数学应用意识。在实际编程中,赋值...
- 问题3指出,一次赋值操作只能给一个变量赋值,选项A是正确的。 2. **变量交换**: - 问题4涉及如何正确地交换两个变量的值。在选项A和B中,简单的赋值会导致两个变量最终都等于最后一个值。选项C中,变量c的值...
例如,当一个表达式中对同一个变量多次自增或自减时,编译器可能在不同的序列点对变量进行操作,这就产生了未定义行为。 未定义行为也是计算机编程中的一个微妙话题,它涉及许多看似合理却具有不确定性行为的计算机...
在选择题的例子里,变量a的值可以被多次赋值,如`a=3`后又有`a=5`,最后输出a的值为5。 3. **赋值语句的格式**: - 赋值语句的左边必须是变量名,右边可以是常量、变量或者表达式,但不能是表达式的运算结果。...
- 应尽量避免在一个表达式中多次使用这些运算符。 2. **兼容性问题**: - 不同的编译器可能对自加/自减运算符的处理方式略有不同。 - 在编写代码时,应考虑跨平台的兼容性问题。 通过上述讨论可以看出,自加(`++...
我们对程序进行了多次测试,分别测试了不同的循环次数: * 外循环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 * 外...
6. **变量的多次赋值**:一个变量可以被多次赋值,每次赋值都会覆盖之前的价值,如`a=5`,`a=7`,最后a的值是7。变量间的辗转赋值,如`N=N+1`,表示将N的当前值加1再赋给N。 7. **赋值与等式的区别**:赋值语句中的...
可以处理一个表达式,当表达式中的变量已经创建时,使用已经创建的变量的值,如果还没创建,就随机化生成一个值带进去运算。如 x+y-sin(x)中x=1,y随机初始化 可以改变已经创建的变量的值。 如 x=4
7. 对于一个变量可以多次赋值,每次赋值将“原值”冲掉,留下“新值”。 二、输入语句 输入语句是一种基本的编程语句,用于从用户那里获取输入信息。其一般格式为:INPUT “提示内容”;变量。 输入语句的功能: ...
此外,当在一个表达式中多次使用同一变量的自增操作符时,如`i++++i`,这种写法在C/C++中是未定义行为(undefined behavior),因此应避免使用。 ### 结论 通过对这部分内容的分析,我们学习了C/C++中`for`循环与`...
SET 是一种基本的赋值方式,它可以将一个值赋给一个变量,但是它一次只能对一个变量进行赋值。如果需要对多个变量赋值,需要使用多个 SET 语句。SELECT 则不同,它可以在一条语句中对多个变量同时赋值。 例如,假定...