近日在看书时偶尔遇到了一个自增,自减运算符的问题,在C#中和C中同一个表达式得到的结果却不一样,自己实在想不明白,特来请教,谢谢各位!
问题是这样的:
设int a=10;
计算a+=a-=a的值。
在Turbo C中得到的结果是0;而在C#中(Visual Studio 2005环境)得到结果确实10!为什么啊?我觉得应该是0啊,因为-=,+=这两个运算符都是右结合性,所以先计算a=a-a=10-10=0,a=a+a=0!另:我比较穷,所以分数较少,见谅!
问题是这样的:
设int a=10;
计算a+=a-=a的值。
在Turbo C中得到的结果是0;而在C#中(Visual Studio 2005环境)得到结果确实10!为什么啊?我觉得应该是0啊,因为-=,+=这两个运算符都是右结合性,所以先计算a=a-a=10-10=0,a=a+a=0!另:我比较穷,所以分数较少,见谅!
解决方案 »
- 用C#做的登录程序的问题
- OleDbConnection中的连接字符串中的Data Sources可以用相对路径吗?
- 应用程序中如何使用缓存
- c#库函数
- 请问又没有办法看到HttpWebRequest这个对象真实发送出去的内容呢?
- 如何调用新实例化后窗体中的控件
- 求助,RichTextBox编辑的时候按回车的时候,在后台代码里怎么得到这个信息,然后用<br>代替。
- 用同一个MediaPlayer控件同时播放视频和声音,视频要求静音。在线等!
- DataSet怎样导出Excel文件?
- 请问在C#里邮件程序怎么写,谁可以详细说一下发送邮件和收邮件的步骤,或者给一个完整的例子,小弟先谢了
- C# JS 都行 怎么得到一组数据当中某个字符最集中的部分提出来?
- 大家帮帮忙,体现CSDN温暖!虽然没有分!
.NET下,当运行完a-=a时候,前面的a+=a的第一个a依然是10
可以理解成这样
a+=a-=a
int a1,a2,a3
a1=a2=a3=10;
a1+a2-a3;
有意思。
我看这个是编译的问题:
C 的编译是从右向左进行编译的 a-=a(0) , a+=a(0)
C#则相反 a+=a(20) , a-=a(10)
刚才用ILDasm看了下就明白了:.method private hidebysig static void Main() cil managed
{
.entrypoint
.maxstack 3
.locals init (
[0] int32 a)
L_0000: nop
L_0001: ldc.i4.s 10
L_0003: stloc.0 //a=10;
L_0004: ldloc.0 //第一个a入运算栈
L_0005: ldloc.0 //第一个a入运算栈
L_0006: ldloc.0 //第一个a入运算栈
L_0007: sub //10-10
L_0008: dup //将结果复制
L_0009: stloc.0 //将结果保存回a,至此a-=a运算结束.注意栈上现在用于运算的就是原先a的值10和a-=a的值0了
L_000a: add //10+0
L_000b: stloc.0 //将结果10保存回变量a
//以下是在控制台输出a的值~
L_000c: ldloc.0
L_000d: call void [mscorlib]System.Console::Write(int32)
L_0012: nop
L_0013: ret
}
对应的C#源码:
using System;class test
{
static void Main ()
{
int a = 10;
a+=a-=a;
Console.Write (a);
}
}
.method private hidebysig static void Main() cil managed
{
.entrypoint
.maxstack 3
.locals init (
[0] int32 a)
L_0000: nop
L_0001: ldc.i4.s 10
L_0003: stloc.0 //a=10;
L_0004: ldloc.0 //第一个a入运算栈
L_0005: ldloc.0 //第二个a入运算栈
L_0006: ldloc.0 //第三个a入运算栈
L_0007: sub //10-10
L_0008: dup //将结果复制
L_0009: stloc.0 //将结果保存回a,至此a-=a运算结束.注意栈上现在用于运算的就是原先a的值10和a-=a的值0了
L_000a: add //10+0
L_000b: stloc.0 //将结果10保存回变量a
//以下是在控制台输出a的值~
L_000c: ldloc.0
L_000d: call void [mscorlib]System.Console::Write(int32)
L_0012: nop
L_0013: ret
}
是先将三个a的值入栈了~
这是C#的一个老问题了,C#其实是想规范一些行为,所以特别做出了这样的规定。对于 A operator B operator C这样的式子。
从左至右依次计算A、B、C的值,然后根据operator的结合顺序计算最终结果。
这一点,你可以在C#语言规范中找到。