Автор Анна Евкова
Преподаватель который помогает студентам и школьникам в учёбе.

Современные языки программирования ( Стандартизация языков программирования )

Содержание:

Введение

Связь между языком, на котором мы думаем, программируем, и задачами и решениями, которые можно представлять в своем воображении, очень тесна. Язык дет программисту набор концептуальных инструментов, если они не отвечают задаче, то их просто игнорируют. Грамотное проектирование и отсутствие ошибок не может гарантироваться чисто за счет языковых средств. На данный момент большинство программ создаются с помощью языков программирования.

Неотъемлемая часть современных ЭВМ – системы программного обеспечения, которые являются логическим продолжением логических средств ЭВМ, расширяющим возможности аппаратуры и область их применения. Основное назначение программного обеспечения – повышение эффективности труда пользователя, а также повышение пропускной способности ЭВМ путем сокращения времени и затрат на подготовку и выполнение программ.

В своей работе мне хотелось бы разобрать несколько основных современных языков, а именно C, C++, Java, Python, а также системы программирования и их составляющие.

Сложно поспорить с тем, что рынок программного обеспечения не стоит на месте. Однако, судя по всему, языки программирования этот факт не слишком заботит. Сравнивая ТОП-10 текущего индекса TIOBE с рейтингом 10-ти летней давности, можно отметить, что он почти не изменился.

Судя по тому, какую динамику роста популярности занял язык программирования Java в 2015 году, другим языкам программирования будет довольно сложно посоперничать с ним в ближайшем будущем. В 2015 году в общем рейтинге он прибавил почти 6%, заняв почти 22% рынка.

Меньший интерес разработчики проявляли к С и С++. Их доля на рынке составила 16% и 7% соответственно. Четвертую позицию данного рейтинга занял C# с долей рынка менее 5%.

Говоря об остальных языках программирования, представленных в рейтинге, стоит отметить, что приличную динамику роста в 2015 году продемонстрировали Python, VisualBasic .NET и Delphi.

Глава 1. Основы программирования

1.1 Стандартизация языков программирования

Концепция языка программирования неотрывно связана с его реализацией. Для того чтобы компиляция одной и той же программы различными компиляторами всегда давала одинаковый результат, разрабатываются стандарты языков программирования. Существует ряд организаций, которые целенаправленно занимаются вопросами стандартизации. Это Американский национальный институт стандартов ANSI (American National Standards Institute), Институт инженеров по электротехнике и электронике IEEE (Institute of Electrical and Electronic Engineers), Организация международных стандартов ISO (International Organization for Standardization).

При создании языка, как правило, выпускается частный стандарт, определяемый разработчиками языка. Если язык получает широкое распространение, то со временем появляются различные версии компиляторов, которые не точно следуют частному стандарту. В большинстве случаев идет расширение зафиксированных первоначально возможностей языка. Для приведения наиболее популярных реализаций языка в соответствие друг с другом разрабатывается согласительный стандарт. Очень важным фактором стандартизации языка программирования является своевременность появления стандарта – до широкого распространения языка и создания множества несовместимых реализаций. В процессе развития языка могут появляться новые стандарты, отражающие современные нововведения. Так, язык FORTRAN первоначально был стандартизирован в 1966 году. В результате был издан стандарт FORTRAN 66. Далее этот стандарт несколько раз пересматривался (в 1977 году был выпущен FORTRAN 77, затем появился и FORTRAN 90).

Язык Java, ставший в последнее время весьма распространенным, постепенно был значительно расширен и модифицирован: новая спецификация получила название Java 2.

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

1.2 Типы данных

Тип данных — фундаментальное понятие теории программирования. Тип данных определяет множество значений, набор операций, которые можно применять к таким значениям и, возможно, способ реализации хранения значений и выполнения операций. Любые данные, которыми оперируют программы, относятся к определённым типам.

Тип (сорт) — относительно устойчивая и независимая совокупность элементов, которую можно выделить во всём рассматриваемом множестве (предметной области).

Полиморфный тип — представление набора типов как единственного типа.

Математически тип может быть определён двумя способами:

- Множеством всех значений, принадлежащим типу.

- Предикатной функцией, определяющей принадлежность объекта к данному типу

Типы данных различаются начиная с нижних уровней системы. Так, например, даже в Ассемблере х86 различаются типы «целое число» и «вещественное число». Это объясняется тем, что для чисел рассматриваемых типов отводятся различные объёмы памяти, используются различные регистры микропроцессора, а для операций с ними применяются различные команды Ассемблера и различные ядра микропроцессора.

Концепция типа данных появилась в языках программирования высокого уровня как естественное отражение того факта, что обрабатываемые программой данные могут иметь различные множества допустимых значений, храниться в памяти компьютера различным образом, занимать различные объёмы памяти и обрабатываться с помощью различных команд процессора.

Ниже перечислены языки программирования по способу определения типов данных:

1) Языки с полиморфным типом данных: одни языки не связывают переменные, константы, формальные параметры и возвращаемые значения функций с определёнными типами, поддерживая единственный полиморфный тип данных. В чистом виде таких языков не встречается, но близкие примеры — MS Visual Basic — тип variant, Пролог, Лисп — списки. В этих языках переменная может принимать значение любого типа, в параметры функции можно передавать значения любых типов, и вернуть функция также может значение любого типа. Сопоставление типов значений переменных и параметров с применяемыми к ним операциями производится непосредственно при выполнении этих операций. Например, выражение a+b, может трактоваться как сложение чисел, если a и b имеют числовые значения, как конкатенация строк, если a и b имеют строковые значения, и как недопустимая (ошибочная) операция, если типы значений a и b несовместимы. Такой порядок называют «динамической типизацией» (соответствует понятиюполиморфизм в ООП, полиморфный тип в теории типов). Языки, поддерживающие только динамическую типизацию, называют иногда «бестиповыми». Это название не следует понимать как признак отсутствия понятия типов в языке — типы данных всё равно есть.

2) Языки с неявным определением типов: казалось бы, BASIC является примером языка без типов. Однако это строго типизированый язык: в нём различаются строковые типы (добавляется символ $), массивы (добавляется []) и числовые типы (ничего не добавляется).

3) Языки с типом, определяемым пользователем: также хорошо известны языки, в которых типы данных определяются автоматически, а не задаются пользователем. Каждой переменной, параметру, функции приписывается определённый тип данных. В этом случае для любого выражения возможность его выполнения и тип полученного значения могут быть определены без исполнения программы. Такой подход называют «статической типизацией». При этом правила обращения с переменными, выражениями и параметрами разных типов могут быть как очень строгими (С++), так и весьма либеральными (Си). Например, в классическом языке Си практически все типы данных совместимы — их можно применять совместно в любых выражениях, присваивать значение переменной одного типа переменной другого почти без ограничений. При таких операциях компилятор генерирует код, обеспечивающий преобразование типов, а логическая корректность такого преобразования остаётся на совести программиста. Подобные языки называют «языками со слабой типизацией». Противоположность им — «языки с сильной типизацией», такие как Ада. В них каждая операция требует операндов строго заданных типов. Никакие автоматические преобразования типов не поддерживаются — их можно выполнить только явно, с помощью соответствующих функций и операций. Сильная типизация делает процесс программирования более сложным, но даёт в результате программы, содержащие заметно меньше трудно обнаруживаемых ошибок.

На практике языки программирования поддерживают несколько моделей определения типов одновременно.

1.3 Структуры данных

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

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

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

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

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

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

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

В зависимости от отсутствия или наличия явно заданных связей между элементами данных следует различать несвязные структуры (векторы, массивы, строки, стеки, очереди) и связные структуры (связные списки).

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

Классификация структур данных:

Важный признак структуры данных - характер упорядоченности ее элементов. По этому признаку структуры можно делить на линейные и нелинейные структуры.

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

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

Информация по каждому типу однозначно определяет :

1) структуру хранения данных указанного типа, т.е. выделение памяти и представление данных в ней, с одной стороны, и интерпретирование двоичного представления, с другой;

2) множество допустимых значений, которые может иметь тот или иной объект описываемого типа;

3) множество допустимых операций, которые применимы к объекту описываемого типа.

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

1.4. Семантика языков программирования

Один из путей исследования взглядов на мир, навязываемых языками программирования, — это изучение семантики (смысла) языковых конструкций. Программирование при помощи конструкций некоторого языка требует мышления в терминах семантики этих конструкций. Таким образом, семантика служит ключом к пониманию процесса мышления программиста. Языки программирования можно разбить на три широкие категории в соответствии с природой семантики этих языков: 1) процедурные языки, 2) функциональные языки и 3) реляционные языки. Смысл конструкции процедурного языка определяется в терминах поведения компьютера при выполнении этой конструкции. Поведение может быть либо внешним (например, вывод сообщения на терминал), либо внутренним (например, изменение значения переменной). Смысл конструкции в функциональном языке (например, вызова функции) определяется в терминах значения, которое она вырабатывает. Вызов функции можно рассматривать как объявление вырабатываемого ею значения. Смысл конструкции в реляционном языке определяется как отношение между отдельными сущностями или классами сущностей. С декларативной точки зрения реляционную конструкцию можно интерпретировать как формулировку того, что существует отношение между аргументами, представленное именем этого отношения.

Уровень языка. Предположим далее, что программист, приступающий к написанию программы, располагает логической спецификацией, в которой четко описана подлежащая решению задача или структура системы, которую необходимо представить. Это предположение позволяет провести классификацию взглядов на мир, навязываемых языками программирования, в соответствии с уровнем языка по отношению к заданной спецификации. Язык низкого уровня дает картину мира, близкую к взгляду на мир с позиций компьютера. Язык высокого уровня обеспечивает взгляд на мир, приближающийся к картине мира, представленной в спецификации задачи. Согласно этому критерию процедурные языки относятся к языкам низкого уровня. В соответствии с семантикой конструкций процедурного языка программист должен мыслить в терминах конструкций, определяющих поведение компьютера. При использовании процедурного языка требуется проведение большой работы по переводу спецификации сложной системы в работоспособную программу. Функциональные языки имеют более высокий уровень, чем процедурные, поскольку программист может мыслить в терминах вычисления значений, а не поведения ЭВМ. Сами же значения нередко являются частью спецификации. Реляционные языки имеют наивысший уровень, так как семантика конструкций реляционного языка весьма близка к спецификации задачи. Взгляд на мир для идеального реляционного языка будет таким же, как и взгляд на мир с позиций логической спецификации, поэтому для преобразования одного в другое понадобятся минимальные усилия. При использовании идеального реляционного языка становится возможным написание программы, структурно изоморфной по отношению к своей спецификации, т. е. для каждой вариации формы спецификации будет существовать соответствующая вариация формы программы.

Глава 2. Классификация языков программирования

2.1. Процедурные языки программирования

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

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

2.2. Язык программирования Си

2.2.1. Описание

Язык Си – это универсальный язык программирования, для которого характерны экономичность выражения, современный набор операторов и типов данных. Язык Си не является ни языком "очень высокого уровня", ни "большим" языком, и не предназначается для некоторой специальной области применения, но отсутствие ограничений и общность языка делают его для многих задач более удобным и эффективным, чем языки, предположительно более мощные. Операционная система, компилятор с языка Си и по существу все прикладные программы системы "ДЕМОС" написаны на Си. Язык Си не связан с какими-либо определенными аппаратными средствами или системами, и на нем легко писать программы, которые можно пропускать без изменений на любой ЭВМ, имеющей Си-компилятор.

Язык Си является универсальным языком программирования. Он первоначально появился в операционной системе UNIX, и развивался как основной язык систем, совместимых с ОС UNIX. Сам язык, однако, не связан с какой-либо одной операционной системой или машиной; и хотя его называют языком системного программирования, так как он удобен для написания операционных систем, он может использоваться для написания любых больших вычислительных программ, программ для обработки текстов и баз данных.

Язык Си - это язык относительно "низкого уровня". Это означает, что Си имеет дело с объектами того же вида, что и большинство ЭВМ, а именно, с символами, числами и адресами. Они могут объединяться и пересылаться посредством обычных арифметических и логических операций, осуществляемых реальными ЭВМ.

В языке Си отсутствуют операции, имеющие дело непосредственно с составными объектами, такими как строки символов, множества, списки или с массивами, рассматриваемыми как целое. Здесь, например, нет никакого аналога операциям PL/1, оперирующим с массивами и строками. Язык не предоставляет никаких других возможностей распределения памяти, кроме статического определения и механизма стеков, обеспечиваемого локальными переменных функций. Сам по себе язык Си не обеспечивает никаких возможностей ввода-вывода. Все эти механизмы высокого уровня должны обеспечиваться явно вызываемыми функциями.

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

Удержание языка в скромных размерах дает реальные преимущества. Так как Си относительно мал, он не требует много места для своего описания и может быть быстро выучен.

Компилятор с Си может быть простым и компактным. Это обеспечивает высокую степень мобильности языка. Поскольку типы

данных и структуры управления, имеющиеся в Си, непосредственно поддерживаются большинством существующих ЭВМ, библиотека, необходимая во время прогона изолированных программ,

оказывается очень маленькой. На СМ-4, например , она содержит только программы для 32-битового умножения и деления и

для упрятывания и восстановления регистров при входе в функцию. Конечно, каждая реализация обеспечивает исчерпывающую,

совместимую библиотеку функций для выполнения операций

ввода-вывода, обработки строк и распределения памяти, но так

как обращение к ним осуществляется только явно, можно, если

необходимо, избежать их вызова; эти функции могут быть компактно написаны на самом Си.

Опять же из-за того, что язык Си отражает возможности

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

вместо этого программы на языке ассемблера. Хотя Си соответствует возможностям многих ЭВМ, он не зависит от какой-либо конкретной архитектуры машины и в силу этого без особых

усилий позволяет писать "переносимые" программы, т.е. программы, которые можно пропускать без изменений на различных

аппаратных средствах.

Язык Си не является языком со строгими типами данных в смысле Паскаля или Алгола-68. Он сравнительно снисходителен

к преобразованию данных, хотя и не будет буйно преобразовывать типы данных подобно языку PL/1. Компилятор не предусматривает никакой проверки индексов массивов, типов аргументов и т.д. во время выполнения программы.

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

Из-за того, что в языке отсутствуют средства ввода/вывода и т.п., при программировании на нем существенную роль играет библиотека стандартных программ, осуществляющих взаимодействие с системой. Во всех системах, совместимых с ОС UNIX, к которым относится и ДЕМОС, существует совместимый набор программ для ввода/вывода, управления памятью, преобразования данных и выполняющих другие функции, использование которых обеспечивает возможность переноса программ на другие ЭВМ.

2.3. Объектно-ориентированные языки программирования

Исторически сложилось так, что программирование возникло и развивалось как процедурное программирование, которое предполагает, что основой программы является алгоритм, процедура обработки данных. Объектно-ориентированное программирование - это методика разработки программ, в основе которой лежит понятие объекта как некоторой структуры, описывающей объект реального мира, его поведение. Задача, решаемая с использованием методики объектно-ориентированного программирования, описывается в терминах объектов и операций над ними, а программа при таком подходе представляет собой набор объектов и связей между ними. Другими словами можно сказать, что объектно-ориентированное программирование представляет собой метод программирования, который весьма близко напоминает наше поведение. Оно является естественной эволюцией более ранних нововведений в разработке языков программирования. Объектно-ориентированное программирование является более структурным, чем все предыдущие разработки, касающиеся структурного программирования. Оно также является более модульным и более абстрактным, чем предыдущие попытки абстрагирования данных и переноса деталей программирования на внутренний уровень.

