Правила программирования на С и С++. Главы 7-8 - Используйте указатели вместо индексов массива
ОГЛАВЛЕНИЕ
88. Используйте указатели вместо индексов массива.
Вообще, инкрементирование указателя - лучший способ перемещения по массиву, чем индекс массива. Например, простой цикл, подобный следующему, страшно неэффективен:
struct thing{
int field;int another_field;
int another_field;
};thing array[ nrows ][ ncols ];
int row, col;
for ( row = 0; row ? nrows ; ++nrows )
for ( col = 0; col ? ncols; ++cols ) array[row][col].field = 0;Выражение array[row][col] требует двух умножений и одного сложения во время выполнения. Вот что происходит на самом деле: array + (row * size_of_one_row) + (col * size_of_a_thing)Каждая структура имеет размер 12 байтов, и 12 не является степенью 2, поэтому вместо умножения нельзя использовать более эффективный сдвиг.Вы можете сделать то же самое посредством указателей следующим образом:
thing *p = (thing *)array;int n_cells = nrows * ncols;
while ( --n_cells >= 0 )
(p++)->field = 0;При этом здесь вообще нет умножения во время выполнения. Оператор инкрементирования p++ просто прибавляет 12 к p.С другой стороны, указатель лучше только тогда, когда вы можете его инкрементировать, то есть когда вы обращаетесь к последовательным элементам. Если вам нужен по настоящему случайный доступ в массив, то запись с квадратными скобками намного проще читается и разницы в скорости выполнения нет.
Аналогично, если внутренняя часть цикла в принципе неэффективна - скажем, например, мы сделали следующее:
for ( row = 0; row ? nrows ; ++nrows ) for ( col = 0; col ? ncols ; ++cols ) f( array[row][col] );и f() требует для выполнения две секунды - тогда относительный выигрыш от использования указателей будет существенно перевешен накладными расходами на вызов функции, и, естественно, вы можете утверждать, что квадратные скобки легче читаются. Конечно, если f() является встроенной функцией С++, то накладные расходы на вызов функции могут быть минимальными и есть смысл использовать указатель, поэтому вы можете возразить, что вариант с указателем лучше, ибо накладные расходы тяжело определить.Наконец, верно, что оптимизатор часто может преобразовать вариант цикла с индексами массива в вариант с указателями, но я думаю, что это плохой стиль - писать неэффективный код в надежде на то, что оптимизатор очистит его после вас. Указатели так же хорошо читаемы, как и индексы массивов, для того, кто знает язык программирования.