CFA LogoCFA Logo Computer
Новости Статьи Магазин Драйвера Контакты
Новости
RSS канал новостей
В конце марта компания ASRock анонсировала фирменную линейку графических ускорителей Phantom Gaming. ...
Компания Huawei продолжает заниматься расширением фирменной линейки смартфонов Y Series. Очередное ...
Компания Antec в своем очередном пресс-релизе анонсировала поставки фирменной серии блоков питания ...
Компания Thermalright отчиталась о готовности нового высокопроизводительного процессорного кулера ...
Компания Biostar сообщает в официальном пресс-релизе о готовности флагманской материнской платы ...
Самое интересное
Программаторы 25 SPI FLASH Адаптеры Optibay HDD Caddy Драйвера nVidia GeForce Драйвера AMD Radeon HD Игры на DVD Сравнение видеокарт Сравнение процессоров

АРХИВ СТАТЕЙ ЖУРНАЛА «МОЙ КОМПЬЮТЕР» ЗА 2003 ГОД

Пашарпанный Си

Сергей Banzai БОЙКО ahura_masda@ua.fm

Более года назад Microsoft явила миру свои новые концептуальные разработки — платформу .NET и, несколько раньше, язык программирования нового поколения C# (подробнее см. статью Игоря ПАВЛОВА «Что .NET грядущий нам готовит», МК 10(233)). Поводом к написанию данной статьи послужило желание более многогранно ознакомить и заинтересовать вас данной темой. Надеюсь, мне это удастся :-).

Part I. Nothing is perfect…

Конец ХХ века ознаменовался бурным развитием информационных технологий. Теория, зревшая веками, наконец-то воплотилась в железе, более того, стала доступной для повседневного использования любому желающему, что не может не радовать. Но мозги — это ведь не просто железо. Поначалу с компьютерами было крайне тяжело общаться. Все программы-инструкции вводились побитно и представляли собой бесконечные вереницы нулей и единиц. Для удобства нули и единицы группируются в байты (8-бит), слова (два байта), а также по 4, 6 и 8 байтов.

Между прочим, бинарная логика — не первый и не единственный претендент на роль основополагающего стандарта. Ее воцарению предшествовали попытки научить ЭВМ мыслить «по-людски», десятичными числами. Дело в том, что механические и электромеханические предки наших полупроводниковых друзей состояли из шестеренок с десятью зубьями, соответственно, имели десятичную логику. И при переходе на чисто электронную базу ЭВМ первого поколения продолжали использовать десятичную арифметику, безусловно, из чисто консервативных соображений :-). Такие системы получались крайне нестабильными и излишне громоздкими. Была очевидна необходимость оптимизации через уменьшение разрядности чисел.

Так, в 50—60-х годах в Советском Союзе существовала система, действовавшая на основе «тринарной» логики (бит («трит»?) может принимать три разные состояния — 0, 1, Z). И несмотря на значительно большую, по сравнению с бинарной, компактность кода (тринарный байт принимает 38=1761 против 28=256 состояний), разработка не имела продолжения. Скорее всего, по причине очевидной и не особо оправданной перспективы усложнения и аппаратной, и программной частей системы… Хотя, кто знает, возможно, в недалеком будущем для продления действия закона Мура понадобится переход и на большее количество состояний бита.

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

Итак, первой оптимизацией труда программистов стал язык низкого уровня Assembler. В нем были реализованы символьное представление машинных регистров и операторов-команд, а также модульная организация программного кода, что тоже очень важно. Assembler — просто чемпион-долгожитель, и по сей день он продолжает успешно использоваться в наиболее чувствительных к скорости и объему используемой памяти частях кода. Оно и понятно, все его операторы работают на уровне операций с регистрами и физическими адресами в памяти (а также в портах ввода/вывода). При этом надо помнить, что Assembler — это прежде всего название технологии. Так, для разных микропроцессоров Assembler имеет свои нюансы, а что касается разных классов процессорных архитектур (х86 INTEL, RISC и др.), тут и говорить нечего — различия огромны. В пользу ассемблера говорит и тот факт, что Unix до появления «Сей» писался именно на нем! Но при всей своей незаменимости, эта среда не лишена очевидных проблем — в ней крайне затруднительно создание объемного кода с массой переменных и данных.

