C# 当++;计数器发生时,内存中发生了什么?

C# 当++;计数器发生时,内存中发生了什么?,c#,c#-4.0,C#,C# 4.0,假设我有: int counter; ++counter; 问题是:内存(堆栈)中发生了什么? 如果有一个新变量在堆栈中创建并复制前一个变量的值,然后添加+1或其使用的临时变量,在那里添加+1,然后将新值放入计数器?计数器的值从内存加载到CPU寄存器中,递增,然后写回相同的内存地址。在此过程中不会分配额外的内存,如果计数器位于堆栈中或其他任何位置,也不会产生任何影响。++计数器将递增计数器并返回新的递增值。 计数器++将递增计数器并返回递增前的值。这取决于它,但通常不会对内存产生任何影响。抖动

假设我有:

int counter;
++counter;
问题是:内存(堆栈)中发生了什么?
如果有一个新变量在堆栈中创建并复制前一个变量的值,然后添加+1或其使用的临时变量,在那里添加+1,然后将新值放入计数器?

计数器的值从内存加载到CPU寄存器中,递增,然后写回相同的内存地址。在此过程中不会分配额外的内存,如果
计数器
位于堆栈中或其他任何位置,也不会产生任何影响。

++计数器将递增计数器并返回新的递增值。 计数器++将递增计数器并返回递增前的值。

这取决于它,但通常不会对内存产生任何影响。抖动所做的最重要的工作之一是尽可能避免使用内存。特别是像你这样的局部变量。它将变量的值存储在CPU寄存器中。而++运算符只生成一条INC机器代码指令,以增加寄存器中的值。非常快,需要0或1个cpu周期。0是公共的,因为它可以与另一条指令并行执行


有关抖动执行的优化列表,请参阅。

这是Jon回答的补充

在变量之前和之后使用++运算符有一个区别。考虑下面的例子:

        int[] arr = { 1, 2, 3 };
        int counter = 0;

        Console.WriteLine(arr[counter++]);
        Console.WriteLine(arr[++counter]);

counter++
将打印1,而
++counter
将打印3。

.Net首先编译为中间语言(IL)

follogin.netc#代码

编译为IL代码,在反汇编程序中查看:

ldc.i4.0    //ldc = load constant on evaluation stack
stloc.0 //Store on top of the evaluation stack
ldloc.0 //Load a local variable
ldc.i4.1 //ldc = load constant on evaluation stack
add //add
stloc.0 //Store on local evaluation stack

ldc.i4.0 //Load contant 0 on the evaluation stack
stloc.1 //Store this on variable location 1
ldloc.1 //Load variable location 1
ldc.i4.1 //Load constant 1 on evaluation stack
add //Add 
stloc.1 //Store on evaluation stack
你可以看到,在这种情况下,这并不重要。这两者的编译方式相同。 首先在堆栈上加载值,存储在变量中。然后在堆栈上加载值1,然后将其添加并保存到变量中


我不确定这将如何最终编译成CPU指令。

不确定您在问什么,但如果是
++
是否是原子的,答案是不是。两者都返回递增的值。这取决于语言-但由于这是C#,我的说法是正确的。一个以i=1和++开始的循环,我将从2开始。这是一个非常全面的答案!
ldc.i4.0    //ldc = load constant on evaluation stack
stloc.0 //Store on top of the evaluation stack
ldloc.0 //Load a local variable
ldc.i4.1 //ldc = load constant on evaluation stack
add //add
stloc.0 //Store on local evaluation stack

ldc.i4.0 //Load contant 0 on the evaluation stack
stloc.1 //Store this on variable location 1
ldloc.1 //Load variable location 1
ldc.i4.1 //Load constant 1 on evaluation stack
add //Add 
stloc.1 //Store on evaluation stack