Правила программирования на С и С++. Главы 1-6 Страница 69. Не делайте одно и то же двумя способами одновременно
|
Страница 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 ) // ... |