Правила программирования на С и С++. Главы 1-6
Страница 69. Не делайте одно и то же двумя способами одновременно


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 )

// ...

 

 
« Предыдущая статья