Это идеально определено в C # .NET a ++ + ++ a ?, Если да, то почему я получаю странный вывод? [Дубликат]

1

Я знаю, что приведенный ниже код приведет к неопределенному поведению в соответствии с стандартом c/c++, но как насчет С#? , После некоторого поиска я обнаружил, что в С# все аргументы/переменные в выражении оцениваются слева направо (пожалуйста, исправьте меня, если я ошибаюсь), Если это верно, чем результат (вывод переменной res) ниже программы, должен быть 3, но его 4??.

class Program
{
    static void Main(string[] args)
    {
        int a = 1;
        int res = (a++) + (++a); //Will This Lead to Undefined Behavior(Like in C/C++)..??
        Console.WriteLine(res);
        Console.ReadLine();
    }
}

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

res = a + ++a; \\Successfully evaluates res to 3

res = ++a + a; \\Sussessfully evaluates res to 4

res = ++a + a++; \\Successfully evaluates res to 4

по аналогии

res= a++ + ++a ; \\should be 3, why я get it 4??

Может кто-нибудь объяснить, смущен.??

  • 4
    Почему вы думаете, что res= a++ + ++a должно быть 3?
  • 0
    Вам также может быть интересен stackoverflow.com/q/1860615/11683 .
Показать ещё 2 комментария
Теги:
undefined-behavior
pre-increment
post-increment

5 ответов

5
Лучший ответ

Ваша программа эквивалентна:

var a = 1;
var temp0 = a++;
var temp1 = ++a;
var res = temp0 + temp1;

И результатом этого является 4.

Еще проще:

var a = 1;
var temp0 = a; a++;
a++; var temp1 = a;
var res = temp0 + temp1;

С# не имеет Undefined Behavior, как C/C++. Это подорвет свойства безопасности.NET. Тем не менее,.NET может и имеет определенное поведение при реализации в нескольких местах. Не здесь.

  • 0
    Хорошо. Теперь это имеет смысл, но не следует ли увеличивать значение a ++ после вычисления полного выражения. ???, я рассчитывал так: - i) temp0 = a (вычисление a ++, просто подставляем 1, но не увеличиваем его ) ii) temp1 = ++ a (сначала увеличивая 1, а затем подставляя его) iii) res = temp0 + temp1 iv) a = a + 1 (вычисляя a ++, поскольку выражение достигло точки с запятой, теперь увеличивается до 1)
  • 0
    Операция приращения - это выражение, которое оценивается локально, как любое другое выражение. Это побочные эффекты не «поставлены в очередь» до конца утверждения.
Показать ещё 5 комментариев
3

a++ == 1 (теперь, a = 2), затем ++a == 3

1 + 3 = 4

Кажется, я прав.

2

Разница между var b = a++ и var b = ++a - это время изменения переменной a.

  • b = a++ сначала присваивает значение a переменной b а затем увеличивает a.
  • b = ++a сначала увеличивает значение a, а затем присваивает его переменной b.

Время назначения делает разницу. Итак, вот ваш код, аннотированный:

int a = 1;     // a = 1
int res = 
    a++        // the value of a (1 is inserted into the equation) and a is increased by 1 - so a == 2
    + ++a      // a is increased by one (a == 3) and its value is inserted into the equation
    ;          // (res = (1 + 3)) == 4

Чтобы сделать его более понятным, код можно переписать следующим образом. И на самом деле это то, как стек С# оценивает ваш код:

int a = 1;
int res = 0;
res += a;      // add a to res                                                - a == 1, res = 1
a += 1;        // increase a (could also be written as a++ or ++a);           - a == 2, res = 1
a += 1;        // increase a again (could also be written as a++ or ++a);     - a == 3, res = 1
res += a;      // add a to res                                                - a == 3, res = 4

В уравнении a значение, а не ссылка. Поэтому каждый раз, когда переменная a встречается в уравнении, ее текущее значение попадает в стек и затем используется при последующей оценке уравнения.

1

условие начала a = 1, res = 0

res = a++ => res = 1, a = 2

+ ++a => a = 3 ПЕРЕД добавлением, res = 4, результат правильный

0

Я согласен с Volte и davidc. Просто попробуйте использовать две переменные вместо одной (a). Например:

int a = 1;
int b = 1;
Console.WriteLine("{0}", a++ + ++b); //this write 3 on console
Console.ReadLine();

Это доказывает, что наш принцип правдивый.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню