Основы программирования

Наследство от языка Си - Функции и Файлы
Индекс материала
Наследство от языка Си
Область Видимости
Объекты и Адреса (Lvalue)
Имена
Типы
Неявное Преобразование Типа
Тип void
Указатели
Вектора
Структуры
Эквивалентность типов
Регистры
Константы
Символьные Константы
Строки
Const
Перечисления
Экономия Пространства
Упражнения
Выражения и Операторы
Программа синтаксического разбора
Функция ввода
Таблица имен
Обработка ошибок
Драйвер
Параметры командной строки
Краткая сводка операций
Порядок вычисления
Побитовые логические операции
Преобразование типа
Свободная память
Сводка операторов
Проверки
Goto
Комментарии и Выравнивание
Упражнения
Функции и Файлы
Компоновка
Заголовочные Файлы
Один Заголовочный Файл
Множественные Заголовочные Файлы
Сокрытие Данных
Файлы как Модули
Как Создать Библиотеку
Функции
ередача Параметров
Возврат Значения
Векторные Параметры
Параметры по Умолчанию
Перегрузка Имен Функций
Незаданное Число Параметров
Все страницы


Глава 4 Функции и Файлы

Все нетривиальные программы собираются из нескольких раздельно компилируемых единиц (их принято называть просто файлами). В этой главе описано, как раздельно откомпилированые функции могут обращаться друг к другу, как такие функции могут совместно пользоваться данными (разделять данные), и как можно обеспечить согласованность типов, которые использются в разных файлах программы. Функции обсуждаются довольно подробно. Сюда входят передача параметров, параметры по умочанию, перегрузка имен функций, и, конечно же, описание и оределение функций. В конце описываются макросы.



4.1 Введение

Иметь всю программу в одном файле обычно невозможно, поскольку коды стандартных библиотек и операционной системы находятся где-то в другом месте. Кроме того, хранить весь текст пользовательской программы в одном файле как правило непрактично и неудобно. Способ организации программы в файлы может помочь читающему охватить всю структуру программы, а также может дать возможность компилятору реализовать эту структуру. Поскольку единицей компиляции является файл, то во всех случаях, когда в файл вносится изменение (сколь бы мало оно ни было), весь файл нужно компилировать заново. Даже для программы умеренных размеров время, затрачиваемое на перекопиляцию, можно значительно снизить с помощью разбиения прораммы на файлы подходящих размеров.

Рассмотрим пример с калькулятором. Он был представлен в виде одного исходного файла. Если вы его набили, то у вас нверняка были небольшие трудности с расположением описаний в правильном порядке, и пришлось использовать по меньшей мере одно «фальшивое» описание, чтобы компилятор смог обработать взаимно рекурсивные функции expr(), term() и prim(). В тексте уже отмечалось, что программа состоит из четырех частей (лесического анализатора, программы синтаксического разбора, таблицы имен и драйвера), но это никак не было отражено в тексте самой программы. По сути дела, калькулятор был написан по-другому. Так это не делается; даже если в этой программе «на выброс» пренебречь всеми соображениями методологии прораммирования, эксплуатации и эффективности компиляции, автор все равно разобьет эту программу в 200 строк на несколько файлов, чтобы программировать было приятнее.

Программа, состоящая из нескольких раздельно компилирумых файлов, должна быть согласованной в смысле использования имен и типов, точно так же, как и программа, состоящая из оного исходного файла. В принципе, это может обеспечить и копоновщик*. Компоновщик – это программа, стыкующая отдельно скомпилированные части вместе. Компоновщик часто (путая) нзывают загрузчиком. В UNIX'е компоновщик называется ld. Однко компоновщики, имеющиеся в большинстве систем, обеспечивают очень слабую поддержку проверки согласованности.

– * или линкер. (прим. перев.)

Программист может скомпенсировать недостаток поддержки со стороны компоновщика, предоставив дополнительную информцию о типах (описания). После этого согласованность программы обеспечивается проверкой согласованности описаний, которые

находятся в отдельно компилируемых частях. Средства, которые это обеспечивают, в вашей системе будут. С++ разработан так, чтобы способствовать такой явной компоновке*.

– * C разработан так, чтобы в большинстве случаев позвлять осуществлять неявную компоновку. Применение C, однако, возросло неимоверно, поэтому случаи, когда можно использовать неявную линковку, сейчас составляют незначительное меньшинтво. (прим. автора)