Опубликован: 23.10.2009 | Уровень: для всех | Доступ: платный
Лекция 3:

Парадигмы программирования

< Лекция 2 || Лекция 3: 1234 || Лекция 4 >
Аннотация: В данной лекции Вы познакомитесь с существовавшими на 01.06.2008г. парадигмами программирования, и, в частности, более подробно узнаете о процедурной парадигме и ее реализациями на языках Quick Basic, Си/C++ и Perl.
Ключевые слова: парадигма программирования, Лисп, мутация, императивный, пошаговое выполнение, Assembler, декларативный язык, Lisp, Prolog, транслятор, парадигма, автор, место, удобочитаемость, formula, COBOL, процедурное программирование, ассемблер, Алгол, JScript, macro, bash, REXX, BAS, REM, CPP, формальный параметр, спецсимвол, директива компилятора, объявление функции, оператор описания, шаблон оформления, имя программы, Basic, MS-DOS, Command, shell, прикладная математика, машинный язык, последовательность операторов, формальный язык, ООП, структурированное программирование, отправитель сообщения, императивный язык, оператор операторов, безусловный переход, периферийное устройство, логический вывод, псевдокод, python, устройство управления, арифметико-логическое устройство, вычислительная система, система команд, организация памяти, центральный процессор, математический сопроцессор, средства разработки, переменная функции, командная оболочка, переменная среды, фактический параметр, синоним, LIFO, строгое соответствие, операция приведения, дизъюнкция, исключающее ИЛИ, булевский тип, операция конкатенации, валидация, Формальной грамматикой, исключительная ситуация, функция в языке программирования, логическое ИЛИ, OCX, символьная обработка, разыменование, код ошибки, application program interface, прикладное программирование, идентификатор переменной, параметр команды, функция кода, WIMP, именованные переменные, вызывающая программа, ISA, внешняя функция, текущая директория

Цель лекции:

  1. Познакомить читателей с основными парадигмами программирования, применяемых в современном программировании;
  2. Научить читателей программировать, читать алгоритмы, создавать программы, на языках программирования, входящих в процедурную парадигму;
  3. Научить правильной записи алгоритмов на языках, входящих в процедурную парадигму.

3.1. Введение. Общие сведения о парадигмах

Общие сведения о парадигмах программирования

За те пятьдесят с небольшим лет, которые существует дисциплина: "программирование", - сменилось несколько поколений правил, концепций, моды, взглядов на то, как надо "писать программы". Все эти правила, концепции, взгляды, мода, наконец, позже назвали в информатике "парадигмами программирования". Вот неполный список парадигм, вместе с датами их появления:

  • 1957г., процедурная парадигма, язык ФОРТРАН, создатель Бэкус;
  • 1967г., функциональная парадигма, язык ЛИСП, создатель Маккарти;
  • 1970г., структурированная парадигма, язык ПАСКАЛЬ, создатель Вирт;
  • 1974г., логическая парадигма, язык ПРОЛОГ;
  • 1983г., объектно-ориентированная парадигма, пример - язык C++, создатель Страуструп.

В конце списка представлены языки программирования и их создатели, внесшие значительный вклад в популяризацию этих парадигм.

В процессе своего развития эти парадигмы "мутировали", "отпочковывались", "объединялись" (так, язык Си объединил в себе процедурную и структурированную парадигму). В результате этих "мутаций" по состоянию на 01.06.2008 года оформились следующие парадигмы программирования:

  1. Процедурная (или модульная) парадигма;
  2. Логическая парадигма;
  3. Объектно-ориентированная парадигма.

Эти три совершенно разные по подходу парадигмы составляют основу современного программирования. Хотя в настоящее время наиболее "модной" является объектно-ориентированная парадигма, остальные парадигмы также используются на практике и изучаются в ВУЗах. Их мы и рассмотрим ниже.

Кроме деления языков программирования по парадигмам, существует также деление языков на "императивные" и "декларативные".

Императивными называются такие языки программирования, в которых описываются в основном "инструкции" по пошаговому выполнению алгоритмов. Все внимание в них отводится лишь реализации этой последовательности действий, а данным и их структуре отводится второстепенная роль. Примером такого рода языков может служить языки создания драйверов устройств: Assembler и C++. При использовании этих языков мы не знаем, какие данные будет отправлять/получать устройство, но зато мы знаем, какие действия нужно осуществить над данными.

