Эта статья является продолжением этой статьи о код-стандартах. В первой статье я описывал, зачем нужно соблюдать стандарты кодирования, если вам это интересно, то переходите по ссылке и читайте. Продолжим список рекомендаций, нумерацию начну сначала:
- Избегайте магических чисел в программе, это кстати частный случай из предыдущего примера.
Суть его вот в чем, например, в оператореif
сравнение можно было бы сделать так:if (8 == currentMonth) { }
Но у человека, который первый раз видит ваш код сразу возникнет вопрос, что это за магическое число 8? Конечно в данном примере не сложно догадаться, что значит восемь, но даже если и так, какой в этом смысл? Другое дело, если бы код выглядел так:
const int august = 8; if ( august == currentMonth) { cout << "Current month - august"; }
По имени переменной понятно, что 8 — это порядковый номер месяца, все предельно ясно и просто.
- В условиях сравнивайте константное значение со значением переменной, а не наоборот.
Данная рекомендация немного усложняет понимание кода, но зато предотвращает появление ошибок времени компиляции. Вернемся все к тому же примеру из пункта 5. Вот фрагмент кода:if (august == currentMonth) { }
В условии я сравниваю значение константы со значением переменной, если бы было наоборот, то ошибка в пункте 5 не была бы поймана. Обратите на это внимание и стройте условие по принципу сравнивания константного значения с переменной, а не переменную с константным значением, хотя это и логичнее. Вот так делать не надо:
if (currentMonth == august) { }
-
Всегда выполняйте начальную инициализацию переменных.
Соблюдение этой рекомендации поможет сэкономить вам кучу времени. Пример из жизни:
#include <iostream> using namespace std; int main() { int sum = 0; for(int i = 0; i < 5; i++) { sum++; } cout << sum; return 0; }
В переменной sum в цикле накапливается сумма. Программа хорошо работает, проверьте. Заметьте, что переменной sum при объявлении был присвоен нуль, это и есть начальная инициализация. Тот же пример но без начальной инициализации:
#include <iostream> using namespace std; int main() { int sum; for(int i = 0; i < 5; i++) { sum++; } cout << sum; return 0; }
Результат будет неправильный, так как небыло начальной инициализации, соответственно и сумма будет неправильной.
- Старайтесь разбивать большие вычисления на отдельные функции.
Код состоящий из нескольких вызовов функций будет намного понятнее, чем код построенный без использования функций и с большим количеством вложенностей. Тут примера приводить не буду, подробнее об этом можно почитать в статье о процедурном программировании.
- Старайтесь объявлять все свои переменные как можно более локальнее.
Эта рекомендация поможет вам более эффективнее использовать память компьютера. Кроме того, вероятность появления ошибки конфликта имен будет минимальной. Давайте рассмотрим пример:// фрагмент кода for(int i = 0; i < 5; i++) { sum++; }
Управляющая переменная
i
объявлена внутри цикла, это значит то, что область её видимости ограничивается областью видимости цикла. С точки зрения физических процессов в памяти, это значит, что когда цикл завершится, память отводимая под переменнуюi
— освободится, а сама переменная i будет удалена. Это процесс полностью обоснован, ведь цикл закончился и переменная уже не нужна, так зачем же она будет занимать память. Тот же пример, но в нем переменная i будет объявлена вне цикла. Этот пример я не придумал, я его часто встречаю в жизни, почему-то некоторым программистам нравится делать так:int i; for(i = 0; i < 5; i++) { sum++; }
или
int i = 0; for(; i < 5; i++) { sum++; }
Обе эти записи абсолютно неприемлемы, это неправильно. Кроме того эти записи выглядят не красиво. Но кроме косметических недостатков, есть другой — намного более важный. Он связан с тем, что при такой организации кода, даже когда цикл завершит свою работу, переменная
i
не будет уничтожена, а значит будет занимать лишнюю память. Кроме всех этих недостатков возможна ситуация возникновения конфликта имен, вот пример.int i = 0; for(; i < 5; i++) { sum++; } int i = 0; for(; i < 5; i++) { sub--; }
Обычная ситуации, мы в коде воспользовались двумя циклами, причем не важно, что конкретно каждый из них делает. Важно то, что они используют одну и ту же управляющую переменную. Отсюда возникнет такая ошибка:
main.cpp:14: error: redeclaration of ‘int i’Но если бы циклы были построены так, то ошибок бы не было:
for(int i = 0; i < 5; i++) { sum++; } for(int i = 0; i < 5; i++) { sub--; }
И память высвобождается в таком случае правильно.
Если вы до конца внимательно прочитали эту статью, можно считать, что качество вашего кода отныне стало лучше, хотя бы, на чуть чуть. И теперь, когда вы приступите к написанию своей очередной программы, не забудьте применять на практике все те приемы, о которых вы прочитали в этой и предыдущей статьях. Если вы хотите изучить более подробно стандартизации в С++, прочитайте книгу «Стандарты программирования на С++ Герб саттер и Андрей Александреску».
Комментарии
Gosha
По поводу пункта 5. Некоторые пишут на обычном СИ без плюсов. В СИ нельзя объявить переменную в любом месте. И по-другому цикл сделать просто невозможно.
ds
В пункте 3 опечатка в слове сумма:
Результат будет не правильный, так как не было начальной инициализации, соответственно и сума будет не правильной.
Сергей Клементьев
В тексте Вы назвали месяц ougest. Может имелось ввиду august?