Не делайте одно и то же двумя способами одновременно
В качестве контрапункта к предыдущему правилу рассмотрим следующий фрагмент (содержащий в себе ошибку):
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 )
// ...