1. Пользуйтесь тегами кода. - [code] ... [/code] 2. Точно указывайте язык, название и версию компилятора (интерпретатора). 3. Название темы должно быть информативным. В описании темы указываем язык!!!
pow() некорректно работает если используется инкремент или декремент в его параметрах. Задание: Совершая обход так: 1 3 4 10 2 5 9 11 6 8 12 15 7 13 14 16 заполнить матрицу а такими значениями: b11b12...bnn
Kod(Показать/Скрыть)
#include <cmath> #include <iostream> #include <windows.h> using namespace std;
main() { int M, N; cout << "Insert N: "; cin >> N;
int b[N]; cout << "Insert b[i]: "; for (int i = 0; i < N; i++) cin >> b[i];
int a[M = N][N]; int i = 0, j = 0, k = 0; while (i < M || j != N - 1) { while (i < M && 0 <= j) a[i++][j--] = pow(b[k++ / N], k % N + 1); if (i == M){i--; j++;} while (0 <= i && j < N - 1) a[i--][++j] = pow(b[k++ / N], k % N + 1); i++; if (j == N - 1) i++; else j++; }
for (int i = 0; i < M; i++) { for (int j = 0; j < N; j++) { cout.width(4); cout << a[i][j]; } cout << endl; } system("pause"); }
В таком исполнении pow(b[k++ / N], k % N + 1); работает так как надо (еще недавно и так не работал, но теперь почему-то работает):
Компилятор 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 не будет.
Кстати, разницу между префиксным и постфиксным ++ (да и -- тоже) знаешь?