Правила программирования на Си и Си++

       

Не делайте одно и то же двумя способами одновременно


В качестве контрапункта к предыдущему правилу рассмотрим следующий фрагмент (содержащий в себе ошибку):

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 )

    // ...



Содержание раздела