- •Предисловие
- •Раздел 1. Полный курс программирования на стандартном языке Си Глава 1. Базовые понятия языка
- •1.1. Алфавит, идентификаторы, служебные слова Алфавит
- •Идентификатор
- •Служебные (ключевые) слова
- •1.2. Константы и строки
- •Символы, или символьные константы.
- •Целые константы.
- •Вещественные константы.
- •Предельные значения и типы арифметических констант.
- •Целые константы и выбираемые для них типы
- •Данные вещественных типов
- •Нулевой указатель.
- •Строки, или строковые константы.
- •1.3. Переменные и именованные константы Переменная как объект.
- •Определение переменных.
- •Предельные значения переменных.
- •Основные типы данных
- •Инициализация переменных.
- •Именованные константы.
- •1.4. Операции
- •Знаки операций.
- •Приоритеты (ранги) операций
- •Унарные (одноместные) операции.
- •1.5. Разделители
- •Квадратные скобки.
- •Круглые скобки.
- •Запятая.
- •Точка с запятой.
- •Двоеточие.
- •Многоточие.
- •Звездочка.
- •Обозначение присваивания.
- •Признак препроцессорных средств.
- •1.6. Выражения и приведение арифметических типов
- •Отношения и логические выражения.
- •Присваивание (выражение и оператор).
- •Приведение типов.
- •Правила преобразования типов
- •Правила стандартных арифметических преобразований
- •Выражения с поразрядными операциями.
- •Условное выражение.
- •Глава 2. Введение в программирование на языке си
- •2.1. Структура и компоненты простой программы
- •Текст программы и препроцессор.
- •Структура программы.
- •Функция форматированного вывода.
- •Программы печати предельных констант.
- •Применимость вещественных данных.
- •Выделение лексем из текста программы.
- •2.2. Элементарные средства программирования Деление операторов языка Си на группы.
- •Программа оценки машинного нуля.
- •Трассировочная таблица
- •Ввод данных.
- •Вычисление объема цилиндра.
- •Сумма членов ряда Фибоначчи.
- •2.3. Операторы цикла Три формы операторов цикла.
- •Приближенное значение экспоненты.
- •Оператор break.
- •Сумма отрезка степенного ряда.
- •Оператор continue.
- •Суммирование положительных чисел.
- •2.4. Массивы и вложение операторов цикла Массивы и переменные с индексами.
- •Вычисление среднего и дисперсии.
- •Упорядочение в одномерных массивах.
- •Инициализация массивов.
- •2.5. Функции Определение функций.
- •Функция для вычисления объема цилиндра.
- •Функция для вычисления скалярного произведения векторов.
- •Обращение к функции и ее прототип.
- •Вычисление биномиального коэффициента.
- •Вычисление объема цилиндра
- •Вычисление площади треугольника.
- •Скалярное произведение векторов.
- •2.6. Переключатели
- •Глава 3. Препроцессорные средства
- •3.1. Стадии и команды препроцессорной обработки
- •Стадии препроцессорной обработки.
- •Директивы препроцессора.
- •3.2. Замены в тексте Директива #define.
- •Цепочка подстановок.
- •3.3. Включение текстов из файлов
- •3.4. Условная компиляция Директивы ветвлений.
- •Операция defined.
- •3.5. Макроподстановки средствами препроцессора
- •Моделирование многомерных массивов.
- •Отличия макросов от функций.
- •Препроцессорные операции в строке замещения.
- •3.6. Вспомогательные директивы
- •Препроцессорные обозначения строк.
- •Реакция на ошибки.
- •Пустая директива.
- •Прагмы.
- •3.7. Встроенные (заранее определенные) макроимена
- •Глава 4. Указатели, массивы, строки
- •4.1. Указатели на объекты Адреса и указатели.
- •Операции над указателями.
- •Арифметические операции и указатели.
- •Указатели и отношения.
- •4.2. Указатели и массивы Указатели и доступ к элементам массивов.
- •Массивы динамической памяти.
- •Функции для выделения и освобождения памяти
- •Массивы указателей и моделирование многомерных массивов.
- •"Матрица" со строками разной длины.
- •4.3. Символьная информация и строки
- •Ввод-вывод символьных данных.
- •Внутренние коды и упорядоченность символов.
- •Строки, или строковые константы.
- •Строки и указатели.
- •Глава 5. Функции
- •5.1. Общие сведения о функциях Определение функции.
- •Описание функции и ее тип.
- •Вызов функции.
- •5.2. Указатели в параметрах функций Указатель-параметр.
- •Имитация подпрограмм.
- •5.3. Массивы и строки как параметры функций Массивы в параметрах.
- •Резюме по строкам-параметрам.
- •5.4. Указатели на функции Указатели при вызове функций.
- •Указатели на функции как параметры
- •Указатель на функцию как возвращаемое функцией значение.
- •Библиотечные функции с указателями на функции в параметрах.
- •5.5. Функции с переменным количеством параметров
- •Доступ к адресам параметров из списка.
- •Макросредства для переменного числа параметров.
- •Примеры функций с переменным количеством параметров.
- •5.6. Рекурсивные функции
- •5.7. Классы памяти и организация программ Локализация объектов.
- •Глобальные объекты.
- •Динамическая память
- •Внешние объекты.
- •5.8. Параметры функции main( )
- •Глава 6. Структуры и объединения
- •6.1. Структурные типы и структуры Производные типы.
- •Структурный тип.
- •Определение структур.
- •Выделение памяти для структур.
- •Инициализация и присваивание структур.
- •Доступ к элементам структур.
- •6.2. Структуры, массивы и указатели Массивы и структуры в качестве элементов структур.
- •Массивы структур.
- •Указатели на структуры.
- •Указатели как средство доступа к компонентам структур.
- •Указатели на структуры как компоненты структур.
- •6.3. Структуры и функции
- •Имитация абстрактных типов данных.
- •6.4. Динамические информационные структуры Статическое и динамическое представление данных.
- •Односвязный список.
- •Рекурсия при обработке списка.
- •6.5. Объединения и битовые поля Объединения.
- •Битовые поля.
- •Глава 7. Ввод и вывод
- •7.1. Потоковый ввод-вывод
- •7.1.1. Открытие и закрытие потока
- •7.1.2. Стандартные файлы и функции для работы с ними
- •Ввод-вывод отдельных символов.
- •Ввод-вывод строк.
- •Форматный ввод-вывод.
- •Спецификаторы форматной строки для функции форматного вывода
- •Спецификаторы форматной строки для функции форматного ввода
- •7.1.3. Работа с файлами на диске
- •Двоичный (бинарный) режим обмена с файлами.
- •Строковый обмен с файлами.
- •Позиционирование в потоке.
- •Трехъязычный словарь "Цифры
- •7.2. Ввод-вывод нижнего уровня
- •7.2.1. Открытие / закрытие файла
- •7.2.2. Чтение и запись данных
- •7.2.3. Произвольный доступ к файлу
- •Глава 8. Примеры разработки программ
- •8.1. Программа с объектами разных классов памяти Постановка задачи.
- •Программная реализация.
- •8.2. Структуры и обработка списков в основной памяти Постановка задачи.
- •Функция main( ).
- •Функция init( ) - "Инициализировать базу данных".
- •Функция delete() - "Удалить все сведения о сотруднике из базы данных".
- •Функция fr( ) - "Возвратить освобожденный элемент в список свободных элементов".
- •Функция input( ) - "Ввести в базу данных сведения о новом сотруднике".
- •Функция print( ) - "Печать списка занятых элементов".
- •Сохранение (восстановление) базы данных.
- •8.3. Сортировка на основе бинарного дерева Статические и динамические данные.
- •Управление динамической памятью.
- •Сортировка с помощью бинарного дерева.
- •Печать результатов сортировки.
- •Раздел 2. Выполнение программ в разных операционных системах Глава 9. Подготовка и выполнение программ
- •9.1. Подготовка программ в операционной системе unix
- •9.1.1. Команда make
- •Формат файла описаний зависимостей модулей.
- •Формат команды make.
- •Макроопределения.
- •Встроенные правила.
- •9.1.2. Библиотеки объектных модулей
- •Стандартные библиотеки.
- •Создание и сопровождение собственных библиотек.
- •9.2. Сборка и выполнение программ в интегрированной среде Turbo с 2.0
- •9.2.1. Состав системы программирования Turbo с 2.0
- •9.2.2. Экран интегрированной среды Turbo с 2.0
- •9.2.3. Система меню среды Turbo с 2.0
- •9.2.4. Настройка среды Turbo с
- •Создание рабочего каталога.
- •Установка в среде Turbo с 2.0 полных имен каталогов.
- •Настройка параметров управления проектом.
- •9.5. Окно определения проекта
- •Сборка и выполнение программы.
- •1. Команды управления курсором:
- •2. Команды вставки и удаления:
- •3. Команды обработки блоков текста:
- •4. Дополнительные команды:
- •9.3.2. Экран интегрированной среды
- •9.3.3. Система меню интегрированной среды
- •Задание полных имен основных и рабочего каталогов.
- •Выбор стандарта языка Си.
- •Установка параметров подсистемы Make.
- •Создание проекта.
- •Задание аргументов командной строки.
- •Сохранение параметров настройки интегрированной среды.
- •Сборка и выполнение программы.
- •Работа в интегрированной среде в последующих сеансах.
- •Раздел 3. Практикум по программированию на языке Си Глава 10. Задачи по программированию
- •10.1. Ознакомительная работа
- •10.2. Итерационные методы и ряды
- •Варианты заданий по итерационным методам и рядам
- •10.3. Работа со строками. Указатели, динамические одномерные массивы
- •10..1. Варианты задач по обработке строк*
- •10.3.2. Рекомендации по обработке строк
- •10.3.3. Пример выполнения задания по обработке строк
- •10.4. Многомерные динамические массивы с переменными размерами
- •10.4.1. Варианты задач для 1-й части задания по многомерным массивам (правила формирования многомерного массива)
- •10.4.2. Варианты для 2-й части задания по многомерным массивам
- •10.4.3. Пример выполнения задания по многомерным динамическим массивам
- •10.5. Функции и указатели
- •10.6. Функции и массивы
- •10.7. Работа со структурами
- •10.7.1. Варианты структур для выполнения работы
- •10.8. Списки и деревья
- •10.8.1. Списки
- •10.8.2. Деревья
- •Приложение 1. Таблицы кодов ascii
- •Коды управляющих символов (0 31)
- •Символы с кодами 32 127
- •Символы с кодами 128 255 (Кодовая таблица 866 - ms-dos)
- •Символы с кодами 128 255 (Кодовая таблица 1251 - ms Windows)
- •Приложение 2. Константы предельных значений
- •Приложение 3. Стандартная библиотека функций языка Си
- •Функции для работы с терминалом в текстовом режиме (файл conio.H)
- •Специальные функции
- •Литература
- •Содержание
- •Раздел 1. Полный курс программирования на стандартном языке Си 4
- •Глава 1. Базовые понятия языка 4
- •Глава 2. Введение в программирование на языке си 33
- •Глава 3. Препроцессорные средства 73
- •Глава 4. Указатели, массивы, строки 91
- •Глава 5. Функции 114
- •Глава 6. Структуры и объединения 155
- •Глава 7. Ввод и вывод 186
- •Глава 8. Примеры разработки программ 218
- •Раздел 2. Выполнение программ в разных операционных системах 256
- •Глава 9. Подготовка и выполнение программ 256
- •Раздел 3. Практикум по программированию на языке Си 282
- •Глава 10. Задачи по программированию 282
- •Подбельский Вадим Валерьевич Фомин Сергей Сергеевич программирование на языке си
- •101000, Москва, ул. Покровка, 7 Телефон (095) 925-35-02, факс (095) 925-09-57
9.1.2. Библиотеки объектных модулей
При разработке программной системы объектные модули функций, входящих в ее состав, целесообразно размещать в библиотеках объектных модулей, а в командной строке вызова компилятора указывать эти библиотеки. Использование библиотек позволяет не задавать непосредственно в командной строке все необходимые для построения исполняемой программы объектные модули. Компоновщик на этапе построения исполняемой программы будет выбирать из библиотеки только те объектные модули функций, которые необходимы.
Стандартные библиотеки.
Стандартные библиотеки. Стандартные библиотеки UNIX хранятся в каталогах /lib или /usr/lib. Ссылка на библиотеки осуществляется при помощи ключа компоновщика -l, который задается в команде ее вызова компилятора языка Си после всех ключей и параметров компилятора. Непосредственно за ключом (без пробела) указывается идентификатор библиотеки, например
где х - часть имени библиотеки (полное имя библиотеки в данном случае libx.a; стандартный префикс для библиотеки "lib"; стандартное расширение имени для библиотеки 'а'). Обратите внимание, что libx.a есть название библиотеки, а не отдельного модуля, поэтому суффикс '.а' не обозначает "модуль на ассемблере", как, например, на рис. 9.2.
Стандартная библиотека языка Си просматривается компоновщиком автоматически, т.е. указание этой библиотеки в командной строке вызова компилятора Си не требуется. Эта библиотека хранится в файле /lib/libc.a.
Библиотека математических функций хранится в файле /lib/libm.a, поэтому указание библиотеки в команде вызова компилятора будет таким: -lm. Напомним, что ключ -1, являющийся ключом компоновщика, необходимо разместить в командной строке вызова компилятора Си после всех других ключей и параметров, так как просмотр библиотеки должен происходить после компиляции, когда становится известно, какие функции из библиотеки нужны для построения исполняемого модуля.
Создание и сопровождение собственных библиотек.
Создание и сопровождение собственных библиотек. В UNIX для создания и сопровождения библиотек объектных модулей служит программа ar (archivator - архиватор). Для библиотек в UNIX принят термин "архив"; отсюда в качестве расширения имени библиотеки используется буква 'а'.
При создании библиотеки необходимо иметь в виду, что компоновщик просматривает библиотечный файл только один раз. Если объектный модуль функции ссылается на другие имена из той же библиотеки, то он должен быть расположен в библиотеке до этих объектных модулей. Некоторые версии UNIX содержат программу ranlib, которая создает оглавление библиотеки, что позволяет компоновщику ld обращаться к элементам библиотеки в произвольном порядке. В других версиях UNIX (например, UNIX System V) функция построения оглавления библиотеки встроена в программы аr и ld.
Главное назначение программы аr - создание и обновление библиотечных файлов, используемых компоновщиком, однако ее можно применять и для любых других аналогичных целей. Формат команды аr:
аr - ключ [ключ...] [позиционное_имя] архив имя. . .
Параметры в команде отделяются пробелами.
Параметр позиционное_имя не является обязательным. Ключей может быть несколько, тогда они записываются без пробелов и только с одним знаком '-'.
Параметр архив задает имя архивного файла.
Параметр имя... является списком имен объектных модулей, которые либо находятся в архиве, либо должны быть туда помещены.
Ключи программы аr имеют следующий смысл:
-d - исключить указанные (с помощью параметра имя...) файлы из архивного файла;
-r -заменить указанные (параметром имя...) файлы в архивном файле. Если вместе с ключом r задается необязательный ключ u, то заменяются только файлы, имеющие более поздние даты модификации, чем файлы в архиве. Этот же ключ используется для включения в библиотеку новых файлов, т.е. файлы, указанные параметром имя... и отсутствующие в библиотеке, добавляются в архив. Обычно новые файлы помещаются в конец архива. Если указать имя файла из архива в параметре позиционное_имя, то можно новые файлы поместить до или после этого файла. Для этого необходимо соответственно добавить к ключу -r необязательные литеры b (before) или a (after);
-t - вывести в стандартный поток вывода оглавление архивного файла. При задании параметра имя... печатается информация только об указанных этим параметром файлах. Этот же ключ используется для включения в библиотеку новых файлов, т.е. файлы, указанные параметром имя... и отсутствующие в библиотеке, добавляются в архив;
-р - вывести в стандартный поток вывода указанные (параметром имя...) файлы из архива;
-х - извлечь из архива указанные (параметром имя...) файлы. Если не задан параметр имя..., из архива извлекаются все файлы. В любом случае собственно архивный файл не изменяется;
-v - выдавать пояснительные сообщения;
-с - создать архивный файл. Обычно программа аr при необходимости создает архивный файл сама. Данный ключ подавляет информационное сообщение, выдаваемое при создании архивного файла.
Для размещения в личной библиотеке объектных модулей функций программы сортировки на основе бинарного дерева (из гл. 8) необходимо выполнить следующую команду:
Здесь libtree.a - имя библиотеки (архивного файла).
Ключ -r задает режим замены объектных модулей, хранящихся в библиотеке, на объектные модули, список которых приведен в командной строке вызова архиватора аr после имени библиотеки. Так как в момент обработки указанной команды библиотеки не существовало, она будет создана автоматически. Ключ -v определяет режим вывода пояснительных сообщений о работе архиватора аr.
После занесения объектных модулей в библиотеку необходимо при помощи программы ranlib скорректировать (или создать) оглавление библиотеки, выполнив команду
Программа ranlib впервые появилась в версии 7 UNIX фирмы AT&T и существует в таких реализациях операционной системы UNIX, как FreeBSD и Solaris. Рекомендуется при работе в других реализациях UNIX ознакомиться со справочной литературой, в которой описывается работа с библиотеками. Наиболее простой способ получения информации о наличии программы ranlib в составе ОС состоит в поиске этой программы в каталогах /bin, /usr/bin, /etc. Если эта программа найдена, прочтите ее описание, которое можно получить на экране дисплея по "самой полезной" команде ОС UNIX - команде man, позволяющей быстро получить справку по многим компонентам, командам и программам UNIX. Например, справку о программе ranlib можно получить так:
Проверим созданную библиотеку, распечатав ее оглавление:
Первая строка - вызов программы-архиватора (аr). Последние 4 строки - это результат работы команды аr. Оглавление библиотеки содержится в разделе библиотеки__.SYMDEF. Остальные строки - это имена объектных модулей, находящихся в библиотеке. После того как библиотека объектных модулей создана, можно построить исполняемый модуль программы сортировки на основе бинарного дерева с помощью команды:
Здесь транслируется головной модуль (tree.c), объектные модули на этапе компоновки выбираются из библиотеки libtree.a, и строится исполняемая программа с именем tree. Ключ компоновщика -l позволяет задать имя библиотеки объектных модулей (полное имя библиотеки: libtree.a).
Предположим, что в исходный текст одной из функций (например, add_node( )) были внесены изменения. Тогда для построения обновленного варианта исполняемой программы необходимо выполнить следующие команды:
На этот раз нет необходимости в повторной трансляции головного модуля (он не подвергался правке), поэтому в последней строке задано имя уже существующего объектного модуля tree.о.
Применим в той же задаче сортировки на основе бинарного дерева команду make для поддержания личной библиотеки объектных модулей в таком состоянии, когда она всегда содержит объектные модули, полученные из последних версий соответствующих исходных модулей. Выше был приведен пример файла зависимостей команды make, в котором все объектные модули, используемые для построения исполняемого модуля программы сортировки, указывались в командной строке вызова компилятора. В варианте make-файла, ориентированном на применение личной библиотеки объектных модулей, появляются 2 целевых файла: исполняемая программа сортировки (tree) и библиотека объектных модулей (libtree.a), причем исполняемая программа зависит от содержимого (объектных модулей) библиотеки. Взаимозависимость этих объектов определяется следующим образом:
Обратите внимание, как указаны зависимость целевого файла tree от библиотеки libtree.a и, в свою очередь, ее зависимость от объектных модулей. Объектный модуль из библиотеки libtree.a указывается так:
имя_библиотеки(имя_модуля).
Для окончательного оформления make-файла используем два встроенных макроса команды make:
$@ - задает имя текущего целевого файла (в нашем случае - последнего (libtree.a));
$? - значение этого макроса вычисляется командой make - это имена всех модулей, которые подвергались изменениям.
Приведем один из вариантов полного текста make-файла (напомним, что его имя по умолчанию - makefile), позволяющего обновлять целевые файлы (исполняемую программу и библиотеку объектных модулей) в соответствии с изменениями в исходных текстах функций, входящих в состав программы сортировки на основе бинарного дерева:
Теперь для того, чтобы построить исполняемый модуль, учитывающий все внесенные изменения в любые функции программы сортировки, необходимо просто набрать на клавиатуре команду make.
После внесения изменений, например, в исходный текст функции new_node( ) и при выполнении команды make получим на экране дисплея следующий протокол:
Строка, следующая за командой вызова архиватора аr (r -new_node.o), - это сообщение архиватора о замене объектного модуля new_node.o в библиотеке libtree.a.
