Псевдокод — это неформальное высокоуровневое описание алгоритма, записанное на обычном английском языке с добавлением небольшого набора ключевых слов в стиле программирования. Он предназначен для чтения человеком при планировании или объяснении логики и не выполняется ни одним компилятором. Короткий пример показывает, как он выглядит.
ЕСЛИ пользователь вошел в систему ТО показать панель управления ИНАЧЕ перенаправить на страницу входа
Этот фрагмент не относится ни к одному языку. Читатель, знающий Python, Java, Go или не знающий ни одного из них, всё равно сможет понять, что он делает. Псевдокод жертвует строгостью настоящего кода ради читаемости, поэтому он встречается в учебниках, интервью у доски, проектных документах и ранних заметках работающих программистов.
Рабочее определение псевдокода
Псевдокод описывает шаги алгоритма, используя намеренное смешение двух регистров. Первый регистр обеспечивает структуру с помощью заглавных ключевых слов, таких как ЕСЛИ, ПОКА, ДЛЯ, ВОЗВРАТ и КОНЕЦ. Второй регистр заполняет действия и условия обычными словами, например «показать панель управления» или «если результат превышает 80». В результате получается текст, более свободный, чем исходный код, и более точный, чем проза.
Дональд Кнут помог установить современное соглашение в первом томе «Искусства программирования», опубликованном в 1968 году. Кнут представлял алгоритмы с формальной блочной структурой и комментариями на естественном языке, и этот гибрид стал стандартной формой для академического описания алгоритмов. В 1970-х и 1980-х годах структурное программирование распространило те же соглашения в учебных классах, а экзаменационные комиссии Великобритании, такие как Cambridge International, AQA и OCR, позже опубликовали собственные справочники по псевдокоду для школьных курсов информатики.
Псевдокод — это не сам алгоритм. Алгоритм — это абстрактная последовательность шагов, решающая задачу. Псевдокод — один из способов записать алгоритм на бумаге, наряду с блок-схемами, обычной прозой и реальным исходным кодом на таком языке, как Python или C++.
Причины, по которым псевдокод оправдывает своё место на практике
Псевдокод отвечает небольшому набору повторяющихся потребностей в работе с программным обеспечением. Первая — это планирование. Программист, который записывает логику в псевдокоде перед открытием редактора, может заметить тупики или пропущенные случаи, не расплачиваясь синтаксисом языка, подключением библиотек и ошибками компиляции. Вторая — обучение. Студенты информатики изучают циклы и условия в псевдокоде, потому что конструкция видна без лишних точек с запятой, скобок и объявлений типов.
Третье применение — коммуникация через языковые барьеры. Команда, в которую входят инженеры, пишущие на Go на бэкенде и на TypeScript на фронтенде, может согласовать один и тот же псевдокод для процедуры проверки, а затем перевести его на оба стека без разногласий по логике. Четвёртое — документация. Исследовательские статьи, патенты и документы Request for Comments в IETF опираются на псевдокод и близкие к нему обозначения, потому что рецензенты имеют разный языковой опыт.
Последнее — код-ревью и технические собеседования. Прохождение функции в псевдокоде заставляет говорящего сосредоточиться на значимых шагах, а не на пунктуации, и часто выявляет ошибки, скрытые в идиомах конкретного языка.
Правила хорошего псевдокода
Большинство руководств по стилю сходятся на небольшом наборе правил. Это скорее рекомендации, чем абсолютный синтаксис, поскольку ни один комитет не владеет псевдокодом так, как органы стандартизации владеют C или HTML. Приведённый ниже список обобщает соглашения, используемые в стандарте псевдокода Калифорнийского политехнического университета, руководстве для учителей Cambridge International и распространённых университетских лекционных заметках.
Пишите ключевые слова заглавными буквами. Слова, такие как ЕСЛИ, ТО, ИНАЧЕ, ПОКА, ДЛЯ, ВЫПОЛНИТЬ, ВОЗВРАТ, НАЧАЛО и КОНЕЦ, пишутся заглавными, чтобы выделяться на фоне окружающих действий и имён переменных.
Одна операция на строку. Строка должна содержать один шаг. Составные строки, объединяющие две идеи, скрывают ошибки и снижают читаемость.
Делайте отступы для вложенных блоков. Всё, что находится внутри ЕСЛИ, ПОКА, ДЛЯ или тела функции, располагается на один уровень глубже. Отступы выполняют ту же работу, что фигурные скобки или пары НАЧАЛО/КОНЕЦ в реальном коде.
Используйте именованные переменные, описывающие смысл. «общаяОценка» лучше, чем «x». «являетсяДопустимымEmail» лучше, чем «флаг». Читатель должен понимать, что хранит переменная, не возвращаясь на десять строк назад.
Оставайтесь независимыми от языка. Избегайте списковых включений Python, дженериков Java, стрелочных функций JavaScript и любого другого синтаксиса, привязывающего описание к одной экосистеме.
Явно закрывайте каждый блок. Завершайте многострочные конструкции с помощью КОНЕЦЕСЛИ, КОНЕЦПОКА, КОНЕЦДЛЯ или КОНЕЦ, чтобы границы были видны с первого взгляда, даже если отступы плохо заметны.
Охватывайте всю логику. Псевдокод не должен пропускать сложные части. Если шаг гласит «обработать ошибку», автор ещё не закончил думать.
Подбирайте имена в соответствии с предметной областью задачи, а не с реализацией. Алгоритм планирования использует слова «встреча» и «доступный слот», а не «объект1» и «массив».
Эти правила сохраняются при переводе. Код, следующий им, остаётся читаемым на любом целевом языке, а это и есть весь смысл написания псевдокода.
Типичные ключевые слова псевдокода
Набор ключевых слов невелик, и большинство авторов признают одно и то же ядро. В таблице ниже перечислены ключевые слова, встречающиеся почти во всех опубликованных справочниках по псевдокоду, а также их назначение и альтернативные написания, используемые разными руководствами по стилю.
| Ключевое слово | Назначение | Распространённые альтернативы |
| НАЧАЛО / КОНЕЦ | Обозначают начало и конец процедуры или блока | СТАРТ / СТОП, { / } в псевдокоде в стиле C |
| ЕСЛИ / ТО / ИНАЧЕ / КОНЕЦЕСЛИ | Условное ветвление | ИНАЧЕ ЕСЛИ, ИНАЧЕЕСЛИ, FI |
| ПОКА / КОНЕЦПОКА | Цикл с предусловием, выполняющийся, пока условие истинно | ВЫПОЛНЯТЬ ПОКА, WEND |
| ДЛЯ / КОНЕЦДЛЯ | Цикл со счётчиком на известное количество итераций | ДЛЯ КАЖДОГО, FOREACH |
| ПОВТОРЯТЬ / ДО | Цикл с постусловием, выполняющийся хотя бы один раз | ВЫПОЛНИТЬ / ПОКА НЕ |
| ВЫБОР / ИЗ / ИНАЧЕ | Множественное ветвление | SWITCH / CASE / DEFAULT |
| ВВОД / ВЫВОД | Чтение от пользователя и запись пользователю | ЧИТАТЬ, ПЕЧАТАТЬ, ОТОБРАЗИТЬ |
| ПРИСВОИТЬ / НАЗНАЧИТЬ | Присвоить значение переменной | стрелка влево, := |
| ВЫЗОВ | Вызов процедуры или функции | ИНВОКИРОВАТЬ, ВЫПОЛНИТЬ |
| ВОЗВРАТ | Возврат значения из функции | ВЫВОД, YIELD |
Точный список зависит от учебника или экзаменационной комиссии. Читатель, освоивший столбец выше, сможет понять почти любой псевдокод, который встретится в книгах, лекциях или спецификациях.
Примеры псевдокода для распространённых алгоритмов
Пять примеров ниже охватывают формы, которые начинающий видит чаще всего. В каждом используются ключевые слова из таблицы, и они не привязаны к конкретному языку. Формат намеренно различается, поскольку реальные инженеры подходят к псевдокоду с разных сторон в зависимости от стоящей перед ними задачи.
Линейный поиск
Задача проста. Дан список элементов и искомое значение; нужно вернуть позицию искомого, если оно есть, или специальное значение, если его нет. Псевдокод проходит по списку от первого индекса до последнего и возвращает результат, как только найдено совпадение.
ФУНКЦИЯ linearSearch(список, искомый) ДЛЯ i ОТ 0 ДО длина(список) – 1 ЕСЛИ список[i] == искомый ТО ВОЗВРАТ i КОНЕЦЕСЛИ КОНЕЦДЛЯ ВОЗВРАТ -1 КОНЕЦФУНКЦИИ
Затраты растут пропорционально размеру списка, поэтому линейный поиск выполняется за O(n) времени. Он работает с любым списком, отсортированным или нет.
Бинарный поиск
ФУНКЦИЯ binarySearch(отсортированныйСписок, искомый) ПРИСВОИТЬ низ = 0 ПРИСВОИТЬ верх = длина(отсортированныйСписок) – 1 ПОКА низ <= верх ПРИСВОИТЬ середина = (низ + верх) / 2 ЕСЛИ отсортированныйСписок[середина] == искомый ТО ВОЗВРАТ середина ИНАЧЕ ЕСЛИ отсортированныйСписок[середина] < искомый ТО ПРИСВОИТЬ низ = середина + 1 ИНАЧЕ ПРИСВОИТЬ верх = середина – 1 КОНЕЦЕСЛИ КОНЕЦПОКА ВОЗВРАТ -1 КОНЕЦФУНКЦИИ
Эта версия предполагает, что список уже отсортирован — это предусловие, обеспечивающее корректность алгоритма. Каждая итерация вдвое сокращает диапазон поиска, что даёт время выполнения O(log n) и объясняет, почему бинарный поиск превосходит линейный на больших отсортированных данных.
FizzBuzz с параллельным переводом
FizzBuzz выводит числа от 1 до 100, заменяя кратные 3 на «Fizz», кратные 5 на «Buzz», а кратные и 3, и 5 на «FizzBuzz». Псевдокод и перевод на Python расположены рядом, чтобы соответствие было очевидным.
Псевдокод:
ДЛЯ i ОТ 1 ДО 100 ЕСЛИ i MOD 15 == 0 ТО ВЫВОД «FizzBuzz» ИНАЧЕ ЕСЛИ i MOD 3 == 0 ТО ВЫВОД «Fizz» ИНАЧЕ ЕСЛИ i MOD 5 == 0 ТО ВЫВОД «Buzz» ИНАЧЕ ВЫВОД i КОНЕЦЕСЛИ КОНЕЦДЛЯ
Python:
for i in range(1, 101): if i % 15 == 0: print(“FizzBuzz”) elif i % 3 == 0: print(“Fizz”) elif i % 5 == 0: print(“Buzz”) else: print(i)
Структура идентична строка в строку. Псевдокод читается немного медленнее из-за явных КОНЕЦЕСЛИ и КОНЕЦДЛЯ, а код на Python — немного быстрее, поскольку отступы сами обозначают блок. Логика одинакова в обоих случаях.
Валидация ввода: с ошибкой и исправленная
Псевдокод требует внимательного чтения, потому что ошибки прячутся в тех же местах, что и в реальном коде. Приведённая ниже версия пытается проверить, что пароль соответствует двум требованиям: не менее 8 символов и хотя бы одна цифра. Она содержит ошибку.
FUNCTION isValid(password) IF length(password) < 8 THEN RETURN false ENDIF FOR each character c IN password IF c IS a digit THEN RETURN true ENDIF ENDFOR ENDFUNCTION
Ошибка находится внизу. Если цикл заканчивается, не найдя цифру, функция ничего не возвращает. Читатель не может сказать, что увидит вызывающий код. Исправление добавляет явный RETURN в конце, чтобы каждый путь возвращал значение.
FUNCTION isValid(password) IF length(password) < 8 THEN RETURN false ENDIF FOR each character c IN password IF c IS a digit THEN RETURN true ENDIF ENDFOR RETURN false ENDFUNCTION
Отсутствие путей возврата — одна из самых распространенных ошибок в псевдокоде на собеседованиях. Правило «полной логики» из начала статьи существует именно для того, чтобы выявить такой пробел.
Факториал через рекурсию
Рекурсия дает псевдокоду возможность показать функцию, вызывающую саму себя. Факториал n, обозначаемый n!, — это произведение всех целых чисел от 1 до n. Рекурсивное определение коротко: 0! и 1! равны 1, а n! для любого большего n равно n, умноженному на (n-1)!. Псевдокод следует определению.
FUNCTION factorial(n) IF n <= 1 THEN RETURN 1 ELSE RETURN n * factorial(n – 1) ENDIF ENDFUNCTION
Первая ветвь — это базовый случай, а вторая — рекурсивный вызов. Каждая рекурсивная функция нуждается в обоих. Функция без базового случая работает бесконечно, а функция без рекурсивного вызова вообще не выполняет рекурсию. Этот псевдокод напрямую транслируется в Python, JavaScript, Ruby или любой другой язык, поддерживающий вызовы функций.
Сравнение псевдокода, блок-схем и исходного кода
Эти три артефакта описывают одну и ту же логику разными способами. Новичок выбирает один из них в зависимости от аудитории и размера алгоритма. В таблице ниже приведены компромиссы.
| Особенность | Псевдокод | Блок-схема | Исходный код |
| Формат | Текст с ключевыми словами | Диаграмма с фигурами | Текст со строгим синтаксисом |
| Аудитория | Программисты и студенты компьютерных наук | Смешанная аудитория, включая непрограммистов | Компиляторы и интерпретаторы |
| Редактирование | Легко редактировать в любом текстовом редакторе | Сложнее редактировать после рисования | Легко редактировать, проверяется компилятором |
| Масштабируется для длинных алгоритмов | Да | Становится громоздким после 10–15 блоков | Да |
| Исполняемый | Нет | Нет | Да |
| Детали реализации | Скрыты | Скрыты | Видимы |
Блок-схемы хорошо подходят для коротких процедур, показываемых заинтересованным сторонам, которые не читают код. Псевдокод подходит для более длинных алгоритмов и естественно читается инженерами. Исходный код — единственный из трех, который может выполнять компьютер. Большинство команд используют более одного из этих артефактов в ходе проекта, и переход от псевдокода к исходному коду обычно является последним шагом перед тестированием.
Распространенные ошибки в псевдокоде
Псевдокод новичков часто содержит небольшое количество повторяющихся ошибок. Первая ошибка — опора на синтаксис конкретного языка. Написание list.append(x) или arr.length внутри псевдокода вовлекает читателя в определенный язык и нарушает правило независимости от языка.
Вторая ошибка — использование неопределенных имен переменных. «data», «value» и «result» встречаются так часто, что теряют смысл. Читатель, видящий «averageGrade» или «remainingDays», понимает переменную без контекста.
Третья ошибка — пропуск сложных шагов с помощью фраз вроде «and then sort the list» или «validate the input». Псевдокод, скрывающий сложную часть, — это не псевдокод, а набросок. Исправление — развернуть каждое нечеткое указание в отдельный блок.
Четвертая — забывание закрывающего ключевого слова блока. FOR без ENDFOR или IF без ENDIF заставляет читателя гадать, где заканчивается блок. Отступы помогают, но одни отступы ненадежны в обычном тексте, где выравнивание может сбиться.
Последняя — написание декоративных предложений вместо операций. «Мы тщательно проверяем каждый элемент» — это не шаг. «ДЛЯ каждого элемента, ЕСЛИ элемент недействителен, ТО отклонить запрос» — это шаг. Псевдокод предназначен для операций, а не для комментариев.
Часто задаваемые вопросы
Чувствителен ли псевдокод к регистру?
Псевдокод обычно считается нечувствительным к регистру. Имена переменных, такие как Countdown и countdown, относятся к одному и тому же значению в большинстве руководств по стилю. Соглашение рекомендует использовать ключевые слова в верхнем регистре (IF, WHILE, FOR) и идентификаторы в смешанном регистре (numberOfPlayers) для читаемости, но это правило скорее стилистическое, чем обязательное.
В чем разница между псевдокодом и блок-схемой?
Псевдокод — это текст. Блок-схема — это диаграмма, построенная из фигур, таких как прямоугольники для процессов и ромбы для решений. Оба описывают один и тот же алгоритм, но псевдокод быстрее читается программистами и масштабируется для более длинной логики, в то время как блок-схема лучше подходит для смешанной аудитории и коротких процедур.
Существует ли стандартный синтаксис для псевдокода?
Единого глобального стандарта не существует. Cambridge International, AQA, OCR и академические учебники публикуют свои собственные соглашения, и они различаются в мелочах, таких как какие терминаторы циклов использовать. Большинство стилей используют одни и те же основные ключевые слова (IF, WHILE, FOR, RETURN) и правила отступов, поэтому читатель, освоивший один стиль, может без труда следовать другим.
Кто изобрел псевдокод?
Ни один человек не изобрел псевдокод. Эта форма развивалась в 1960-х и 1970-х годах вместе со структурным программированием. «Искусство программирования» Дональда Кнута, первый том которого был опубликован в 1968 году, установил доминирующую конвенцию для описания алгоритмов в академической работе, и практика распространилась оттуда в классы и отраслевую документацию.
Можно ли преобразовать псевдокод в код?
Да. Псевдокод часто является первым черновиком алгоритма, и программист переводит каждую строку на целевой язык, такой как Python, Java или C. Чем ближе псевдокод к реальному языку, тем прямее перевод. Нестрогий псевдокод, написанный почти прозой, может потребовать больше интерпретации, но логические шаги по-прежнему отображаются на языковые конструкции один к одному.
Комментарии
Категории
Случайное

7 советов от экспертов: как выгодно

Срок жизни SSL-сертификатов сократили

Как оценивается экологическое

Ошибка 504 Gateway Timeout: что это
