Если послушать разговоры программистов друг с другом, то довольно часто можно услышать: «Мне не нравится язык А, потому что…» Среди разнообразных «потому что» выдвигаются обычно отсутствие тех или иных возможностей или необходимость при выполнении каких-либо действий производить «почесывание левого уха правой рукой». Несколько реже можно услышать высказывания типа: «Язык А хуже, чем язык В, потому что…»
Однако естественное желание программистов произвести оценку и сравнение различных языков программирования приводит, как правило, к однобокому сравнению их с точки зрения какой-либо области применения.
Выбор из используемых сегодня языков программирования одного, наилучшим образом подходящего для решения задачи, может оказаться трудным не только для начинающих, но и для специалиста.
Несмотря на изобилие, разработка и реализация новых языков продолжается по мере расширения использования компьютеров. Импульсом к созданию новых языков программирования является не только желание улучшить уже существующие, но и стремление крупных организаций к созданию языков для расширения задач определенного класса.
Давно замечено, что стоимость разработки и сопровождения программного обеспечения во много раз превышает стоимость используемых аппаратных средств. Поэтому выбор языка программирования, на котором будет осуществляться реализация проекта, является важным фактором, влияющим на снижение суммарных расходов по проекту.
К сожалению, языки программирования сложно сравнивать и оценивать.
Критерии для их сравнения и оценки плохо определены и не всегда учитывают цели, которые были поставлены при разработке того или иного языка программирования.
Какие же факторы должны учитываться при выборе языка программирования?
Ясно, что на первое место ставится соответствие языка программирования типу решаемой задачи. Если оказывается, что несколько языков подходит для решения данной задачи, то следует отдать предпочтение языку, которым программист лучше владеет, поскольку трудно написать хорошую программу на языке, который плохо усвоен. Философы говорят, что человек по-настоящему начинает понимать свой язык только после знакомства с одним из иностранных. Многие филологи высказываются более категорично: знание одного языка – это незнание никакого. Плох тот программист, который не хотел бы стать опытным. Профессионал должен знать в совершенстве 3–4 языка программирования и иметь общее представление еще минимум о 10. Фактор знакомства с языком не должен превалировать над всеми другими факторами. Если для решения задачи несколько языков одинаково хороши и программист одинаково успешно может ими пользоваться, то предпочтение отдается языку, обладающему более быстродействующим транслятором, с лучшей системой отладки, или создающему более эффективный код. Такая информация не всегда имеется в распоряжении программиста, но это дело практики и времени (при желании затраченного на исследование такого рода).
Компактность компилятора и скорость компиляции, длина и быстродействие объектной программы относятся к важнейшим характеристикам языка, но они останутся всего лишь благим пожеланием, если он не будет обладать таким весьма важным свойством, как простота.
Простота языка программирования, в первую очередь, нужна его разработчику и программисту. Простота ведет к более простому и более надежному компилятору.
Исторически наиболее простыми языками считают машинные языки и языки ассемблера первых ЭВМ. Речь идет не о простоте изучения, а о простоте реализации языка для машины.
В настоящее время машинные языки значительно усложнились, число команд, содержащихся в арсенале машины, превышает сотню; появились мощные операционные системы и программист, хорошо знающий язык ассемблера, встречается не часто. Теперь наблюдается тенденция к росту сложности самих языков программирования. Однако будущее – за простыми, хорошо структурированными языками. Разработчики языков должны перенять опыт у инженеров-конструкторов ЭВМ, которые давно используют такие средства достижения простоты и четкости организации сложных систем, как модульность, иерархичность, стандартизация.
Простота в некоторых языках программирования подменяется свойством «модульность», под которым понимается возможность работать, используя лишь подмножество языка. Иными словами, программист может не изучать язык полностью, а овладеть только теми его элементами, которые он считает необходимыми для своих задач.
Основным признаком языка высокого уровня является не то, что он позволяет писать программы в сжатой форме с использованием привычных слов, букв вместо цифр, как это имело место при программировании на машинном языке, а то, насколько он соответствует законам нашего мышления, нашим интеллектуальным возможностям. Насколько глубоко конструкции языка уходят от действительной реализации в машинных кодах является мерой высоты уровня языка.
Ключевые (зарезервированные) слова облегчают синтаксический анализ языка, однако их не должно быть слишком много.
Простоте языка способствует единообразие в символике. Негативный пример: в языках семейства dBase знак «=» – это и присвоение, и проверка на равенство; а «;» – это и разделитель операторов, и перенос на другую строку.
Надежность языка – это свойство, которое характеризуется вероятностью безошибочного написания и трансляции программы. Ошибки при написании программы зависят не только (и не столько) от свойств языка, сколько от квалификации программиста. Понятие надежности относительное. Надежность транслятора связана со свойствами языка, а способность обнаруживать ошибки тоже в значительной мере зависит от конструкций языка.
Быстрота трансляции в период зарождения и первых шагов языков программирования считалась несущественным показателем качества языка, поскольку планировалось, что этап трансляции однократный, однако со временем стало ясно, что этот этап в процессе разработки программы используется довольно часто (например, при обучении наблюдается обратная ситуация – программа много раз транслируется, а исполняется один раз).
Методы трансляции очень быстро развиваются, а теория трансляторов еще далека от завершения. В настоящее время самый «быстрый» транслятор – фирмы Borland.
Широко распространено мнение, что при разработке языка не обязательно заботиться об эффективности машинного кода, поскольку можно построить оптимизирующий транслятор, решающий эту задачу. Но это плохо подтверждается практикой.
Если оптимизация программы компилятором предусмотрена, то с помощью механизма указаний можно давать указания компилятору относительно того, что является критерием оптимизации – быстродействие или объем занимаемой памяти. Не следует пренебрегать таким показателем качества языка, как эффективность объектного кода, достаточно учесть следующие:
1. Сложность задач, решаемых с помощью ЭВМ, растет быстрее, чем производительность и ресурсы вычислительных систем.
2. Как бы ни было велико быстродействие ЭВМ и сколько бы не снижалась ее стоимость, оба качества проявляются при рациональном использовании.
3. Быстродействие ЭВМ не может расти неограниченно, хотя бы потому, что электромагнитные сигналы распространяются с конечной скоростью. Производительность ЭВМ растет главным образом за счет роста производительности процессора и оперативного запоминающего устройства. Совершенствование внешней памяти, периферии идет медленнее.
Критерий удобочитаемости для человека нередко приносится в жертву «удобочитаемости» для машин. Иногда ради сокращения текста программы от нее отказываются за счет соглашений об умолчании и неявных допущений. Естественно, компилятор или специальный программный модуль могут восстановить все сокращения.
Одним из важных элементов, способствующих удобочитаемости, являются комментарии. Оформление комментариев остается полностью в руках программиста. От того, насколько удачны комментарии и сколь удобно они размещены, существенно зависит скорость понимания программы.
Продуманный выбор имен в программе облегчает чтение программы.
Достижением в этой области можно считать «венгерскую нотацию», которая названа в честь родины ее создателя Charles Simonyi. Согласно ей имена функций строят по принципу «глагол – существительное». Например: Creat Window – создать окно.
Программа воспринимается лучше, когда имена переменных и других объектов раскрывают их содержание, т.е. язык для этого должен позволять достаточно длинные имена. Такого нельзя было позволить в ФОРТРАНЕ.
Блочность структуры завоевала широкое признание благодаря очевидным выгодам, ощущаемым как в процессе реализации языка, так и при программировании. Идеи структурного программирования наиболее естественным образом реализуются именно в языках с блочной структурой. Понятие структурного программирования рассмотрим позже (тема 5). Ясность структуры программы дает программисту большие преимущества. Структурную программу легче проектировать, понимать, сопровождать. В настоящее время по ряду объективных причин сложилась ситуация, когда первым языком программирования, с которым сталкивается начинающий, является Бейсик, который имеет слаборазвитую структуру данных, а также метки и условные переходы как средство реализации сложных алгоритмов. Все это не позволяет рекомендовать Бейсик в качестве учебного средства при изучении программирования. Его считают «вредным» языком, прививающим плохой стиль. Однако Бейсик имеет и положительные качества как самый распространенный и достаточно простой язык.
В современном программировании сконцентрировано внимание на языках СИ и Паскаль по двум причинам.
Во-первых, потому что эти языки программирования имеют сегодня очень большое значение. Во-вторых (и это, наверное, более важно), потому что значение этих языков программирования возрастет в ближайшем будущем еще больше.
2.4. История языка программирования С/С++
Язык С++ развился из С, который в свою очередь был создан на основе двух предшествующих языков — BSPL и В. Язык ВСРL был создан в 1967 году Мартином Ричардом как язык для написания компиляторов и программного обеспечения операционных систем. Кен Томпсон предусмотрел много возможностей в своем языке В — дубликате BCPL и использовал В да создания ранних версий операционной системы UNIX в Веll Laboratories в 1970 году на компьютере DEC PDP-7. И BCPL, и В были «нетипичными языками» — каждый элемент данных занимал одно слово в памяти и бремя обработки элемента данных, например, как целого или действительного числа падало на плечи программиста.
Язык С был развит из В Деннисом Ритчи в Веll Laboratories и первоначально реализован на компьютере DEC PDP-11 в 1972 году. С использует многие важные концепции BCPL и B, а также добавляет новые типы данных и другие свойства. Первоначально С приобрел широкую известность как язык разработки операционной системы UNIX. Сегодня фактически все новые операционные системы написаны на С или на С++. С независим от аппаратных средств. При тщательной разработке на С можно написать мобильные программы, переносимые на большинство компьютеров.
В конце 70-х годов С развился в то, что теперь относят к «традиционному С», «классическому С» или «С Кернигана и Ритчи».
Широкое распространение С на различных типах компьютеров (иногда называемых аппаратными платформами) привело, к сожалению, ко многим вариациям языка. Они были похожи, но несовместимы друг с другом. Это стало серьезной проблемой для разработчиков программ, нуждавшихся в написании совместимых программ, которые можно было бы выполнять на нескольких платформах. Стало ясно, что необходима стандартная версия С. В 1983 году при Американском Национальном Комитете Стандартов в области вычислительной техники и обработки информации был создан технически комитет X3J11, чтобы «обеспечить недвусмысленное и машинно-независимое определение языка». В 1989 году стандарт был утвержден. ANSI скооперировался с Международной Организацией Стандартов (ISO), чтобы стандартизовать С в мировом масштабе.
Совместный стандарт был опубликован в 1990 году и назван ANSI/ISO 9899:1990.
Разработчиком языка Си++ является Бьерн Страуструп. В своей работе он опирался на опыт создателей языков Симула, Модула 2, абстрактных типов данных. Основные работы велись в исследовательском центре компании Bell Labs.
На сегодня стандарт языка утвержден Международной организацией по стандартзации ISO. Его номер ISO/IEC 14882.
Си++ является универсальным языком программирования, в дополнение к которому разработан набор разнообразных библиотек. Поэтому, строго говоря, он позволяет решить практически любую задачу программирования. Тем не менее, в силу разных причин (не всегда технических) для каких-то типов задач он употребляется чаще, а для каких-то – реже.
С++ как преемник языка С широко используется в системном программировании. На нем можно писать высокоэффективные программы, в том числе операционные системы, драйверы и т.п. Язык С++ один из основных языков разработки трансляторов.
Поскольку системное программное обеспечение часто бывает написано на языке С или С++, то и программные интерфейсы к подсистемам ОС тоже часто пишут на С++. Соответственно, те программы, даже и прикладные, которые взаимодействуют с операционными системами, написаны на языке С++.
Распределенные системы, функционирующие на разных компьютерах, также разрабатываются на языке С++. Этому способствует то, что у широко распространенных компонентных моделей CORBA и COM есть удобные интерфейсы на языке С++.
Обработка сложных структур данных – текста, бизнес-информации, Internet-страниц и т.п. – одна из наиболее распространенных возможностей применения языка. В прикладном программировании, наверное, проще назвать те области, где язык С++ применяется мало.
Разработка графического пользовательского интерфейса на языке С++ выполняется, в основном, тогда, когда необходимо разрабатывать сложные, нестандартные интерфейсы. Простые программы чаще пишутся на языках Visual Basic, Java и т.п.
Программирование для Internet в основном производится на языках Java, VBScript, Perl.
В целом надо сказать, что языки С и С++ в настоящее время относятся к числу наиболее мощных и наиболее распространенных языков высокого уровня.