В предыдущих статьях частично были затронуты правила хорошего тона в оформлении программного кода. Кроме того, что грамотно оформленный код улучшает восприятие информации, это еще выступает и залогом того, что программа удачно скомпилируется без каких-либо предупреждений или еще хуже ошибок. Поэтому и решил посвятить данной теме отдельную статью. Преступим.
Из чего же состоит программа?
Программу условно можно поделить на несколько частей:
Строка #include <______> - подключаем файл библиотеки;
Объявляем константы (постоянные величины). Один из примеров использования – задание размера массива «const N = 20;».
Глобальные переменные. Они объявляются перед основной функцией. Преимущество таких переменных в том, что к ним могут обращаться любые процедуры/функции программы, без повторного объявления переменных в телах соответствующих процедур/функций.
Объявление процедур/функций. Без объявления транслятор выдаст ошибки/предупреждение. Конечно можно обойтись и без объявления. Но тогда необходимо записать заголовок и тело функции/процедуры перед основной программой (функцией). Данный вид записи не совсем удобный и правильный.
Основная функция (программа). Как писал ранее, её можно разместить до/после подпрограмм. Настоятельно не рекомендую размещать основную функцию между функциями второго плана (подпрограммами). Нет, если вы разместите – ничего плохого не случится. Пока у вас 3-4 вторичные функции, все будет хорошо, но когда число функций перевалит за десятки… Вы просто можете не найти функцию «main».
За область видимости переменных уже немного рассказывал, поэтому повторюсь. Глобальные могут вызываться/использоваться из любой процедуры/функции. Локальные объявляются только в процедурах и функциях, в которых они используются. Следующий пример показывает различие между локальными и глобальными переменными.
#include <stdio.h> // подключаем файл библиотеку
char color; // объявление глобальной переменной
void int_variable () //советую создавать отдельную функции, которая будет присваивать
{ //глобальным переменным начальные значения. Не будет ошибкой, если присвоит
color = 0; // начальное значение, при объявлении переменной. Но «грамотнее» будет присваивать
} // начальные значения отдельной функцией.
void variable_no_change ()
{
char color; // объявление локальной переменной
color = 3; // присваиваем локальной переменной значение 3
}
void variable_first_change ()
{
color = 5; // присваиваем глобальной переменной значение 5
}
void variable_second_change ()
{
char color; // локальная переменая
color = 4; // присваиваем локальной переменной значение 4
:: color = ::color * 2 + color; // «работа» по изменению значения глобальной переменной
}
main()
{
int_variable ();
variable_first_change (); // color = 5;
variable_second_change (); // color = 5*2 + 4 = 14;
variable_no_change (); // color не меняется
printf ( "%d", color ); // печать глобальной переменной (14)
}
Комментарии по представленной программе:
- Глобальные переменные не объявляются во вторичных функциях.
- При объявлении во вторичных функциях глобальных и локальных переменных с одинаковыми названиями, во вторичных функциях используются локальные переменные.
- В случае, когда в подпрограмме необходимо обратится к глобальной переменной с таким же именем, как и у локальной, перед именем глобальной переменной ставится «::» «::color = :: color * 2 + color;»
Однако правилом «грамотной записи» в Сишке считается использования глобальных переменных, как можно реже. В идеале – не пользоваться ими вообще. Причина кроется в том, что глобальные переменные затрудняют анализ и отладку программы, повышается вероятность допущения ошибки (которая может выйти боком). Представьте, что какая-то подпрограмма изменила значение глобальной переменной, а вы этого не заметили…. Кроме этого существенно увеличивается размер программы. Созданные глобальные переменные «хранятся» в блокt данных постоянно, а не создаются при выполнения подпрограммы (после завершения удаляются).
Поэтому использовать глобальные переменные следует только тогда, когда есть необходимость в хранении системных настроек (размер шрифта и т.п.) или переменная служит контейнером для хранения данных, которые используют для выполнения своей работы вторичные функции и в какой-либо другой способ передать им эти данные невозможно.
Данные в процедуры/функции по возможности нужно передавать через их собственные параметры. В случае, если есть необходимость, чтобы подпрограмма меняла значения переменных, нужно передавать параметр по ссылке.
Оформление текста программы
Помните, говорил о том, что хочу, чтобы вы не верили на слово, а разбирались в программном коде? Обратим наши взоры на две абсолютно одинаковые программы (одинаковые в плане понимания их «шелезякой»).
Вот теперь и скажите, какая из программ конфетка, а какая …не конфетка) Вы наглядно увидели пример грамотного оформления.
Грамотно оформленный текст программы поможет при поиске и исправление ошибок (хотел бы сказать у нас ошибок не будет, но куда же без них). Кроме этого другой программист (или вы через определенный период времени) с легкостью сможет разобраться в алгоритме работы написанной вами программы
Оформление процедур и функций
Мы поговорили о тексте программы, теперь затронем такой аспект работы, как оформлении функций/процедур.
Если в программе выполняются одинаковые операции, то их следует оформлять в виде подпрограмм.
Имена процедур/функций должны быть осознанными и нести информационную нагрузку. Иными словами человек должен посмотреть на заголовок функции/процедуры и понять, что она делает.
ОБЯЗАТЕЛЬНО используйте комментарии. Перед заголовком функции не поленитесь и распишите всё, что может пригодится при работе с данной частью кода. Например: какие параметры используются, что выполняет, возвращает ли значение (если да, то какое) и т.д.
Всегда старайтесь писать подпрограммы длиной не более 15-20 строк. Чем больше строчек кода, тем запутаннее и сложнее становится алгоритм для понимания. Если вы знаете, что подпрограмма будет большой, воспользуйтесь римской пословицей: «Разделяй и властвуй» и разбейте её на
более мелкие процедуры/функции.
Используйте пустые строки или «//****….****» «//------…..-----», чтобы разделять части подпрограммы.
Отступы
Для визуального выделения структурных блоков программы используют отступы. Они помогают искать лишние и недостающие скобки, уменьшают время, что затрачивается на понимание логики программы, позволяя легче находить ошибки.
Общепринятые правила расстановки отступов:
- Величина отступа равна 2-4 символа.
- Дополнительным отступом выделяются:
- циклы for, while, do-while
- условный оператор if и блок else
- оператор множественного выбора switch
Пример записи программы «лесенкой»:
Спасибо за уделённое время. Продолжение следует...