a = b + (b = a) * 0; = 两边的运算从右向左的,先计算 b + (b = a) * 0 到了具体的 b + (b = a) * 0 又从左向右计算 所以是 2 + (2 = 1) * 0 计算后就是 2 + 0 赋给了 左边的 a ,此时 b 成为了1 结果就是 2--1
不同语言,运算符优先级不同??PHP对于上面的这种写法,运算结果就不同。 我现在纠结的是 b + (b = a) * 0 这一段,是先把左边的b解析了之后再算(b = a) * 0呢?还是先算 (b = a) * 0 之后再算b+(b = a) * 0 从左到右,先乘除后加减,遇到括号的先算,,,唉,好纠结,
php不懂。 不同语言的语法规则可能是不同的,就像java的数组和c的数组,差异就非常大。
public class java { public static void main(String[] args) { int a = 10, b = 20; a = b + (b = a) * 0; System.out.println(a + "--" + b);//2--1 } } Compiled from "java.java" public class java { public java(); Code: 0: aload_0 1: invokespecial #1 // Method java/lang/Object."<init>":()V 4: return LineNumberTable: line 1: 0 public static void main(java.lang.String[]); Code: 0: bipush 10 // 将byte类型的数转换为int类型的数,然后压入栈 2: istore_1 // 是将堆栈中的值弹出存入相应的变量区 --- 此处表示 a = 10 3: bipush 20 5: istore_2 // 此处表示 a = 20 6: iload_2 // iload_2是将变量区中的值暂存如堆栈中 此处是 b的值 7: iload_1 // 此处是 a 的值 8: dup // 复制栈顶的值 此时的栈 顶 10 -> 10 -> 20 9: istore_2 // 存储到变量2 也就是b 此处表示 b = a 此时的栈 顶 10 -> 20 10: iconst_0 // 0 入栈顶 此时的栈 顶 0 -> 10 -> 20 11: imul // 将栈顶两int型数值相乘并将结果压入栈顶(两int出栈) 此时的栈 顶 0 -> 20 12: iadd // 将栈顶两int型数值相加并将结果压入栈顶(两int出栈) 此时的栈 顶 20 13: istore_1 // 保存到变量1 此处代表 a = 20 14: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream; 类入栈 17: new #3 // class java/lang/StringBuilder 新建 StringBuilder 20: dup //复制 为什么需要复制栈顶呢? 或许所有 new 的时候都会这样吧 21: invokespecial #4 // Method java/lang/StringBuilder."<init>":()V 初始化 (我猜他会有出栈的) 24: iload_1 // 这一句及以下的一句 表示 println 中的 a 25: invokevirtual #5 // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder; 28: ldc #6 // String -- // 这一句及以下的一句 表示 println 中的 “--” 30: invokevirtual #7 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 33: iload_2 // 这一句及以下的一句 表示 println 中的 b 34: invokevirtual #5 // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder; 37: invokevirtual #8 // Method java/lang/StringBuilder.toString:()Ljava/lang/String; 调用toString 40: invokevirtual #9 // Method java/io/PrintStream.println:(Ljava/lang/String;)V 输出 43: return LineNumberTable: line 4: 0 line 5: 6 line 6: 14 line 7: 43 }
我不知道 把代码 int a = 10, b = 20; 改成 int b = 20 , a = 10 ; 的时候会是什么样子如果有人有兴趣的话 可以改一下试一试
明白了吗 ?一开始存储的是 变量 b 的值(20) 之后你再改变 b 也无济于事了当然,你可以想办法直接改变Java的堆栈 (但是那样还不如直接用汇编语言)
= 两边的运算从右向左的,先计算 b + (b = a) * 0
到了具体的 b + (b = a) * 0 又从左向右计算
所以是 2 + (2 = 1) * 0
计算后就是 2 + 0 赋给了 左边的 a ,此时 b 成为了1
结果就是 2--1
不同语言,运算符优先级不同??PHP对于上面的这种写法,运算结果就不同。
我现在纠结的是 b + (b = a) * 0 这一段,是先把左边的b解析了之后再算(b = a) * 0呢?还是先算 (b = a) * 0 之后再算b+(b = a) * 0
从左到右,先乘除后加减,遇到括号的先算,,,唉,好纠结,
不同语言的语法规则可能是不同的,就像java的数组和c的数组,差异就非常大。
public static void main(String[] args) {
int a = 10, b = 20;
a = b + (b = a) * 0;
System.out.println(a + "--" + b);//2--1
}
}
Compiled from "java.java"
public class java {
public java();
Code:
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: return
LineNumberTable:
line 1: 0 public static void main(java.lang.String[]);
Code:
0: bipush 10 // 将byte类型的数转换为int类型的数,然后压入栈
2: istore_1 // 是将堆栈中的值弹出存入相应的变量区 --- 此处表示 a = 10
3: bipush 20
5: istore_2 // 此处表示 a = 20
6: iload_2 // iload_2是将变量区中的值暂存如堆栈中 此处是 b的值
7: iload_1 // 此处是 a 的值
8: dup // 复制栈顶的值 此时的栈 顶 10 -> 10 -> 20
9: istore_2 // 存储到变量2 也就是b 此处表示 b = a 此时的栈 顶 10 -> 20
10: iconst_0 // 0 入栈顶 此时的栈 顶 0 -> 10 -> 20
11: imul // 将栈顶两int型数值相乘并将结果压入栈顶(两int出栈) 此时的栈 顶 0 -> 20
12: iadd // 将栈顶两int型数值相加并将结果压入栈顶(两int出栈) 此时的栈 顶 20
13: istore_1 // 保存到变量1 此处代表 a = 20
14: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream; 类入栈
17: new #3 // class java/lang/StringBuilder 新建 StringBuilder
20: dup //复制 为什么需要复制栈顶呢? 或许所有 new 的时候都会这样吧
21: invokespecial #4 // Method java/lang/StringBuilder."<init>":()V 初始化 (我猜他会有出栈的)
24: iload_1 // 这一句及以下的一句 表示 println 中的 a
25: invokevirtual #5 // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
28: ldc #6 // String -- // 这一句及以下的一句 表示 println 中的 “--”
30: invokevirtual #7 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
33: iload_2 // 这一句及以下的一句 表示 println 中的 b
34: invokevirtual #5 // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
37: invokevirtual #8 // Method java/lang/StringBuilder.toString:()Ljava/lang/String; 调用toString
40: invokevirtual #9 // Method java/io/PrintStream.println:(Ljava/lang/String;)V 输出
43: return
LineNumberTable:
line 4: 0
line 5: 6
line 6: 14
line 7: 43
}
移动到 11 和 12 之间,变成 : 11: imul // 将栈顶两int型数值相乘并将结果压入栈顶(两int出栈) 此时的栈 顶 0 -> 20
11.5: iload_2 // iload_2是将变量区中的值暂存如堆栈中 此处是 b的值
12: iadd // 将栈顶两int型数值相加并将结果压入栈顶(两int出栈) 此时的栈 顶 20如果你想让Java本来就是那样 也还是有办法 : 修改编译器(Java.exe)
楼主的问题,很类似当年这个,参考里面我的回复:
http://bbs.csdn.net/topics/390400914?page=1