stringtranslate.com

Императивное программирование

В информатике императивное программирование — это парадигма программирования программного обеспечения , в которой используются операторы , изменяющие состояние программы . Во многом так же, как повелительное наклонение в естественных языках выражает команды, повелительное наклонение программы состоит из команд , которые должен выполнить компьютер . Императивное программирование фокусируется на описании того, как программа работает шаг за шагом, [1] , а не на высокоуровневом описании ее ожидаемых результатов.

Этот термин часто используется в отличие от декларативного программирования , которое фокусируется на том, что должна выполнить программа, без указания всех деталей того, как программа должна достичь результата. [2]

Процедурное программирование

Процедурное программирование — это тип императивного программирования, при котором программа состоит из одной или нескольких процедур (также называемых подпрограммами или функциями). Эти термины часто используются как синонимы, но использование процедур оказывает существенное влияние на то, как выглядят императивные программы и как они создаются. Тяжелое процедурное программирование, в котором изменения состояния локализуются в процедурах или ограничиваются явными аргументами и возвратами процедур, является формой структурного программирования . С 1960-х годов структурное программирование и модульное программирование в целом пропагандировались как методы улучшения удобства сопровождения и общего качества императивных программ. Концепции объектно-ориентированного программирования пытаются расширить этот подход.

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

Обоснование и основы императивного программирования

Парадигма программирования, используемая для создания программ почти для всех компьютеров, обычно соответствует императивной модели. [примечание 1] Цифровое компьютерное оборудование предназначено для выполнения машинного кода , который является собственным для компьютера и обычно пишется в императивном стиле, хотя для некоторых архитектур, таких как Lisp-машины, существуют низкоуровневые компиляторы и интерпретаторы, использующие другие парадигмы .

С этой низкоуровневой точки зрения состояние программы определяется содержимым памяти, а операторы представляют собой инструкции на родном машинном языке компьютера. Императивные языки более высокого уровня используют переменные и более сложные операторы, но по-прежнему следуют той же парадигме. Рецепты и контрольные списки процессов , хотя и не являются компьютерными программами , также представляют собой знакомые концепции, по стилю схожие с императивным программированием; каждый шаг — это инструкция, и физический мир сохраняет это состояние. Поскольку основные идеи императивного программирования концептуально знакомы и непосредственно воплощены в аппаратном обеспечении, большинство компьютерных языков относятся к императивному стилю.

Операторы присваивания в императивной парадигме выполняют операцию над информацией, расположенной в памяти, и сохраняют результаты в памяти для последующего использования. Кроме того, императивные языки высокого уровня позволяют вычислять сложные выражения , которые могут состоять из комбинации арифметических операций и оценок функций , а также присваивать полученное значение памяти. Операторы цикла (например, циклы while , do while и for ) позволяют выполнять последовательность операторов несколько раз. Циклы могут либо выполнять содержащиеся в них операторы заранее определенное количество раз, либо выполнять их повторно, пока не будет выполнено какое-либо условие. Операторы условного ветвления позволяют выполнять последовательность операторов только при выполнении некоторого условия. В противном случае операторы пропускаются, и последовательность выполнения продолжается с следующего за ними оператора. Операторы безусловного ветвления позволяют перенести последовательность выполнения в другую часть программы. К ним относятся переход (называемый goto во многих языках), переключатель и вызов подпрограммы, подпрограммы или процедуры (который обычно возвращается к следующему оператору после вызова).

На раннем этапе разработки языков программирования высокого уровня введение блока позволило создавать программы, в которых группу операторов и объявлений можно было рассматривать как один оператор. Это, наряду с введением подпрограмм , позволило выражать сложные структуры путем иерархической декомпозиции в более простые процедурные структуры.

Многие императивные языки программирования (такие как Fortran , BASIC и C ) являются абстракциями языка ассемблера . [3]

История императивных и объектно-ориентированных языков

Самыми ранними императивными языками были машинные языки первых компьютеров. Инструкции на этих языках были очень простыми, что упрощало аппаратную реализацию, но затрудняло создание сложных программ. FORTRAN , разработанный Джоном Бэкусом в International Business Machines (IBM) начиная с 1954 года, был первым крупным языком программирования, устранившим препятствия, создаваемые машинным кодом при создании сложных программ. ФОРТРАН был компилируемым языком , который допускал именованные переменные, сложные выражения, подпрограммы и многие другие функции, которые сейчас распространены в императивных языках. В следующие два десятилетия появилось множество других крупных императивных языков программирования высокого уровня. В конце 1950-х и 1960-х годах АЛГОЛ был разработан для облегчения выражения математических алгоритмов и даже служил целевым языком операционной системы для некоторых компьютеров. MUMPS (1966) довел императивную парадигму до логического предела, вообще не имея никаких операторов, полагаясь исключительно на команды, вплоть до того, что команды IF и ELSE стали независимыми друг от друга, связанными только внутренней переменной с именем $. ТЕСТ. COBOL (1960) и BASIC (1964) были попытками сделать синтаксис программирования более похожим на английский. В 1970-х годах Pascal был разработан Никлаусом Виртом , а C был создан Деннисом Ритчи , когда он работал в Bell Laboratories . Вирт продолжил разработку Модулы-2 и Оберона . Для нужд Министерства обороны США Джин Ичбиа и команда Honeywell начали разработку Ada в 1978 году , после 4-летнего проекта по определению требований к языку. Спецификация была впервые опубликована в 1983 году с изменениями в 1995, 2005 и 2012 годах.

В 1980-е годы наблюдался быстрый рост интереса к объектно-ориентированному программированию . Эти языки были императивными по стилю, но добавляли возможности для поддержки объектов . За последние два десятилетия 20-го века появилось множество таких языков. Smalltalk -80, первоначально задуманный Аланом Кеем в 1969 году, был выпущен в 1980 году Исследовательским центром Xerox в Пало-Альто ( PARC ). Опираясь на концепции другого объектно-ориентированного языка — Simula (который считается первым в мире объектно-ориентированным языком программирования , разработанным в 1960-х годах), — Бьёрн Страуструп разработал C++ , объектно-ориентированный язык, основанный на C. Разработка C++ началась в 1979 году, а первая реализация была завершена в 1983 году. В конце 1980-х и 1990-х годах известными императивными языками, основанными на объектно-ориентированных концепциях, были Perl , выпущенный Ларри Уоллом в 1987 году; Python , выпущенный Гвидо ван Россумом в 1990 году; Visual Basic и Visual C++ (включая Microsoft Foundation Class Library (MFC) 2.0), выпущенные Microsoft в 1991 и 1993 годах соответственно; PHP , выпущенный Расмусом Лердорфом в 1994 году; Java от Джеймса Гослинга ( Sun Microsystems ) в 1995 году, JavaScript от Брендана Эйха ( Netscape ) и Ruby от Юкихиро «Маца» Мацумото, оба выпущенные в 1995 году. Microsoft .NET Framework (2002) по своей сути является императивной, поскольку являются его основными целевыми языками: VB.NET и C# , которые на нем работают; однако функциональный язык Microsoft F# также работает на нем.

Примеры

Фортран

ФОРТРАН (1958 г.) был представлен как «Система ПЕРЕВОДА математических формул IBM». Он был разработан для научных расчетов без средств для работы со струнами . Наряду с объявлениями , выражениями и операторами он поддерживал:

Это удалось, потому что:

Однако поставщики, не принадлежащие IBM, также написали компиляторы Fortran, но с синтаксисом, который, скорее всего, не сработает с компилятором IBM. [4] Американский национальный институт стандартов (ANSI) разработал первый стандарт Фортрана в 1966 году. В 1978 году Фортран 77 стал стандартом до 1991 года. Фортран 90 поддерживает:

КОБОЛ

