
- •Предисловие
- •Раздел 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
Выделение лексем из текста программы.
Выделение лексем из текста программы. В главе 1 мы ввели понятие лексемы, перечислили их группы (идентификаторы, знаки операций и т.д.) и определили состав каждой из групп лексем. Первая задача, которую решает компилятор, - это лексический анализ текста программы. В результате лексического анализа из сплошного текста выделяются лексические единицы (лексемы). Программисту полезно знать, какими правилами при этом руководствуется компилятор.
Компилятор просматривает символы (литеры) текста программы слева направо. При этом его первая задача - выделить лексемы языка. За очередную лексическую единицу принимается наибольшая последовательность литер, которая образует лексему. Таким образом, из последовательности int_line компилятор не станет выделять как лексему служебное слово int, a воспримет всю последовательность как введенный пользователем идентификатор.
В соответствии с тем же принципом выражение d+++b трактуется как d++ +b, а выражение b-->с эквивалентно (b--)>с.
Следующая программа иллюстрирует сказанное:
Результат выполнения программы:
Результаты вычисления выражений n+++m, n-->m, m-->n полностью соответствуют правилам интерпретации выражений на основе таблицы рангов операций (см. табл. 1.4). Унарные операции ++ и -- имеют ранг 2. Аддитивные операции + и - имеют ранг 4. Операции отношений имеют ранг 6.
2.2. Элементарные средства программирования Деление операторов языка Си на группы.
Деление операторов языка Си на группы. Если вспомнить вопросы, перечисленные в начале главы 1, то окажется, что мы уже получили ответы на многие из них. Введен алфавит языка и его лексемы; приведены основные типы данных, константы и переменные; определены все операции; рассмотрены правила построения арифметических выражений, отношений и логических выражений; описана структура программы; рассмотрены средства вывода из ЭВМ арифметических значений с помощью функции printf( ); определен оператор присваивания.
В этом и следующих параграфах второй главы мы ответим на остальные вопросы, сформулированные в главе 1, и этого будет достаточно, чтобы писать на языке Си программы для решения задач вычислительного характера.
Вернемся вновь к структуре простой программы, состоящей только из одной функции с именем main( ).
директивы_препроцессора
void main( )
{ определения_объектов;
исполняемые_операторы;
}
Как мы уже договорились, пока нам будет достаточно двух препроцессорных директив #include <...> и #define. В качестве определяемых объектов будем вводить переменные и константы базовых типов. А вот об исполняемых операторах в теле функции нужно говорить подробно.
Каждый исполняемый оператор определяет действия программы на очередном шаге ее выполнения. У оператора (в отличие от выражения) нет значения. По характеру действий различают два типа операторов: операторы преобразования данных и операторы управления работой программы.
Наиболее типичные операторы преобразования данных - операторы присваивания и произвольные выражения, завершенные символом "точка с запятой":
Так как вызов функции является выражением с операцией "круглые скобки" и операндами "имя функции", "список фактических параметров", к операторам преобразования данных можно отнести и оператор вызова или обращения к функции:
имя_функции (список_фактических_параметров) ;
Мы уже использовали обращение к библиотечной функции printf( ), параметры которой определяли состав и представление на экране дисплея выводимой из программы информации. С точки зрения процесса преобразования информации функция printf( ) выполняет действия по перекодированию данных из их внутреннего представления в последовательность кодов, пригодных для вывода на экран дисплея.
Операторы управления работой программы называют управляющими конструкциями программы. К ним относятся:
• составные операторы;
• операторы выбора;
• операторы циклов;
• операторы перехода.
К составным операторам относят собственно составные операторы и блоки. В обоих случаях это последовательность операторов, заключенная в фигурные скобки. Отличие блока от составного оператора - наличие определений в теле блока. Например, приведенный ниже фрагмент программы - составной оператор:
Наиболее часто блок употребляется в качестве тела функции.
Операторы выбора - это условный оператор (if) и переключатель (switch).
Операторы циклов в языке Си трех видов - с предусловием (while), с постусловием (do) и параметрический (for).
Операторы перехода выполняют безусловную передачу управления: goto (безусловный переход), continue (завершение текущей итерации цикла), break (выход из цикла или переключателя), return (возврат из функции).
Перечислив операторы управления программой, перейдем к подробному рассмотрению тех из них, которых будет достаточно для программирования простейших алгоритмов.
Условный оператор имеет сокращенную форму:
if (выражение_условие) оператор;
где в качестве выражения_условия могут использоваться: арифметическое выражение, отношение и логическое выражение. Оператор, включенный в условный, выполняется только в случае истинности (т.е. при ненулевом значении) выражения условия. Пример:
Кроме сокращенной формы, имеется еще и полная форма условного оператора:
if (выражениеусловие)
onepamop_1;
else
оператор_2;
Здесь в случае истинности выражения-условия выполняется только оператор_1, при нулевом значении выражения-условия выполняется только оператор_2. Например:
Оператор в сокращенном варианте оператора if, и оператор_1 и оператор_2 в полном операторе if могут быть как отдельными, так и составными операторами.
Несмотря на традиционность условного оператора, проиллюстрируем его выполнение схемами (рис, 2.2).
Рис. 2.2. Схемы условных операторов (выражение-условие - условие после if): а - сокращенная форма; б - полная форма
Итак, что в условных операторах в качестве любого из операторов (после условия или после else) может использоваться составной оператор. Например, при решении алгебраического уравнения 2-й степени ах2+bх+с=0 действительные корни имеются только в случае, если дискриминант (b2-4ас) неотрицателен. Следующий фрагмент программы иллюстрирует использование условного оператора при определении действительных корней x1, х2 квадратного уравнения:
Во фрагменте предполагается, что переменные d, b, a, x1, х2 - вещественные (типа float либо double). До приведенных операторов переменные а, b, с получили конкретные значения, для которых выполняются вычисления. В условном операторе после if находится составной оператор, после else - только один оператор - вызов функции printf( ). При вычислении корней используется библиотечная функция sqrt( ) из стандартной библиотеки компилятора. Ее прототип находится в заголовочном файле math.h (см. Приложение 3).
Метки и пустой оператор. Метка - это идентификатор, помещаемый слева от оператора и отделенный от него двоеточием ":". Например,
Чтобы можно было поставить метку в любом месте программы (или задать пустое тело цикла), в язык Си введен пустой оператор, изображаемый только одним символом ";". Таким образом, можно записать такой помеченный пустой оператор:
Оператор перехода. Оператор безусловного перехода имеет следующий вид:
goto идентификатор;
где идентификатор - одна из меток программы. Например:
goto СОН; или goto МЕТКА;
Введенных средств языка Си вполне достаточно для написания примитивных программ, которые не требуют ввода исходных данных. Алгоритмы такого сорта достаточно редко применяются, но для иллюстрации некоторых особенностей разработки и выполнения программ рассмотрим следующую задачу.