// Лучше: инициализирует переменную
int speedupFactor = -1;
if (condition)
speedupFactor = 2;
// лучше: инициализирует переменную
int speedupFactor = condition ? 2 : -1;
Варианты, отмеченные как лучшие, не имеют промежутка между определением и инициализацией.
// Не рекомендуется: не инициализирует переменную
int speedupFactor;
if (condition) {
// ... код ...
speedupFactor = somevalue;
} else {
// ... код ...
speedupFactor = someothervalue;
}
// Лучше: инициализирует переменную
int speedupFactor = ComputeSpeedupFactor();
МАХ_РАТН
(см. рекомендации 77 и 78). Если вы уверены, что массивы всегда будут рассматриваться как строки в стиле С с завершающим нулевым символом, то такого немедленного присваивания будет достаточно:
// Допустимо: Создание пустой строки
char path[MAX_PATH];
path[0] = ' ';
Более безопасная инициализация заполняет все элементы массива нулевыми значениями:
// Лучше: заполняем нулями весь массив
char path[MAX_PATH] = { ' ' };
Рекомендованы оба варианта, но в общем случае вы должны предпочитать безопасность излишней эффективности.
Входные буферы и данные, описанные как volatile
, которые записываются непосредственно аппаратным обеспечением или другими процессами, не требуют инициализации программой.
20. Избегайте длинных функций и глубокой вложенности
Краткость — сестра таланта. Чересчур длинные функции и чрезмерно вложенные блоки кода зачастую препятствуют реализации принципа 'одна функция — одна задача' (см. рекомендацию 5), и обычно эта проблема решается лучшим разделением задачи на отдельные части.
Каждая функция должна представлять собой связную единицу работы, несущую значимое имя (см. рекомендацию 5 и обсуждение рекомендации 70). Когда функция вместо этого пытается объединить малые концептуальные элементы такого рода в одном большом теле функции, это приводит к тому, что она начинает делать слишком многое.
Чрезмерно большая по размеру функция и чрезмерная вложенность блоков (например, блоков if
, for
, while
и try
) делают функции более трудными для понимания и сопровождения, причем зачастую без каких бы то ни было оснований.
Каждый дополнительный уровень вложенности приводит к излишним интеллектуальным нагрузкам при чтении кода, поскольку при этом требуется хранить в памяти 'стек' наподобие 'вошли в цикл… вошли в блок try
… вошли в условный оператор… еще в один цикл…'. Вам никогда не приходилось продираться сквозь сложный код и искать, какой же именно из множества конструкций for
, whilе
и т.п. соответствует вот эта закрывающая фигурная скобка? Более хорошее и продуманное разложение задачи на функции позволит читателю вашей программы одновременно удерживать в голове существенно больший контекст.
Воспользуйтесь здравым смыслом. Ограничивайте длину и глубину ваших функций. Далее приведены некоторые добрые советы, которые помогут вам в этом.
•
•
• if
там, где их можно заменить оператором &&
.
• try
-блоках (см. рекомендацию 13).
•
•
Функция может на законных основаниях быть длинной и/или глубокой, если ее функциональность нельзя разумно разделить на отдельные подзадачи, поскольку каждое такое потенциальное разделение требует передачи массы локальных переменных и контекста (что приводит к еще менее удобочитаемому результату). Но если несколько таких потенциальных функций получают аналогичные аргументы, они могут быть кандидатами в члены нового класса.
21. Избегайте зависимостей инициализаций между единицами компиляции