Использование объектно-ориентированного программирования является хорошим решением при разработке крупных программных проектов. Чем проект объемнее и сложнее, тем больше выгоды вы получите при использовании объектно-ориентированной технологии программирования. Одним из наибольших преимуществ объектно-ориентированного программирования является возможность многократного использования программного кода. Если вы, к примеру, создали класс, то можете порождать от него новые классы и изменять их свойства и функциональное назначение.

В качестве примера объектно-ориентированных языков в дальнейшем будем рассматривать такие языки как C++, Java, Python.

2.4. Язык программирования С++

2.4.1. Описание

C++ — компилируемый статически типизированный язык программирования общего назначения. Поддерживает разные парадигмы программирования, но, в сравнении с его предшественником — языком Си, — большое внимание уделяется поддержке объектно-ориентированного и обобщённого программирования.

В 1990-х годах язык стал одним из наиболее широко применяемых языков программирования общего назначения.

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

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

Язык С++ проектировался для поддержки абстракции данных и объектно-ориентированного программирования в добавление к традиционному стилю С. Впрочем, это не значит, что язык требует какого-то одного стиля программирования от всех пользователей.

Сейчас мы рассмотрим достоинства и недостатки языка, чтобы понять, что же делает его настолько мощным и универсальным инструментом в руках программиста.

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

2.4.2. Достоинства

C++ — чрезвычайно мощный язык, который содержит средства создания эффективных программ практически любого назначения, от низкоуровневых утилит и драйверов до сложных программных комплексов самого различного назначения. В частности: поддерживаются различные стили и технологии программирования, включая традиционное директивное программирование, ООП, обобщённое программирование, метапрограммирование(шаблоны, макросы).

Предсказуемое выполнение программ является серьезным достоинством для построения систем реального времени. Весь код, который неявно генерируется компилятором для реализации языковых возможностей (например, при x нулевое значение, а потом интерпретирует его как значение условия в операторе if). Так как нуль соответствует логическому значению «ложь», блок операторов в условной конструкции не выполнится никогда. Ошибки такого рода трудно выявлять, но во многих современных компиляторах предлагается диагностика некоторых подобных конструкций.

Операции присваивания (=), инкрементации (++), декрементации (--) и другие возвращают значение. В сочетании с изобилием операций это позволяет создавать трудночитаемые выражения. Наличие этих операций в Си было вызвано желанием создать инструмент ручной оптимизации кода, но в нынешнее время оптимизирующие компиляторы обычно генерируют оптимальный код и на традиционных выражениях. С другой стороны, один из главных принципов языков Си и C++ — позволять программисту писать в любом стиле, а не навязывать «хороший» стиль.

