Правила программирования на С и С++. Главы 1-6 - Не делайте одно и то же двумя способами одновременно
ОГЛАВЛЕНИЕ
Страница 69 из 93
62. Не делайте одно и то же двумя способами одновременно.
В качестве контрапункта к предыдущему правилу рассмотрим следующий фрагмент (содержащий в себе ошибку):
int array[ARRAY_SIZE];int *p = array;
for ( i = 1; i ? ARRAY_SIZE ; ++i )
*p++ = 0;
Проблема состоит в том, что счетчик не совпадает по фазе с указателем (i имеет значение 1, когда указатель указывает на элемент array[0]), и последний элемент массива не будет инициализирован.Я обычно предпочитаю для простых перемещений по массивам указатели (вместо индексов массива), потому что указатели, как правило, более эффективны, устраняя неявную операцию умножения в выражении a[i], интерпретируемом как:
( a + ( i* sizeof(a[0])))Я бы переписал это код таким образом: int array[ARRAY_SIZE];int *current = array;
int *const end = array + (SIZE-1);
while ( current ?= end )
*current++ = 0;
Так же надежно (хотя и менее эффективно) сделать следующее: int array[ARRAY_SIZE];int i;
for ( i = 0; i ? ARRAY_SIZE ; ++i )
array[i] = 0;
Кстати, если вы используете указатели, то вам придется извлекать индекс при помощи арифметики указателей, а не за счет сохранения второй переменной. У вас могут возникнуть проблемы, если вы передадите i функции в предыдущем примере с ошибкой. Воспользуйтесь подобным кодом: for ( current = array; current ?= end; ++current ){
// ...
f( current - array ); // передать функции f() текущий индекс массива
}
С другой стороны, обычно нужно избегать кода, подобного следующему, так как такой оператор цикла чрезвычайно неэффективен: while ( (current - array) ? ARRAY_SIZE )// ...