Язык программирования 1973 года
Ранние языки высокого уровня (ЯВУ)
С середины 1950-х начали появляться языки третьего поколения (3GL), такие как Фортран, Лисп и Кобол, а в конце 1950-х годов появился Алгол.
Обновленные версии перечисленных языков до сих пор имеют хождение в разработке программного обеспечения, и каждый из них оказал определенное влияние на последующее развитие языков программирования. Следует заметить, что на формат и применение ранних языков программирования в значительной степени влияли интерфейсные ограничения. (Из Википедии)
В период 1960-х — 1970-х годов были разработаны основные парадигмы языков программирования, используемые в настоящее время, хотя во многих аспектах этот процесс представлял собой лишь улучшение идей и концепций, заложенных еще в первых языках III поколения:
Разделы страницы о языках программирования высокого уровня:
На основе многих языков третьего поколения были созданы их объектно-ориентированные версии.
Обзоры о языках программирования третьего поколения (3GL)
Предок Бэйсика. Имеет солидную библиотеку математических и других формул. Версии: Фортран-77 и Фортран-90.
Диалектом APL является функциональный векторный язык программирования J. В отличие от APL он не требует специальной раскладки клавиатуры для ввода математических символов, поскольку использует символы ASCII.
Предок Паскаля, Модулы, Ады, т.к. имел красивую и плодотворную идею «правильного» структурного программирования.
Алго́л (англ. Algol от англ. algorithmic — алгоритмический и англ. language — язык) — несколько версий языков программирования, применяемых при составлении программ для решения научно-технических задач на ЭВМ. Разработан комитетом по языку высокого уровня IFIP в 1958—1960 годах (Алгол 58, Алгол 60); усовершенствован в 1964—1968 годах (Алгол 68). Алгол был популярен в Европе, в том числе в СССР, в то время как сравнимый с ним язык Фортран был распространён в США и Канаде. Оказал заметное влияние на все разработанные позднее императивные языки программирования — особенно на язык Pascal.
Обычно названием Алгол именуют Алгол 60, в то время как Алгол 68 рассматривается как самостоятельный язык. (Википедия)
Использование Кобола калечит ум. Его преподавание, следовательно, должно рассматриваться как уголовное преступление. (Дейкстра)
Кобол обычно критикуется за многословность и громоздкость, поскольку одной из целей создателей языка было максимально приблизить конструкции к английскому языку. До сих пор Кобол считается языком программирования, на котором было написано больше всего строк кода. Например, к 1997 году активно использовалось около 240 миллиардов строк кода на Коболе. Около 90 % финансовых транзакций в мире обрабатывается кодом на Коболе, и 75 % коммерческой обработки данных написано на Коболе. Общая стоимость используемого в настоящее время коболовского кода оценивается в 2 триллиона долларов США. И до сих пор ежегодно пишутся миллионы новых строк кода на Коболе.
Практически невозможно научить хорошему стилю программирования студентов, которые раньше имели дело с Бейсиком; в качестве программистов они умственно покалечены без надежды на восстановление. (Edsger Wybe Dijkstra)
Как и любые преимущества, простота Бейсика оборачивалась, особенно в ранних версиях трудностями структурирования; кроме того, Бейсик не допускал рекурсию – интересный прием, позволяющий составлять эффективные и в то же время короткие программы. В первых версиях Бейсика, в 1960-е, 1970-е годы, вначале каждой строки надо было ставить цифровую метку номера оператора (как в Фортране). В последующих версиях это утомительное занятие было устранено. Был исключено ключевое слово LET (взять) в математических операторах.
Попытка скрестить всё лучшее от Фортрана до Алгола. Не прижился и практически и не дал идейных всходов теоретически.
PL/1 содержит все основные конструкции, характерные для так называемых языков высокого уровня, а также ряд специфичных средств, удобных для практического программирования. Язык напоминает конструктор с большим числом деталей – пользователю достаточно освоить только те части языка, которые ему практически необходимы. Его операторы довольно емки, что часто позволяет получить запись программы более компактную, чем на других языках. Знающий PL/1 программист без труда осваивает любой другой язык того же или близкого класса.
Вместе с тем, ПЛ/1 имеет и ряд недостатков, затрудняющих изучение и использование языка. Основные из них таковы. Во-первых, имеется много дублирующих друг друга средств их сложно запомнить, не ясно, что когда применять, кроме того, это снижает как скорость трансляции, так и скорость выполнения программ. Во-вторых, программы получаются не совсем машинно-независимыми.
Все технологии смертны, только язык C вечен!
Популярность этого языка быстро переросла рамки конкретной операционной системы и конкретных задач системного программирования. В настоящее время любая инструментальная и операционная система не может считаться полной, если в ее состав не входит компилятор языка Си.
На Си можно создавать программы, которые делают все, что пожелаешь. Нет другого такого языка, который бы так же стимулировал к программированию. Создается впечатление, что остальные языки программирования воздвигают искусственные препятствия для творчества, а Си – нет. Использование этого языка позволяет сократить затраты времени на создание работающих программ. Си позволяет программировать быстро, эффективно и предсказуемо. Еще одно преимущество Си заключается в том, что он позволяет использовать все возможности вашей ЭВМ. Этот язык создан программистом для использования другими программистами, чего о других языках программирования сказать нельзя.
Однако, язык Си предъявляет достаточно высокие требования к квалификации использующего его программиста. При изучении Си желательно иметь представление о структуре и работе компьютера. Большую помощь и более глубокое понимание идей Си, как языка системного программирования, обеспечат хотя бы минимальное знание языка ассемблер. Уровень старшинства некоторых операторов не является общепринятым, некоторые синтаксические конструкции могли бы быть лучше. Тем не менее, как оказалось Си – чрезвычайно эффективный и выразительный язык, пригодный для широкого класса задач.
Язык программирования Паскаль был разработан профессором кафедры вычислительной техники Швейцарского Федерального института технологии Николасом Виртом в 1968 году как альтернатива существующим и все усложняющимся языкам программирования, таким, как PL/1, Algol, Fortran. Интенсивное развитие Паскаля привело к появлению уже в 1973 году его стандарта в виде пересмотренного сообщения, а число трансляторов с этого языка в 1979 году перевалило за 80.
В начале 80-х годов Паскаль еще более упрочил свои позиции с появлением трансляторов MS-Pascal и Turbo-Pascal для ПЭВМ. С этого времени Паскаль становится одним из наиболее важных и широко используемых языков программирования. Существенно то, что язык давно вышел за рамки академического и узко профессионального интереса и используется в большинстве университетов высокоразвитых стран не только как рабочий инструмент пользователя.
Важнейшей особенностью Паскаля является воплощенная идея структурного программирования. Другой существенной особенностью является концепция структуры данных как одного из фундаментальных понятий.
Язык программирования высокого уровня Ада назван в часть Августы Ады Байрон, графини Лавлейс и дочери английского поэта лорда Байрона. Она была ассистентом, коллегой и сторонницей Чарльза Беббиджа, математика и изобретателя вычислительной машины, названной аналитической машиной. С помощью Ч. Беббиджа в 1830 г. она написала практически законченную программу на аналитической машине для вычисления чисел Бернулли. Поэтому графиню можно назвать первым в мире программистом на вычислительной машине.
Язык Ада возник в результате международного конкурса языковых проектов проходящего в 1978-1979 годах. Участники должны были удовлетворить довольно жестким, детально разработанным требованиям. Интересно, что все языки, дошедшие до последних туров этого конкурса, были основаны на Паскале. В этой связи Аду можно предварительно охарактеризовать как Паскаль, развитый с учетом перечисленных выше требований. При этом авторы пошли в основном по пути расширения Паскаля новыми элементами. В результате получился существенно более сложный язык.
Модульный язык системного программирования Модула (1980 г.) и его потомки
Можно считать, что история языка Модула начинается в 1980 году, когда Никлаус Вирт, один из выдающихся специалистов по теории информации, известный большинству специалистов по вычислительной технике в основном как создатель языка Паскаль, опубликовал описание нового языка программирования, названного им Модула. В отличие от Паскаля, который был по замыслу языком для обучения программирования, Модула с самого начала представлял собой язык для профессиональных системных программистов, продолжая лучшие традиции своего предшественника и обогащая их новыми идеями, соответствующих таким требованиям к языкам программирования, как структурность, модульность и способность к расширению.
Как и множество других языков программирования, Модула подвергалась эволюции, во время которой ее первоначальное название было переделано в имя Модула-2. Одновременно с развитием языка Модула для него создавались новые компиляторы, однако, ни один из них не мог соперничать с лучшими реализациями языков Паскаль и Си, например, разработанных фирмой Борланд. В этот переходный для языка Модула период лучшей считалась реализация фирмы Logitech, которая по своим характеристикам проигрывала Турбо Паскалю и Турбо Си. Только в 1988 году после появления на американском рынке системы Top Speed, Модула-2 заняла достойное место среди процедурных языков, предназначенных для системного программирования.
Объектно-ориентированные потомки Модулы-2 (Оберон, Модула-3)
Важно заметить, что Вирт не признавал необходимость объектно-ориентированного программирования и утверждал, что всё можно сделать Модулой. Вроследствии появились языки Модула-3 и Оберон.
Оберон — язык программирования высокого уровня, разработанный Никлаусом Виртом, для исполнения программ, исполняемых в одноимённой операционной системе, авторами которой являются Никлаус Вирт и Юрг Гуткнехт (1986—1989 годы). Основой для Оберона послужил язык Модула-2. Первоначально систему хотели писать на самой Модуле, но увидели, что её надо доработать и сократить, что и привело к появлению Оберона. Целью проекта было создание с нуля обозримой и надежной операционной системы для персонального компьютера.
История языков программирования: как Haskell стал стандартом функционального программирования
Теоретические основы императивного программирования были заложены ещё в 30-х годах XX века Аланом Тьюрингом и Джоном фон Нейманом. Теория, положенная в основу функционального подхода, формировалась в 20-х и 30-х годах. В числе разработчиков математических основ функционального программирования — Мозес Шёнфинкель (Германия и Россия) и Хаскелл Карри (Англия), а также Алонзо Чёрч (США). Шёнфинкель и Карри заложили основы комбинаторной логики, а Чёрч является создателем лямбда-исчисления.
Функциональное программирование как раз основано на идеях из комбинаторной логики и лямбда-исчисления.
Но теория так и оставалась теорией, пока в начале 50-х прошлого века Джон МакКарти не разработал язык Lisp (1958), который стал первым почти функциональным языком программирования. На протяжении многих лет у Lisp не было конкурентов. Позднее появились функциональные языки программирования APL (1964), ISWIM (1966) и FP (1977), которые не получили столь широкого распространения.
Со временем Lisp перестал удовлетворять некоторым требованиям разработчиков программ, особенно с ростом объема и сложности программного кода. В связи с этим обстоятельством всё большую роль стала играть типизация. В конце 70-х — начале 80-х годов XX века интенсивно разрабатывались модели типизации, подходящие для функциональных языков.
Большинство этих моделей включали в себя поддержку таких мощных механизмов как абстракция данных и полиморфизм. Появилось множество типизированных функциональных языков: ML, Scheme, Hope, Miranda, Clean и многие другие. Вдобавок постоянно увеличивалось число диалектов.
ML (1973) – первый язык с типизацией Хиндли–Милнера;
Scheme (1975) — это один из двух самых популярных диалектов языка Lisp;
SASL, KRC, Miranda (1972–1985) – одни из первых ленивых языков;
Hope (1980) – один из первых языков с алгебраическими типами данных.
Хаскелл Карри
В результате вышло так, что практически каждая группа, занимающаяся функциональным программированием, использовала собственный язык. Это препятствовало дальнейшему распространению этих языков и порождало многочисленные проблемы.
История языка Haskell начинается в 1987 году. Один за другим появлялись новые функциональные языки программирования. После выхода Miranda (Research Software Ltd, 1985 год) возрос интерес к ленивым вычислениям: к 1987 году возникло более дюжины нестрогих чисто функциональных языков программирования.
Miranda использовался наиболее широко, но это было запантетованное ПО. На конференции по функциональным языкам программирования и компьютерной архитектуре (FPCA, 1987) в Портленде (Орегон) участники пришли к соглашению, что должен быть создан комитет для определения открытого стандарта для подобных языков. Целью комитета являлось объединение существующих функциональных языков в один общий, который бы предоставлял базис для будущих исследований в разработке функциональных языков программирования.
Так появился Haskell. Он был назван в честь одного из основателей комбинаторной логики Хаскела Кaрри (Haskell Curry).
К концу 1980-х годов было создано много функциональных языков. Часть из них оказали значительное влияние на Haskell:
Новый язык должен был стать свободным языком, пригодным для исследовательской деятельности и решения практических задач. Свободные языки основаны на стандарте, который формулируется комитетом разработчиков. Дальше любой желающий может заняться реализацией стандарта, написать компилятор языка. Первая версия стандарта Haskell была опубликована 1 апреля 1990 года.
Haskell 1.0 — 1.4
Первая версия Haskell (Haskell 1.0) была выпущена в 1990г. Попытки комитета вылились в серию реализаций языка (1.0, 1.1, 1.2, 1.3, 1.4).
Haskell 98
В конце 1997 года версии Haskell 98 необходимо было специфицировать в одну стабильную, минимальную и портативную версию языка и сопроводительную стандартную библиотеку для изучения, как основу будущего развития. Комитет положительным образом принял создание расширений и вариаций haskell 98 путем добавления и внедрения экспериментальных особенностей.
В феврале 1999 года стандарт языка Haskell 98 впервые был опубликован, как «The Haskell 98 Report». В январе 2003 года измененная версия была опубликована как «Haskell 98 Language and Libraries: The Revised Report». Язык продолжил стремительно развиваться, реализация компилятора Glasgow Haskell Compiler (GHC) представляет фактический стандарт языка.
Haskell 2010
Современный стандарт Haskell — Haskell 2010 — был анонсирован 24 ноября 2009 года; GHC поддерживает его с версии 7.0.1.
По сравнению с Haskell ’98 он содержал следующие изменения:
• Do и If Then Else
• Иерархические модули
• Объявления пустых переменных
• Решение устойчивости
• Интерфейс сторонних функций
• Линейный синтаксис комментариев
• Охраняющие паттерны
• Облегченных анализ зависимостей
• Указания для языка (pragma)
• Отсутствие паттернов n+k
Дополнительные изменения были опубликованы 7 января 2011 года:
• Отсутствие контекста типов данных
• Маркированные списки переменных
Haskell продолжает развиваться и сегодня. Но стабильные версии опираются на стандарты 1998 и 2010 года соответственно. Но кроме них в Haskell включается множество расширений, постоянно вносятся новые идеи. Над языком работают нескольких странах мира — это Англия, Нидерланды, Америка и Австралия. Интерес к Haskell вызван популярностью многопроцессорных технологий. Модель Haskell хорошо подходит для параллельных вычислений.
От создателя Haskell
Curry — встраиваемый язык программирования общего назначения, реализованный поверх языка Haskell. Язык Curry плавно соединяет в себе возможности функционального программирования (вложенные выражения, функции высших порядков, ленивые вычисления), логического программирования (логические переменные, частичные структуры данных, встроенная система поиска) и методов программирования для параллельных систем (параллельное вычисление выражений с синхронизацией по логическим переменным).
Более того, язык Curry предоставляет дополнительные механизмы по сравнению с чистыми языками программирования (по сравнению с функциональными языками — поиск и вычисления по неполным данным, по сравнению с логическими языками — более эффективный механизм вычислений благодаря детерминизму и вызову по необходимости для функций).
Популярность
На сайте Github сейчас занимает 23-ю строчку по популярности среди языков программирования.
В индексе TIOBE он находится на 38 месте:
В рейтинге RedMonk Haskell стоит достаточно высоко — на 16-й позиции. В данном случае рейтинг строится на основе оценки сочетания популярности на GitHub, плюс активность обсуждений на Stack Overflow.
Проекты
На Haskell реализовано много сложных проектов:
• Компиляторы и другие средства разработки.
• Распределенная система управления версиями Darcs.
• Интерпретатор/компилятор Pugs для языка Perl 6.
• Язык описания аппаратных средств Lava.
• Система обработки натурального языка LOLITA.
• Системы доказательства теорем Equinox / Paradox и Agda.
Фильтрация спама — одна из самых главных задач, которую решают инженеры Facebook. Крупнейшая социальная сеть обрабатывает сообщения от более 1,5 миллиарда человек, так что можно оценить масштаб проблемы. В 2015 году компания внедрила новые антиспамерские фильтры, для разработки которых использовала язык программирования Haskell.
Несмотря на молодость, экспериментальный статус и относительно низкую популярность, Facebook выбрал именно Haskell для создания важного модуля. Один из инженеров Луис Брэнди (Louis Brandy), который входит в группу разработчиков нового антиспамерского фильтра, провел два года за этим проектом вместе с коллегами. В интервью Wired он объяснил, чем они руководствовались.
Луис Брэнди, аккуратно подбирая слова, назвал Haskell идеально подходящим для реализации спам-фильтра в Facebook, потому что он отлично обрабатывает параллельные задачи и позволяет разработчикам легко и удобно устанавливать эти задачи на лету. Facebook настолько большой проект, а спамеры настолько быстро меняют тактику, что необходим инструмент для разработки и постоянной модификации спам-фильтров, которые вступят в действие немедленно.
Если посмотреть на развитие современного интернета, то по этому пути должны пойти многие интернет-проекты, для которых важны масштабируемость и реагирование в реальном времени. По мнению разработчиков Facebook, у языка Haskell есть все шансы на широкую популярность. Мешает только тот факт, что Haskell довольно сильно отличается от других языков — и это затрудняет массовую миграцию на него.
Тем не менее, индустрия точно двигается в нужном направлении, как показывает пример новых языков программирования, ориентированных на выполнение параллельных процессов, например, Go от Google и Rust от Mozilla. Пусть они не такие эффективные, как Haskell, зато проще в изучении. В любом случае, Haskell можно поблагодарить за то, что он подтолкнул к развитию другие языки программирования и способствовал запуску новых перспективных проектов.
Евгений Козлов в своем блоге рассказал о впечатлениях от работы с Haskell:
Недостатки
В первую очередь – высокий порог вхождения в язык. Да, Haskell прекрасен, чист и лаконичен, но достигается это не бесплатно, а путём долгого перестроения мозга и изучения сложных абстракций вроде монад, монадных трансформеров, линз и машин.
Во-вторых – это сложность написания производительного кода. Так как в Haskell весь код ленив, то можно запросто достичь такой ситуации, когда в памяти накоплены гигабайты отложенных вычислений, но они не вычисляются, потому что ещё не затребованы.
Положительные стороны
В первую очередь, конечно же чистота языка. Чистота в обоих смыслах: чистота функций и полное отсутствие ООП-парадигмы. Это очень здорово, что ты можешь посмотреть на сигнатуру функции и понять, может ли она производить побочные эффекты или нет. Отсутствие ООП означает, что нет возможности сделать страшные вещи вроде непроверенных приведений из базового класса в подкласс.
Если написан код, то его сложно интерпретировать двумя способами. Например, нельзя перепутать применение функции и ссылку на функцию, как в Scala, так как в Haskell функции являются объектами первого класса. Или, например, нельзя перепутать функцию с типом или классом, так как все функции должны начинаться с маленькой буквы, а типы/классы – с большой.
Свойство языка, без которого разговор о Haskell был бы бессмысленным – это полиморфизм. Вряд ли будет преувеличением, если я скажу, что Haskell является языком с максимальным количеством переиспользованного кода. Любая хоть сколько-нибудь повторяющаяся функциональность выносится в абстракцию.
Язык программирования Си
Си (англ. C ) — стандартизированный процедурный язык программирования, разработанный в начале 1970-х годов сотрудниками Bell Labs Кеном Томпсоном и Денисом Ритчи как развитие языка Би. Си был создан для использования в операционной системе (ОС) портирован на многие другие операционные системы и стал одним из самых используемых языков программирования. Си ценят за его эффективность; он является самым популярным языком для создания системного программного обеспечения. Его также часто используют для создания прикладных программ. Несмотря на то, что Си не разрабатывался для новичков, он активно используется для обучения программированию. В дальнейшем синтаксис языка Си стал основой для многих других языков (см.: Си-подобный синтаксис).
Для языка Си характерны лаконичность, современный набор конструкций управления потоком выполнения, структур данных и обширный набор операций.
Содержание
Особенности
Обзор
Язык программирования Си отличается минимализмом. Авторы языка хотели, чтобы программы на нём легко компилировались с помощью однопроходного компилятора, после компиляции каждой элементарной составляющей программы соответствовало весьма небольшое число машинных команд, а использование базовых элементов языка не задействовало библиотеку времени выполнения. Однопроходный компилятор компилирует программу, не возвращаясь назад, к уже откомпилированному тексту. Поэтому использованию функции должно предшествовать её объявление. Код на Си можно легко писать на низком уровне абстракции, почти как на ассемблере. Иногда Си называют «универсальным ассемблером» или «ассемблером высокого уровня», что отражает различие языков ассемблера для разных платформ и единство стандарта Си, код которого может быть скомпилирован без изменений практически на любой модели компьютера. Си часто называют языком среднего уровня или даже низкого уровня, учитывая то, как близко он работает к реальным устройствам.
Компиляторы Си разрабатываются сравнительно легко благодаря относительно низкому уровню языка и скромному набору элементов. Поэтому данный язык доступен на самых различных платформах (возможно, круг этих платформ шире, чем у любого другого существующего языка). К тому же, несмотря на свою низкоуровневую природу, язык позволяет создавать переносимые программы и поддерживает программиста в этом. Программы, соответствующие стандарту языка, могут компилироваться на самых различных компьютерах.
Си создавался с одной важной целью: сделать более простым написание больших программ с минимумом ошибок по правилам процедурного программирования, не добавляя лишних накладных расходов на итоговый код программы компилятором, как это всегда делают языки очень высокого уровня, такие как Бейсик. С этой стороны Си имеет следующие важные особенности:
Вот некоторые особенности других языков программирования, которых не имеет Си:
Несмотря на то, что в Си нет столь многого, а это было важно в начале, язык был хорошо принят, потому что он позволял быстро создавать компиляторы для новых платформ, а также позволял программистам довольно точно представлять, как выполняются их программы. Благодаря этому программы, написанные на Си, эффективнее написанных на многих других языках. Как правило, лишь оптимизированный вручную код на ассемблере может работать ещё быстрее, потому что он даёт полный контроль над машиной, однако развитие современных компиляторов вместе с усложнением современных процессоров быстро сократило этот разрыв.
Одним из последствий высокой эффективности и переносимости Си стало то, что многие компиляторы, интерпретаторы и библиотеки других языков высокого уровня часто выполнены на языке Си.
Программа «Hello, World!»
Эта простая программа, появившаяся в первом издании книги «Язык программирования Си» Кернигана и Ритчи, обычно является первой программой большинства учебников Си. Она печатает сообщение «Hello World!» на стандартном устройстве вывода (которым, как правило, является монитор (дисплей), но может быть и файл, какое-либо устройство или область в памяти, в зависимости от того, как отражается стандартное устройство вывода на данной платформе).
Несмотря на то, что на большинстве современных компиляторов эта программа может быть корректно скомпилирована, она порождает несколько предупреждений на компиляторах стандарта ANSI C. Кроме того, этот код не будет компилироваться, если компилятор жёстко следует стандарту int в качестве возвращаемого значения. Эти сообщения можно убрать, если внести в эту программу несколько небольших изменений:
В первой строке программы расположена директива препроцессора #include, встретив которую, компилятор заменяет её на полный текст файла, на который она ссылается. В данном случае эта строка будет заменена стандартным заголовочным файлом stdio.h в каталоге стандартных заголовочных файлов.
Следующая строка является объявлением функции с именем main. Эта функция в программе Си является особенной, так как выполняется первой при запуске программы, то есть служит так называемой точкой входа в программу.
Фигурные скобки после функции main обозначают её определение. Слово int говорит, что функция main возвращает (вычисляет) целое число. Слово void показывает, что функция main не требует от вызывающего ни параметров, ни аргументов.
Выражение return заставляет программу прекратить выполнение данной функции (main в этом случае), возвращая вызвавшей функции значение, указанное после ключевого слова return (0 в этом случае). Так как текущая функция — это main, то вызывающим является то, что запустило программу. Последняя фигурная скобка обозначает конец определения функции main.
Комментарии
Текст, заключённый в служебные символы /* и */ в этом порядке, полностью игнорируется компилятором. Компиляторы, совместимые со стандартом C99, также позволяют использовать комментарии, начинающиеся с символов // и заканчивающиеся переводом строки
Система типов в Си подобна типам в других потомках Алгола, таких, как Паскаль. В Си имеются типы целых чисел различных размеров, со знаком и без, чисел с плавающей запятой, символов, перечисляемых типов (enum) и записей-структур (struct). Кроме того, язык Си предлагает тип объединение (union), с помощью которого можно либо хранить в одном месте памяти разнородные данные, не пересекающиеся по времени существования (это позволяет экономить память), либо обращаться к содержимому участка памяти, как к данным разных типов (что позволяет менять тип-интерпретацию данных, не меняя сами данные).
Хранение данных
Одной из самых важных функций любого языка программирования является предоставление возможностей для управления памятью и объектами, хранящимися в ней.
В Си есть три разных способа выделения памяти для объектов:
Все три этих способа хранения данных пригодны в различных ситуациях и имеют свои преимущества и недостатки. Например, статическое выделение памяти не имеет накладных расходов по выделению, автоматическое выделение — лишь малые расходы при выделении, а вот динамическое выделение потенциально требует больших расходов и на выделение, и на освобождение памяти. С другой стороны, память стека гораздо больше ограничена, чем статическая, или память в куче. Только динамическая память может использоваться в случаях, когда размер используемых объектов заранее неизвестен. Большинство программ на Си интенсивно используют все три этих способа.
Там, где это возможно, предпочтительным является автоматическое или статическое выделение памяти, потому что такой способ хранения объектов управляется компилятором, что освобождает программиста от трудностей ручного выделения и освобождения памяти, как правило, служащего источником трудно отыскиваемых ошибок в программе. К сожалению, многие структуры данных имеют переменный размер во время выполнения программы, поэтому из-за того, что автоматически и статически выделенные области должны иметь известный фиксированный размер во время компиляции, очень часто требуется использовать динамическое выделение. Массивы переменного размера — самый распространённый пример такого использования памяти.
Набор используемых символов
Проблемы
Многие элементы Си потенциально опасны, а последствия неправильного использования этих элементов зачастую непредсказуемы. Керниган говорит: «Си — инструмент, острый, как бритва: с его помощью можно создать и элегантную программу, и кровавое месиво». В связи со сравнительно низким уровнем языка многие случаи неправильного использования опасных элементов не обнаруживаются и не могут быть обнаружены ни при компиляции, ни во время исполнения. Это часто приводит к непредсказуемому поведению программы. Иногда в результате неграмотного использования элементов языка появляются уязвимости в системе безопасности. Необходимо заметить, что использования многих таких элементов можно избежать.
Чаще всего источником ошибки является обращение к несуществующему элементу массива. Несмотря на то, что Си непосредственно поддерживает статические массивы, он не имеет средств проверки индексов массивов (проверки границ). Например, возможна запись в шестой элемент массива из пяти элементов, что, естественно, приведёт к непредсказуемым результатам. Частный случай такой ошибки называется ошибкой переполнения буфера. Ошибки такого рода приводят к большинству проблем с безопасностью.
Другим потенциальным источником опасных ситуаций служит механизм указателей. Указатель может ссылаться на любой объект в памяти, включая и исполняемый код программы, и неправильное использование указателей может порождать непредсказуемые эффекты и приводить к катастрофичным последствиям. К примеру, указатель может быть неинициализированным или, в результате неверных арифметических операций над указателем, указывать в произвольное место памяти; на некоторых платформах работа с таким указателем может вызвать аппаратный останов программы, на незащищённых же платформах это может привести к порче произвольных данных в памяти, причём эта порча может проявиться в самые произвольные моменты времени и намного позже момента порчи. Также, область динамической памяти, на которую ссылается указатель, может быть освобождена (и даже выделена после этого под другой объект) — такие указатели называются «висячими». Или, наоборот, после манипуляций с указателями на область динамической памяти может не остаться ссылок, и тогда эта область, называемая «мусором» (garbage), никогда не будет освобождена, что может приводить к «утечкам памяти» в программе. В других языках подобные проблемы пытаются решить введением более ограниченных ссылочных типов.
Проблемой является также то, что автоматически и динамически создаваемые объекты не инициализируются и они могут содержать значения, оставшееся в памяти от ранее удалённых объектов. Такое значение полностью непредсказуемо, оно меняется от одной машины к другой, от запуска к запуску, от вызова функции к вызову. Если программа использует такое значение, то результат будет непредсказуемым и не обязательно проявится сразу. Современные компиляторы пытаются диагностировать эту проблему некоторым анализом исходного кода, хотя в общем случае статическим анализом это решить нельзя.
Ещё одной распространённой проблемой является то, что память не может быть использована снова, пока она не будет освобождена программистом с помощью функции free(). В результате программист может случайно забыть освобождать эту память, но продолжать её выделять, занимая всё большее и большее пространство. Это обозначается термином утечка памяти. Наоборот, возможно освободить память слишком рано, но продолжать её использовать. Из-за того, что система выделения может использовать освобождённую память по-другому, это ведёт к непредсказуемым последствиям. Эти проблемы решаются в языках со сборкой мусора. С другой стороны, если память выделяется в функции и должна освобождаться после выхода из функции, данная проблема решается с помощью автоматического вызова деструкторов в языке C++, или с помощью локальных массивов, используя расширения С99.
Функции с переменным количеством аргументов также являются потенциальным источником проблем. В отличие от обычных функций, имеющих прототип, стандартом не регламентируется проверка функций с переменным числом аргументов. Если передаётся неправильный тип данных, то возникает непредсказуемый, если не фатальный результат. Например, семейство функций printf стандартной библиотеки языка Си, используемое для генерации форматированного текста для вывода, хорошо известно за его потенциально опасный интерфейс с переменным числом аргументов, которые описываются строкой формата. Проверка типов в функциях с переменным числом аргументов является задачей каждой конкретной реализации такой функции, однако многие современные компиляторы в частности проверяют типы в каждом вызове printf, генерируя предупреждения в случаях, когда список аргументов не соответствует строке формата. Следует заметить, что невозможно статически проконтролировать даже все вызовы функции printf, поскольку строка формата может создаваться в программе динамически, поэтому как правило никаких проверок других функций с переменным числом аргументов компилятором не производится.
Для помощи программистам на Си в решении этих и многих других проблем было создано большое число отдельных от компиляторов инструментов. Такими инструментами являются программы дополнительной проверки исходного кода и поиска распространённых ошибок, а также библиотеки, предоставляющие дополнительные функции, не входящие в стандарт языка, такие как проверка границ массивов или ограниченная форма сборки мусора.
История
Ранние разработки
Язык программирования Си был разработан в лабораториях Bell Labs в период с 1969 по 1973 годы. Согласно Ритчи, самый активный период творчества пришёлся на 1972 год. Язык назвали «Си» (C — третья буква латинского алфавита), потому что многие его особенности берут начало от старого языка «Би» (B — вторая буква латинского алфавита). Существует несколько различных версий происхождения названия языка Би. Кен Томпсон указывает на язык программирования
К 1973 году язык Си стал достаточно силён, и большая часть ядра UNIX, первоначально написанная на ассемблере PDP-11/20, была переписана на Си. Это было одно из самых первых ядер операционных систем, написанное на языке, отличном от ассемблера; более ранними были лишь системы ПЛ/1) и TRIPOS (написана на BCPL).
В 1978 году Ритчи и Керниган опубликовали первую редакцию книги «Язык программирования Си». Эта книга, известная среди программистов как «K&R», служила многие годы неформальной спецификацией языка. Версию языка Си, описанную в ней, часто называют «K&R C». (Вторая редакция этой книги посвящена более позднему стандарту ANSI C, описанному ниже.)
K&R ввёл следующие особенности языка:
K&R C часто считают самой главной частью языка, которую должен поддерживать компилятор Си. Многие годы даже после выхода ANSI C, он считался минимальным уровнем, которого следовало придерживаться программистам, желающим добиться от своих программ максимальной портативности, потому что не все компиляторы тогда поддерживали ANSI C, а хороший код на K&R C был верен и для ANSI C.
После публикации K&R C в язык было добавлено несколько «неофициальных» возможностей, поддерживаемый компиляторами AT&T и некоторых других производителей:
ANSI C и ISO C или C89
В конце 1970-х годов Си начал вытеснять Бейсик с позиции ведущего языка для программирования микрокомпьютеров. В 1980-х годах он был адаптирован для использования в IBM PC, что привело к резкому росту его популярности. В то же время Бьярне Строуструп и другие в лабораториях Bell Labs начали работу по добавлению в Си возможностей объектно-ориентированного программирования. Язык, который они в итоге сделали, C++, в настоящее время является самым распространённым языком программирования для платформы Microsoft Windows. Си остаётся более популярным в UNIX-подобных системах.
В 1983 году Американский Национальный Институт Стандартизации (ANSI) сформировал комитет для разработки стандартной спецификации Си. По окончании этого долгого и сложного процесса в 1989 году он был наконец утверждён как «Язык программирования Си» ANSI X3.159-1989. Эту версию языка принято называть ANSI C или C89. В 1990 году стандарт ANSI C был принят с небольшими изменениями (ISO) как ISO/IEC 9899:1990.
Одной из целей этого стандарта была разработка надмножества K&R C, включающего многие особенности языка, созданные позднее. Однако комитет по стандартизации также включил в него и несколько новых возможностей, таких как прототипы функций (заимствованные из С++) и более сложный препроцессор.
ANSI C сейчас поддерживают почти все существующие компиляторы. Почти весь код Си, написанный в последнее время, соответствует ANSI C. Любая программа, написанная только на стандартном Си, гарантированно будет правильно выполняться на любой платформе, имеющей соответствующую реализацию Си. Однако большинство программ написаны так, что они будут компилироваться только определённым компилятором, потому, что:
Вот некоторые новые особенности С99:
Интерес к поддержке новых особенностей С99 в настоящее время смешан. В то время как GCC, компилятор Си от Sun Microsystems и некоторые другие компиляторы в настоящее время поддерживают большую часть новых особенностей С99, компиляторы компаний Microsoft не делают этого, причём похоже, что две эти компании и не думают их добавлять.
Связь с C++
Язык программирования С++ произошёл от Си. Однако в дальнейшем Си и C++ развивались независимо, что привело к росту несовместимостей между ними. Последняя редакция Си, С99, добавила в язык несколько конфликтующих с С++ особенностей. Эти различия затрудняют написание программ и библиотек, которые могли бы нормально компилироваться и работать одинаково в компиляторах Си и C++, что, конечно, запутывает тех, кто программирует на обоих языках.
Бьёрн Строуструп, придумавший C++, неоднократно выступал за максимальное сокращение различий между Си и C++ для создания максимальной совместимости между этими языками. Противники же такой точки зрения считают, что так как Си и C++ являются двумя различными языками, то и совместимость между ними не так важна, хоть и полезна. Согласно этому лагерю, усилия по уменьшению несовместимости между ними не должны препятствовать попыткам улучшения каждого языка в отдельности.
Вот различия между этими языками, существующие на сегодня:
Си перенял от C++ ряд особенностей:
Приоритет операций в Си
Ниже приведены операции в порядке убывания приоритета. Операции, приведённые на одной строчке, имеют одинаковый приоритет. Операции, помеченные как R->L, имеют правую ассоциативность (то есть при сочетании равноприоритетных операций без скобок они вычисляются справа налево; при этом порядок вычисления аргументов большинства операций не специфицирован и зависит от реализаций):
Известные компиляторы языка Си [2]
Компиляторы на динамические языки и платформы
Иногда, в целях переноса тех или иных библиотек, функций и инструментов, написанных на Си, в иную среду, требуется компиляция Си-кода на язык более высокого уровня или в код виртуальной машины, предназначенной для такого языка.
Следующие проекты предназначены для этих целей:
Примечания
См. также
Ссылки
Литература
Смотреть что такое «Язык программирования Си» в других словарях:
Язык программирования C++ — Эта статья о книге; о языке программирования см.: C++. Язык программирования C++ The C++ Programming Language Автор: Бьёрн Страуструп Язык оригинала: английский Оригинал издан: 1986 Издательство: Addison–Wesley … Википедия
Язык программирования — искусственный (формальный) язык, предназначенный для записи алгоритмов. Язык программирования задается своим описанием и реализуется в виде специальной программы: компилятора или интерпретатора. По английски: Programming language Синонимы:… … Финансовый словарь
ЯЗЫК ПРОГРАММИРОВАНИЯ — (programming language) Язык, используемый для выдачи задания (программы) (program) компьютеру (computer). Существует два основных вида языков программирования: языки низкого уровня (low level languages) и языки высокого уровня (high level… … Словарь бизнес-терминов
язык программирования — Язык, предназначенный для представления программ. Примечание К традиционным языкам программирования процедурного типа относят, как правило, языки для представления программ в виде последовательности предписания [ГОСТ 28397 89] Тематики обеспеч.… … Справочник технического переводчика
ЯЗЫК ПРОГРАММИРОВАНИЯ — это совокупность набора символов (алфавита) системы, правил образования (синтаксис) и истолкования конструкции из символов (семантика) для задания алгоритмов с использованием символов естественного языка. В самом общем виде формальный язык… … Большая политехническая энциклопедия
ЯЗЫК ПРОГРАММИРОВАНИЯ — ЯЗЫК ПРОГРАММИРОВАНИЯ, система слов и правил, используемая для создания программ для КОМПЬЮТЕРА. Большинство компьютеров работает на основе двоичных языков (использующих два знака, 0 и 1), которые называют МАШИННЫМИ КОДАМИ. Для формулировки… … Научно-технический энциклопедический словарь
Язык программирования — Язык программирования формальная знаковая система, предназначенная для записи компьютерных программ. Язык программирования определяет набор лексических, синтаксических и семантических правил, задающих внешний вид программы и действия,… … Википедия
Язык программирования C — Си Семантика: процедурный Тип исполнения: компилируемый Появился в: 1969 73 г. Автор(ы): Кен Томпсон, Денис Ритчи Типизация данных: статическая Основные реализации … Википедия
Язык программирования — ОСНОВНЫЕ ПОНЯТИЯ 1 Язык программирования Programming language Язык, предназначенный для представления программ. Примечание К традиционным языкам программирования процедурного типа относят, как правило, языки для представления программ в виде… … Словарь-справочник терминов нормативно-технической документации
язык программирования — programavimo kalba statusas T sritis automatika atitikmenys: angl. programming language vok. Programmiersprache, f rus. язык программирования, m pranc. langage de programmation, m … Automatikos terminų žodynas