Увеличение до и после в C#

Я немного озадачен тем, как компилятор C# обрабатывает до и после увеличения и уменьшения.

Когда я кодирую следующее:

int x = 4;
x = x++ + ++x;

x будет иметь значение 10 впоследствии. Я думаю, это потому, что наборы предварительного увеличения x в 5что делает это 5+5 который оценивает 10, Тогда постинкремент обновится x в 6, но это значение не будет использоваться, потому что тогда 10 будет назначен на x,

Но когда я кодирую:

int x = 4;
x = x-- - --x;

затем x будет 2 после этого. Кто-нибудь может объяснить, почему это так?

6 ответов

Решение

x-- будет 4, но будет 3 на момент --x, так что это будет 2, то у вас будет

x = 4 - 2

Кстати, ваш первый случай будет x = 4 + 6

Вот небольшой пример, который распечатает значения для каждой части, возможно, так вы поймете это лучше:

static void Main(string[] args)
{
    int x = 4;
    Console.WriteLine("x++: {0}", x++); //after this statement x = 5
    Console.WriteLine("++x: {0}", ++x); 

    int y = 4;
    Console.WriteLine("y--: {0}", y--); //after this statement y = 3
    Console.WriteLine("--y: {0}", --y);

    Console.ReadKey();
}

это распечатывает

x++: 4
++x: 6
y--: 4
--y: 2

Давайте посмотрим на IL, который генерируется из этого оператора

IL_0002:  ldloc.0     

Загружает значение x в стек. Стек => (4)

IL_0003:  dup         

Дублирует самый верхний элемент в стеке. Стек => (4, 4)

IL_0004:  ldc.i4.1    

Нажмите 1 на стек. Стек => (1, 4, 4)

IL_0005:  sub         

Вычтите два верхних значения и поместите результат в стек. Стек => (3, 4)

IL_0006:  stloc.0     

Сохраните самое верхнее значение стека обратно в x. Стек => (4)

IL_0007:  ldloc.0     

Загрузите значение x обратно в стек. Стек => (3, 4)

IL_0008:  ldc.i4.1    

Загрузите значение 1 в стек. Стек => (1, 3, 4)

IL_0009:  sub         

Вычтите два. Стек => (2, 4)

IL_000A:  dup         

Дублировать верхнее значение => (2, 2, 4)

IL_000B:  stloc.0     

Сохраните верхнее значение обратно в x. Стек => (2, 4)

IL_000C:  sub      

Вычтите два верхних значения. Стек => (2)

IL_000D:  stloc.0  

Сохраните это значение обратно в x. х == 2

Из вашего комментария:

Я думал, что пост- и преинкременты выполняются после / до оценки всей кодовой строки - но они выполняются после / до оценки каждого элемента в выражении.

Ваше недоразумение является чрезвычайно распространенным. Обратите внимание, что в некоторых языках, таких как C, оно не указывается, когда побочный эффект становится видимым, и поэтому допустимо, но не обязательно, чтобы ваше утверждение было истинным в C.

Это не так в C#; в C# побочные эффекты кода на левой стороне выражения всегда наблюдаются до выполнения кода на правой стороне (из одного потока; в многопоточных сценариях все ставки отключены).

Для более подробного объяснения того, что делают операторы инкремента в C#, смотрите:

В чем разница между i++ и ++i?

Там очень много дополнительных ссылок на статьи, которые я написал по этой часто неправильно понимаемой теме.

Самое интересное, что вы получите совершенно другой ответ с компилятором C++.NET.

int x = 4;
x = x++ + ++x; // x = 11
x = 4;
x = x-- - --x; // x = -1

Конечно, разница в результатах определяется различной семантикой - это кажется нормальным. Но, несмотря на понимание того факта, что два компилятора.net не ведут себя одинаково для таких базовых вещей, меня тоже смущает.

В этом примере

int x = 4;
x = x++ + ++x;

Вы можете сломать это как:

x = 4++; which is = 5
x = 4 + ++5; which is 4 + 6
x = 10

Так же,

int x = 4;
x = x-- - --x;

Вот,

x = 4--; which is = 3
x = 4 - --3; which is 4 - 2
x = 2

Проще говоря, вы можете сказать, заменить текущее значение x, но для каждого ++ или - добавить / вычесть значение из x.

Я думаю, что объяснение для случая ++ + ++ неверно:

команда........... значение х

.................. не определен

int x = 4.......... 4

х ++...............5 (первое слагаемое 4)

++ x............... 6 (второе слагаемое 6)

x = summand1 + summand2..4 + 6 = 10

Аналогичное объяснение для случая - - -

команда........... значение х

.................. не определен

int x = 4.......... 4

х --...............3 (подвектор 4)

--x............... 2 (вычитаемое 2)

х = вычитающее-вычитаемое..4-2=10

Другие вопросы по тегам