Здравствуйте, Аноним, Вы писали:
А>Здравствуйте, watch-maker, Вы писали:
WM>>Можно просто заменить цикл [0..n) на цикл [-n..0). Это позволит, не меняя направление просмотра массива, использовать упрощённое сравнение с нулём как признак завершения цикла. Собственно, компиляторы так тоже делают.
А>А это не усложнит индексацию по переменной цикла?
Просто базой будет служить не начало массива, а его конец. То есть код вида
T* base = array + 0;
for (int i = 0; i < n; ++i)
action(base[i]);
будет заменён на
T* base = array + n;
for (int i = -n; i < 0; ++i)
action(base[i]);
Как видно, тело цикла никак не изменилось. Изменилось лишь условие продолжения цикла (стало проще) и код инициализации цикла (стал сложнее). Так как обычно цикл делает более одной итерации, то условие проверяется чаще и на нём имеет смысл сэкономить.
Но разумеется, не стоит бросаться переписывать все циклы во вторую форму, ибо у них хуже читаемость, проверка условия в таких циклах редко является тормозом (а на суперскалярных процессорах отличий между двумя вариантами может вообще не быть), да и компилятор обычно сам способен сделать такую замену.
Ну и интересно ещё то, что компилятор часто использует два регистра для прохода по массиву: счётчик и указатель. Счётчик всегда движется к нулю, а указатель непосредственно индексирует обрабатываемый элемент. В таком случае различий между двумя вариантами не будет вообще.