Имя: Пароль:
LIFE
 
OFF: У кого сколько получится: int i = 5; i = ++i + ++i;
🠗 (Asmody 04.08.2019 21:23)
,
0 ambrozii-fadeevich-s
 
02.08.19
13:48
1. 14 44% (7)
2. 13 31% (5)
3. Другое 19% (3)
4. 16 6% (1)
5. 12 0% (0)
6. 15 0% (0)
Всего мнений: 16

Смотрю - пошла мода на нестандартные вычисления. У кого сколько получится: int i = 5; i = ++i + ++i;
47 y88
 
02.08.19
14:48
(46) похоже так. Олипиадная задачка
48 Йохохо
 
02.08.19
15:00
(46) только вот "++(++5)=7 >> 7+7 = 14" это лишнее чтение, т.к. результат первой операции уже известен. и вообще боян и (45)
49 bolobol
 
02.08.19
15:01
(48) По запросу "UB" - яндекс выдаёт: ГИБДД - официальный сайт. Вы на что намекаете??
50 trad
 
02.08.19
15:04
(44)
inc(i)inc(i)+inc(i)+
6
7
14
8
22
51 ДенисЧ
 
02.08.19
15:06
52 Dionis Sergeevich
 
02.08.19
15:06
Intellij idea выдает 13
53 1Сергей
 
02.08.19
15:07
(49) Undefined Behaviour
54 Йохохо
 
02.08.19
15:12
предиктед
55 Конструктор1С
 
02.08.19
15:20
double a = 1000000.0;
double b = 0.01;

for (int i=1; i<=100; i++)
     a = a + b;

System.out.println("a = " + a);

сколько думаете будет?
56 bolobol
 
02.08.19
15:30
(55) Слышал, что будет 42, долго считать тут
57 Dionis Sergeevich
 
02.08.19
15:33
(55) ну логично же что 1000001.0
58 trad
 
02.08.19
15:38
59 mikecool
 
02.08.19
15:44
вот из-за такого мозголомства и надо расписывать операции по строкам
60 Конструктор1С
 
02.08.19
15:47
(57) не-а

a = 1000001.0000000009

это распространенная багофича с числами с плавающей запятой
61 Dionis Sergeevich
 
02.08.19
15:49
(60) а эта багофича с точки зрения логики как то объяснена?
62 bolobol
 
02.08.19
15:54
(61) Свободный ради-кал?
63 Конструктор1С
 
02.08.19
15:55
(61) х.з. Ну типа особенности работы с такими числами
64 Провинциальный 1сник
 
02.08.19
15:57
(19) Подавляющее большинство багов и уязвимостей в софте - именно тяжкое наследие языка Си. Писали бы на паскале - всё было бы стабильнее на порядок.
65 Fish
 
02.08.19
15:58
(64) А если бы на 1С, то стабильнее на 10 порядков :)
66 Конструктор1С
 
02.08.19
16:03
double a1 = 1000000.0;
double a2 = 100000.0;
double b = 0.01;

for (int i=1; i<=100; i++) {
    a1 = a1 + b;
    a2 = a2 + b;
}

System.out.println("a1 = " + a1);
System.out.println("a2 = " + a2);
_________________________________________

a1 = 1000001.0000000009
a2 = 100000.99999999948

вот такие пироги
67 bolobol
 
02.08.19
16:11
(64) И тормознее на порядок порядков. Это не наследие Си - это сопроцессор математический
68 Провинциальный 1сник
 
02.08.19
16:15
(67) Не преувеличивайте. Софт, написанный на паскале (тот же QIP к примеру) не тормознее сишного. Си - это переносимый ассемблер, для написания ядер и драйверов. То, что его начали использовать не по назначению, огромная ошибка отрасли, которая аукается до сих пор..
69 Глок 17
 
02.08.19
16:15
(0) В уме считал по человеческой логике, получилось 13.
Проверил на компе, тоже получилось 13

13
70 bolobol
 
02.08.19
16:18
(68) Я писал программы и на том и на том - разница достигала х100 в производительности
71 Провинциальный 1сник
 
02.08.19
16:19
(70) А на ассемблере еще быстрее будет, если правильно написать.. это не аргумент. Всё зависит от конкретного компилятора и от примененного алгоритма.
72 bolobol
 
02.08.19
16:23
(71) А, ну если "не аргумент" и "от алгоритма"... тогда - "Ваша точка зрения ясна..." и бла-бла-бла- все дела
73 Глок 17
 
02.08.19
16:25
(71) Писал на ассемблере преобразователь частоты в 2/3 раза. Для считывания показаний датчика оборотов с мотора для передачи в тахометр при замене двигателя с 4х цилиндров на 6 цилиндров. Программа заняла 10 байтов, один цикл рассчетов выполнялся за 3 такта. Попробуй на паскале написать, сколько тактов займет
74 Кирпич
 