Макросы (#define) являются мощным, но опасным средством. Они сохранены в C++ несмотря на то, что необходимости в них, благодаря шаблонам и встроенным функциям, почти нет. В унаследованных стандартных Си-библиотеках много потенциально опасных макросов.

Некоторые преобразования типов неинтуитивны. В частности, операция над беззнаковым и знаковым числами выдаёт беззнаковый результат.

C++ допускает пропуск break в ветви оператора switch с целью последовательного выполнения нескольких ветвей. В языке Java принят такой же подход. Есть мнение, что понимание кода при этом затрудняется. Например, в языке C# следует всегда писать либо break, либо использовать goto case N для явного указания порядка выполнения.

Препроцессор, унаследованный от Си, довольно примитивен. С одной стороны это приводит к тому, что с его помощью нельзя (или тяжело) осуществить некоторые задачи метапрограммирования, а с другой, вследствие своей примитивности, он нередко приводит к ошибкам и требует много действий по обходу потенциальных проблем. Некоторые языки программирования (например, Scheme и Nemerle) имеют намного более мощные и более безопасные системы метапрограммирования (также называемые макросами, но мало напоминающие макросы Си/C++).

Плохая поддержка модульности (по сути, в классическом Си модульность на уровне языка отсутствует, её обеспечение переложено на компоновщик). Подключение интерфейса внешнего модуля через препроцессорную вставку заголовочного файла (#include) серьёзно замедляет компиляцию при подключении большого количества модулей (потому что результирующий файл, который обрабатывается компилятором, оказывается очень велик). Эта схема без изменений скопирована в C++. Для устранения этого недостатка, многие компиляторы реализуют механизм прекомпиляции заголовочных файлов (англ. Precompiled header).

2.4.3. Недостатки

Трудность и избыточность, из-за которых C++ трудно изучать, а построение компилятора сопряжено с большим количеством проблем. В частности:

Многие конструкции С++ позволяют делать то же самое, что и конструкции Си, которые также присутсвуют в С++. Например, приведение типов при помощи dynamic_cast позволяет привести указатель или ссылку строго в пределах иерархии классов. Это делает код более надёжным, декларативным и позволяет находить приведения в пределах иерархии при помощи инструментов типа grep. Однако вследствие требования высокой степени совместимости с Си старое приведение типов всё ещё поддерживается.

Иногда шаблоны приводят к порождению кода очень большого объёма. Для уменьшения размера машинного кода можно специальным образом подготавливать исходный код. Иным решением является стандартизованная ещё в 1998 году возможность экспорта шаблонов. Некоторые авторы считают, что её трудно реализовать и поэтому она доступна не во всех компиляторах. «Раздувание» машинного кода вследствие использования шаблонов часто преувеличивается, и современные компиляторы во многих случаях успешно устраняют это явление.

Метапрограммирование на основе шаблонов C++ весьма трудоемко и при этом ограничено в возможностях. Оно состоит в реализации средствами шаблонов C++ интерпретатора примитивного функционального языка программирования, выполняющегося во время компиляции. Сама по себе данная возможность весьма привлекательна, но такой код довольно сложно воспринимать и отлаживать. Менее распространённые языки Lisp/Scheme, Nemerle имеют более мощные и одновременно более простые для восприятия подсистемы метапрограммирования. Кроме того, в языке D реализована сравнимая по мощности, но значительно более легкая в применении подсистема шаблонного метапрограммирования.

Явная поддержка функционального программирования есть только в будущем стандарте c++0x. Данный пробел устраняется различными библиотеками (Loki, Boost), использующими средства метапрограммирования для расширения языка функциональными конструкциями (например, поддержкой лямбд/анонимных методов), но качество подобных решений сильно уступает качеству встроенных в функциональные языки решений. Такие возможности функциональных языков, как сопоставление с образцом, вообще крайне сложно эмулировать средствами метапрограммирования.

Некоторые считают недостатком языка C++ отсутствие встроенной системы сборки мусора. С другой стороны, средства C++ позволяют реализовать сборку мусора на уровне библиотеки. Противники сборки мусора полагают, что RAII является более достойной альтернативой. С++ позволяет пользователю самому выбирать стратегию управления ресурсами.

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

2.4.4. Оценка

Язык C++ явился мощным и стремительным рывком в развитии программирования. C++ и по сей день занимает господствующее положение среди языков программирования в мире. Огромное множество профессиональных программистов использует именно его при разработке разного рода проектов. Очевидно, этот язык будет сохранять свое положение ещё не один год, при этом по-прежнему развиваясь и совершенствуясь.

2.5. Язык программирования Java

2.5.1. Описание

Язык программирования Java является объектно-ориентированным языком программирования, который был создан Джеймсом Гослингом (James Gosling) и другими инженерами в компании Sun Microsystems. Он был разработана в 1991 году, как часть проекта "Green Project", и официально объявлен 23 мая 1995 года, в SunWorld, а выпущен в ноябре. Java была изначально разработана как замена для C++ (хотя набор функций больше похожа на Objective C) и известный как Дуб (в честь дерева за пределами офиса Гослинга).

Существовали четыре основных цели при создании языка Java:

1. Объектно-ориентированный язык.

2. Независимость от целевой платформы (более или менее).

3. Содержание объектов и библиотеки для работы в сети.

4. Безопасное выполнение удаленного кода.

2.5.2. Объектная ориентация

Первая характеристика, объектно-ориентированный подход ("ОО"), относится к методу программирования для чайников и дизайну язык. Основная идея ОО заключается в разработке программного обеспечения все это "вещи" (то есть объекты), которыми можно манипулировать, а не действия, которые нужно выполнять. Это основано на том, что первое (вещи) изменяются реже и радикальнее, чем действия, что делает такие объекты (на самом деле вещи, содержащие данные) более стабильной основу для разработки программного обеспечения. Целью является, делать большие проекты программного обеспечения легко управляемыми, таким образом, можно добиться повышения качества и сокращения числа неудачных проектов программирования для начинающих.

2.5.3. Независимость от целевой платформы

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

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

Первый метод - это просто компиляция непосредственно в машинный код, как традиционные компилятор, пропуская этап превращения программы в байт-код целиком. Этим достигается большая производительность, но за счет утраты мобильности и переносимости программ. Другой метод, "В процессе исполнения" или "JIT", компилирует байт-код Java в машинный код во время выполнения программы. Более сложные виртуальные машины даже использовали динамические перекомпиляции, в которой VJM может анализировать поведение работы программы и выборочно перекомпилировать и оптимизировать критические части программы. Обе эти технологии позволяют программе воспользоваться скоростью машинного код без потери мобильности.

Портативность является технически трудной целью для достижение и успех Java в достижении этой цели является предметом споров. Хотя на самом деле можно писать программы для платформы Java, которые ведут себя одинаково на многих платформах , но все же большее количество доступных платформ не выполняет программу как ожидалось, а выдает небольшое количество ошибок или несоответствий, что привело к появлению пародии на известный лозунг компании Sun "Написал один раз, работает везде" в другой "Написал один раз, отлаживал везде ".

2.5.4. Безопасное выполнение удаленного кода

Платформа Java была одной из первых систем для обеспечения широкой поддержки для выполнения кода из удаленных источников. Апплет может работать в браузере пользователя, в процессе выполнения кода может загрузить маленький кусочек чужого кода с удаленного сервера HTTP и выполнить. Удаленное выполнения кода происходит в весьма ограниченной "песочнице", которая защищает пользователя от некорректного или вредоносного кода. Издатели таких приложений могут подать заявку на сертификат, который они могли бы использовать для цифровой подписи апплетов как "безопасный", что дает им разрешение, чтобы вырваться из "песочницы" и получить доступ к локальной файловой системе и сети, конечно, предположительно этот процесс происходит под контролем пользователя.

2.5.5. Оценка

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

Java как правило, более высокого уровня, чем аналогичные языки (такие как C++), что означает, что языку Java не хватает функций, таких как аппаратные или для работы с конкретными типами данных или, например, низкоуровневые указатели на произвольные ячейки памяти. Хотя этими функциями часто злоупотребляют или используются программистами неправильно, они также являются мощными инструментами. Однако, технология Java включает Java Native Interface (JNI), способ вызова машинного кода из кода на языке Java. С JNI можно использовать эти возможности.

Некоторые программисты также жалуются на отсутствие множественного наследования, мощный инструмент нескольких объектно-ориентированных языков программирования, например, С++. Язык Java отделяет наследование типа и реализации, что позволяет наследование несколько определений типа через интерфейсы, но только единичное наследование типа данных с помощью иерархии классов. Это позволяет использовать большинство из преимуществ множественного наследования, избегая при этом многие из его опасностей. Кроме того, с помощью конкретных классов, абстрактных классов, а также интерфейсы, программист на языке Java имеет возможность выбора полной, частичной или нулевой реализации для типа объекта, он сам определяет, что обеспечивает максимальную полезность в разработке приложений.

2.6. Язык программирования Python

2.6.1. Описание

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

Python отличается сильной типизацией. Сильная типизация выделяется тем, что язык не позволяет смешивать в выражениях различные типы и не выполняет автоматические неявные преобразования, например нельзя вычесть из строки множество.

Объявление переменных необязательно, названия восприимчивы к регистру (var и VAR — две разные переменные).

Язык Python объектно-ориентирован, все в языке является объектом.

Python поддерживает несколько парадигм программирования, в том числе структурное, объектно-ориентированное, функциональное, императивное и аспектно-ориентированное. Основные архитектурные черты — динамическая типизация, автоматическое управление памятью, полная интроспекция, механизм обработки исключений, поддержка многопоточных вычислений и удобные высокоуровневые структуры данных. Код в Python организовывается в функции и классы, которые могут объединяться в модули (которые в свою очередь могут быть объединены в пакеты).

Эталонной реализацией Python является интерпретатор CPython, поддерживающий большинство активно используемых платформ. Он распространяется свободно под очень либеральной лицензией, позволяющей использовать его без ограничений в любых приложениях, включая проприетарные. Есть реализации интерпретаторов для JVM (с возможностью компиляции), MSIL (с возможностью компиляции), LLVM и других. Проект PyPy предлагает реализацию Питона на самом Питоне, что уменьшает затраты на изменения языка и постановку экспериментов над новыми возможностями.

Python — активно развивающийся язык программирования, новые версии (с добавлением/изменением языковых свойств) выходят примерно раз в два с половиной года. Вследствие этого и некоторых других причин на Python отсутствуют ANSI, ISO или другие официальные стандарты, их роль выполняет CPython.

2.6.2 Философия Python

Разработчики языка Python придерживаются определённой философии программирования, называемой «Дзэном Питона» и её текст выдаётся интерпретатором Python по команде import this (работает один раз). Автором этой философии считается Тим Пейтерс:

- Красивое лучше уродливого.

- Явное лучше неявного.

- Простое лучше сложного.

- Сложное лучше усложнённого.

- Плоское лучше вложенного.

- Разрежённое лучше плотного.

- Удобочитаемость важна.

- Частные случаи не настолько существенны, чтобы нарушать правила.

- Однако практичность важнее чистоты.

- Ошибки никогда не должны замалчиваться.

- За исключением замалчивания, которое задано явно.

- В случае неоднозначности сопротивляйтесь искушению угадать.

- Должен существовать один — и, желательно, только один — очевидный способ сделать это.

- Хотя он может быть с первого взгляда не очевиден, если ты не голландец.

- Сейчас лучше, чем никогда.

- Однако, никогда чаще лучше, чем прямо сейчас.

- Если реализацию сложно объяснить — это плохая идея.

- Если реализацию легко объяснить — это может быть хорошая идея.

Заключение

Изобретение языка программирования высшего уровня позволило нам общаться с машиной, понимать её. Развилась наука программирования с того времени, как появились языки программирования, а ведь язык программирования высшего уровня, судя по всему ещё младенец. Но если обратить внимание на темпы роста и развития новейших технологий в области программирования, то можно предположить, что в ближайшем будущем, человеческие познания в этой сфере, помогут произвести на свет языки, умеющие принимать, обрабатывать и передавать информации в виде мысли, слова, звука или жеста. Так и хочется назвать это детище компьютеризированного будущего: «языки программирования "высочайшего" уровня». Возможно, концепция решения этого вопроса проста, а ближайшее будущее этого проекта уже не за горами.

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

Список использованной литературы

При написании данной курсовой работы использовались книги и сайты:

1. «Бьерн Страуструп — «Язык программирования С++»

2.Павловская Т.А. — «C и C++. Программирование на языке высокого уровня».

3. Керниган Б.В., Ритчи Д., Фьюэр А. “Язык программирования Си.” Русский перевод: Москва: Финансы и Статистика. 1985 г.;

4. Терренс П. “Языки программирования: разработка и реализация”, 1979 г.;

5. Роберт У. Себеста. Основные концепции языков программирования = Concepts of Programming Languages / Пер. с англ. -- 5-е изд. -- М.: Вильямс, 2001. -- 672 с. -- 5000 экз. -- ISBN 5-8459-0192-8 (рус.), ISBN 0-201-75295-6 (англ.)

6. Вольфенгаген В. Э. Конструкции языков программирования. Приёмы описания. -- М.: Центр ЮрИнфо Р, 2001. -- 276 с. -- ISBN 5-89158-079-9

7. http://www.tiobe.com/tiobe-index/

8. https://tproger.ru/

9. https://habrahabr.ru/