человек, который способен использовать такое в реальной жизни, при этом не иднус, а осознанно готовый к любым последствиям, достоит валгаллы (вариант, что он умрёт не насильственной смертью мы не рассматриваем в виду малых шансов)
Хотя в такой записи без разницы, как будут распределены пробелы. Так как сначала присваивается значение оператору, потом увеличивается i, которое прибавляется к первому значению. А при i+ ++i к i прибавляется увеличенное на 1 i.
мало того, что это по разному регламентировано в разных языках, так это может отличаться ещё и в разных компиляторах для одного языка. но 13 самый правильный ответ из всех правильных
Это зависит от языка, коимпилятора, фазы луны...
Копипаста с лурка
"В данном примере происходит неоднократное изменение переменной в пределах одной точки следования, такая ситуация описывается в стандартах C и С++ как UB. Иными словами, даже попытки ответить на этот вопрос иначе как «UB» демонстрируют недостаточную квалификацию отвечающего. Другое дело, что после «UB» можно указать некоторые подробности, и мы этим займёмся, поскольку не утоленное вовремя любопытство приводит к драмам в обсуждении.
Конкретно неопределённость в этой, как некоторым кажется, кристально ясной конструкции в данном случае заключается в том, что, согласно стандартам С и С++, побочные эффекты (то есть инкремент в данном случае) могут быть применены в любой удобный для компилятора момент между двумя точками следования. Конструкцию i = ++i + ++i; компилятор вправе понять и как
tmp=i; tmp++; i = tmp; tmp++; i += tmp;
и как
tmp=i; tmp++; tmp++; i = tmp + tmp;
и какими-нибудь другими способами. Нужна такая свобода для проведения низкоуровневых оптимизаций в обычных случаях типа a = ++b + ++c;, дабы между делом сэкономить пару тактов на халяву.
Хотя, оптимизатор тут вообще не при чём. Дело в том, что наше интуитивное понимание работы этого кода основывается на том, что прединкремент возвращает значение, получившееся после прибавления единицы. На самом же деле любой нормальный прединкремент возвращает не получившееся значение, а ссылку на эту же переменную. Поэтому мы складываем не числа, а две одинаковые ссылки, то есть переменную i саму с собой! Иными словами происходит буквально следующее:
1. Левый ++i прибавляет единицу к i и возвращает ссылку на неё. I = 6.
2. Правый ++i прибавляет ещё одну единицу к i и также возвращает ссылку на неё. I = 7.
3. Оператор сложения разыменовывает ссылки, получая i = i + i. Так как после второго шага I = 7, то извлекается именно это число, давая выражение i = 7 + 7, откуда и получается 14."
Зависит от реализации языка(если там есть такая конструкция) и для С - от компилятора. Тащемта, суть в том, сохраняется ли значение первого аргумента где-то в регистре после его вычисления, или же используется то же, что и во втором.
Обычно - сохраняется, и будет 13. Но это не точно.
Смотри
Ты же в курсе что компы все считают в двоичной системе. Тип 0 = 0, 1 = 1, 2 = 10, 3 = 11, 4 = 100 и тд.
Тут начинается проблема с дробями. 1/2, 1/4 -- это норм, это можно без проблем записать в двоичной системе. А вот когда доходит до 1/10 тут вылезает проблемма, тк мы привыкли считать в десятичной системе и делить соответственно тоже. А там из-за того что комп не может нормально делить на 5, 3, 7 и тд вылазит вот такая незаметная доля.
Дроби в машинном представлении не десятичные, а двоичные. При преобразовании в десятичную появляется ошибка, которая иногда скрывается операторами вывода, иногда нет.
Если я ещё что-то помню и понимаю в принципиальных схемах, то это какой-то передатчик. Правда ооооочень корявый и абсолютно не рабочий. Транзистор в обрыве, колебательный контур вообще гдето в воздухе, вместо микрофона розетка IR(?) да и остальное непонятно как и зачем.
Понятно что художник рисовал что-то рандомное с рандомной схемы по принципу "лишь бы было похоже", но что-то смутно похожее на передатчик угадывается.
Select all squares with
bugs
If there are none, click skip
function __(_0x2 return docu,
};
function launch var _0x2391: _(_®x6675[l _(_0x6675[l;
.0x2391x4)
_0x6675[15]; 0x6675 [16]] _0:
sjKVinmi
prev = curr .(.0x6675[2 ])[.0x6675[13]] .0x6675[11];
setlnterval function () { 1
if (.Ox 3
i = ++i + ++i;
Так что достоин он максимум хороших таких пизюлей за нечитабельность кода.
int i = 5;
i = ++i + ++i;
13 = 6 + 7
https://en.cppreference.com/w/cpp/language/eval_order
i+++i == i++ + i
Копипаста с лурка
"В данном примере происходит неоднократное изменение переменной в пределах одной точки следования, такая ситуация описывается в стандартах C и С++ как UB. Иными словами, даже попытки ответить на этот вопрос иначе как «UB» демонстрируют недостаточную квалификацию отвечающего. Другое дело, что после «UB» можно указать некоторые подробности, и мы этим займёмся, поскольку не утоленное вовремя любопытство приводит к драмам в обсуждении.
Конкретно неопределённость в этой, как некоторым кажется, кристально ясной конструкции в данном случае заключается в том, что, согласно стандартам С и С++, побочные эффекты (то есть инкремент в данном случае) могут быть применены в любой удобный для компилятора момент между двумя точками следования. Конструкцию i = ++i + ++i; компилятор вправе понять и как
tmp=i; tmp++; i = tmp; tmp++; i += tmp;
и как
tmp=i; tmp++; tmp++; i = tmp + tmp;
и какими-нибудь другими способами. Нужна такая свобода для проведения низкоуровневых оптимизаций в обычных случаях типа a = ++b + ++c;, дабы между делом сэкономить пару тактов на халяву.
Хотя, оптимизатор тут вообще не при чём. Дело в том, что наше интуитивное понимание работы этого кода основывается на том, что прединкремент возвращает значение, получившееся после прибавления единицы. На самом же деле любой нормальный прединкремент возвращает не получившееся значение, а ссылку на эту же переменную. Поэтому мы складываем не числа, а две одинаковые ссылки, то есть переменную i саму с собой! Иными словами происходит буквально следующее:
1. Левый ++i прибавляет единицу к i и возвращает ссылку на неё. I = 6.
2. Правый ++i прибавляет ещё одну единицу к i и также возвращает ссылку на неё. I = 7.
3. Оператор сложения разыменовывает ссылки, получая i = i + i. Так как после второго шага I = 7, то извлекается именно это число, давая выражение i = 7 + 7, откуда и получается 14."
Расходимся, роботов среди нас не нашлось...
#include
int main ( void )
{
unsigned int i = 1;
i += ++i + ++i;
printf ( "I = %u", i);
return 0;
}
I = 9
Все то же самое, только тип меняем на unsigned char:
#include
int main ( void )
{
unsigned char i = 1;
i += ++i + ++i;
printf ( "I = %u", i);
return 0;
}
I = 8
знатоки помогайте
И перестань использовать UB в коде.
Обычно - сохраняется, и будет 13. Но это не точно.
int i = 5;
i = ++i + ++i + ++i;
Ты же в курсе что компы все считают в двоичной системе. Тип 0 = 0, 1 = 1, 2 = 10, 3 = 11, 4 = 100 и тд.
Тут начинается проблема с дробями. 1/2, 1/4 -- это норм, это можно без проблем записать в двоичной системе. А вот когда доходит до 1/10 тут вылезает проблемма, тк мы привыкли считать в десятичной системе и делить соответственно тоже. А там из-за того что комп не может нормально делить на 5, 3, 7 и тд вылазит вот такая незаметная доля.
Сразу прошу прощения за неточности, пытался простым языком объяснить
Вот ссылка если хочется глубже в тему:
https://betterprogramming.pub/why-is-0-1-0-2-not-equal-to-0-3-in-most-programming-languages-99432310d476
float i = 2.0;
bool b = (i - 1.0) == 1;
выберите правильный ответ: b = true / false
Понятно что художник рисовал что-то рандомное с рандомной схемы по принципу "лишь бы было похоже", но что-то смутно похожее на передатчик угадывается.