1.3.1.3. Управляющие конструкции
Произошедшая в 1970-х годах революция в структурном программировании была вызвана плохой читабельностью разработанных в 1950-60-х годах языков, в которых недоставало управляющих операторов. В частности, распространилось мнение, что беспорядочное использование оператора безусловного перехода goto значительно снижает читабельность программы. Программа, которую можно прочесть последовательно от начала до конца, значительно проще для понимания, чем программа, для прослеживания хода выполнения которой читателю требуется переходить от одного оператора к другому, находящемуся в любом месте программы.
Однако в некоторых языках использование goto было необходимо для перехода назад: эти операторы нужны, например, для построения циклов while в языке FORTRAN 77. Использовавшимся в начале 1970-х годов версиям языка BASIC и FORTRAN не хватало управляющих операторов, которые налагали бы строгие ограничения на использование безусловных переходов, поэтому писать удобочитаемые программы на этих языках было трудно.
Большинство появившихся позднее языков программирования имело достаточное количество управляющих операторов, так что потребность в операторе безусловного перехода практически отпала. Была также доказана теорема Э.Дейкстры, согласно которой любой императивный алгоритм может быть реализован с использованием трех основных управляющих конструкций: цепочки, условного оператора и цикла while. Таким образом, управляющие конструкции языка уже не так влияют на его читабельность, как это было раньше.
1.3.1.4. Типы и структуры данных
Существенный вклад в читабельность программ вносят имеющиеся средства определения типов и данных. Если в некотором языке нет булевских данных, то для индикаторов может использоваться числовой тип. Тогда присваивание sum_is_too_big = 1 будет не совсем понятным, в то время как в языке с булевским типом можно записать выражение sum_is_too_big = true, смысл которого существенно яснее.
Аналогично, тип данных, называемый записью, обеспечивает более читабельный способ хранения информации о сотрудниках, чем набор сходных массивов, в каждом из которых хранится отдельный элемент данных, как это бывает, если в языке не предусмотрена поддержка записей. В языке FORTRAN 77, например, информация о сотрудниках может храниться в следующих массивах:
CHARACTER (LEN = 30) NAME (100)
INTEGER AGE (100), EMPLOYEE_NUMBER (100)
REAL SALARY (100)
1.3.1.5. Синтаксическая структура
Существенное влияние на читабельность программ оказывает синтаксис элементов языка программирования. Ниже перечислены три элемента синтаксической структуры языка, воздействующие на читабельность программы.
Формы идентификаторов.
Ограничение длины идентификаторов до маленьких размеров уменьшает читабельность. Например, в языке FORTRAN 77 длина идентификатора не может превышать шести символов, поэтому в нем часто невозможно использовать осмысленные названия переменных. Еще большей крайностью отличается созданный Национальным институтом стандартизации США (ANSI – American National Standards Institute) язык BASIC, в котором идентификатор может состоять только из одной буквы или сочетания, состоящего из буквы и следующей за ней цифры.
Специальные слова.
Внешний вид программ существенно зависит от набора специальных слов языка (begin, end, for, …). Особенно важен способ образования составных операторов. В некоторых языках для формирования групп используются согласованные пары слов или символов. В языке Pascal для всех управляющих структур, кроме оператора repeat, используется пара специальных слов begin-end, причем даже там, где она может быть пропущена. В языке C для той же цели используются фигурные скобки. В обоих вариантах недостатком можно считать единообразное завершение группы операторов. Иногда довольно трудно определить, какая именно группа замыкается очередным оператором end или символом }. В языках FORTRAN 90 и Ada эта проблема не так остра, поскольку для каждого вида группы операторов используется отдельный синтаксис замыкания. В языке Ada, например, для замыкания конструкции ветвления используется оператор end if, а для замыкания цикла – оператор end loop. Это пример противоречия между простотой языка Pascal, приводящей к малому количеству зарезервированных слов, и лучшей читабельностью языка Ada, обеспеченной многочисленными зарезервированными словами.
Другим важным вопросом является использование специальных слов языка в качестве имен переменных в программе. Если такая возможность есть, то программа может оказаться весьма запутанной. Например, в языке FORTRAN 90 такие специальные слова, как DO и END, можно использовать в качестве имен переменных, так что их появление в программе может означать не то что кажется на первый взгляд.
Форма и значение.
Облегчить чтение программы могут также операторы, само появление которых отчасти указывает на их цели. В некоторых случаях этот принцип нарушается двумя языковыми конструкциями, идентичными или похожими по форме, но различными по смыслу, который может зависеть от контекста. В языке C, например, смысл слова static зависит от контекста, в котором оно появляется. Если оно использовано при определении переменной внутри функции, это означает, что данная переменная создается во время компиляции. Если слово static используется при определении переменной вне всех функций, это означает, что она видима только в файле, содержащем данное описание.
Одна из основных претензий к набору команд оболочки операционной системы UNIX связана с тем, что названия этих команд не всегда связаны с их предназначением. Например, название используемой в системе UNIX команды grep может быть расшифровано только при наличии предварительных знаний, а также опыта работы с текстовым редактором ed системы UNIX. Для начинающих пользователей системы UNIX появление указанной команды ни о чем не говорит.
В текстовом редакторе ed команда /стандартное выражение/ выполняет поиск подстроки, совпадающей с указанным стандартным выражением. Если предварить эту команду атрибутом g, то ее выполнение станет глобальным, определяя весь редактируемый файл как область поиска. Употребление атрибута p после указанной команды приведет к печати строки, содержащей искомое выражение. Таким образом, команда g/стандартное_выражение/p, которая сокращается до grep (по первым буквам), печатает все строки файла, содержащие подстроку, совпадающую с искомым стандартным выражением.