M. УЭИТ - Язык Си - руководство для начинающих
Если вышеприведенные рассуждения выглядят скучными и непонятными, не огорчайтесь. Дело в том, что процесс перевода удалось переложить на сам компьютер! "Умные" программы, называемые компиляторами, выполняют весь объем работы, связанный с этим переводом. Детали процесса зависят от особенностей конкретной системы. Ниже кратко описано несколько способов перевода.
Компиляция Си-программы в ОС UNIX
Компилятор с языка Си в ОС UNIX называется cc. Чтобы осуществить компиляцию нашей программы, на клавиатуре дисплея необходимо набрать только строку:
cc inform.c
Через несколько секунд интерпретатор команд ОС UNIX выдаст на экран дисплея символ "приглашение", информируя нас, что задание выполнено. (Вообще говоря, мы можем получить предупреждения и сообщения об ошибках в том случае, если программа была написана с ошибками, но давайте предположим, что все было сделано правильно.) Если мы используем директиву Is, осуществляющую вывод на экран списка имен файлов, мы обнаружим новый файл с именем a.out — файл с выполняемой программой, содержащий результат трансляции (или "компиляции") нашей исходной программы. Чтобы выполнить ее, мы должны только набрать на клавиатуре символы a.out и на экране дисплея появится фраза:
Символ .c используется как окончание имени файла с Си-программой.
РИС. 1.4. Создание Си-программы в среде ОС UNIX.
Программа-компилятор, называемая сс, объединяет несколько последовательных шагов задания в один. Это станет более очевидным, когда мы рассмотрим выполнение аналогичного процесса компиляции на персональном компьютере.
Компиляция Си-программы на IBM PC
(компиляторы Microsoft С и Lattice С)
Описанное ниже разбиение процесса компиляции программы на последовательные шаги зависит как от операционной системы, так и от самого компилятора. Конкретный пример, который мы здесь рассматриваем, — это функционирование компилятора Microsoft С под управлением операционной системы PC DOS I.I (Компилятор Lattice С, лежащий в основе версии, реализованной фирмой Microsoft, запускается по аналогичным правилам, только вместо команд mс1 и mc2 необходимо использовать команды lс1 lс2.
Так же как и прежде, мы считаем, что исходная программа содержится в файле inform.с. Наша первая команда выглядит следующим образом:
mcl inform
(Компилятор интерпретирует строку символов inform как inform.с.) Если ошибок нет, то в результате будет получен промежуточный файл с именем inform.q. Затем мы набираем на клавиатуре следующую команду:
mc2 inform
в результате выполнения которой будет создан файл с именем inform.obj, содержащий так называемый "объектный код" (код на языке машины), соответствующий нашей исходной программе. (Объяснения приведены ниже.) После этого вводится команда
link с inform
по завершении которой создается файл inform.ехе. Наша цель достигнута — получен файл, содержащий выполняемую программу. Если мы затем введем команду
inform. ехе
или просто
inform
то наша программа начнет выполняться.
РИС. 1.5. Создание Си-программы при помощи компиляторов Microsoft С и Lattice С.
На самом деле вы можете не знать, что происходит, когда вы пользуетесь вышеописанной процедурой, но, если вам интересно, мы кратко опишем выполняемые при этом действия.
Что здесь нового? Во-первых, новым является то, что вводится файле именем inform.obj. Поскольку в нем содержится машинный код, непонятно, почему мы не остановились в этом месте? Ответом может служить то, что полная программа включает в себя части, которые мы не писали. Например, мы использовали команду printf, являющуюся программой, помещенной в Си-библиотеку. Вообще говоря, может возникать необходимость использовать в программе стандартные процедуры, помещенные в различные библиотеки. Эта потребность приводит к использованию второго нового понятия — команды link.
Программа link является частью операционной системы IBM POS. Она связывает наш объектный код (находящийся в файле inform.obj) с некоторыми стандартными процедурами, содержащимися в файле c.obj, и, кроме того, осуществляет поиск требуемых объектных модулей в той библиотеке, которую мы указываем (программа link запрашивает требуемое имя во время выполнения); в данном случае это будет библиотека с именем lc.lib. Затем указанная программа объединяет все найденные модули в одну полную программу.
Программа сс, работающая под управлением ОС UNIX, во время выполнения проходит аналогичную последовательность шагов; отличие состоит только в том, что она "скрывает" этот факт от нас, уничтожая файл с объектным модулем после его использования для получения полной программы. (Но в случае необходимости в ответ на соответствующий запрос компилятор выдаст нам объектный файл под именем inform.о.)
Альтернативный способ трансляции
В некоторых компиляторах с языка Си, работающих на персональных ЭВМ, реализованы другие способы трансляции. Метод, который только что обсуждался, можно охарактеризовать тем, что в результате мы получаем файл, содержащий объектный код (имя файла оканчивается символами. obj), а затем используем системный компоновщик для получения файла с выполняемой программой (его имя оканчивается символами ехе). Альтернативный метод состоит в том, что в результате трансляции мы вначале имеем файл, содержащий "ассемблерный код" (имя файла оканчивается символами. asm), а затем используем системную программу, называемую ассемблером, для получения файла с выполняемой программой.
Утомленный читатель может воскликнуть: "Как, неужели еще один код?" Поэтому сразу же поясним: ассемблерный код тесно связан с машинным кодом. Фактически это тот же самый код, только представленный в символьном виде. Например, JMP может соответствовать коду 11101001, являющемуся частью машинной команды, в результате выполнения которой осуществляется "перескок" (переход) к другой ячейке. (Вы, вероятно, представляете себе компьютер, снующий по пчелиным сотам, а мы имеем в виду другие ячейки памяти.) Программисты не без основания считают, что ассемблерный код более легок для восприятия, чем чисто машинный код, а задача перевода с одного языка на другой вполне может быть возложена на специальную программу, называемую ассемблером.
Почему компиляция?
Читатели, пользовавшиеся языком Бейсик, могут удивиться, зачем столько шагов для того, чтобы выполнить программу. Кажется, что такой способ компиляции требует больше времени (и в некоторых случаях это может быть действительно так). Но, поскольку в результате компиляции программа выполняется гораздо быстрее чем обычная программа, написанная на Бейсике, вам просто приходится испытывать некоторые неудобства при получении гораздо эффективнее работающего конечного продукта.
НЕКОТОРЫЕ СОГЛАШЕНИЯ
Теперь мы уже почти готовы начать последовательное описание языка Си. Нам осталось только упомянуть о некоторых соглашениях, которых мы будем придерживаться.
Вид шрифта
Для представления текста программ, данных ввода-вывода, имен файлов, программ и переменных мы применяем специальный шрифт, похожий на тот, который вы можете видеть на экране дисплея или на бумаге при выводе на печать. Мы уже использовали его несколько раз, но если вы не обратили на это внимания, то запомните, что он выглядит следующим образом:
printf (" Здравствуйте! n ");
Цвет
Сообщения компьютера во время диалога с пользователем даются голубым цветом; кроме того, важные слова, отражающие основные идеи или понятия, используемые в данной главе, мы помещаем перед текстом главы и печатаем также голубым цветом.
Устройство ввода-вывода
Вообще говоря, существует много способов ведения диалога человека с ЭВМ, но мы будем предполагать, что вы вводите команды при помощи клавиатуры и читаете ответ на экране дисплея.
Функциональные клавиши
Обычно вы посылаете команду ЭВМ, нажимая на клавишу с надписью enter (ввод), с/r (возврат каретки) или return (возврат). Названия клавиш иногда обозначаются прописными буквами. Пусть клавиша [enter] — [ввод]. Здесь квадратные скобки означают, что вы должны нажать на единственную клавишу, а не набирать все слово по буквам.
Кроме того, мы будем упоминать управляющие символы, назы вая их [CTRL/d]. Это обозначение указывает на то, что необходимо нажать клавишу [d], держа одновременно нажатой клавишу control.
Наша вычислительная система