COBOL (1959) означает «Общий бизнес-ориентированный язык». Фортран манипулировал символами. Вскоре стало понятно, что символы не обязательно должны быть числами, поэтому были введены строки. [5] На разработку COBOL повлияло Министерство обороны США, при этом Грейс Хоппер внесла основной вклад. Заявления были английскими и многословными. Целью было разработать язык, на котором менеджеры могли бы читать программы. Однако отсутствие структурированных заявлений помешало достижению этой цели. [6]

Развитие COBOL строго контролировалось, поэтому не возникло диалектов, требующих стандартов ANSI. Как следствие, он не менялся в течение 15 лет до 1974 года. Версия 1990-х годов действительно внесла существенные изменения, такие как объектно-ориентированное программирование . [6]

Алголь

АЛГОЛ (1960) означает «АЛГОРИТМИЧЕСКИЙ ЯЗЫК». Это оказало глубокое влияние на дизайн языков программирования. [7] Разработанный комитетом европейских и американских экспертов по языкам программирования, он использовал стандартные математические обозначения и имел удобочитаемый структурированный дизайн. Алгол был первым, кто определил свой синтаксис , используя форму Бэкуса-Наура . [7] Это привело к появлению компиляторов , управляемых синтаксисом . Он добавил такие функции, как:

Прямые потомки Алгола включают Паскаль , Модулу-2 , Аду , Дельфи и Оберон на одной ветке. В другой ветке есть C , C++ и Java . [7]

Базовый

BASIC (1964) означает «Универсальный код символических инструкций для начинающих». Он был разработан в Дартмутском колледже для обучения всех его студентов. [8] Если бы ученик не перешел на более мощный язык, он все равно помнил бы Бейсик. [8] Интерпретатор Basic устанавливался в микрокомпьютеры , выпущенные в конце 1970-х годов. По мере роста индустрии микрокомпьютеров рос и язык. [8]

Компания Basic стала пионером интерактивных сеансов . [8] Он предлагал команды операционной системы в своей среде:

Однако синтаксис Basic был слишком простым для больших программ. [8] В последних диалектах добавлена ​​структура и объектно-ориентированные расширения. Microsoft Visual Basic до сих пор широко используется и обеспечивает графический интерфейс пользователя . [9]

С

Язык программирования C (1973 г.) получил свое название потому, что язык BCPL был заменен на B , а компания AT&T Bell Labs назвала следующую версию «C». Его целью было написать операционную систему UNIX . [10] C — относительно небольшой язык, поэтому на нем легко писать компиляторы. Его рост отражал рост аппаратного обеспечения в 1980-х годах. [10] Его рост также обусловлен тем, что он имеет возможности языка ассемблера , но использует синтаксис высокого уровня . В него добавлены расширенные функции, такие как:

Карта памяти компьютера

C позволяет программисту контролировать, в какой области памяти должны храниться данные. Для хранения глобальных переменных и статических переменных требуется наименьшее количество тактов . Стек автоматически используется для стандартных объявлений переменных . Куча памяти возвращается в переменную-указатель из malloc()функции.

  • Область глобальных и статических данных технически представляет собой две области. [11] Одна область называется сегментом инициализированных данных , где хранятся переменные, объявленные со значениями по умолчанию. Другая область называется блоком, начатым сегментом , где хранятся переменные, объявленные без значений по умолчанию.
  • Адреса переменных, хранящихся в глобальной и статической области данных , устанавливаются во время компиляции. Они сохраняют свои значения на протяжении всего процесса.
  • Глобальная и статическая область хранят глобальные переменные , объявленные поверх (вне) функции main(). [12] Глобальные переменные видны main()всем остальным функциям исходного кода.