Декларативными называются языки программирования, в которых алгоритм работы с данными "зашит" в языке программирования, а сама программа представляет собой данные, упорядоченные и структурированные таким образом, что их легко обрабатывают "стандартные" алгоритмы вывода. В декларативных языках как бы "нет разницы" между данными и алгоритмом, их обрабатывающим. От "значения" данных, подаваемых на вход программы, зависит дальнейшее направление расчетов. Примерами декларативных языков могут служить языки: LISP и Prolog. И программа, и данные на языке ЛИСП представляют собой "списки" вместе с функциями, выполняемыми над ними. На языке ПРОЛОГ есть условное разделение программы на данные ("факты") и код ("правила", "продукции"). Но это разделение достаточно условно: и факты, и правила имеют одну и ту же форму записи.

Декларативные языки лучше всего использовать в случаях, когда "данные управляют программой": при написании экспертных систем, при конструировании трансляторов с языков программирования, для большинства задач искусственного интеллекта. Именно там их использование приведет к наибольшей эффективности.

3.2. Процедурная парадигма

Эта парадигма является самой "древней" и, одновременно, - самой простой в реализации и обучении программирования. На основе этой парадигмы изучаются языки программирования в школе. И поэтому, вполне естественно, автор поставил ее на первое место.

3.2.1. История возникновения парадигмы

"Истоки" процедурной парадигмы программирования лежат в далеких 50-х годах прошлого века. После появления ЭВМ с архитектурой "фон Неймана" появилась возможность компьютеру "самому", без участия человека, проводить сложные вычисления. Эти годы и стали переломными в становлении профессии "программист". Чтобы произвести сложные вычисления, нужно сначала написать сложный алгоритм. Поскольку сложный алгоритм трудно реализовать в ЭВМ так же, как на калькуляторе, появилась необходимость в "записи" алгоритмов на более "понятном" человеку языке, чем язык машинных кодов ЭВМ. Так, вначале появился язык ассемблера, представляющий машинные коды в "удобочитаемом" виде.

В 1957 году Бэкус разработал первый язык высокого уровня: ФОРТРАН. Эта аббревиатура переводится как: "FORmula TRANslator", - переводчик формул. Как следует из его названия, его назначение - это числовые вычисления. С помощью этого языка можно было "кодировать" численные алгоритмы, не вдаваясь в архитектуру ЭВМ, количество регистров в ее процессоре, особенности ее функционирования, и другие, "не важные" для прикладного программиста вопросы. Вскоре, в начале 60-х годов прошлого века, появился язык: "COBOL", - язык, предназначенный для коммерческих вычислений. Аббревиатура "COBOL" расшифровывается как: "COmmon Business Oriented Language" - "язык, ориентированный на общий бизнес".

В реализации этих языков была предусмотрена (как и в ассемблере) возможность "разбивки общего алгоритма" на несколько независимых модулей: "процедур". "Нанизывая" процедуры в основном модуле программы, как гирлянды на нитку, можно получить алгоритмы любой сложности. В этом и состоит преимущество процедурного программирования.

Таким образом, возникла "процедурная парадигма", гласящая:

"Реализацию алгоритмов вычислений необходимо создавать с помощью мелких, не зависимых друг от друга процедур, которые вызывают друг друга в соответствии с логикой программы".

Эта парадигма проста не только в "написании" алгоритма, но и его отладке: нужно убедиться в "работоспособности" каждого из модулей, что намного проще, чем отладка всего алгоритма целиком.

3.2.2. Языки, поддерживающие парадигму

Среди языков, поддерживающих процедурную парадигму программирования, используются следующие языки программирования:

  • Ассемблер;
  • Фортран;
  • Кобол;
  • Алгол;
  • PL 1;
  • Бейсик;
  • Си;
  • Паскаль;
  • Perl;
  • VB Script;
  • Jscript;
  • Multi Edit Macro Script;
  • MS-DOS Command Shell;
  • NDOS Shell;
  • Bash shell;
  • tc shell;
  • REXX;
  • язык SQL-запросов;
  • и др.

Все они поддерживают создание "модулей" - функций и подпрограмм, которые разрабатываются и тестируются независимо, и осуществление "вызовов" между ними.

3.2.3. Представление программ и реализация вычислений

Прежде, чем передать код программы на обработку компилятору, программист должен соответствующим образом оформить код программы. В этом разделе даются общие правила оформления кода программы на разных языках программирования.

3.2.3.1. Quick Basic