02.08.19
16:27
(70) между разными компиляторами Си тоже может быть разница х100
75 Глок 17
 
02.08.19
16:31
У кого получается не 13, вы как считали? Что за бредятина
76 bolobol
 
02.08.19
16:33
(75) "Всё не читал, но осуждаю"?
77 Глок 17
 
02.08.19
16:34
(76) По шагам расписываю:

i = ++i + ++i;

1. Считаем первое слагаемое: ++i = ++5 = 6. 6 записывается в i

2. Считаем второе слагаемое: ++i = ++6 = 7

3. Складываем оба слагаемых: 6 + 7 = 13

Куда проще?
78 Глок 17
 
02.08.19
16:40
(26) >>  Дело в том что инкремент записывается в одну и ту же ячейку памяти

Это ошибка. Результат двух выражений не должен записываться в одну и ту же ячейку памяти. Если бы компилятор так работал, то это был бы дичайший баг.
79 bolobol
 
02.08.19
16:42
(77) То есть, всё-таки, "чукча не читатель"... в (46) и в (50) двумя вариантами описано явление 14-ти в ответ.
80 Dionis Sergeevich
 
02.08.19
16:44
(77) я думаю что тут дело в IDE - некоторые, вычисоив первое а++ запомнили значение, а не указатель, другие наоборот
81 Глок 17
 
02.08.19
16:45
(79) Так это ты чукча не читатель. Я же разжевал все подробно в (77). А в (46) вообще какой-то бред написан.
82 Dionis Sergeevich
 
02.08.19
16:46
В итоге в случае с заполненным значением 6 + 7, а с заполненной ссылкой а + а
83 Глок 17
 
02.08.19
16:46
(80) Не важно что ты запомнишь, указатель или значение. Сам подумай. Выполнилось выражение, его значение записалось в новую ячейку памяти. Выполнили то же самое выражение. С какого перепугу мы будем записывать новый результат в уже занятую ячейку, а не в новую?
84 Dionis Sergeevich
 
02.08.19
16:47
*запомненной
85 Глок 17
 
02.08.19
16:47
(82) Ссылки должно получиться две разных
86 Глок 17
 
02.08.19
16:48
++ это оператор, которые не только увеличивает значение переменной, но и ВОЗВРАЩАЕТ результат инкремента. Мы складываем не значения переменной i, а результаты, которые вернули два разных оператора инкремента.
87 Dionis Sergeevich
 
02.08.19
16:48
(83) дело в том что инкремент присваивает результат переменной, поэтому в указателе значение 7, а + а даст 14. А в случае работы со значениями - результат первого инкремента будет запомнен до второго инкремента
88 Глок 17
 
02.08.19
16:49
(87) Я заранее ответил на это чуть выше
89 Глок 17
 
02.08.19
16:50
(87) в указателе на i згачение 7. а в указателе на предыдущий результат выполнения значение 6
90 Глок 17
 
02.08.19
16:52
У (++i) и у (i) должны быть разные указатели. Иначе будет неправильный результат в виде 14.
91 Глок 17
 
02.08.19
16:53
Но по правилам хорошего программирования писать как в (0) конечно же запрещено на любом яп.
92 Nyoko
 
02.08.19
16:56
6+8=14

14
93 Конструктор1С
 
02.08.19
17:34
(92) а почему 8?
94 Глок 17
 
02.08.19
18:02
10 + 6 = 16

16
95 v77
 
02.08.19
18:31
(86) "++ это оператор, которые не только увеличивает значение переменной, но и ВОЗВРАЩАЕТ результат инкремента."
Это с сегодняшнего дня? Надо запомнить.
96 Глок 17
 
02.08.19
18:36
(95) Лучше запомни если не можешь понять
97 Глок 17
 
02.08.19
18:40
The increment and decrement operators will add one (+1) or subtract one (-1), respectively, to their operand, and then return a value.
98 v77
 
02.08.19
18:41
(96) Ну я как бы понимаю, что 14 получится. Вот ты не можешь понять и выдумываешь какие то новые правила и отрицаешь реальность.

14
99 Глок 17
 
02.08.19
18:43
(98) Но ты не правильно понимаешь, поэтому не хочешь принять правила, и выдумываешь свои
100 v77
 
02.08.19
18:44
(97) но создатели компиляторов Си делают по своему. от бунтари :)
101 Глок 17
 
02.08.19
18:46
(100) не все, а только криворукие.

Выражение (0) нужно упростить для однозначности, чтобы даже v77 было понятно:

i = 5;
++i;
a2 = i;
++i;
a2 = i;
i = a1 + a2;
102 Глок 17
 
02.08.19
18:47
Опечатка, в первом присвоении a1 вместо а2
103 Глок 17
 
