
- •Алфавит.
- •Объявления и определения
- •Структура и компоненты простой программы
- •Текст программы и препроцессор.
- •Структура программы.
- •Функция форматированного вывода.
- •Программы печати предельных констант.
- •Применимость вещественных данных.
- •Выделение лексем из текста программы.
- •2.2. Элементарные средства программирования Деление операторов языка Си на группы.
- •Программа оценки машинного нуля.
- •Трассировочная таблица
- •Переключатели
- •Ввод данных.
- •Вычисление объема цилиндра.
- •Операторы цикла
- •Три формы операторов цикла.
- •Приближенное значение экспоненты.
- •Оператор break.
- •Сумма отрезка степенного ряда.
- •Оператор continue.
- •Суммирование положительных чисел.
- •2.4. Массивы и вложение операторов цикла Массивы и переменные с индексами.
- •Вычисление среднего и дисперсии.
- •Упорядочение в одномерных массивах.
- •Инициализация массивов.
- •Моделирование многомерных массивов.
- •Ввод и вывод
- •7.1. Потоковый ввод-вывод
- •7.1.1. Открытие и закрытие потока
- •7.1.2. Стандартные файлы и функции для работы с ними
- •Ввод-вывод отдельных символов.
- •Ввод-вывод строк.
- •Форматный ввод-вывод.
- •Спецификаторы форматной строки для функции форматного вывода
- •Спецификаторы форматной строки для функции форматного ввода
- •Работа с файлами на диске
- •Двоичный (бинарный) режим обмена с файлами.
- •Строковый обмен с файлами.
- •Позиционирование в потоке.
- •Трехъязычный словарь "Цифры
- •7.2. Ввод-вывод нижнего уровня
- •7.2.1. Открытие / закрытие файла
- •7.2.2. Чтение и запись данных
- •7.2.3. Произвольный доступ к файлу
- •Теоретические положения Управление экраном в текстовом режиме в ms dos
- •Основные функции работы в текстовом режиме
- •2.5. Функции Определение функций.
- •Функция для вычисления объема цилиндра.
- •Функция для вычисления скалярного произведения векторов.
- •Обращение к функции и ее прототип.
- •Вычисление объема цилиндра
- •Вычисление площади треугольника.
- •Скалярное произведение векторов.
- •Препроцессорные средства
- •Глава 6. Структуры и объединения
- •6.1. Структурные типы и структуры Производные типы.
- •Структурный тип.
- •Определение структур.
- •Выделение памяти для структур.
- •Инициализация и присваивание структур.
- •Доступ к элементам структур.
- •Модули:
- •Некоторые понятия:
Препроцессорные средства
В предыдущих главах мы познакомились с некоторыми базовыми понятиями и основными средствами (может быть, не самыми эффективными) программирования языка Си. Начиная с данной главы, начнем подробное изучение тех особенностей и возможностей, которыми Си отличается от других языков программирования и которые принесли ему заслуженную популярность и любовь профессиональных программистов.
Несколько нетрадиционно для пособий по языку Си начнем дальнейшее изложение материала о возможностях препроцессора. Это позволит в следующих главах продемонстрировать эффективность препроцессорных средств и их применимость при решении разнородных задач. Откладывать, как часто принято, изучение препроцессора на конец курса по языку Си, по нашему мнению, не совсем удачно. Даже в начальных (вступительных) главах 1 и 2 пришлось затронуть некоторые важные вопросы препроцессорной обработки. Введены константы, определяемые директивой #define, проиллюстрированы некоторые правила включения в программу текстов заголовочных файлов для связи со стандартной библиотекой компилятора. Этих сведений вполне достаточно, чтобы программировать на языке Си, вводить с помощью #define собственные обозначения констант и не испытывать затруднений в использовании стандартных библиотек.
К сожалению, именно на таком уровне использования препроцессора остаются многие программисты, не обратившие внимания на другие возможности препроцессорной обработки текста программы. А возможности препроцессора весьма интересные, особенно в областях макрообработки и условной компиляции. Введя в этой главе препроцессорные средства, мы сможем в следующих главах показать способы и возможности их применения при решении задач разных классов.
Прежде чем перейти к изложению материала, отметим, что препроцессор обрабатывает почти любые тексты, а не только тексты программ на языке Си. Обработка программ - это основная задача препроцессора, однако он может преобразовывать произвольные тексты, и этой возможностью программисту не следует пренебрегать в своей работе.
Итак, на входе препроцессора - текст с препроцессорными директивами, на выходе препроцессора - текст без препроцессорных директив (см. рис. 1.1).
Глава 6. Структуры и объединения
6.1. Структурные типы и структуры Производные типы.
Производные типы. Из базовых типов (и типов, определенных программистом) можно формировать производные типы, к которым относятся: указатели, массивы, функции, структуры и объединения. Указатели, массивы, структуры и объединения являются производными типами данных. Иногда в качестве производного типа в руководствах по языку Си указывают строки, однако напоминаем, что в соответствии с синтаксисом языка строковый тип в нем отсутствует. Строка определяется как частный случай одномерного массива, т.е. как массив с элементами типа char, последний элемент которого равен '\0'.
Указатели и массивы подробно рассмотрены в предыдущих главах. Эта глава посвящена структурам и объединениям. Прежде чем рассматривать их особенности и возможности, введем некоторые терминологические соглашения стандарта, которые не всегда понятны сами собой.
Данные базовых типов (int, float, ...) считаются скалярными данными. Массивы и структуры являются агрегирующими типами данных в отличие от объединений и скалярных данных, которые относятся к неагрегирующим типам. С массивами и скалярными данными мы уже хорошо знакомы, поэтому различие между агрегирующими и неагрегирующими типами поясним на примере массивов и скалярных данных базовых типов. Обычно агрегирующий тип включает несколько компонентов. Например, массив long B[12] состоит из 12 элементов, причем каждый элемент имеет тип long. Язык Си позволяет определять и одноэлементные массивы. Так, массив float A[l] состоит из одного элемента А[0]. Однако одноэлементные массивы есть слишком частный случай обыкновенных массивов со многими элементами. Итак, в общем случае массив есть агрегирующий тип данных, состоящий из набора однотипных элементов, размещенных в памяти подряд в соответствии с ростом индекса. Для агрегирующего типа данных (например, для массива) в основной памяти ЭВМ выделяется такое количество памяти, чтобы сохранять (разместить) одновременно значения всех элементов. Этим свойством массивов мы уже неоднократно пользовались. Например, следующее выражение позволяет вычислить количество элементов массива В[ ]:
sizeof(B)/sizeof(B[0])
Для данных неагрегирующих типов в основной памяти ЭВМ выделяется область памяти, достаточная для размещения только одного значения. С тем, как это происходит для скалярных типов, мы уже хорошо знакомы. С особенностями выделения памяти для объединений познакомимся в этой главе.