Когда ++ не дает такие же результаты, как +1? - PullRequest
27 голосов
/ 22 сентября 2008

Следующие два фрагмента кода C # дают разные результаты (при условии, что переменный уровень используется как до, так и после рекурсивного вызова). Почему?

public DoStuff(int level)
{
  // ...
  DoStuff(level++);
  // ...
}

public DoStuff(int level)
{
  // ...
  DoStuff(level+1);
  // ...
}

Прочитав некоторые ответы ниже, я подумал, что было бы целесообразно опубликовать трассировки стека для уровней ++, ++ level и level + 1, чтобы подчеркнуть, насколько обманчива эта проблема.

Я упростил их для этого поста. Рекурсивная последовательность вызовов начинается с DoStuff (1).

// уровень ++

DoStuff(int level = 1)
DoStuff(int level = 2)
DoStuff(int level = 2)
DoStuff(int level = 2)

// ++ level

DoStuff(int level = 4)
DoStuff(int level = 4)
DoStuff(int level = 3)
DoStuff(int level = 2)

// уровень + 1

DoStuff(int level = 4)
DoStuff(int level = 3)
DoStuff(int level = 2)
DoStuff(int level = 1)

Ответы [ 15 ]

0 голосов
/ 22 сентября 2008

Хотя заманчиво переписать как:

DoStuff(++level);

Лично я считаю, что это менее читабельно, чем приращение переменной до вызова метода. Как отмечено в нескольких ответах выше, следующее будет более понятным:

level++;
DoStuff(level);
0 голосов
/ 22 сентября 2008

Насколько мне известно, выражение параметра вычисляется первым и получает значение уровня. Сама переменная увеличивается до вызова функции, потому что компилятору все равно, используете ли вы выражение в качестве параметра или иным образом ... Все, что он знает, это то, что он должен увеличить значение и получить старое значение как результат выражение.

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

0 голосов
/ 22 сентября 2008

В первом примере используется значение индекса, увеличивается значение и обновляется индекс.

Во втором примере используется значение «index» плюс 1, но не изменяется содержимое «index».

Так что, в зависимости от того, что вы хотите здесь сделать, в магазине могут быть сюрпризы!

0 голосов
/ 22 сентября 2008

level + 1 отправляет любой уровень + 1 в функцию. level ++ отправляет уровень функции и затем увеличивает его.

Вы можете пройти уровень ++, и это, вероятно, даст вам желаемый результат.

0 голосов
/ 22 сентября 2008

Первый фрагмент кода использует оператор приращения после операции, поэтому вызов выполняется как DoStuff (level) ;. Если вы хотите использовать здесь оператор приращения, используйте DoStuff (уровень ++);.

...