![]() |
1. Пользуйтесь тегами кода. - [code] ... [/code]
2. Точно указывайте язык, название и версию компилятора (интерпретатора).
3. Название темы должно быть информативным.
В описании темы указываем язык!!!
![]() |
sheka |
![]()
Сообщение
#1
|
![]() Я. ![]() ![]() ![]() ![]() Группа: Пользователи Сообщений: 809 Пол: Мужской Реальное имя: Саша Репутация: ![]() ![]() ![]() |
pow() некорректно работает если используется инкремент или декремент в его параметрах.
Задание: Совершая обход так: 1 3 4 10 2 5 9 11 6 8 12 15 7 13 14 16 заполнить матрицу а такими значениями: b11b12...bnn Kod (Показать/Скрыть)
В таком исполнении pow(b[k++ / N], k % N + 1); работает так как надо (еще недавно и так не работал, но теперь почему-то работает): результат (Показать/Скрыть)
а в таком pow(b[k / N], ++k % N + 1); - нет: результат (Показать/Скрыть)
Сообщение отредактировано: sheka - 8.10.2011 0:02 |
![]() ![]() |
IUnknown |
![]()
Сообщение
#2
|
![]() a.k.a. volvo877 ![]() ![]() ![]() ![]() ![]() Группа: Пользователи Сообщений: 1 013 Пол: Мужской Репутация: ![]() ![]() ![]() |
Цитата Компилятор GNU GCC (CodeBlocks 10.05) ничего не выдает. Неправда. Зайди в Project -> Build Options, в Compiler Flags включи "Enable all compiler warnings" (которая -Wall), и пересобери проект. Можешь узнать очень много интересного ![]() Теперь по while (i < M && 0 <= j) a[i++][j--] = pow(b[k / N], (++k) % N + 1);, что будет выполнено раньше, вычисление первого параметра со старым значением k, а потом инкремент и вычисление второго параметра с новым значением, или наоборот, сначала значение k инкрементируется, и вычислится второй параметр для pow(), а потом с той, уже увеличенной k, будет вычисляться первый параметр - не может никто. Это компиляторозависимо, и, кроме всего прочего, зависит от оптимизатора, ибо в конечном счете он выбирает, в каком порядке вычислять параметры, чтоб было как можно оптимальней. А это уже неопределенное поведение со всеми вытекающими последствиями: нестабильная работа программы (ты ж сам говорил, что раньше не работало, теперь вдруг заработало, помнишь? Явный признак, что что-то не так), и предупреждение, выдаваемое компилятором. Кстати, с первым вариантом: while (i < M && 0 <= j) a[i++][j--] = pow(b[k++ / N], k % N + 1);- абсолютно та же история, побочный эффект присутствует и там, а что если сначала вычислится второй параметр, а только потом - первый? Упс... Опять перестанет работать... Для гарантированного порядка вычисления - используй временные переменные, тогда UB не будет. Кстати, разницу между префиксным и постфиксным ++ (да и -- тоже) знаешь? Сообщение отредактировано: IUnknown - 8.10.2011 22:28 |
![]() ![]() |
![]() |
Текстовая версия | 14.08.2025 10:08 |