В языке Quick Basic есть следующие правила оформления программ:

  1. Программа на языке Quick Basic находится в файле с расширением "*.bas";
  2. Основная программа начинается с первого ее оператора;
  3. Желательно "нумеровать" все строки файла метками - натуральными числами. Нумерацию строк желательно начинать с числа 10 и задать шаг нумерации тоже 10;
  4. Заканчиваться вычисления в программе должны оператором: " STOP ";
  5. Завершаться описание всех алгоритмических конструкций в программе необходимо оператором: " END ";
  6. На каждый оператор выделяется одна строка;
  7. Комментарии к строкам алгоритма должны начинаться отдельной строкой, после ключевого слова: " REM ", которые указываются сразу после метки (или вместо метки);
  8. Подпрограммы на языке: "Quick Basic", оформляются отдельно, внутри файла;
  9. Оформление подпрограмм начинается с ключевого слова: " SUB ", за которым идет имя подпрограммы;
  10. Выполнение программы на языке "Quick Basic", открытой в его оболочке ("qbasic.exe"), начинается после выбора меню: "Run" -> "Continue", или нажатием клавиши: "F5".
3.2.3.2. C/C++

На языке Си и, частично, С++, существуют следующие правила оформления программ:

  1. Программа на языке Си находится в файле с расширением: "*.c", а на языке C++ - с расширением "*.cpp";
  2. Файлы с "заголовочной частью" к основной программе находятся в файлах с расширением "*.h" и "*.hpp";
  3. Основная программа (которая затем будет запускаться по имени файла, например, "myprog.exe"), должна иметь имя и расширение "myprog.c". То есть, в общем случае, имя основного файла проекта - "<имя проекта>.c" (для программ на Си) или "<имя проекта>.cpp" (для программ на языке С++), где <имя проекта> будет соответствовать имени Вашей программы после компиляции;
  4. Файл с программой начинается с включения (в заголовочной части) файлов с расширением "*.h" и "*.hpp", с помощью прагма оператора: " include ". При этом имена заголовочных файлов, находящихся в одном каталоге с файлами-описаниями алгоритма, заключаются в кавычки, а имена файлов, пути к которым прописаны в переменной операционной системы: " INCLUDE ", заключаются между знаками: "<…>", например:
    • #include <stdio.h>
    • #include "myprog.h"
  5. Далее в файле с основной программой задается основная функция алгоритма: " main ", - управляющая вызовом всех остальных функций и подпрограмм.
    Примечание: при программировании на языке Си с использованием библиотеки Windows API основной функцией алгоритма становится функция: WinMain. Подробнее об этой функции смотри [89].
  6. Функция " main " из пункта 5 может возвращать целое значение (тип "int"). Это значение впоследствии используется при запуске функции внутри командного файла оболочки операционной системы, для его реакции на неудачный результат работы этой функции. Принято, что в случае успешного результата своей работы функция " main " возвращает нулевой результат.
  7. Функция " main " может принимать в качестве аргументов следующие формальные параметры:

    main( int argc, char *argv[], char *env[]), где

    • argc - число аргументов у функции. Эта переменная принимает значение 1 в случае отсутствия опций и параметров, 2 в случае присутствия одного параметра и т.п.;
    • *argv[] - массив символьных переменных - указателей на опции и аргументы программы, запускаемой из командной строки. При этом элементу "0" соответствует полное путевое имя файла с запускаемой программой. Элементам с номерами: "1" - "argc-1" соответствуют аргументы программы, набранные в командной строке, с соответствующими номерами (по-порядку);
    • *env[] - массив символьных переменных - указателей на системное окружение операционной системы, в которой запускается скомпилированная программа.
  8. Комментарии на языках: "Си" и "С++" обозначаются следующим образом:
    • Игнорирование конца строки вслед за комментарием: "//" ;
    • Игнорирование текста внутри "скобок" - спецсимволов: "/* … */".
  9. Тексты-описания функций и процедур на языке: "Си" располагаются либо после описания функции " main ", либо в отдельных файлах (с расширениями: "*.C" и "*.CPP" соответственно для функций "Си" и "С++").
  10. В "заголовочных файлах" (с расширением: "*.h" и "*.hpp") задаются, во-первых, директивы компилятору на обработку файлов, во-вторых, макрофункции и макроподстановки, в-третьих, определения констант и глобальных переменных в программе, и, в-четвертых, объявления функций. Формат описания заголовочной части смотри в приложении I к данной лекции и в книге [31].
  11. Перед запуском программы, написанной на языках Си и С++, необходимо сначала "скомпилировать" модули и "построить", скомпоновать (" Build ") проект в IDE (с именем: "<имя проекта>" ), а затем запустить ее, либо набрав в командной строке: <имя проекта>.exe {<опции>}*, либо щелкнув на иконке этой программы (в Windows).

