2010-12-12 3 views
8

Я этот кодСообщение прибавка вопрос

static void Main(string[] args) 
{ 
    int x = 20; 
    int y = 35; 
    x = y++ + x++; 
    y = ++y + ++x; 
    Console.WriteLine(x); 
    Console.WriteLine(y); 
    Console.ReadLine(); 
} 

Я ожидал, что выход будет й = 57 и Y = 94. Однако, при выполнении он дал мне 56 и 93. По некоторым причинам после приращения оператор не выполняется в строке 3.

Это потому, что мы назначаем результат выражения в строке 3 на сам х? Существуют ли какие-либо другие сценарии, в которых оператор post increment не будет работать так, как ожидалось.

Спасибо.

+3

Просто подсказка: сценарии, подобные этому, намного легче понять, если вы поместите каждый тестовый пример в отдельную функцию. Проверка того, что происходит во втором задании, излишне затруднена из-за первого назначения. –

ответ

13
int x = 20; 
int y = 35; 
// x = y++ + x++; this is equivalent of 
tmp = 35 + 20; y++; x++; x = tmp; 
// so here we have x = 55; y = 36 
// y = ++y + ++x; 
y ++; // 37 
x ++; // 56; 
y = x + y; 
// so here we have y = 93, x = 56; 
+0

Спасибо. Это очищает мои сомнения. – stackoverflow

3

Порядок выполнения определяется приоритетом и ассоциативностью оператора.

Назначение прав-ассоциативно, так

x = y + x++; 

можно переписать

t = y + x++; 
x = t; 

Я не мог найти очень четкое заявление для того, что происходит ++ перед =.
Но текст в § 14.2 документа Ecma означает, что побочный эффект происходит как часть оценки i++. В F(i) + G(i++) * H(i), H(i) вызывается с новым значением i.

+0

Обратите внимание, однако, что порядок _evaluation_ не должен обеспечивать выполнение определенного порядка _execution_. – SoftMemes

+0

@Freed верен. Порядок выполнения * операторов * определяется приоритетом и ассоциативностью. Порядок * оценки подвыражений * всегда слева направо. –

+2

Я также отмечаю, что ваше утверждение о присвоениях неверно, если «x» - это выражение с побочным эффектом. Например: M(). X = y + N(). X ++ не совпадает с t = y + N(). X ++; M(). X = t; потому что это меняет порядок, в котором называются М и N. –

9

Правила в C# чрезвычайно просты. Это:

  • Подвыражения выражения оцениваются ВЛЕВО В ПРАВО, период, конец рассказа.
  • побочный эффект оператора приращения происходит, когда оператор оценивается.

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

x = y++ + x++; 

Оцените адрес x и сохраните его.

t1 = &x; 

Оцените адрес y.

t2 = &y; 

Оценить значение, хранящееся в только что вычисленном адресе. Это 35.

t3 = *t2; // 35 

Вычисленное значение является значением выражения; это значение до приращение.

Добавьте одно значение.

t4 = t3 + 1; // 36 

Магазин 36 в адресе. y теперь 36.

*t2 = t4; // y = 36 

Теперь сделайте то же самое для й ++:

t5 = &x; 
t6 = *t5;  // 20 
t7 = t6 + 1; // 21 
*t5 = t7;  // x = 21 

ОК, теперь мы должны сделать дополнение:

t8 = t3 + t6; // 35 + 20 = 55 

и назначить, что по адресу, рассчитанном на первое:

*t1 = t8; // x = 55; 

В конце этого утверждения x имеет имеет три значения. 20, 21 и 55. У имеет два значения, 35 и 36. х теперь 55 и у теперь 36.

y = ++y + ++x; 

Теперь мы снова делаем то же самое, но на этот раз мы используем значение после того, как приращения. Следуйте по:

t1 = &y; 
t2 = &y; 
t3 = *t2; // 36 
t4 = t3 + 1; // 37 
*t2 = t4; // y = 37; 
t5 = &x; 
t6 = *t5; // 55 
t7 = t6 + 1; // 56; 
*t5 = t7; // x = 56; 
t8 = t4 + t7; // 93 
*t1 = t8; // y = 93; 

Так что к концу этого утверждения у имело три значения: 36, 37 и 93. х имеет два значения: 55 и 56 лет теперь 93 и х теперь 56.

Я ожидал, что выход будет х = 57, у = 94.

Почему вы ожидаете, что? Ваше ожидание противоречило спецификации C#; Мне было бы интересно узнать, почему вы ожидали неправильного результата. Как вы ожидали, что код для этого будет сгенерирован? Ожидали ли вы приращения после задание? Почему они это сделали? Приращение происходит, когда значение оператора инкремента оценивается и, очевидно, должно произойти до дополнение, которое, очевидно, должно произойти до назначения. Таким образом, приращение не может произойти после задание.

По какой-то причине оператор пост прирост не получает выполненный в соответствии 3.

Как на земле, вы прибудете к такому выводу? Уверяю вас, это, безусловно, выполняется. Шаг за шагом в отладчике, если вы мне не верите.

+0

1+, от устья лошади ... – SoftMemes

+0

спасибо за подробный ответ .. наше понимание пост-приращения было неправильным. x = y ++ + x ++; для нас означало x = y + x; y = y + 1; x = x + 1; Таким образом мы достигли 20 + 35; 35 + 1; 55 + 1; и поскольку последнее выражение было на х, мы предположили его 56. – stackoverflow

Смежные вопросы