- •Предисловие
- •1. Элементы языка
- •1.1. Свободная форма записи программы
- •1.2. Консоль-проект
- •1.2.1. Создание проекта в CVF
- •1.2.2. Создание проекта в FPS
- •1.2.3. Операции с проектом
- •1.2.4. Файлы с исходным текстом
- •1.3. Операторы
- •1.4. Объекты данных
- •1.5. Имена
- •1.6. Выражения и операции
- •1.7. Присваивание
- •1.8. Простой ввод/вывод
- •1.8.1. Некоторые правила ввода
- •1.8.2. Ввод из текстового файла
- •1.8.3. Вывод на принтер
- •1.9. Рекомендации по изучению Фортрана
- •1.10. Обработка программы
- •2. Элементы программирования
- •2.1. Алгоритм и программа
- •2.2. Базовые структуры алгоритмов
- •2.2.1. Блок операторов и конструкций
- •2.2.2. Ветвление
- •2.2.3. Цикл
- •2.2.3.1. Цикл "с параметром"
- •2.2.3.2. Циклы "пока" и "до"
- •2.2.4. Прерывание цикла. Объединение условий
- •2.3. Программирование "сверху вниз"
- •2.3.1. Использование функций
- •2.3.2. Использование подпрограмм
- •2.3.3. Использование модулей
- •2.4. Этапы проектирования программ
- •2.5. Правила записи исходного кода
- •3. Организация данных
- •3.1. Типы данных
- •3.2. Операторы объявления типов данных
- •3.2.1. Объявление данных целого типа
- •3.2.2. Объявление данных вещественного типа
- •3.2.3. Объявление данных комплексного типа
- •3.2.4. Объявление данных логического типа
- •3.3. Правила умолчания о типах данных
- •3.4. Изменение правил умолчания
- •3.5. Буквальные константы
- •3.5.1. Целые константы
- •3.5.2. Вещественные константы
- •3.5.3. Комплексные константы
- •3.5.4. Логические константы
- •3.5.5. Символьные константы
- •3.6. Задание именованных констант
- •3.7. Задание начальных значений переменных. Оператор DATA
- •3.8. Символьные данные
- •3.8.1. Объявление символьных данных
- •3.8.2. Применение звездочки для задания длины строки
- •3.8.3. Автоматические строки
- •3.8.4. Выделение подстроки
- •3.8.5. Символьные выражения. Операция конкатенации
- •3.8.6. Присваивание символьных данных
- •3.8.7. Символьные переменные как внутренние файлы
- •3.8.8. Встроенные функции обработки символьных данных
- •3.8.9. Выделение слов из строки текста
- •3.9. Производные типы данных
- •3.9.1. Объявление данных производного типа
- •3.9.2. Инициализация и присваивание записей
- •3.9.2.1. Конструктор производного типа
- •3.9.2.2. Присваивание значений компонентам записи
- •3.9.2.3. Задаваемые присваивания записей
- •3.9.3. Выражения производного типа
- •3.9.4. Запись как параметр процедуры
- •3.9.5. Запись как результат функции
- •3.9.6. Пример работы с данными производного типа
- •3.9.7. Структуры и записи
- •3.9.7.1. Объявление и присваивание значений
- •3.9.7.2. Создание объединений
- •3.9.8. Итоговые замечания
- •3.10. Целочисленные указатели
- •3.11. Ссылки и адресаты
- •3.11.1. Объявление ссылок и адресатов
- •3.11.2. Прикрепление ссылки к адресатам
- •3.11.3. Инициализация ссылки. Функция NULL
- •3.11.4. Явное открепление ссылки от адресата
- •3.11.5. Структуры со ссылками на себя
- •3.11.6. Ссылки как параметры процедур
- •3.11.7. Параметры с атрибутом TARGET
- •3.11.8. Ссылки как результат функции
- •4. Массивы
- •4.1. Объявление массива
- •4.2. Массивы нулевого размера
- •4.3. Одновременное объявление объектов разной формы
- •4.4. Элементы массива
- •4.5. Сечение массива
- •4.6. Присваивание массивов
- •4.7. Маскирование присваивания
- •4.7.1. Оператор и конструкция WHERE
- •4.7.2. Оператор и конструкция FORALL
- •4.8. Динамические массивы
- •4.8.1. Атрибуты POINTER и ALLOCATABLE
- •4.8.2. Операторы ALLOCATE и DEALLOCATE
- •4.8.3. Автоматические массивы
- •4.9. Массивы - формальные параметры процедур
- •4.9.1. Массивы заданной формы
- •4.9.2. Массивы, перенимающие форму
- •4.9.3. Массивы, перенимающие размер
- •4.10. Использование массивов
- •4.11. Массив как результат функции
- •4.12. Встроенные функции для массивов
- •4.12.1. Вычисления в массиве
- •4.12.2. Умножение векторов и матриц
- •4.12.3. Справочные функции для массивов
- •4.12.3.1. Статус размещаемого массива
- •4.12.3.2. Граница, форма и размер массива
- •4.12.4. Функции преобразования массивов
- •4.12.4.1. Элементная функция MERGE слияния массивов
- •4.12.4.2. Упаковка и распаковка массивов
- •4.12.4.3. Переформирование массива
- •4.12.4.4. Построение массива из копий исходного массива
- •4.12.4.5. Функции сдвига массива
- •4.12.4.6. Транспонирование матрицы
- •4.13. Ввод/вывод массива под управлением списка
- •4.13.1. Ввод/вывод одномерного массива
- •4.13.2. Ввод/вывод двумерного массива
- •5. Выражения, операции и присваивание
- •5.1. Арифметические выражения
- •5.1.1. Выполнение арифметических операций
- •5.1.2. Целочисленное деление
- •5.1.3. Ранг и типы арифметических операндов
- •5.1.4. Ошибки округления
- •5.2. Выражения отношения и логические выражения
- •5.3. Задаваемые операции
- •5.4. Приоритет выполнения операций
- •5.5. Константные выражения
- •5.6. Описательные выражения
- •5.7. Присваивание
- •6. Встроенные процедуры
- •6.1. Виды встроенных процедур
- •6.2. Обращение с ключевыми словами
- •6.3. Родовые и специфические имена
- •6.4. Возвращаемое функцией значение
- •6.5. Элементные функции преобразования типов данных
- •6.6. Элементные числовые функции
- •6.7. Вычисление максимума и минимума
- •6.8. Математические элементные функции
- •6.8.1. Экспоненциальная, логарифмическая функции и квадратный корень
- •6.8.2. Тригонометрические функции
- •6.9. Функции для массивов
- •6.10. Справочные функции для любых типов
- •6.11. Числовые справочные и преобразовывающие функции
- •6.11.1. Модели данных целого и вещественного типа
- •6.11.2. Числовые справочные функции
- •6.12. Элементные функции получения данных о компонентах представления вещественных чисел
- •6.13. Преобразования для параметра разновидности
- •6.14. Процедуры для работы с битами
- •6.14.1. Справочная функция BIT_SIZE
- •6.14.2. Элементные функции для работы с битами
- •6.14.3. Элементная подпрограмма MVBITS
- •6.14.4. Пример использования битовых функций
- •6.15. Символьные функции
- •6.16. Процедуры для работы с памятью
- •6.17. Проверка состояния "конец файла"
- •6.18. Неэлементные подпрограммы даты и времени
- •6.19. Случайные числа
- •6.20. Встроенная подпрограмма CPU_TIME
- •7. Управляющие операторы и конструкции
- •7.1. Оператор GOTO безусловного перехода
- •7.2. Оператор и конструкции IF
- •7.2.1. Условный логический оператор IF
- •7.2.2. Конструкция IF THEN END IF
- •7.2.3. Конструкция IF THEN ELSE END IF
- •7.2.4. Конструкция IF THEN ELSE IF
- •7.3. Конструкция SELECT CASE
- •7.4. DO-циклы. Операторы EXIT и CYCLE
- •7.5. Возможные замены циклов
- •7.6. Оператор STOP
- •7.7. Оператор PAUSE
- •8. Программные единицы
- •8.1. Общие понятия
- •8.2. Использование программных единиц в проекте
- •8.3. Работа с проектом в среде DS
- •8.4. Главная программа
- •8.5. Внешние процедуры
- •8.6. Внутренние процедуры
- •8.7. Модули
- •8.8. Оператор USE
- •8.9. Атрибуты PUBLIC и PRIVATE
- •8.10. Операторы заголовка процедур
- •8.10.1. Общие характеристики операторов заголовка процедур
- •8.10.2. Результирующая переменная функции
- •8.11. Параметры процедур
- •8.11.1. Соответствие фактических и формальных параметров
- •8.11.2. Вид связи параметра
- •8.11.3. Явные и неявные интерфейсы
- •8.11.4. Ключевые и необязательные параметры
- •8.11.5. Ограничения на фактические параметры
- •8.11.6. Запрещенные побочные эффекты
- •8.12. Перегрузка и родовые интерфейсы
- •8.12.1. Перегрузка процедур
- •8.12.2. Перегрузка операций и присваивания
- •8.12.3. Общий вид оператора INTERFACE
- •8.13. Ассоциирование имен
- •8.14. Область видимости имен
- •8.15. Область видимости меток
- •8.16. Ассоциирование памяти
- •8.16.1. Типы ассоциируемой памяти
- •8.16.2. Оператор COMMON
- •8.16.3. Программная единица BLOCK DATA
- •8.17. Рекурсивные процедуры
- •8.18. Формальные процедуры
- •8.18.1. Атрибут EXTERNAL
- •8.18.2. Атрибут INTRINSIC
- •8.19. Оператор RETURN выхода из процедуры
- •8.20. Оператор ENTRY дополнительного входа в процедуру
- •8.21. Атрибут AUTOMATIC
- •8.22. Атрибут SAVE
- •8.23. Атрибут STATIC
- •8.24. Атрибут VOLATILE
- •8.25. Чистые процедуры
- •8.26. Элементные процедуры
- •8.27. Операторные функции
- •8.28. Строка INCLUDE
- •8.29. Порядок операторов и директив
- •9. Форматный ввод/вывод
- •9.1. Преобразование данных. Оператор FORMAT
- •9.2. Программирование спецификации формата
- •9.3. Выражения в дескрипторах преобразований
- •9.4. Задание формата в операторах ввода/вывода
- •9.5. Списки ввода/вывода
- •9.5.1. Элементы списков ввода/вывода
- •9.5.2. Циклические списки ввода/вывода
- •9.5.3. Пример организации вывода
- •9.6. Согласование списка ввода/вывода и спецификации формата. Коэффициент повторения. Реверсия формата
- •9.7. Дескрипторы данных
- •9.8. Дескрипторы управления
- •9.9. Управляемый списком ввод/вывод
- •9.9.1. Управляемый именованным списком ввод/вывод
- •9.9.1.1. Объявление именованного списка
- •9.9.1.2. NAMELIST-вывод
- •9.9.1.3. NAMELIST-ввод
- •9.9.2. Управляемый неименованным списком ввод/вывод
- •9.9.2.1. Управляемый неименованным списком ввод
- •9.9.2.2. Управляемый неименованным списком вывод
- •10. Файлы Фортрана
- •10.1. Внешние и внутренние файлы
- •10.2. Позиция файла
- •10.3. Устройство ввода/вывода
- •10.4. Внутренние файлы
- •10.5. Внешние файлы
- •10.6. Записи
- •10.6.1. Типы записей
- •10.6.2. Записи фиксированной длины
- •10.6.3. Записи переменной длины
- •10.6.4. Сегментированные записи
- •10.6.5. Потоки
- •10.6.6. CR-потоки
- •10.6.7. LF-потоки
- •10.7. Передача данных с продвижением и без
- •10.8. Позиция файла перед передачей данных
- •10.9. Позиция файла после передачи данных
- •10.10. Двоичные последовательные файлы
- •10.11. Неформатные последовательные файлы
- •10.12. Текстовые последовательные файлы
- •10.13. Файлы, подсоединенные для прямого доступа
- •10.14. Удаление записей из файла с прямым доступом
- •10.15. Выбор типа файла
- •11. Операции над внешними файлами
- •11.1. Оператор BACKSPACE
- •11.2. Оператор REWIND
- •11.3. Оператор ENDFILE
- •11.4. Оператор OPEN
- •11.5. Оператор CLOSE
- •11.6. Оператор READ
- •11.7. Оператор ACCEPT
- •11.8. Оператор FIND
- •11.9. Оператор DELETE
- •11.10. Оператор UNLOCK
- •11.11. Оператор WRITE
- •11.12. Оператор PRINT
- •11.13. Оператор REWRITE
- •11.14. Оператор INQUIRE
- •11.15. Функция EOF
- •11.16. Организация быстрого ввода/вывода
- •12.1. Некоторые сведения об объектах ActiveX
- •12.2. Для чего нужен конструктор модулей
- •12.3. Интерфейсы процедур управления Автоматизацией
- •12.4. Идентификация объекта
- •12.5. Примеры работы с данными Автоматизации
- •12.5.1. OLE-массивы
- •12.5.2. BSTR-строки
- •12.5.3. Варианты
- •12.6. Другие источники информации
- •12.7. Как воспользоваться объектом ActiveX
- •12.8. Применение конструктора модулей
- •12.9. Пример вызова процедур, сгенерированных конструктором модулей
- •Приложение 1. Вывод русского текста в DOS-окно
- •Приложение 2. Нерекомендуемые, устаревшие и исключенные свойства Фортрана
- •П.-2.1. Нерекомендуемые свойства Фортрана
- •П.-2.1.1. Фиксированная форма записи исходного кода
- •П.-2.1.2. Оператор EQUIVALENCE
- •П.-2.1.3. Оператор ENTRY
- •П.-2.1.4. Вычисляемый GOTO
- •П.-2.1.5. Положение оператора DATA
- •П.-2.2. Устаревшие свойства Фортрана, определенные стандартом 1990 г.
- •П.-2.2.1. Арифметический IF
- •П.-2.2.2. Оператор ASSIGN присваивания меток
- •П.-2.2.3. Назначаемый GOTO
- •П.-2.2.4. Варианты DO-цикла
- •П.-2.2.5. Переход на END IF
- •П.-2.2.6. Альтернативный возврат
- •П.-2.2.7. Дескриптор формата H
- •П.-2.3. Устаревшие свойства Фортрана, определенные стандартом 1995 г.
- •П.-2.4. Исключенные свойства Фортрана
- •Приложение 3. Дополнительные процедуры
- •П.-3.1. Запуск программ
- •П.-3.2. Управление программой
- •П.-3.3. Работа с системой, дисками и директориями
- •П.-3.4. Управление файлами
- •П.-3.5. Генерация случайных чисел
- •П.-3.6. Управление датой и временем
- •П.-3.7. Ввод с клавиатуры и генерация звука
- •П.-3.8. Обработка ошибок
- •П.-3.9. Аргументы в командной строке
- •П.-3.10. Сортировка и поиск в массиве
- •П.-3.11. Управление операциями с плавающей точкой
- •Литература
- •Предметный указатель
- •Оглавление
8. Программные единицы
8.1. Общие понятия
При разработке алгоритма исходная задача, как правило, разбивается на отдельные подзадачи. Процесс выделения подзадач крайне важен. Можно без преувеличения сказать, что квалификация программиста во многом определяется его способностью рационально разбить исходную задачу на фрагменты, которые впоследствии реализуются в виде отдельных программных единиц. В Фортране 77 выделенные фрагменты оформлялись, как правило, в виде главной программы и внешних процедур.
Выделенные фрагменты должны обмениваться данными. В Фортране 77
такой обмен выполнялся через |
параметры процедур, common-блоки и, |
в случае процедуры-функции, |
через возвращаемое ею значение. |
В программной единице BLOCK DATA переменным именованного com- mon-блока можно было задать начальные значения.
Фортран 90 и 95, сохраняя все возможности Фортрана 77, дополнительно позволяют:
•создавать модули, содержащие глобальные данные и модульные процедуры;
•создавать внутренние процедуры, расположенные внутри главной программы, внешней или модульной процедуры.
Эти нововведения дополнительно позволяют:
•использовать различным программным единицам объявленные в модуле глобальные данные и имеющиеся в нем процедуры;
•использовать объявленные в модуле данные во всех процедурах этого модуля;
•использовать один и тот же объект данных во внутренней процедуре и в ее носителе.
Таким образом, в Фортране можно создать такие программные единицы, как:
•главная программа;
•модули;
•внешние процедуры;
•внутренние процедуры;
•BLOCK DATA.
Дополнительно к названным в программной единице (кроме BLOCK DATA) можно определить и операторные функции (разд. 8.24).
Модуль - это самостоятельная программная единица, которая может в общем случае содержать объявления данных, common-блоков, интерфейсы процедур, namelist-группы и модульные процедуры. Все не
216
8. Программные единицы
объявленные PRIVATE компоненты модуля доступны в других (кроме BLOCK DATA) программных единицах.
В Фортране существует два вида процедур: подпрограммы и функции. Подпрограмма - это именованная программная единица, в заголовке которой присутствует оператор SUBROUTINE. Вызов подпрограммы осуществляется по ее имени в операторе CALL или при выполнении
задаваемого присваивания.
Функция - это именованная программная единица, вызов которой выполняется по ее имени из выражения. В ее заголовке присутствует оператор FUNCTION. Функция содержит результирующую переменную, получающую вследствие выполнения функции значение, которое затем используется в выражении, содержащем вызов функции. Также функция вызывается и при выполнении задаваемой операции.
В Фортране можно задать внешние, внутренние и модульные процедуры.
Внешняя процедура является самостоятельной программной единицей и существует независимо от использующих ее программных единиц. К любой внешней процедуре можно обратиться из главной программы и любой другой процедуры.
Модули и внешние процедуры могут компилироваться отдельно от использующих их программных единиц.
Внутренняя процедура задается в главной программе, внешней или модульной процедуре. Главная программа или процедура называются носителями содержащихся в них внутренних процедур. Обратиться к внутренней процедуре можно только внутри ее носителя. Сами же внутренние процедуры уже не могут содержать в себе других внутренних процедур.
Модульная процедура задается в модуле и доступна, если она не объявлена PRIVATE, в любой использующей модуль программной единице. Модуль также является носителем по отношению к заданной в нем модульной процедуре, которая, в свою очередь, может быть носителем определенной в ней внутренней процедуры.
Фортран 90 и 95 в отличие от Фортрана 77 поддерживают рекурсивные вызовы процедур, т. е. такие вызовы, в которых процедура прямо или косвенно обращается сама к себе. Оператор заголовка рекурсивной процедуры содержит префикс RECURSIVE.
8.2. Использование программных единиц в проекте
В создаваемом пользователем проекте могут использоваться:
•встроенные процедуры;
•подключаемые процедуры и модули;
•создаваемые при разработке проекта процедуры и модули.
217
О. В. Бартеньев. Современный ФОРТРАН
Встроенные процедуры входят в состав Фортрана и автоматически включаются в исполняемый код при обращении к ним в тексте программы. Примеры встроенных процедур: SIN, ALOG, TRIM.
Подключаемые процедуры и модули находятся в ранее созданных и поставляемых с Фортраном библиотеках. Перечень и описание таких модулей и процедур дан в прил. 3.
Также с CVF и FPS поставляются математические библиотеки и библиотеки математической статистики.
Все поставляемые с CVF и FPS процедуры при правильной установке программ по умолчанию доступны для компилятора и компоновщика. Для их использования в программной единице следует выполнить ссылку на модуль, содержащий глобальные данные и интерфейсы процедур. Ссылка осуществляется оператором USE.
Пользователь может создать собственные прикладные библиотеки и использовать хранимые в них процедуры и модули в любом из своих проектов. Для доступа к содержащим объектный код библиотекам пользователю следует указать построителю ее полное имя.
Процедуры и модули проекта содержат свежие решения и на начальных стадиях разработки хранятся в исходном коде. Размещаются новые программные единицы, как правило, в разных файлах. Если в файле находится несколько процедур или модулей, то порядок их размещения произвольный. Однако текст модуля должен быть размещен до первой имеющейся на него ссылки. В общем случае в одном файле могут существовать внешние процедуры, модули и главная программа. В то же время осмысленное разбиение программных единиц по файлам, порядок их размещения в каждом из файлов, правильное разделение процедур на внешние, внутренние и модульные существенно облегчает разработку программы и ее последующее сопровождение в процессе эксплуатации.
На последующих стадиях работы над программой часть отлаженных процедур и модулей может храниться в откомпилированном виде (объектном коде), часть - включена в библиотеки, содержащие объектный код программных единиц. Недоработанные программные единицы попрежнему хранятся в исходном коде.
Создаваемые процедуры и модули реализуют выделенные при разработке алгоритма фрагменты и решают проблемы обмена данными между ними. Фрагмент реализуется в виде процедуры, если он:
•представляет типовую задачу, например поиск экстремума функции;
•представляет обособленную задачу, например В/В данных и контроль ошибок В/В.
Также в виде процедур оформляется повторяющийся в программе более одного раза код. Оформление фрагментов в виде процедур улучшает качество программы, сокращает время ее разработки, отладки и
218
8. Программные единицы
тестирования. Вопрос выбора типа процедуры (внешней, модульной или внутренней) неразрывно связан с проблемой организации данных.
Процедуры и модули полезны и по другой причине. Часто к работе над большим проектом необходимо привлечь бригаду программистов. Организовать работу бригады можно, лишь поручив каждому участнику реализацию той или иной группы процедур и модулей. Понятно, что предварительно должна быть определена общая структура программы, выделены фрагменты, определены данные, которыми фрагменты обмениваются, и способы обмена данными (ассоциирование параметров, ассоциирование через носитель, use-ассоциирование, ассоциирование памяти). Такая предварительная и чрезвычайно важная работа называется
проектированием программы.
Итак, процедуры и модули:
•позволяют сократить расходы на создание программы;
•улучшают читаемость программы и, следовательно, облегчают ее последующую модификацию;
•приводят к сокращению исходного кода;
•могут быть включены в библиотеки и вызваны из любой программы;
•позволяют разделить работу над программой между разными программистами.
8.3. Работа с проектом в среде DS
В CVF и FPS программа рассматривается как проект. Типы возможных проектов приведены в табл. 8.1.
Таблица 8.1. Типы проектов
Тип проекта |
Особенности |
Консоль (EXE) |
Однооконный основной проект без графики |
|
|
Стандартная графика (EXE) |
Однооконный основной проект с графикой |
|
|
QuickWin-графика (EXE) |
Многооконный основной проект с графикой |
|
|
Windows-приложение (EXE) |
Многооконный основной проект с полным |
|
графическим интерфейсом и Win32 API- |
|
функциями |
Статическая библиотека (LIB) Библиотечные процедуры, подключаемые в EXEфайлы
Динамическая библиотека |
Библиотечные процедуры, подключаемые |
(DLL) |
в процессе выполнения |
Первые 4 типа требуют наличия главной программы. Два последних - библиотечные проекты без главной программы.
Тип проекта задает вид генерируемого кода и некоторые параметры проекта. Например, он определяет опции, которые использует компилятор,
219
О. В. Бартеньев. Современный ФОРТРАН
библиотеки, применяемые компоновщиком, задает по умолчанию размещение выходных файлов, константы проекта и т. д. Задание типа проекта выполняется при его создании. Порядок создания проекта в CVF и FPS и некоторые операции с проектами рассмотрены в разд. 1.2.
После создания нового проекта можно сгенерировать две его модификации: Debug и Release. Первая - содержит применяемые в режиме отладки настройки компилятора и компоновщика. Вторая - ориентирована на получение рабочего, не содержащего отладочного кода EXE-файла. В любой из них можно изменить настройки компилятора и компоновщика. Используя цепочку Build - Configurations можно добавить или удалить модификацию. Каждая из модификаций может быть сгенерирована в своей директории. По умолчанию имя директории для модификации совпадает с именем модификации, но оно может быть изменено в результате выполнения цепочки Build - Settings - General - установить директории в полях области Output directories - OK. Генерируемую по умолчанию модификацию можно изменить, выполнив цепочку Build - Set (Active) Default Configuration - выбор конфигурации - OK.
В проекте используются файлы с исходными текстами программ и файлы ресурсов, хранящие, например, диалоговые окна. Также могут быть ссылки на модули (оператор USE), файлы с объектным кодом (ссылка указывается как параметр опции построителя) и динамически подключаемые библиотеки (в результате употребления атрибута DLLIMPORT). Кроме того, в исходном коде можно указать путь к библиотекам, содержащим вызываемые процедуры, применив нужное число раз директиву $objcomment lib : "имя библиотеки". Указанное имя будет сохранено в объектном коде и затем использовано компоновщиком при сборке приложения.
Модули, если их исходный код не содержится в проекте, ищутся компилятором по имени, указанному в операторе USE. Расширение искомых файлов - MOD. Порядок поиска:
1)поиск в директории, содержащей файлы проекта;
2)в директориях, заданных в опции компилятора /I в порядке их следования. При задании в опции более одной директории имена директорий разделяются пробелами: /I "myfiles/" /I "mylib/";
3)в директориях, заданных в переменной окружения INCLUDE, например
в файле autoexec.bat.
Кроме того, в проект можно включить файл с исходным текстом, употребив строку INCLUDE или директиву $INCLUDE. Строка (директива) может содержать полное имя включаемого файла (т. е. имя и путь к файлу). Если же полное имя файла не указано, то компилятор ищет файл в той же последовательности, какая применяется для модуля.
220