
- •Предисловие
- •Раздел 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
Функция fr( ) - "Возвратить освобожденный элемент в список свободных элементов".
Функция fr( ) - "Возвратить освобожденный элемент в список свободных элементов". Эта вспомогательная функция используется в функции delete( ):
Функция input( ) - "Ввести в базу данных сведения о новом сотруднике".
Функция input( ) - "Ввести в базу данных сведения о новом сотруднике". Функция input( ) должна вводить информацию о новом сотруднике, сохраняя алфавитный порядок записей в базе данных. При реализации этой функции возникают трудности: буквы национального алфавита (в данном случае кириллицы) в международной таблице кодов не упорядочены по возрастанию внутренних кодов, что требует для операций упорядочения дополнительных перекодировок с применением промежуточных словарей. Чтобы в рассматриваемой задаче не отвлекаться на решение этой проблемы, договоримся, что при вводе новой записи в уже существующую базу данных добавляемый элемент подсоединяется к хвостовому элементу списка занятых элементов. Однако при этом необходимо помнить, что алфавитный порядок в списке занятых элементов будет нарушен.
Как было решено ранее, информацию о новом сотруднике будем вводить в первый свободный элемент списка с последующей привязкой этого элемента к списку занятых. Приведем текст функции input( ):
Функция print( ) - "Печать списка занятых элементов".
Функция print( ) - "Печать списка занятых элементов". Реализуем функцию печати списка занятых элементов в том порядке, в котором они связаны. В качестве упражнений самостоятельно разберите варианты функции печати с ранжированием выводимой информации по окладу, кодам отделов, кодам должностей, дате поступления на работу.
Функция print( ) может быть реализована следующим образом:
Сохранение (восстановление) базы данных.
Сохранение (восстановление) базы данных. Поскольку в рассматриваемом примере база данных реализована в виде двунаправленного списка в основной памяти и она стирается (ее содержимое исчезает) при завершении работы программы, необходимо предусмотреть как сохранение базы данных во внешней памяти, так и загрузку базы данных из внешней памяти в следующем сеансе работы с ней.
Перед разработкой функции "выгрузка" базы данных в файл на диске необходимо определить формат и состав выгружаемых данных.
Собственно база данных (в виде двух независимых двунаправленных списков - списка занятых элементов и списка свободных элементов) располагается в массиве st структур типа struct person (см. главную программу). Информация о количестве элементов в этих списках, а также указатели на начало и конец списков располагаются в структуре Ctrl типа struct control.
Рассмотрим один из простейших вариантов создания на диске резервной копии базы данных о сотрудниках учреждения. Он состоит в том, что сначала необходимо записать в файл управляющую информацию (содержимое структуры Ctrl), а за ней - весь массив структур (байт за байтом), тем более что в рассматриваемом примере он невелик (7 Кбайт). При восстановлении базы данных из файла на диске читается управляющая информация и размещается в структуре Ctrl, затем читается информация, расположенная в файле за управляющей информацией, и размещается в области основной памяти, отведенной под массив структур st.
Такая схема копирования (восстановления) обладает существенным недостатком: вместе с содержательной информацией в файл записываются и значения указателей (адреса основной памяти), содержащиеся в элементах списков базы данных. Таким образом, при принятой схеме копирования (восстановления) программа обслуживания базы данных будет работать при выполнении условия неизменности адреса загрузки программы в основную память. При работе на персональном компьютере в операционных системах MS-DOS и UNIX (однопользовательский режим) вызванная для выполнения программа будет загружена на то же самое место в основной памяти только в том случае, если между сеансами работы с программой не производились "системные" работы, повлекшие за собой перераспределение основной памяти.
Однако, несмотря на неполную надежность восстановления, приведем исходные тексты функций save( ) - "выгрузить базу данных в файл на диске" и load( ) - "восстановить базу данных из файла". В этих функциях показано, как можно выгрузить (и затем восстановить) из основной памяти в файл на диске содержимое переменных различных типов.
Операция sizeof, примененная в функциях save( ) и load( ), вычисляет длину операнда в байтах. Операторы с = (char *)pti; и с = (char *)ptr; производят явное преобразование указателя pti на целое и указателя ptr на структуру соответственно в указатели на символы, что позволяет использовать последние в качестве аргументов в функциях putc( ) и getc( ) для побайтного обмена с файлом.
В функции save( ) производится запись в файл на диске всех элементов массива структур. Запись производится функцией putc( ) побайтно. Поэтому в программе необходимо описать указатель на символы, т.е. типа char*. Для работы с массивом структур необходим указатель на структуру типа person, содержащую сведения о сотруднике учреждения, и указатель потока, связанный с файлом, в котором производится сохранение базы данных. Назовем этот файл bd.dat.
Приведем текст функции save( ):
Функция load( ) может быть реализована следующим образом:
Перед восстановлением базы данных с диска проверяют, пуст ли список занятых элементов в основной памяти. Если нет, то выдается запрос "Производить загрузку?". В случае неположительного ответа, обозначаемого латинской буквой N или n, загрузка информации в БД из файла не производится.
Для того чтобы программа обслуживания базы данных стала не зависимой от адреса загрузки в основную память, модернизируем функции save() и load() следующим образом:
• будем выгружать (записывать) в файл не весь массив структур, а только список занятых элементов;
• после чтения содержимого файла в массив структур скорректируем значения указателей, образующих связи в связных списках базы данных, т.е. установим реальные адреса в указателях.
На рис. 8.10 показаны состояние списка занятых элементов в массиве структур до выгрузки в файл, структура файла с информацией из базы и состояние массива структур после восстановления базы данных из файла. В общем случае элементы списка, содержащего сведения о сотрудниках, к концу сеанса работы с базой данных могут располагаться не в соседних элементах массива. Однако после выгрузки в файл эти элементы окажутся рядом. Читая из файла в массив структур список занятых элементов байт за байтом, мы размещаем элементы списка с начала массива структур, т.е. элементы списка, в котором хранятся сведения о сотрудниках, в общем случае попадают на новые места в массиве структур, и требуется корректировка адресов в элементах этого списка. Эта процедура аналогична процедуре инициализации массива структур перед началом работы с базой данных. Началом списка свободных элементов будет первый элемент массива структур, не занятый загруженной из файла информацией.
Рис. 8.10. Второй вариант схемы сохранения (восстановления) базы данных
Приведем текст функции save2( ) - "сохранить в файле на диске только список занятых элементов":
Приведем текст функции load2( ) - "загрузить в основную память (прочитать из файла) базу данных из файла с корректировкой адресов, содержащихся в указателях элементов списков базы данных".
В качестве упражнения рекомендуем разработать более надежную схему и формат хранения базы данных и соответствующие функции сохранения (восстановления). В качестве возможного варианта формата хранения базы данных в файле на диске можно использовать следующий:
#1
name=фамилия
dерnаmе=название_отдела
depnumb=код_отдела
price=зарплата
job=код_должности
joname=долукиость
date=дата_приема_на_работу
#2
name=фамшия
где
#1, #2,... - номера записей;
name=, depname=, ... - имена полей в структуре, содержащей сведения о сотрудниках учреждения;
фамилия, название_отдела, ... - содержимое полей структуры в символьном виде.
Файл в таком формате и символьном представлении значений полей структур легко прочитать и модифицировать с помощью любого текстового редактора. Имена полей можно использовать для контроля правильности обработки записи при вводе (см. гл. 7, форматный ввод). Список занятых элементов базы данных формируется в момент ввода данных из файла.
Для того чтобы подготовить программный комплекс к последующей обработке (трансляция, сборка), в простейшем случае необходимо с помощью текстового редактора собрать все функции в один файл (набор данных). Этот файл должен иметь следующую структуру:
• объектов, используемых во вспомогательных функциях (массив структур типа struct person, управляющие переменные в структуре ctrl);
• описание внешних переменных;
• функция main( );
• функция init( );
• функция find( );
• функция fr( );
• функция delete( );
• функция input( );
• функция print( );
• функция save( ) или функция save2( );
• функция load( ) или функция load2( ).
Подробно подготовка программного комплекса для работы с базой данных о сотрудниках учреждения описана в главе 9.