Подробнее о других аспектах программирования на C/C++ смотри: [31, 51, 92,78]

3.2.3.3. Perl

В языке Perl существуют следующие правила оформления программных модулей:

  1. Программа на языке Perl находится в файле с расширением: "*.pl".
  2. Начинаться программа должна с директивы компилятору, имеющей следующий синтаксис:
    #!<путь к интерпретатору Perl> {<опции>}
    Листинг 3.1.

    Например:

    #!/usr/bin/perl
    Листинг 3.2.
    • для интерпретатора perl в UNIX, и
      #!perl -w
      Листинг 3.3.
    • для интерпретатора perl в Windows. Опция -w означает: "включить отладку сценариев"
  3. Основная программа начинается с первого ее оператора, а заканчивается - концом файла или оператором описания функций " sub ".
  4. Комментарии на языке Perl обозначаются как: "#". Все символы, набранные после этого знака, игнорируются интерпретатором.
  5. Описание подпрограмм и функций начинается со слова " sub ", после которого идет блок с операторами. Подпрограмма завершается при выходе из этого блока:
    sub <имя функции> {<тело функции>}
    Листинг 3.4.
  6. Вызов подпрограммы осуществляется следующим образом:
    [<переменная>=] '<имя функции> [(<аргументы>)]
    Листинг 3.5.
    где <переменная> - присвоенное значение-результат работы функции; <имя функции> - имя, зарезервированное в 3.4. Аргументами могут быть строковый литерал либо ссылка:
    <аргументы> ::= {<литерал>|\<имя фактического параметра>}+
    Листинг 3.6.
  7. Объявление процедур осуществляется либо сразу же после основной функции, либо в отдельном файле-библиотеке (расширение - "*.pl") или модуле (расширение - "*.pm"). Подробнее о реализации библиотек и модулей см. [59]. Стандартные же шаблоны оформления модулей и библиотек см. в [приложении App03002].
  8. Доступ к аргументам (как основной программы, так и функций) осуществляется через переменную: " @_ ".
  9. Программа ("макрос", "скрипт") на языке Perl может выдавать целое значение при выходе из нее (с помощью функции: " exit( <целое число> ) "). По "джентльменскому соглашению" программа возвращает "0" в случае своего нормального завершения.
  10. Для запуска макросов в командной строке необходимо набрать:
    perl <полное имя макроса> {<аргументы>}
    Листинг 3.7.
    где <полное имя макроса> - имя программы (с расширением: "*.pl") вместе с его путевым именем; <аргументы> - передаваемые программе аргументы-значения.
Примечание. Если в качестве аргументов используются имена файлов, необходимо указывать их полные путевые имена.
Примечание. В приложении III к данной лекции представлены тексты командных файлов Windows, с помощью которых можно "облегчить" выполнение сценариев на Perl, указывая не абсолютные путевые, а "относительные" имена файлов. Инструкция к ним прилагается.

3.3. Резюме процедурной парадигмы

В данной лекции Вы познакомились с процедурной парадигмой и ее реализациями на языках Quick Basic, Си/C++ и Perl. В приложениях и пунктах для самостоятельной работы Вы легко разберетесь с особенностями программирования на языках оболочек операционных систем: MS-DOS Command Shell и BASH shell Linux. Теперь Вы, по крайней мере, можете записать "шапку" с заголовочной частью для указанных языков программирования и сценариев. Собственно записью конструкций алгоритмов мы займемся в следующей лекции.

3.4. Для самостоятельного изучения

  1. Прочтите разделы из [4, 80-83, 84, 85], посвященные синтаксису и семантике командных файлов MS-DOS;
  2. Прочтите разделы из [80-83], а также онлайновое руководство по Norton Utilities for DOS, посвященные синтаксису и семантике командных файлов NDOS. Для этого Вам, может быть, потребуется установить Norton Utilities 8.0 Rus из архива;
  3. Прочтите разделы из [66] и, у кого есть возможность, справочные файлы к Core Utile bash-shell Linux.
  4. Просмотрите текст, приведенный в приложении к данной лекции.
< Лекция 2 || Лекция 3: 1234 || Лекция 4 >
Юрий Фролов
Юрий Фролов
Украина
Ольга Галанина
Ольга Галанина
Россия