Через некоторое время вычислительные машины вышли из статуса лабораторного эксперимента, превратились в незаменимых помощников в решении разнообразных математических, экономических, научных и любых других сложных задач. Возросший спрос определил появление множества высокоуровневых языков программирования. Особенно многочисленными стали семейства языков Fortran и Algol. Самым известным представителем последнего из них является Pascal, обретший свою вторую жизнь в продукте Delphi фирмы Borland. Тем временем экспонентный рост сложности вычислительных систем требовал соответствующего повышения надежности, эргономичности, продуктивности работы и разработки программного обеспечения. Необходимость соответствовать этим требованиям приводила к быстрому увеличению объемов приложений. Код превращался в непроходимые джунгли, за которыми невозможно проследить ход самой программы. Такое положение дел требовало поистине революционных изменений в технологии программирования. Так в 60-х годах прошлого столетия и появилось структурное программирование. Структурные языки обогатились массой усовершенствований: добавились условные операторы и процедуры с локальными переменными.

И вот на этой благодатной почве произошло то, что по праву называют началом современной эры программирования. А именно, в 1972 году системный программист Ден Ричи разработал язык Си, в котором успешно сочетались мощность, элегантность и выразительность. Что сделало Си, начиная с 80-х годов, самым популярным языком структурного программирования. Но недолго музыка играла. При достижении объема кода порядка 5000 строк возникают проблемы в понимании программ и у структурного Си. В конце 70-х наступил момент, когда запахло новой революцией в концептуальном аппарате программирования. Появилось объектно-ориентированное программирование (ООП). Принципы ООП позволяли создать понятный программный проект значительно большего размера. А так как популярный Си не поддерживал ООП, назрела необходимость создания его ООП-версии. В 1979 году Бъярн Страуструп не стал изобретать велосипед, а лишь дополнил весьма удачный синтаксис языка Си новыми ООП-конструкциями. Соответственно, назван язык был «Си с классами» а в 83-м переименован в более лаконичное С++ (СРР). За неимением реальных конкурентов, в начале 90-х С++ заслуженно приобретает огромную популярность и массовость.

Наконец, вспомним времена, которые оставили заметный след в памяти современной молодежи. А именно начало 90-х, когда массовое внедрением РС’шек в народно-капиталистическое хозяйство и стремительное увеличение числа интернет-пользователей поставили на первый план проблему межплатформенной переносимости кода. Для решения этой задачи понадобился новый язык —Java. В 1991 году группа разработчиков компании Sun Microsystems начала создание кроссплатформенного языка Oak, который предполагали использовать при создании аппаратного обеспечения для встроенных контроллеров. Позже новый язык был переименован в Java и быстро завоевал доверие на просторах Интернета. Синтаксис Java основан на Си, ООП-модель — на С++, а переносимость достигнута за счет транслирования исходников в промежуточный язык —байт-код, предназначенный для исполнения виртуальной машиной Java (JVM). Таким образом, Java-программу можно запустить на любой платформе, содержащей JVM, которая, в свою очередь, уже реализована для множества систем. В то же время для запуска С/С++-программ требовалась перекомпиляция исходников в машинный код для каждой платформы отдельно, что является дорогим и трудоемким процессом. И все-таки, несмотря на ряд удачных идей, реализованных в Java, эта среда имеет ряд досадных ограничений. Так, детище Sun не поддерживает многоязыкового программирования. Способность совместной работы компонентов программы, написанных на разных языках, представляется весьма полезной и необходимой для написания больших программ, а также компонентов для динамических библиотек, etc. Не последней проблемой в жизни солнечной Jav’ы является отсутствие прямой поддержки средой Windows.

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

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

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

Part II. C# vs. .NET Framework

Новое время ставит новые задачи, что я и пытался продемонстрировать в несколько затянувшейся предыстории. Смею надеяться, терпеливый читатель сможет шире взглянуть на такой специфический род человеческой деятельности как программирование. Попытки создания совершенного языка программирования предпринимаются столь же долго, сколь существует само программирование. Следующей ступенью в эволюции компьютерных языков стал C# (читается «си шарп» с несколько невнятным «р»). Новые задачи и нерешенные проблемы подвигли в конце 90-х компанию Microsoft на разработку нового языка программирования, являющегося составной частью общей стратегии .NET.

В середине 2000-го года увидела свет альфа-версия C#. Наш герой напрямую связан с тремя наиболее используемыми и популярными во всем компьютерном мире языками — Си, С++, Java. Создатель Шарпа (Андерс Хейльсберг) пошел по проторенному пути, сосредоточившись на улучшениях и инновациях и оставив за основу объектную модель С++, синтаксис и большинство операторов Си. От Java Шарп взял прогрессивную идею использования промежуточного кода. И хотя C# и Java стоят на одной эволюционной ступени, между ними существуют глубокие различия. Тем не менее, если вы знаете Си/С++, то при изучении C# у вас не возникнет проблем в понимании синтаксиса. Аналогично, умение работать на Java облегчит вам освоение некоторых концепций C# .

