Файл: В., Фомин С. С. Курс программирования на языке Си Учебник.docx
ВУЗ: Не указан
Категория: Не указан
Дисциплина: Не указана
Добавлен: 16.03.2024
Просмотров: 193
Скачиваний: 1
ВНИМАНИЕ! Если данный файл нарушает Ваши авторские права, то обязательно сообщите нам.
Стандартные библиотеки. Стандартные библиотеки UNIX хранятся в каталогах /lib или /usr/lib. Ссылка на библиотеки осуществляется при помощи ключа компоновщика -l, который задается в команде сс вызова компилятора языка Си после всех ключей и параметров компилятора. Непосредственно за ключом (без пробела) указывается идентификатор библиотеки, например:
%cc . . . . -lx
где x - часть имени библиотеки (полное имя библиотеки в данном случае libx.a; стандартный префикс для библиотеки «lib»; стандарт-
■■III
Подготовка и выполнение программ
ное расширение имени для библиотеки 'a'). Обратите внимание, что libx.a есть название библиотеки, а не отдельного модуля, поэтому суффикс '.a' не обозначает «модуль на ассемблере», как, например, на рис. 8.2.
Стандартная библиотека языка Си просматривается компоновщиком автоматически, то есть указание этой библиотеки в командной строке вызова компилятора Си не требуется. Эта библиотека хранится в файле /lib/libc.a.
Библиотека математических функций хранится в файле /lib/ libm.a, поэтому указание библиотеки в команде вызова компилятора будет таким: -lm. Напомним, что ключ -l, являющийся ключом компоновщика, необходимо разместить в командной строке вызова компилятора Си после всех других ключей и параметров, так как просмотр библиотеки должен происходить после компиляции, когда становится известно, какие функции из библиотеки нужны для построения исполняемого модуля.
Создание и сопровождение собственных библиотек. В UNIX для создания и сопровождения библиотек объектных модулей служит программа ar (archivator - архиватор). Для библиотек в UNIX принят термин «архив»; отсюда в качестве расширения имени библиотеки используется буква 'а'.
При создании библиотеки необходимо иметь в виду, что компоновщик просматривает библиотечный файл только один раз. Если объектный модуль функции ссылается на другие имена из той же библиотеки, то он должен быть расположен в библиотеке до этих объектных модулей. Некоторые версии UNIX содержат программу ranlib, которая создает оглавление библиотеки, что позволяет компоновщику ld обращаться к элементам библиотеки в произвольном порядке. В некоторых реализациях UNIX функция построения оглавления библиотеки встроена в программы ar и ld.
Главное назначение программы ar - создание и обновление библиотечных файлов, используемых компоновщиком, однако ее можно применять и для любых других, аналогичных целей. Формат команды ar:
ar -ключ [ключ...] [позиционное_имя] архив имя. . .
Параметры в команде отделяются пробелами.
Параметр позиционное_имя не является обязательным. Ключей может быть несколько, тогда они записываются без пробелов и только с одним знаком '-'.
Параметр архив задает имя архивного файла.
Параметр имя... является списком имен объектных модулей, которые либо находятся в архиве, либо должны быть туда помещены.
Ключи программы ar имеют следующий смысл:
-
-d - исключить указанные (с помощью параметра имя...) файлы из архивного файла; -
-г - заменить указанные (параметром имя...) файлы в архивном файле. Если вместе с ключом r задается необязательный ключ u, то заменяются только файлы, имеющие более поздние даты модификации, чем файлы в архиве. Этот же ключ используется для включения в библиотеку новых файлов, то есть файлы, указанные параметром имя... и отсутствующие в библиотеке, добавляются в архив. Обычно новые файлы помещаются в конец архива. Если указать имя файла из архива в параметре по- зиционное_имя, то можно новые файлы поместить до или после этого файла. Для этого необходимо соответственно добавить к ключу -r необязательные литеры b (before) или a (after); -
-t - вывести в стандартный поток вывода оглавление архивного файла. При задании параметра имя... печатается информация только об указанных этим параметром файлах. Этот же ключ используется для включения в библиотеку новых файлов, то есть файлы, указанные параметром имя... и отсутствующие в библиотеке, добавляются в архив; -
-p - вывести в стандартный поток вывода указанные (параметром имя...) файлы из архива; -
-x - извлечь из архива указанные (параметром имя...) файлы. Если не задан параметр имя..., из архива извлекаются все файлы. В любом случае собственно архивный файл не изменяется; -
-v - выдавать пояснительные сообщения; -
-c - создать архивный файл. Обычно программа ar при необходимости создает архивный файл сама. Данный ключ подавляет информационное сообщение, выдаваемое при создании архивного файла.
Для размещения в личной библиотеке объектных модулей функций иллюстративной программы необходимо выполнить следующую команду:
%ar -rv libtree.a add_node.o new_node.o print.o
Здесь libtree.a - имя библиотеки (архивного файла).
Ключ -r задает режим замены объектных модулей, хранящихся в библиотеке, на объектные модули, список которых приведен в командной строке вызова архиватора ar после имени библиотеки. Так как в момент обработки указанной команды библиотеки не существовало, она будет создана автоматически. Ключ -v определяет режим вывода пояснительных сообщений о работе архиватора ar.
После занесения объектных модулей в библиотеку необходимо при помощи программы ranlib скорректировать (или создать) оглавление библиотеки, выполнив команду
%ranlib libtree.a
Рекомендуется ознакомиться с описанием программы ranlib до ее использования. Например, справку о ней можно получить так:
%man ranlib
Проверим созданную библиотеку, распечатав ее оглавление:
%ar -t libtree.a _ _.SYMDEF add_node.o new_node.o print.o
Первая строка - вызов программы-архиватора (ar). Последние 4 строки - это результат работы команды ar. Оглавление библиотеки содержится в разделе библиотеки _ _.SYMDEF. Остальные строки - это имена объектных модулей, находящихся в библиотеке. После того как библиотека объектных модулей создана, можно построить исполняемый модуль программы сортировки на основе бинарного дерева с помощью команды:
%cc -o tree tree.c -ltree
Здесь транслируется головной модуль (tree.c), объектные модули на этапе компоновки выбираются из библиотеки libtree.a, и строится исполняемая программа с именем tree. Ключ компоновщика -l позволяет задать имя библиотеки объектных модулей (полное имя библиотеки: libtree.a).
Предположим, что в исходный текст одной из функций (например, add_node( )) были внесены изменения. Тогда для построения обновленного варианта исполняемой программы необходимо выполнить следующие команды:
%cc -c add_node.c
%ar -rv libtree.a add_node.o
%cc -o tree tree.o -ltree
На этот раз нет необходимости в повторной трансляции головного модуля (он не подвергался правке), поэтому в последней строке задано имя уже существующего объектного модуля tree.o.
Применим в той же иллюстративной программе утилиту make для поддержания личной библиотеки объектных модулей в таком состоянии, когда она всегда содержит объектные модули, полученные из последних версий соответствующих исходных модулей. Выше был приведен пример файла зависимостей утилиты make, в котором все объектные модули, используемые для построения исполняемого модуля программы сортировки, указывались в командной строке вызова компилятора. В варианте make-файла, ориентированном на применение личной библиотеки объектных модулей, появляются два целевых файла: исполняемая программа сортировки (tree) и библиотека объектных модулей (libtree.a), причем исполняемая программа зависит от содержимого (объектных модулей) библиотеки. Взаимозависимость этих объектов определяется следующим образом:
tree: tree.o \ add_node.o \ new_node.o \ print.o \ libtree.a
libtree.a: libtree.a(add_node.o) \ libtree.a(new_node.o) \ libtree.a(print.o)
Обратите внимание, как указаны зависимость целевого файла tree от библиотеки libtree.a и, в свою очередь, ее зависимость от объектных модулей. Объектный модуль из библиотеки libtree.a указывается так:
имя_библиотеки(имя_модуля).
Для окончательного оформления make-файла используем два встроенных макроса утилиты make:
-
$@ - задает имя текущего целевого файла (в нашем случае - последнего (libtree.a)); -
$? - значение этого макроса вычисляется утилитой make - это имена всех модулей, которые подвергались изменениям.
Приведем один из вариантов полного текста make-файла (напомним, что его имя по умолчанию - makefile), позволяющего обновлять целевые файлы (исполняемую программу и библиотеку объектных модулей) в соответствии с изменениями в исходных текстах функций, входящих в состав иллюстративной программы:
tree: tree.o \
add_node.o \
new_node.o \ print.o \ libtree.a libtree.a: libtree.a(add_node.o) \ libtree.a(new_node.o) \ libtree.a(print.o)
ar -rv $@ $?
ranlib $@
cc -o tree tree.c -ltree
Теперь, для того чтобы построить исполняемый модуль, учитывающий все внесенные изменения в любые функции программы сортировки, необходимо просто набрать на клавиатуре команду make.
После внесения изменений, например в исходный текст функции new_node( ), и при выполнении команды make получим на экране дисплея следующий протокол:
%make
cc -o -c new_node
ar -rv libtree.a new_node.o
r - new_node.o ranlib libtree.a
cc -o tree tree.c -ltree
Строка, следующая за командой вызова архиватора ar (r - new_ node.o), - это сообщение архиватора о замене объектного модуля new_node.o в библиотеке libtree.a.
Контрольные вопросы
-
Опишите упрощенную схему подготовки программ к выполнению, характерную для большинства операционных систем. -
Дайте определения исходного и объектного модулей. -
Объясните необходимость существования объектного модуля. -
Перечислите возможные технологии сборки готовой к выполнению программы. -
Для чего служит утилита make в операционных системах семейства UNIX? -
Опишите схему подготовки исполняемой программы в ОС UNIX. -
Что является исходными данными для утилиты make? -
Дайте определение целевого файла. -
Приведите формат файла описаний зависимостей модулей. -
Припомните формат команды make. -
Что позволяет использование библиотек объектных модулей? -
Опишите процесс трансляции и выполнения программ из командной строки ОС UNIX.
Приложение 1
ТАБЛИЦЫ КОДОВ ASCII
Таблица П1.1. Коды управляющих символов (0-31)
Символ | Код 10 | Код 08 | Код 16 | Клавиши | Значение |
nul | 0 | 0 | 00 | "@ | Нуль |
soh | 1 | 1 | 01 | "A | Начало заголовка |
stx | 2 | 2 | 02 | "B | Начало текста |
etx | 3 | 3 | 03 | "C | Конец текста |
eot | 4 | 4 | 04 | "D | Конец передачи |
enq | 5 | 5 | 05 | "E | Запрос |
ack | 6 | 6 | 06 | "F | Подтверждение |
bel | 7 | 7 | 07 | "G | Сигнал (звонок) |
bs | 8 | 10 | 08 | "H | Забой (шаг назад) |
ht | 9 | 11 | 09 | "I | Горизонтальная табуляция |
lf | 10 | 12 | 0A | "J | Перевод строки |
vt | 11 | 13 | 0B | "K | Вертикальная табуляция |
ff | 12 | 14 | 0C | "L | Новая страница |
cr | 13 | 15 | 0D | "M | Возврат каретки |
so | 14 | 16 | 0E | "N | Выключить сдвиг |
si | 15 | 17 | 0F | "O | Включить сдвиг |
dle | 16 | 20 | 10 | "P | Ключ связи данных |
dc1 | 17 | 21 | 11 | "Q | Управление устройством 1 |
dc2 | 18 | 22 | 12 | "R | Управление устройством 2 |
dc3 | 19 | 23 | 13 | "S | Управление устройством 3 |
dc4 | 20 | 24 | 14 | "T | Управление устройством 4 |
nak | 21 | 25 | 15 | "U | Отрицательное подтверждение |
syn | 22 | 26 | 16 | "V | Синхронизация |
etb | 23 | 27 | 17 | "W | Конец передаваемого блока |
can | 24 | 30 | 18 | "X | Отказ |
em | 25 | 31 | 19 | "Y | Конец среды |
sub | 26 | 32 | 1A | "Z | Замена |
esc | 27 | 33 | 1B | "[ | Ключ |
351
Таблица П1.1. Коды управляющих символов (0-31) (окончание)
Символ | Код 10 | Код 08 | Код 16 | Клавиши | Значение |
fs | 28 | 34 | 1C | "\ | Разделитель файлов |
gs | 29 | 35 | 1D | "] | Разделитель группы |
rs | 30 | 36 | 1E | "" | Разделитель записей |
us | 31 | 37 | 1F | | Разделитель модулей |
1 ... 24 25 26 27 28 29 30 31 ... 42
В графе «Клавиши» обозначение " соответствует нажатию клавиши Ctrl, вместе с которой нажимается соответствующая «буквенная» клавиша, формируя код символа.
Таблица П1.2. Символы с кодами 32-127
Символ | Код 10 | Код 08 | Код 16 | | Символ | Код 10 | Код 08 | Код 16 |
пробел | 32 | 40 | 20 | | | 58 | 72 | 3A |
! | 33 | 41 | 21 | | ; | 59 | 73 | 3B |
« | 34 | 42 | 22 | | < | 60 | 74 | 3C |
# | 35 | 43 | 23 | | = | 61 | 75 | 3D |
$ | 36 | 44 | 24 | | > | 62 | 76 | 3E |
% | 37 | 45 | 25 | | ? | 63 | 77 | 3F |
& | 38 | 46 | 26 | | @ | 64 | 100 | 40 |
' | 39 | 47 | 27 | | A | 65 | 101 | 41 |
( | 40 | 50 | 28 | | B | 66 | 102 | 42 |
) | 41 | 51 | 29 | | C | 67 | 103 | 43 |
* | 42 | 52 | 2A | | D | 68 | 104 | 44 |
+ | 43 | 53 | 2B | | E | 69 | 105 | 45 |
, | 44 | 54 | 2C | | F | 70 | 106 | 46 |
- | 45 | 55 | 2D | | G | 71 | 107 | 47 |
. | 46 | 56 | 2E | | H | 72 | 110 | 48 |
/ | 47 | 57 | 2F | | I | 73 | 111 | 49 |
0 | 48 | 60 | 30 | | J | 74 | 112 | 4A |
1 | 49 | 61 | 31 | | K | 75 | 113 | 4B |
2 | 50 | 62 | 32 | | L | 76 | 114 | 4C |
3 | 51 | 63 | 33 | | M | 77 | 115 | 4D |
4 | 52 | 64 | 34 | | N | 78 | 116 | 4E |
5 | 53 | 65 | 35 | | O | 79 | 117 | 4F |
6 | 54 | 66 | 36 | | P | 80 | 120 | 50 |
7 | 55 | 67 | 37 | | Q | 81 | 121 | 51 |
8 | 56 | 70 | 38 | | R | 82 | 122 | 52 |
9 | 57 | 71 | 39 | | S | 83 | 123 | 53 |
1 ... 25 26 27 28 29 30 31 32 ... 42