Я знаю, что приведенный ниже код приведет к неопределенному поведению в соответствии с стандартом 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??
Может кто-нибудь объяснить, смущен.??
Ваша программа эквивалентна:
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 может и имеет определенное поведение при реализации в нескольких местах. Не здесь.
a++ == 1 (теперь, a = 2), затем ++a == 3
1 + 3 = 4
Кажется, я прав.
Разница между 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
встречается в уравнении, ее текущее значение попадает в стек и затем используется при последующей оценке уравнения.
условие начала a = 1, res = 0
res = a++
=> res = 1, a = 2
+ ++a
=> a = 3 ПЕРЕД добавлением, res = 4, результат правильный
Я согласен с Volte и davidc. Просто попробуйте использовать две переменные вместо одной (a). Например:
int a = 1;
int b = 1;
Console.WriteLine("{0}", a++ + ++b); //this write 3 on console
Console.ReadLine();
Это доказывает, что наш принцип правдивый.
res= a++ + ++a
должно быть 3?