С другой стороны, объявления переменных внутри main(), других функций или внутри { } разделителей блоков являются локальными переменными . Локальные переменные также включают переменные формальных параметров . Переменные параметров заключаются в круглые скобки определений функций. [13] Они обеспечивают интерфейс для функции.
  • Локальные переменные , объявленные с использованием staticпрефикса, также хранятся в глобальной и статической области данных. [11] В отличие от глобальных переменных, статические переменные видны только внутри функции или блока. Статические переменные всегда сохраняют свое значение. Примером использования может быть функцияint increment_counter(){ static int counter = 0; counter++; return counter;}
  • Локальные переменные , объявленные без staticпрефикса, включая переменные формальных параметров, [15] называются автоматическими переменными [12] и сохраняются в стеке. [11] Они видны внутри функции или блока и теряют свою область действия при выходе из функции или блока.
  • C предоставляет malloc()библиотечную функцию для выделения динамической памяти. [17] Заполнение кучи данными — это дополнительная функция копирования. Переменные, хранящиеся в куче, экономично передаются функциям с помощью указателей. Без указателей весь блок данных пришлось бы передавать в функцию через стек.

С++

В 1970-х годах инженерам-программистам требовалась языковая поддержка, чтобы разбивать большие проекты на модули . [18] Одной из очевидных особенностей было физическое разложение больших проектов на отдельные файлы . Менее очевидной особенностью было логическое разложение больших проектов на абстрактные типы данных . [18] В то время языки поддерживали конкретные ( скалярные ) типы данных, такие как целые числа, числа с плавающей запятой и строки символов . Конкретные типы данных имеют представление как часть своего имени. [19] Абстрактные типы данных представляют собой структуры конкретных типов данных с присвоенным новым именем. Например, список целых чисел можно назвать .integer_list

На объектно-ориентированном жаргоне абстрактные типы данных называются классами . Однако класс — это всего лишь определение; память не выделяется. Когда память выделяется классу, она называется объектом . [20]

Объектно-ориентированные императивные языки , разработанные путем объединения потребности в классах и необходимости безопасного функционального программирования . [21] В объектно-ориентированном языке функция присваивается классу. Назначенная функция тогда называется методом , функцией -членом или операцией . Объектно-ориентированное программирование — это выполнение операций над объектами . [22]

Объектно-ориентированные языки поддерживают синтаксис для моделирования отношений подмножества/надмножества . В теории множеств элемент подмножества наследует все атрибуты, содержащиеся в надмножестве . Например, студент – это человек. Следовательно, множество студентов является подмножеством множества людей. В результате студенты наследуют все признаки, общие для всех людей. Кроме того, студенты обладают уникальными качествами, которых нет у других людей. Объектно-ориентированные языки моделируют отношения подмножества/надмножества с помощью наследования . [23] Объектно-ориентированное программирование стало доминирующей языковой парадигмой к концу 1990-х годов. [18]

C++ (1985) первоначально назывался «C с классами». [24] Он был разработан для расширения возможностей C за счет добавления объектно-ориентированных средств языка Simula . [25]

Объектно-ориентированный модуль состоит из двух файлов. Файл определений называется файлом заголовка . Вот заголовочный файл C++ для класса GRADE в простом школьном приложении:

// оценка.h // -------// Используется, чтобы позволить нескольким исходным файлам включать // этот файл заголовка без ошибок дублирования. // См.: https://en.wikipedia.org/wiki/Imperative_programming/Include_guard // ------------------------------- --------------- #ifndef GRADE_H #define GRADE_Hclass GRADE { public : // Это операция конструктора. // ---------------------------------- GRADE ( const char Letter );           // Это переменная класса. // ------------------------- char Letter ;    // Это операция-член. // --------------------------- intgrade_numeric ( const char Letter ) ;        // Это переменная класса. // ------------------------- int numeric ; }; #endif   

Операция конструктора — это функция с тем же именем, что и имя класса. [26] Он выполняется, когда вызывающая операция выполняет newоператор.

Другой файл модуля — это исходный файл . Вот исходный файл C++ для класса GRADE в простом школьном приложении:

//grade.cpp // --------- #include "grade.h" GRADE :: GRADE ( const char Letter ) { // Ссылаемся на объект, используя ключевое слово 'this'. // ---------------------------------------------- этот - > буква = буква ;          // Это временная сплоченность // ------------------------- this -> numeric = Grade_numeric ( Letter ); }      int GRADE :: Grade_numeric ( const char Letter ) { if ( ( Letter == 'A' || Letter == 'a' ) ) return 4 ; else if ( ( буква == 'B' || буква == 'b' ) ) return 3 ; else if ( ( буква == 'C' || буква == 'c' ) ) return 2 ; else if ( ( буква == 'D' || буква == 'd' ) ) return 1 ; else if ( ( буква == 'F' || буква == 'f' ) ) return 0 ; иначе вернуть -1 ; }                                                                                  

Вот заголовочный файл C++ для класса PERSON в простом школьном приложении:

// person.h // -------- #ifndef PERSON_H #define PERSON_Hкласс PERSON { public : PERSON ( const char * name ); константный символ * имя ; }; #endif           

Вот исходный файл C++ для класса PERSON в простом школьном приложении:

// person.cpp // ---------- #include "person.h" ЧЕЛОВЕК :: ЧЕЛОВЕК ( const char * name ) { this -> name = name ; }        

Вот заголовочный файл C++ для класса STUDENT в простом школьном приложении:

// Student.h // --------- #ifndef STUDENT_H #define STUDENT_H#include "person.h" #include "grade.h"  // СТУДЕНТ — это подмножество ЧЕЛОВЕКА. // -------------------------------- класс STUDENT : public PERSON { public : STUDENT ( const char * name ); ~ СТУДЕНТ (); ОЦЕНКА * оценка ; }; #endif             

Вот исходный файл C++ для класса STUDENT в простом школьном приложении:

// Student.cpp // ----------- #include "student.h" #include "person.h"  STUDENT :: STUDENT ( const char * name ) : // Выполняем конструктор суперкласса PERSON. // ---------------------------------------------------------------- - ЧЕЛОВЕК ( имя ) { // Больше нечего делать. // ------------------- }            STUDENT ::~ STUDENT () { // освобождаем память оценки // во избежание утечек памяти. // ---------------------------------------------------------------- - удалить это -> оценка ; }      

Вот программа-драйвер для демонстрации:

// Student_dvr.cpp // --------------- #include <iostream> #include "student.h"  int main ( void ) { СТУДЕНТ * студент = новый СТУДЕНТ ( «Студент» ); студент -> оценка = новая GRADE ( 'a' );                 std :: cout // Обратите внимание, что студент наследует имя ЧЕЛОВЕКА << студент -> имя << ": Числовая оценка = " << студент -> оценка -> числовая << " \n " ;           // освобождаем память студента // чтобы избежать утечек памяти. // ---------------------------------------------------------------- - удалить студента ;    вернуть 0 ; } 

Вот make-файл для компиляции всего:

# makefile # -------- все : Student_dvr очистить :  rm  Student_dvr  *.oстудент_двр : студент_двр . уровень cpp . о студент . о человек . o c++ Student_dvr.cpp Grade.o Student.o Person.o -o Student_dvr           Grade.o : Оценка . уровень cpp . ч С++ -c ранг.cpp     студент.о : студент . студент ЦПП . ч С++ -c студент.cpp     person.o : человек . cpp человек . ч С++ -c person.cpp     

Смотрите также

Примечания

  1. ^ Реконфигурируемые вычисления являются заметным исключением.

