Назад | Вперед

Раздел 1. Основы программирования

Тема 1. Основные положения и определения

Процесс программирования
Уровни языков программирования
Компиляторы и интерпретаторы
Системы программирования

Процесс программирования

Как известно из курса дисциплины «Информатика», под программой в этой предметной области понимается логически упорядоченная последовательность команд, необходимых для управления компьютером, т.е. выполнения им конкретных операций. Программирование же, как род деятельности сводится к созданию последовательности команд, необходимой для решения опреде­ленной задачи с помощью ЭВМ, а люди, обученные процессу их составления с помощью языков программирования (программированию) называются программистами [8].
Процесс поиска ошибок в программе называется тестированием, а процесс устранения ошибок — отладкой.
Появление первых компьютеров породило программирование как науку. Разрабатывались первые математические теории обработки информации, средства доказательства правильности программ, оптимизации кода, создания эффективных компиляторов, формального тестирования и т. д. Затем, с появлением универсальных языков программирования третьего поколения, эти аспекты стали менее актуаль­ными — исследования шли и идут в основном в области автоматической генерации исходных текстов и повышения эффективности компиляторов. При этом программирование одновременно становится и искусством - миллионы людей, не имевших специального образо­вания, получили возможности применять компьютеры для решения собственных прикладных задач, что потребовало от них мастерства создавать правильно работающие программы. Искусством программирование остается и сегодня для профессиональных разработчиков и любителей, создающих программы в одиночку или в небольших компаниях, где все решает индивидуальное мастерство.
Как следует из логики программирования, сначала всегда разрабатывается алгоритм действий, а потом он записы­вается на одном из таких языков. В итоге получается текст программы — полное, законченное и детальное описание алгоритма на языке программирования.
Процессор компьютера — это большая интегральная микросхема. Все команды и данные он получает в виде электрических сигналов, которые можно представить как совокупности нулей и единиц, то есть числами. Разным командам соответствуют разные числа. Поэтому реально, на физическом уровне программное обеспечение, под управлением которого работает процессор, представляет собой последова­тельность чисел, называемую машинным кодом.
В то же время, управлять компьютером нужно в определенной последовательности или говорят - по определенному алгоритму. Следовательно, алгоритм — это точно определенное описание способа решения задачи в виде конечной (по времени) последовательности действий.
Описать даже простую такую последовательность действий компьютера в машинном коде весьма сложно, причем эта сложность резко возрастает с увеличением трудоемкости решения нужной задачи. Поэтому сегодня для представления алгоритма в виде, понятном компьютеру, служат так называемые языки программирования.
Языки программирования — это специальные искусственные языки. От естественных они отлича­ются ограниченным числом «слов», значение которых понятно транслятору, и очень строгими правилами записи команд (операторов). Совокупность подобных тре­бований образует синтаксис языка программирования, а смысл каждой команды и других конструкций языка - его семантику. Нарушение формы записи программы приводит к тому, что ЭВМ не может понять назначение оператора и выдает сообщение о синтаксической ошибке, а правильно написанное, но не отвечающее алгоритму использование команд языка приводит к семантическим ошибкам (назы­ваемые еще логическими ошибками или ошибками времени выполнения).


Наверх

Уровни языков программирования

Разные типы процессоров имеют разные наборы команд. Если язык программирования ориентирован на конкретный тип процессора и учитывает его особенности, то он называется языком программирования низкого уровня. В данном случае «низкий уровень» не значит «плохой». Имеется в виду, что операторы языка близки к машин­ному коду и ориентированы на конкретные команды процессора.
Языком самого низкого уровня является язык ассемблера, который просто представ­ляет каждую команду машинного кода, но не в виде чисел, а с помощью символьных условных обозначений, называемых мнемониками. Однозначное преобразование одной машинной инструкции в одну команду ассемблера называется транслитерацией. Так как наборы инструкций для каждого модели процессора отличаются, конкретной компьютерной архитектуре соответствует свой язык ассемблера, и написанная на нем программа может быть использована только в этой среде.
С помощью языков низкого уровня создаются очень эффективные и компактные программы, так как разработчик получает доступ ко всем возможностям процессора. С другой стороны, при этом требуется очень хорошо понимать устройство компью­тера, затрудняется отладка больших приложений, а результирующая программа не может быть перенесена на компьютер с другим типом процессора. Подобные языки обычно применяют для написания небольших системных приложений, драй­веров устройств, модулей стыковки с нестандартным оборудованием, когда важней­шими требованиями становятся компактность, быстродействие и возможность пря­мого доступа к аппаратным ресурсам. В некоторых областях, например в машинной графике, на языке ассемблера пишутся библиотеки, эффективно реализующие требующие интенсивных вычислений алгоритмы обработки изображений.
Языки программирования высокого уровня значительно ближе и понятнее человеку, нежели компьютеру. Особенности конкретных компьютерных архитектур в них не учитываются, поэтому создаваемые программы на уровне исходных текстов легко переносимы на другие платформы, для которых создан транслятор этого языка. Разрабатывать программы на языках высокого уровня с помощью понятных и мощ­ных команд значительно проще, а ошибок при создании программ допускается гораздо меньше.


Наверх

Компиляторы и интерпретаторы

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


Наверх

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

Итак, в самом общем случае для создания программы на языке программи­рования высокого уровня необходимо написать исходный текст программы, проверить его на отсутствие синтаксических ошибок и перевести в машин­ный код. При этом если будут обнаружены синтаксические ошибки, то результирующий код создавать, очевидно,  не имеет смысла.
На этом этапе уже возможно получение готовой программы, но чаще всего в ней либо не хватает некоторых компонентов, либо исходный текст большой программы разбит, как правило, на модули (файлы с исходными текстами), потому что хранить все тексты в одном файле неудобно. Поэтому транслятор обычно выдает проме­жуточный (объектный) код каждого модуля в виде двоичного файла со специальным стандартным расширением (например - * .obj или *.tpu), которые затем надо объединить в одно целое.
Кроме того, к ним надо добавить машинный код фрагментов программы (подпрограмм), реализующих различные стандартные функции (например, вычисляющих математические функции Sin(x) или Ln(x)). Такие функции, обычно, содержатся в библиотеках (файлах со стан­дартным расширением .lib), которые поставляются вместе с компилятором. При чем, сгене­рированный код модулей и подключенные к нему стандартные функции надо объединить в одно целое с учетом требований операционной системы, то есть получить на выходе программу, от­вечающую определенному формату.
Поэтому объектный код, полученный после транслятора, обрабатывается специальной программой — редактором связей или сборщиком, который выполняет связывание объектных модулей и машинного кода стандартных функций, находя их в библиотеках, и формирует на выходе работоспособное приложение - исполнимый код для конкретной платформы,
Если по каким-то причинам один из объектных модулей или нужная библио­тека не обнаружены (например, неправильно указан каталог с библиотекой), то сборщик сообщает об ошибке и готовой программы не получается.
Исполнимый код — это законченная программа, которую можно запустить на любом компьютере, где установлена операционная система, для которой эта программа создавалась. Как правило, итоговый файл имеет расширение *.exe или *.com.
Таким образом, в стандартную поставку любой системы программирования, как правило, входят как минимум три компонента,

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


Рис. 1.1 Система программирования Borland Pascal 7.0

Наверх

Назад | Вперед