02.08.19
18:48
Если выражение вызывает непонятки, его всегда нужно раскладывать. Тогда ошибок будет меньше
104 v77
 
02.08.19
18:49
(101) Криворукие это компиляторы GCC, Microsoft и Clang, я так понимаю. А какие тогда правильные компиляторы?
105 Глок 17
 
02.08.19
18:49
(104) Там где результат 13
106 NorthWind
 
02.08.19
18:58
(105) неверно ты разложил. Подвох в том, что сначала по правилам приоритета выполняются все i++, и только потом происходит сложение. В результате складывается не 7 и 6, а 7 и 7. А если сделать ++i + ++i + ++i, то будет уже 8 + 8 + 8 = 24... ну и так далее.
107 Глок 17
 
02.08.19
19:02
(106) Ну и откуда у тебя в первом слагаемом 7, если сначала мы получаем 6? Во втором получаем 7. Затем по логике мы должны сложить результаты предыдущих вычислений, а не то что сейчас хранится в переменной i. Ты просто пытаещься подогнать логику под сишный компилятор, из-за чего она страдает.
108 Глок 17
 
02.08.19
19:10
Вот аналог того что в (0):

(i = 6) + (i = 7)

Какой результат будет у этого бредового выражения?
109 Глок 17
 
02.08.19
19:12
Из первых скобок выползет результат 6, из вторых выползет 7, затем они сложатся, получится 13. В i будет записано 7, но нам пофиг что там, потому что мы складываем не i + i, а результаты операций в скобках.
110 NorthWind
 
02.08.19
19:35
(107) Нет. См. (35). Там пипец какая интересная табличка. Приоритетной операцией, причем с очень высоким приоритетом, являются прединкремент. Приоритет ВЫШЕ умножения и деления! Сначала, вперед всех остальных, в данном случае выполнятся они. Сколько их будет - столько и выполнятся. И только потом пойдет сложение уже над выполненными прединкрементами. Поэтому 7 + 7.
111 v77
 
02.08.19
19:47
Надо определиться сначала о каком языке речь. В Java и C# будет 13. В Си будет 14
112 ДенисЧ
 
03.08.19
20:39
113 stopa85
 
03.08.19
20:59
С++ даст 14, а вот ява или си шарп 13.

14
114 Конструктор1С
 
04.08.19
11:41
(113) таки, а почему вы предлагаете ровняться на плюсы?
115 Фрэнки
 
04.08.19
11:43
(114) скажу для поддержки разговора, что 1С платформа написана на С++ :-)
116 NorthWind
 
04.08.19
18:30
(114) а таки, собственно, почему бы и нет?
117 Глобальный_
Поиск
 
04.08.19
20:01
Чё за дебильный код? Почему+++++++19 а нельзя написать +20, это кстати сэкономит байты.
118 Глобальный_
Поиск
 
04.08.19
20:02
Инкреметы они оптимизируют.ну и пишите на ассемблере тогда
119 Глобальный_
Поиск
 
04.08.19
20:07
Когда количество библиотек в миллионы раз превышает количество кода , играться плюсами и пузырьками это удел преподов на первом курсе.
120 Глобальный_
Поиск
 
04.08.19
20:09
Выдохнул :)
121 stopa85
 
04.08.19
21:17
(114) не было бы плюсов, не было бы этой загадки. Она, кстати, очень важна для понимания языка.
122 DrZombi
 
гуру
05.08.19
06:54
10 :)

Другое
123 DrZombi
 
гуру
05.08.19
06:54
(117) Видимо автору языка, было так интересней извращаться :)
124 DrZombi
 
гуру
05.08.19
06:55
+(122) Тут так то не описано, что за язык, что за математика...  :)
125 Провинциальный 1сник
 
05.08.19
11:25
(110) При чем тут приоритет.. Даже со всеми приоритетами, когда мы выполняем сложение, мы по логике должны взять уже рассчитанный РАНЕЕ первый операнд (++i), а не пытаться его рассчитать ЕЩЕ РАЗ после второго(++i). И будет 13. Если компилятор С++ выдает 14 - это очередное подтверждение тезиса что Си - плохой язык.

13
126 bolobol
 
05.08.19
12:42
(125) Глупости, никаких "ещё раз" в примере нет. Есть две операции увеличения i _до_сложения.
127 Провинциальный 1сник
 
05.08.19
13:33
(126) ++i - это инкремент переменной и одновременно возврат этого увеличенного значения в вызывающее выражение. То есть, если в выражении ++i встречается дважды, то и вычислено оно будет дважды.. сначала от исходного значения, потом от уже вычисленного. И только потом сложены эти промежуточные результаты. И получается 13. Вообще не понимаю, как может быть 14.
128 Smile 8D
 