«Шарп» содержит множество инновационных свойств, к наиболее важным из них относят встроенную поддержку компонентов ПО. Фактически новый Си создан как компонентно-ориентированный язык. Такие его элементы как свойства, методы и события непосредственно обеспечивают упомянутую поддержку. Еще одной важнейшей характеристикой C# стала способность работать в многоязыковом окружении. В связи с этим необходимо рассмотреть взаимоотношения C# и .NET Framework — средой, в которой он работает. Во-первых, C# изначально разрабатывался Microsoft для создания кода .NET Framework, а во-вторых, эта среда определяет библиотеки, используемые Шарпом.

Сама же система .NET Framework обеспечивает совместную работу различных языков программирования и выполнение платформонезависимых приложений. При этом она ни в коей мере не ограниченна OS Windows. Набор языков, доступных при создании полноценного .NET-кода, насчитывает аж 17 штук, а на момент прочтения вами этой статьи, наверное, и того больше. Таким образом, вкусить .NET сможет каждый, и это радует :-).

Си-Шарп использует две важные составляющие системы .NET Framework. Первая — это библиотека классов .NET. Следовательно, одно из условий переносимости вашей программы — ограниченность средствами, определенными библиотекой классов .NET. Второе — это не зависящая от языка среда исполнения (Common Language Runtime, CLR), система, управляющая исполнением вашей программы. Как вы понимаете, каждой отдельной платформе — своя личная CLR, именно она позволяет создавать мультиплатформенные многоязыковые программы, а также обеспечивает безопасность передачи данных. Более подробно система .NET и принципы работы CLR рассмотрены в уже упоминавшейся выше статье Игоря Павлова. Дабы не повторяться, я упомяну лишь самые основные этапы создания и исполнения .NET-программ.

Итак, среда исполнения CLR управляет исполнением кода, адаптированного к системе .NET, и работает она следующим образом. Компилируя C# и любую другую .NET-программу, получают файл со специальным кодом, названным промежуточным языком Microsoft (Microsoft Intermediate Language, MSIL). MSIL определяет набор переносимых инструкций, независимых от конкретного процессора. По существу, MSIL является «переносимым ассемблером» и воплощает развитие концепции байт-кода Java. Кстати, в файле скомпилированной .NET-программы кроме MSIL-кода содержится компонент метаданных — надо полагать, с его помощью CLR обеспечивает контроль и безопасность .NET-файлов. Далее CLR-среда, получив на исполнение .NET-программу (универсальный MSIL-код), запускает JIT-компилятор (Just In Time — В Нужный Момент), который-то и превращает MSIL во внутренний код, причем компилирует части программного кода по мере необходимости. Создается своеобразный «динамический вариант» исполняемого кода, а мы получаем скомпилированную программу, которая выполняется «на лету» — с той же скоростью (ну, почти), что и обыкновенные программы, но на любом процессоре.

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

У читателя, наделенного истинно программерским пытливым умом, могут возникнуть некоторые важные вопросы. Например, а зачем было выдумывать этот ваш C#, не проще ли было адаптировать С++ под .NET Framework? По сути, Microsoft так и сделала, добавив в С++ так называемые управляемые расширения. Но ведь C# специально разрабатывался для .NET-платформы, он предназначен для поддержки и развития этой технологии, поэтому позволяет намного легче выполнить поставленную задачу. Между прочим, сама Microsoft, по заявлениям ее представителей, расставляет акценты следующим образом. Предлагая принять за основные .NET-языки С# и Visual Basic, компания отмечает полную непринципиальность этого выбора. Скажем, штат ваших программистов работает на С++, программирует мейнфреймы на Cobol’e (также почтенный долгожитель), и на здоровье — им не придется переучиваться для работы в новой прогрессивной системе, тратить деньги и время работодателя.

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

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

Рекомендуем ещё прочитать:






Данную страницу никто не комментировал. Вы можете стать первым.

Ваше имя:
Ваша почта:

RSS
Комментарий:
Введите символы или вычислите пример: *
captcha
Обновить





Хостинг на серверах в Украине, США и Германии. © sector.biz.ua 2006-2015 design by Vadim Popov