java中的 "+="运算符 与C的区别

问题概述

C语言中的 += 符号

大家在c语言的学习过程中,一定接触过 += 这个常见的运算符.。+= 属于复合赋值运算符的一种. 和 “+=” 同一类的符号还有 -= *= 等。他们的的运算规则也十分简单,如下面的例子:

#include<stdio.h>
int main(){
	int m=3;
	printf("%d",m+=2);     //输出5
	printf("m=%d",m);      //输出m=5
	return 0;
} 

对于 m+=2 ,我们可以把它转换成式子 m=m+2 来看。对于这整个表达式,m的值整个表达式 的值均被更新为 m+2 的值
不过在遇到多个 += 时,情况变得稍微复杂。本例仅给出多个 += 的情况。例子如下:

#include<stdio.h>
int main(){
	int m=3;
	printf("%d",m+=m+=2);  //输出10
	printf("m=%d",m);      //输出m=10
	return 0;
} 

为什么会输出10?我们可以先将这个式子还原为易于人理解的情况。

表达式m的值
m+=m+=23
m+=(m=m+2)3
m+=55
m=m+55
m10

可以看到,m的值在表达式计算的过程中在变动。每遇到一次+=, m的值都会变化

java中的+=符号

java 中也存在+=之类符号,用法和c也很相似。日常使用中我们可能不会知道他们的区别。

public class test {
	public static void main(String []args) {
		int m=3;
		System.out.println(m+=2);    //输出5
		System.out.println("m="+m);  //输出m=5
	}
}

但是当我们按照c的规律递推时,则无法得出和c类似的结果。

public class test {
	public static void main(String []args) {
		int m=3;
		System.out.println(m+=m+=2);   //输出8
		System.out.println("m="+m);    //输出m=8
	}
}

为什么呢?

初步分析

我们从java与c程序的结果可初步知道,m的值最终会与整个表达式的值相等。这也符合赋值运算符的计算规律。

做其他例子做出假设

我们可以先试着拆散这个式子,把这个式子拆成两段:

public class test {
	public static void main(String []args) {
		int m=3;
		System.out.println(m+=m+=2);    //输出8
		System.out.println("m="+m);     //输出m=8
		//----------------将式子拆开--------------
		int n=3;
		n+=2;                           //第一步
		System.out.println(n);          //输出m=5
		n+=n;                           //第二步
		System.out.println(n);          //输出m=10
	}
}

结果是不是很熟悉? m在第一阶段为5,在第二阶段为10不正是C代码中计算的结果吗
我们可以做几个假设:

  • java中+=这类的符号计算方向与c不同
  • java中+=这类符号在连续使用时,变量变化规律与c不同
    • java在计算表达式时,各项数值已经确定,并不会自动更新 (仅对于+=这类运算符)

检验假设

  1. java中+=这类的符号计算方向与c不同:
    第一个假设很好验证,我们就拿原来的式子做验证。第一个假设很好验证,我们就拿原来的式子做验证。
表达式m的值
m+=m+=23
(m+=m)+=23
m+=26
m9
结果和m=8明显不符。同时,当你在eclipse中输入 **(m+=m)+=2** 时,会发现编译器报错。

编译器报错提示

从编译器错误知道,式子m+=m 在计算以后返回的结果为数值,而数值并不能进行+=运算。这个假设明显不成立。
  1. java中+=这类符号在连续使用时,变量变化规律与c不同
    1. c语言代码中,m最明显的变化就是每遇到一次+=, m的值都会变化。会不会是这个问题?

会不会是在计算表达式时,各项数值已经确定,并不会自动更新的问题?

表达式m的值
m+=m+=23
m+=53
m8

和结果m=8对应上了,那用这理论能否推算出其他式子结果呢?


	public class test {
		public static void main(String []args) {
			int m=3;
			System.out.println(m+=m+=m+=2);    //结果为11
			System.out.println("m="+m);        //结果为11
		}
	}

这套理论应该是正确的

探求真理

虽然已经大致知道这段代码的运行方法,但是总是会有点担心会有问题。
这时我们可以用javap反编译工具找出代码运行的过程。

//test.java文件
class test{
    public static void main(String []args){
        int m=3;
        m+=m+=2;
    }
}

在cmd窗口中对test.java进行反编译在这里插入图片描述
我们主要看的是main函数中,Code的内容
指令大全:https://blog.csdn.net/hudashi/article/details/7062675

指令作用
iconst_3将int型(3)推送至栈顶
istore_1将栈顶int型数值存入第二个本地变量
iload_1将第二个int型本地变量推送至栈顶
iinc [变量] [参数]对变量进行自增操作,自增量为参数
istore_1将栈顶int型数值存入第二个本地变量
iadd将栈顶两int型数值相加并将结果压入栈顶

详细解读

0:  iconst_3
1:  istore_1
2:  iload_1
3:  iinc          1, 2
6:  iload_1
7:  iadd
8:  istore_1

详细情况:

栈(底>顶 )变量对应操作
03将int型(3)推送至栈顶
1(1): 3将栈顶int型数值存入第二个本地变量(m)
23(1):3将第二个int型本地变量推送至栈顶
33(1):5对本地变量(m)进行自增2操作
63 , 5(1):5将第二个int型本地变量(m)推送至栈顶
78(1):5将栈顶int型数值存入第二个本地变量(m)
8(1):8将栈顶int型数值存入第二个本地变量(m)

由此我们可以知道,在计算+=符号前,java已经将式子拆散并确定了+=中的 自身变量 值。
在+=为5个的时候,我们能很清晰的看到确定值的过程
在这里插入图片描述

表达式m的值对应操作行
m+=m+=m+=m+=m+=230、1
m=( m=(m=(m=(m+=2 )+2 )+2 )+2 )+232、3、4、5
m=( m=(m=(m=(m+=2 )+2 )+2 )+2 )+256
m=( m=(m=(m=5+2 )+2 )+2 )+259
m=( m=(m=(m=7 )+2 )+2 )+2510
m=( m=(m= (m=7)7+2 )+2 )+2511
m=( m=(m=7+2 )+2 )+2712
m=( m=(m=9 )+2 )+2713
m=( m= (m=9) 9+2 )+2714
m=( m=9+2 )+2915
m=( m=11 )+2916
m=( m=11 )11+2917
m=11+21118
m=131119
m1320

结论

java在计算+=的过程,可以近似看为展开。但计算表达式时,各项数值已经确定,并不会自动更新。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值