|
Программирование >> Решение нетривиальных задач
for( i = 10; --i >= 0; ) переменная i вновь инициализиру- ется после рекурсивного вызова, поэтому она может быть статичес- } кой. Вот другой: int f() static int depth = 0; static int depth max = 0; ++depth; depth max = max( depth, depth max ); if( depth > 10 ) return -1; уровень рекурсии слишком глубок. f(); --depth; return depth max; В этом последнем случае переменная depth используется для передачи информации - глубины рекурсии - от одного экземпляра подпрограммы другому, рекурсивному экземпляру этой же самой подпрограммы. Переменная depth max хранит след достигнутой максимальной глубины рекурсии. depth вовсе не будет работать, если она должна будет сохранять свое значение после вызовов - весь смысл в том, что каждый рекурсивный вызов модифицирует эту переменную. 56.3. Используйте счетчик экземпляров объектов вместо инициализирующих функций Инициализирующие функции, с очевидным исключением в виде конструкторов Си++, не должны использоваться просто потому, что слишком просто забыть их вызвать. Многие системы с оконным интерфейсом, например, требуют, чтобы вы вызывали функцию инициализации окна перед его созданием (и другую - закрытия - после удаления последнего окна). Это плохая идея. Уладьте эту проблему при помощи счетчика экземпляров, который обычно в Си должен быть глобальной переменной (объявленной статической для ограничения области ее видимости). Сделайте это так: static int num windows = 0; ограничьте доступ к текущему модулю create window() if( ++num windows == 1 ) только что создано первое окно initialize video system(); ... destroy window() { ... if( --num windows == 0 ) только что уничтожено shutdown video system(); последнее окно В Си++ вы можете для этой цели использовать статический член класса. 56.4. Если оператор if завершается оператором return, то не используйте else Вместо: if( условие ) return xxx; else делать массу вещей(); обычно лучше записать: if ( условие ) return xxx; делать массу вещей(); Лучше сделать так, чтобы последним оператором return был аварийный возврат по ошибке, так чтобы вы получили сообщение об ошибке, если нечаянно заблудились. Условный оператор также может решать эту проблему в простых ситуациях и делать код более читаемым для новичка. Вместо: f() { ... if( x ) return 12 3; else if ( y ) return 45 6; else return ERROR; используйте f() { ... return x ? 12 3 : y ? 456 : ERROR ; Заметьте, насколько форматирование улучшает читаемость предыдущего кода. Одна распространенная ситуация, в которой у вас имеется множество точек возврата, выглядит следующим образом: if( A ) return FAIL; else if( B ) return SUCCESS; else Масса кода return SUCCESS; Подозрительны два одинаковых возвращаемых значения. Вы можете устранить это следующим образом. Во-первых, избавьтесь от повтора возвращаемых значений, переместив их во внешний уровень вот так: if( A ) return FAIL; else if( B ) else Масса кода return SUCCESS; Затем освободитесь от предложения if, связанного с пустым оператором: if( A ) return FAIL; else if( B ) Масса кода return SUCCESS;
|
© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки. |