Рекомендации

  1. ^ Джайн, Аниша (10 декабря 2022 г.). «Обещания Javascript — есть ли лучший подход?». Середина . Проверено 20 декабря 2022 г.
  2. ^ «Императивное программирование: обзор старейшей парадигмы программирования». Цифровой гид IONOS . 21 мая 2021 г. Проверено 3 мая 2022 г.
  3. ^ Брюс Экель (2006). Думаем на Java. Образование Пирсона . п. 24. ISBN 978-0-13-187248-6.
  4. ^ Аб Уилсон, Лесли Б. (2001). Языки сравнительного программирования, третье издание . Аддисон-Уэсли. п. 16. ISBN 0-201-71012-9.
  5. ^ Уилсон, Лесли Б. (2001). Языки сравнительного программирования, третье издание . Аддисон-Уэсли. п. 24. ISBN 0-201-71012-9.
  6. ^ Аб Уилсон, Лесли Б. (2001). Языки сравнительного программирования, третье издание . Аддисон-Уэсли. п. 25. ISBN 0-201-71012-9.
  7. ^ abcd Wilson, Лесли Б. (2001). Языки сравнительного программирования, третье издание . Аддисон-Уэсли. п. 19. ISBN 0-201-71012-9.
  8. ^ abcde Wilson, Лесли Б. (2001). Языки сравнительного программирования, третье издание . Аддисон-Уэсли. п. 30. ISBN 0-201-71012-9.
  9. ^ Уилсон, Лесли Б. (2001). Языки сравнительного программирования, третье издание . Аддисон-Уэсли. п. 31. ISBN 0-201-71012-9.
  10. ^ abc Wilson, Лесли Б. (2001). Языки сравнительного программирования, третье издание . Аддисон-Уэсли. п. 37. ИСБН 0-201-71012-9.
  11. ^ abcd «Схема памяти программ на C». 12 сентября 2011 г.
  12. ^ аб Керниган, Брайан В.; Ричи, Деннис М. (1988). Язык программирования C, второе издание . Прентис Холл. п. 31. ISBN 0-13-110362-8.
  13. ^ Уилсон, Лесли Б. (2001). Языки сравнительного программирования, третье издание . Аддисон-Уэсли. п. 128. ИСБН 0-201-71012-9.
  14. ^ abc Керриск, Майкл (2010). Программный интерфейс Linux . Нет крахмального пресса. п. 121. ИСБН 978-1-59327-220-3.
  15. ^ Керриск, Майкл (2010). Программный интерфейс Linux . Нет крахмального пресса. п. 122. ИСБН 978-1-59327-220-3.
  16. ^ Керниган, Брайан В.; Ричи, Деннис М. (1988). Язык программирования C, второе издание . Прентис Холл. п. 185. ИСБН 0-13-110362-8.
  17. ^ Керниган, Брайан В.; Ричи, Деннис М. (1988). Язык программирования C, второе издание . Прентис Холл. п. 187. ИСБН 0-13-110362-8.
  18. ^ abc Wilson, Лесли Б. (2001). Языки сравнительного программирования, третье издание . Аддисон-Уэсли. п. 38. ISBN 0-201-71012-9.
  19. ^ Страуструп, Бьярн (2013). Язык программирования C++, четвертое издание . Аддисон-Уэсли. п. 65. ИСБН 978-0-321-56384-2.
  20. ^ Уилсон, Лесли Б. (2001). Языки сравнительного программирования, третье издание . Аддисон-Уэсли. п. 193. ИСБН 0-201-71012-9.
  21. ^ Уилсон, Лесли Б. (2001). Языки сравнительного программирования, третье издание . Аддисон-Уэсли. п. 39. ИСБН 0-201-71012-9.
  22. ^ Уилсон, Лесли Б. (2001). Языки сравнительного программирования, третье издание . Аддисон-Уэсли. п. 35. ISBN 0-201-71012-9.
  23. ^ Уилсон, Лесли Б. (2001). Языки сравнительного программирования, третье издание . Аддисон-Уэсли. п. 192. ИСБН 0-201-71012-9.
  24. ^ Страуструп, Бьярн (2013). Язык программирования C++, четвертое издание . Аддисон-Уэсли. п. 22. ISBN 978-0-321-56384-2.
  25. ^ Страуструп, Бьярн (2013). Язык программирования C++, четвертое издание . Аддисон-Уэсли. п. 21. ISBN 978-0-321-56384-2.
  26. ^ Страуструп, Бьярн (2013). Язык программирования C++, четвертое издание . Аддисон-Уэсли. п. 49. ИСБН 978-0-321-56384-2.
Первоначально основано на статье Стэна Зайберта «Императивное программирование» из Nupedia , под лицензией GNU Free Documentation License .