05.08.19
13:37
(106) Вы так уверенно рассуждаете, но выше в (46) уже написали, что ++i + ++i + ++i дает 22, а не 24, что можно проверить в компиляторе с++, на который так же давали выше ссылку. К сожалению, при 3х слагаемых правила уже работают по другому.
129 Smile 8D
 
05.08.19
13:44
(127) Не забывайте, что ++i прибавляет и возвращает значение в выражение, а i++ сначала возвращает, а затем уже прибавляет. И ваш негатив в сторону языков, в которых это используется, вызван скорее непониманием зачем эти механизмы были придуманы. Естественно, что пример из загадки искусственный, а инкременты реально используются обычно при вызовах из разных процедур\потоков, где требуется использовать текущее значение и параллельно его изменить.
130 Провинциальный 1сник
 
05.08.19
13:47
(129) Согласен, прибавляет и возвращает. Первый операнд 6 после инкремента, второй 7 после инкремента. Потом выполяем сложение. Получаем 6+7=13. Почему 14 то???
131 Smile 8D
 
05.08.19
13:51
(130) Ну про это уже выше написали, что приоритет у операции выше, чем у сложения, даже ссылку кидали. Вы же не возмущаетесь, что умножение выполняют раньше чем сложение.
А вот почему при 3х слагаемых логика меняется мне непонятно и не нравится)
132 Провинциальный 1сник
 
05.08.19
13:56
(131) Так я не спорю о приоритетах! И рассуждаю именно в смысле того, что СНАЧАЛА делаем инкременты и возвращаем значения инкрементов, и только потом складываем. Но откуда 14?
133 bolobol
 
05.08.19
14:03
(132) Ещё один "нечитатель". Ранее всё по полочкам разложено было неоднократно. И ладно когда тролль только зарегистрированный делает вид что не видит...
134 Провинциальный 1сник
 
05.08.19
14:09
(133) Блин, ну ткните пальцем, ГДЕ разжовано? Читаю, вижу логичные предпосылки, потом бац - парадоксальный вывод.
135 Провинциальный 1сник
 
05.08.19
14:10
+(134) Откуда берется семерка в первом операнде???
136 bolobol
 
05.08.19
14:16
(135) в (46) и в (50) - двумя языками изложено
137 Провинциальный 1сник
 
05.08.19
14:17
А, понял. Если строить дерево вычисления выражения по приоритетам, то будет именно 13. Но если считать сишным способом "инкремент записывается в одну и ту же ячейку памяти, и в результате к тому моменту когда надо сложить два слагаемых, складывается в реальности уже 7 и 7, а не 7 и 6", тогда понятно. Но блин, символ в одном месте выражения и в другом - это НЕ ОДНА ячейка памяти, а узел в дереве расчета. А тут получается "дерево-мутант". Си - плохой язык.
138 bolobol
 
05.08.19
14:24
(137) Позволю себе не согласиться. Использование одной и той же переменной (й+й) не должно вызывать два чтения и два помещения в разные регистры для дальнейшего сложения. Именно из-за этого, программы на Си и работают в х100 раз быстрее альтернативно одарённых языков.
139 Провинциальный 1сник
 
05.08.19
14:45
На лурке тема разжована, оказывается это древний баянище)
http://lurkmore.to/%2B%2Bi_%2B_%2B%2Bi
140 Глок 17
 
05.08.19
17:35
(110) Ты не понял. Понятно что инкремент имеет высокий приоритет. Но почему ты продолжаешь складывать 7 + 7, если результаты инкоементов нам дали два слагаемых: 6 и 7?
141 Глок 17
 
05.08.19
17:43
(138) >> Именно из-за этого, программы на Си и работают в х100 раз быстрее альтернативно одарённых языков.

Ага. Только выдают не тот результат, который нужен. Главное быстро :)))
142 Глок 17
 
05.08.19
17:45
Чтобы выражение (0) правильно работало на Си, нужно его преобразовать:

int i = 5;
int tmp = ++i;
i = tmp + ++i;
143 stopa85
 
07.08.19
19:16
(127) нет не правильно. В С++ операция ++i возвращает ссылку на объект (указатель на область памяти, где записано значение), а не копию объекта. Ты путаешь с java и c#.

Вот и получается, что по этому указателю в ОЗУ компьютера находится значение и увеличивается на 1. Потом оно находится еще раз и увеличивается на один еще раз. Потом складывается само с собой. Это нужно понимать. Это, что ли, философия языка.
144 ambrozii-fadeevich-s
 
09.08.19
11:11
(139) Это намного древнее баянище.


(142)
145 ambrozii-fadeevich-s
 
09.08.19
11:14
(142) Если правильно преобразовать, то получится не то, что ожидает среднестатистический интерпретатор
int i = 5;
++i;
++i;
i = i + i;
146 ambrozii-fadeevich-s
 
09.08.19
11:15
пятница же!
Компьютер — устройство, разработанное для ускорения и автоматизации человеческих ошибок.