 Quick C Компилятор с языка СИ фирмы Микрософт Руководство программиста

Quick C Компилятор с языка СИ фирмы Микрософт Руководство программиста

Часть 1
Часть 2
Часть 3
Часть 4
Часть 5
Часть 6
Часть 7
Часть 8
Часть 9
Часть 10
Часть 11
Приложение 1
Приложение 2
Приложение 3
Приложение 4


           Программное обеспечение персональных компьютеров

                                Quick C
                 Компилятор с языка СИ фирмы Микрософт
                       Руководство программиста

      Перевод с английского : Новиковой Н.А.

                            Москва 1988 г.

    Поздравляем вас  с приобретением  компилятора Microsoft  Quick-C! Вы
приобрели  один  из  наиболее   мощных  пакетов,  работающих  с   языком
СИ-идеальный   набор   инструментальных   средств   как   для начинающих
программистов,  так  и   для  опытных  раразработчиков   математического
обеспечения.

    Компилятор Microsoft Quick-C использует  язык СИ в полном  объеме, и
кроме того, имеет как и мощность, переносимость, гибкость языка СИ,  так
и идеальную среду для разработки программ. Он включает в себя  следующие
средства:

    -В  Интегрированной  программной  среде  вы  получите весь требуемый
набор инструментов. Компилятор Microsoft  Quick-C имеет в едином  пакете
полный  набор  инструментальных   средств  для  разработки   программ:
интегрированный редактор для  написания программ, компилятор  и отладчик

(глава  8).   С  помощью   компилятора  Microsfot   Quick-C  вы   можете
компилировать,   выполнять,   отлаживать,   редактировать   и   повторно
компилировать  программы,  не  покидая  Интегрированную среду разработки
программ.   Компилятор   Quick-C    может   создавать   программы    для
непосредственного  выполнения,  либо  автономные  объектные  файлы   для
использования в  библиотеках плюс  выполняемые файля  для дальнейшего их
запуска под управлением операционной системы DOS. Поскольку все наиболее
часто используемые библиотечные СИ-функции встроены в программную среду,
подсоединяться  к  внешним   библиотекам  обычно  не   требуется.  Любые
стандартные СИ-библиотеки, не встроеные в программную среду, могут  быть
загружены  в  библиотеку,  конструируемую  пользователем,  известную под
именем Quick.

    -Легкий  в  изучении  редактор  текстов,  совместимый  с  редактором
WordStar. Изучить  редактор текстов  Quick-C очень  просто. Если  вы уже
знакомы с  программой WordStar  фирмы Micro  Pro, считайте,  что вы  уже
знаете  большинство  комманд  редактора  Quick-C,  поскольку  они  точно
соответствуют  командам  редактора  WordStar.   (раздел 7.1.1. описывает
ключи редактора Quick-C).

    -Быстрое  выявление  ошибок  с  помощью  Интегрированного отладчика.
Quick-C имеет большой  инструментальный набор средств  профессионального
отладчика, который делает возможным быстрое выявление ошибок программной
логики. С помощью отладчика Quick-C вы можете:

                       -прослеживать выполнение программы строка за
                        строкой;
                       -устанавливать многочисленные точки прерывания;
                       -во время выполнения программы в отдельном
                        окне высвечивать значение переменных;
                       -переключаться между высвечиванием программы и
                        программным выводом;
                       -производить поиск определенных функций в исходной
                        программе.

    Данные возможности отладчика описываются в разделах 8.2-8.2.4.  Если
даже  список  данных  возможностей  покажется  вам  неполным,  программы
Quick-C вы можете отлаживать с помощью многооконного отладчика Microsoft
Code View, поставляемого  с Оптимизирующим компилятором  фирмы Microsoft
или другого продукта фирмы Microsoft.

    -Получение помощи. У вас  появились вопросы по синтаксису  оператора
языка СИ? О типах аргументов библиотечной процедуры? О ключах  редактора
Quick-C? Вы можете быстро получить ответы на свои вопросы,  воспользуясь
контекстно-зависимым   встроеным   средством   Help   пакета    Quick-C.
Просмотрите   заголовки   меню,   подведите   блок   выбора   к    имени
соответствующей  функции  и  нажмите  ключ.  Вам  не нужно даже покидать
редактор; информация появится в отдельном окне верхней части экрана.

    -Графическая библиотека добавит программам эффект изобразительности.
Графическая библиотека, поставляемая  как часть библиотек  Quick-C, дает
возможность пользователю строить сложные графические изображения. Данная
библиотека поддерживает полный список графических адаптеров  компьютеров
фирмы IBM и совместимых с ними,  включая адаптеры VGA, MDA, CGA, EGA.  О
графической библиотеке может прочесть в Главе 4.

    -Быстрая отладка  программ и  последующая оптимизация  их в  помощью
Оптимизирующего компилятора Microsoft C. Поскольку компилятор  Microsoft
Quick-C  полностью  совместим  с    Оптимизирующим  компилятором   фирмы
Microsoft на уровне исходных и объектых файлов, вы можете добавить своим
программам   гибкость   и   мощность,   обеспечиваемую    Оптимизирующим
компилятором. Если вы разрабатываете программы с помощью Оптимизирующего
компилятора фирмы Microsoft,  компилятор Quick-C можно  использовать для
ускорения  разработки  программ  на  ранних  фазах, а затем для придания
программе законченности применить Оптимизирующий компилятор.

    -Интерфейс  с  пользователем,  совместимый  с  операционной системой
OS/2. Интерфейс с пользователем для компилятора Microsoft Quick-C  очень
прост  в   изучении.  Просто   выбирайте  команды   из  меню,  пользуясь
клавиатурой,  мышью  или  тем  и  другим;  либо нажимайте для выполнения
определенных команд  специальные ключи,  без открытия  меню. Интерфейс с
пользователем  пакета  Quick-C  выглядит  и  работает  аналогично новому
интерфейсу с операционной системой OS/2.

    -Автоматическая  поддержка  больших  программ.  Компилятор   Quick-C
автоматически  поддерживает   обработку  больших   программ  с   большим
количеством  модулей.  Как  только  вы  редактируете  один  из  модулей,
составляющих программу,  он добавляется  в "программный  список". Затем,
при  перестройке  программы,  Quick-C  сэкономит  ваше  время,  так  как
перекомпилироваться  будут  только  те  модули,  которые  изменились  со
времени последнего построения программы. Программый список  запоминается
в  файле,  совместимом  в  утилитой  программной  поддержки MAKE; затем,
программы  могут  быть  автоматически  обновлены  вне  среды  разработки
программ пакета Quick-C.

    -Всевозможные дополнительные средства: Компилятор Microsoft  Quick-C
предлагает следующие дополнительные средства:

    -Полный набор  инструментальных утилит,  удовлетворяющих почти  всем
нуждам  программирования.   Этот  набор   включает  в   себя  программу,
управляющую  компиляцией  и  компановкой  (QCL),  оверлейный компановщик
фирмы Microsoft (LINK); программу управления библиотеками  (LIB);утилиту
поддержки программ (MAKE). -Упрощенное управление памятью,  использующее
одну из четырех моделей памяти. Программа QCL поддерживает четыре модели
памяти: малую, среднюю, компактную и большую.

    -Отдельная справочная документация.  Данная документация включает  в
себя  справочник  по  языку  СИ  и стандартным библиотечным процедурам с
большим количеством отлаженных программных примеров.

                         Требования к системе

    Компилятор   Microsoft   Quick-C   требует   следующей   минимальной
конфигурации:  Персональный  компьютер   IBM  или  совместимый   с  ним,
функционирующий под управлением  операционной системы MS-DOS  или PC-DOS
версии 2.1  или выше.  Два устройства  чтения гибких  дисков, либо  один
дисковод для гибких дисков и один жесткий диск. 448К оперативной памяти.

                 Как пользоваться данным руководством

    Компилятор   Microsoft   Quick-C   разработан   для   широкого круга
пользователей:  от  начинающих-новичков  в  программировании  до опытных
разработчиков,   хорошо   владеющих   языком   СИ.   Для  различных нужд
пользователей предназначены различные части руководства.

    В  нижеследующих  параграфах  объясняется,  как  организовано данное
руководство,  предлагаются  различные  разделы  для  различных категорий
пользователей  и  описываются  остальные  руководства, входящие в данный
пакет.

                 Как организовано данное руководство.

    В части  1 данного  руководства, "С  чего начать",  объясняется, как
установить компилятор Quick-C,  осуществляется знакомство с  программной
средой пакета Quick-C и описываются наиболее важные особенности языка СИ
для программистов,  владеющих другими  языками программирования,  такими
как Basic  или Pascal.  В данной  части кроме  того рассказывается,  как
пользоваться поставляемой с пакетом Quick-C графической библиотекой.

    В части 2, "Программная  среда пакета Quick-C", рассказывается,  как
редактировать, компилировать и отлаживать программы в программной  среде
пакета Quick-C.

    В  части  3  данного  руководства,  "Набор инструментальных программ
пакета Quick-C", объясняется  каким образом компилировать  и компановать
программы  с  помощью  автономных  программ  QCL  и  LINK, как построить
библиотеки Quick  посредством программы  LINK и  автономные библиотеки с
помощью утилиты LIB; а также, каким образом осуществлять поддержку своих
программ с помощью утилиты MAKE.

    В  приложениях  к  данному  руководству  содержится   дополнительная
информация, которая может быть полезной для вас:

      -таблица кодов ASCII;
      -описание моделей памяти, поддерживаемых пакетом Quick-C;
      -описание интерфейса между Microsoft C и Microsoft Macro
       Assembler (MASM);
      -список сообщений об ошибках.

    Краткий  справочник,  включенный  в  данное  руководство дает список
ключей  редактирования  Quick-C,  ключей  процесса  отладки  и  ключевых
последовательностей.

            Что вам следует прочесть в данном руководстве.

    Всем  пользователям  нужно  прочесть  Главу  1,  "Установка и запуск
пакета Quick-C", в которой даны инструкции по установке  математического
обеспечения компилятора. Если вы хотите на практике попробовать работу с
компилятором, вам  следует провести  сеанс работы,  описанный в  разделе
1.7.4.

    Как  изучать  пакет  Quick-C  дальше  зависит  от  ваших  конкретных
потребностей, как описано ниже:

    -Для пользователей-новичков в программировании  и языке СИ. Если  вы
изучаете одновременно и программирование, и язык СИ, посмотрите в данном
введении  раздел  "Что  нужно  для  изучения",  в  котором  дан   список
рекомендованного чтения.

    -Для программистов, новичков  в языке СИ.  Если вы имеете  некоторый
опыт  в  программировании,  но  никогда  не программировали на языке СИ,
смотрите в  Главе 3,  "Quick-C, быстрый  старт" особенности  языка СИ  и
различия между СИ и другими языками программирования, такими как BASIC и
Pascal.

    -Для пользователей, использующих для программирования графику пакета
Quick-C. Прочтите Главу 4, "Работа с графикой пакета Quick-C", в которой
даются  инструкции  по  написанию  программ с использованием графических
функций, поставляемых с компилятором Microsoft Quick-C.

    -Для пользователей, незнакомы2 с Интегрированной средой разра- ботки
прогорамм.  Прочтите  Главу  2,  "Введение  в  Программную  среду пакета
Quick-C", в которой кратко описаны основные компоненты программной среды
пакета Quick-C. Затем вам  следует прочесть Часть 2,  "Программная среда
пакета  Quick-C",  в  ней  дана  информация  об  использовании редактора
связей, компилятора  и отладчика,  встроенных в  программную среду пакет
Quick-C.

    -Для пользователей, интересующихся другими программными  средствами,
поставляемыми   с   пакетом   Quick-C.   Прочтите   Часть   3,    "Набор
инструментальных программ пакета  Quick-C", в которой  описаны следующие
программные  средства:  программа,  управляющая  процессом  компиляции и
компановки  QCL;  компановщик  LINK;  программа, управляющая построением
библиотек LIB и утилита MAKE, осуществляющая поддержку ваших программ

                Другие руководства, входящие в комплект
             документации, поставляемой с пакетом Quick-C.

    С пакетом Quick-C поставляются еще два руководства:

    -В "Справочном руководстве по языку СИ фирмы Microsoft"  описывается
совместимый со стандартом ANSI выриант языка СИ фирмы Microsoft.

    -В  "Справочном  руководстве   по  библиотеке  исполняющей   системы
Microsoft C" описывается более 350 библиотечных процедур и 34 включаемых
файлов, поставляемых с компилятором Microsoft Quick-C.

                        Что нужно для изучения.

    Для изучения языка СИ вам могут понадобиться следующие книги. Список
литературы  составлен  в  порядке  возрастания  сложности,  от  пособий,
предназначенных для начинающих, до пособий для опытных программистов:

    - Hancock, Les, Morris Krieger.  "The C Primer, 2d ed.  New York: Mc
Graw-Hill, 1985" (Руководство по языку СИ для начинающих программистов).

    -     Schildt,     Herbert.      "C     Made     Easy."    Berkeley,
CA:Osborne/McGraw-Hill, 1985.(Хорошее пособие по  языку СИ для тех,  кто
знаком с языком BASIC).

    - *Waite, Mitchell, Stephine Prata, Donald Martin.  "C Primer Plus."
Indianopolis,  IN:Howard  W.Sams,  Inc.,  1984  (Введение  в  язык   СИ,
пользующееся наибольшим спросом).

    - Plum, Thomas.   "Learning to Program  in C". Cardiff,  New Jersey:
Plum Hall, Inc., 1983.   (Широко распространенное пособие для  колледжей
по изучению программирования с использованием языка СИ).

    -  Kochan,  Stephen.   "Programming  in  C".  Hasbrouck Neights, NJ:
Hayden Book Company, Inc., 1983.   (Исчерпывающее пособие по языку СИ  с
некоторыми погружением в среду операционной системы UNIX).

    - Harbison, Saiuel P., Gny L. Steele, Jr. "C:A Reference Manual,  2d
ed."  Englewood Cliffs, NJ: Prentice-Hall,Inc., 1987 (Полный  справочник
по языку СИ. Второе издание включает стандарт ANSI).

    -  **Kernighan,  Brian  W.,  Dennis  M.Ritchie.   "Jhe C Programming
Language."   Englewood  Cliffs,  NJ:  Prentice  Hall, Inc., 1978.(Ориги-
нальная классическая книга по языку СИ. Известна под названием "K&R" или
"белая книга". Будет полезна для вас, как только вы изучите язык СИ).

    -  Tondo,  Clovis  L.,  Scott  E.  Gimple.   "Jhe  C  Answer  Book".
Englewood Cliffs, NJ: Prentice-Hall,  Inc., 1985.  (Собрание ответов  на
упражнения, заданные в книге К&R. Дополнительный том к K&R).

    - Jaeshke, Rex. "Solutions  in C". Reading, Massachusentts:  Addison
Wesley, 1986.  (Полезное собрание примеров программ на языке СИ).

    -  Word,   Robert.   "Debugging   C".  Indianopolis,   Indiana:  Que
Corporation, 1986.  (Руководство по технике отладки программ).

    -  Schustack,  Steve.   "Variations  in  C:"  Redmond,   Washington:
Microsoft Press, 1985.  (Руководство  по программированию на языке  СИ в
сфере бизнеса).

    -  Hansen,  Augie.   "Proficient  C:" Redmond, Washington: Microsoft
Press, 1987 (Руководство для опытных  программистов на языке СИ в  среде
операционной системы MS-DOS).

---------------------------------------------------------------------

*Есть русский перевод в издательстве "Мир" Примечание переводчика.
**есть русский перевод в издательстве "Финансы и статистика"
Примечание переводчика.
---------------------------------------------------------------------

              Как получить помощь от фирмы Microsoft Inc.

    Если   у   вас   появились   какие-либо   проблемы  с использованием
математического  обеспечения,   пожалуйста  направьте   ваши  замечания,
используя бланк, приложенный к данному руководству.

    Если у  вас есть  какие-нибудь дополнения  или пожелания, касающиеся
документации, сопровождающей  программный продукт,  воспользуйтесь также
бланком прилотранство для  объединенных библиотек, подробности  смотрите
Раздел 1.4).   EM,87 Чтобы  сообщить программе  SETUP, как  обрабатывать
операции с  плавающей точкой  с помощью  эмуляции сопроцессора  8087 или
80287 (EM), или используя реальный сопроцессор (87). Обычно, задаете EM,
посколько программная среда пакета Quick-C использует эмулятор.

                                                 ЧАСТЬ 1

                            С чего начать.

    Данная  часть  руководства  поможет  вам  начать  программировать  с
помощью компилятора Microsoft Quick-C.

    В  Главе  1  рассказывается,  как  установить  компилятор  с помощью
программы SETUP, и как войти и выйти из среды разработки программ; кроме
того,  в  данной  Главе  приведен  пример  сеанса  работы с компилятором
Quick-C, во время которого вы можете научиться загружать,  компилировать
и выполнять программы.

    В Главе  2 описана  Программная среда  пакета Quick-C  и ее основные
возможности. Данная Глава написана для тех пользователей, которые  хотят
попробовать  работать  с  пакетом  Quick-C  без  детального изучения его
систем меню и команд.

    Глава  3  знакомит  с  языком  програмирования СИ тех пользователей,
которые знают другие языки программирования, например Pascal или Basic.

    В Главе 4 рассказывается,как писать программы, пользуясь стандартным
набором графических функций, поставляемых в пакете Quick-C.

                             ГЛАВА 1.

                  Установка и запуск пакета Quick-C.

1.1.  Подготовка резервных копий ваших дискет.
1.2.  Проверка содержимого дискет.
1.3.  Установка пакета Quick-C.
      1.3.1. Установка системы на жесткий диск.
      1.3.2. Установка пакета на систему с гибкими дисками.
1.4.  Использование автономных библиотек.
1.5.  Использование графической библиотеки Microsoft C.
1.6.  Если вы имеете устройство "мышь".
1.7.  Запуск компилятора Quick-C.
1.8.  Сохранение опций: Стартовый файл QC.INI.

    В данной Главе рассказывается,  как установить и запускать  в работу
компилятор    Microsoft    Quick-C.    Перед    изучением    компилятора
удостоверьтесь, что:

   1. Вы сделали резервные копии дистрибутивных дискет
      (см. Раздел 1.1).
   2. Проверьте содержимое ваших дистрибутивных дискет
      (см. Раздел 1.2).
   3. Прочтите файл README.DOC с вашей рабочей копии дистрибутивного
      диска PRODUCT, чтобы узнать изменения и добавления, сделанные
      в математическом обеспечении со времени издания документации.
   4. Запустите программу SETUP для установки математического обес-
      печения на вашей системе (см. Разделы 1.3.1.1-1.3.1.2 и
      1.3.2.1-1.3.2.2).
   5. Установите операционную среду вашей операционной системы DOS
      для того, чтобы упростить поиск ваших файлов (см. Раздел 1.4).

    Некоторые процедуры DOS упоминаются в данной Главе. В частности, для
присвоения  значений  переменным  операционной  среды  DOS  используются
команды  DOS  SET  и  PATH.  Если  вы не знакомы с какой-либо упомянутой
процедурой DOS,  обратитесь к  руководству польдователя  по операционной
системе DOS.

---------------------------------------------------------------------

Примечание:

    В данном руководстве "DOS" означает операционные системы как MS-DOS,
так и PC-DOS.

---------------------------------------------------------------------

                  1.1 Получение резервных копий ваших
                        дистрибутивных дисков.

    После того, как вы распаковали дистрибутивные дискеты,  поставляемые
в  пакете  Quick-C,  вам  следует  сделает  рабочие  копии  этих  дискет
посредством  команды  DOS   COPY,  либо  утилиты   DISKCOPY.  Сохраняйте
оригинальные диски для получения рабочих копий в дальнейшем.

                   1.2. Проверка содержимого ваших
                        дистрибутивных дисков.

    Когда  вы  первый  раз  смотрите  ваш  пакет,  вам следует тщательно
проверить  комплектность  математического  обеспечения.   Дистрибутивная
дискета  Product,  входящая  в   ваш  пакет,  содержит  файл   с  именем
PACKING.LST;  этот  файл  содержит  список  всех  файлов  и  документов,
входящих в пакет Microsoft Quick-C.

    Для соответствия новым  возможностям, добавленным в  пакет Microsoft
Quick-C, некоторые файлы или программы могут находиться на дисках  иных,
чем  диски,  описанные  в  данном  руководстве.  Если вы не можете найти
нужный  вам  файл  или  программу,  посмотрите  список  файлов  в  файле
PACKING.LST,  вы  сможете   узнать,  на  какой   дистрибутисной  дискете
находится нужный вам файл или программа.

                    1.3. Установка пакета Quick-C.

    Для установки программного  обеспечения вам следует  воспользоваться
программой  SETUP,  находящейся  на  вашей рабочей копии дистрибутивного
диска Libraries#1. Разделы, следующие далее, дают следующую информацию:

   1. Что делает программа SETUP при установке программного
      обеспечения.
   2. Как запустить программу SETUP для установки программного обес-
      печения на систему с жестким или гибкими дисками.
   3. Как сконфигурировать операционную среду системы DOS для
      ускорения поиска нужных файлов в пакете Quick-C.

---------------------------------------------------------------------

    Примечание

    Если  у  вас  имеется  версия  5.0 Оптимизирующего компилятора фирмы
Microsoft Inc., пропустите описанную далее процедуру установки системы и
выполните  программу  SETUP,  поставленную  с  пакетом   Оптимизирующего
компилятора.  Программа  SETUP  версии  5.0  Оптимизирующего компилятора
Microsoft  C  установит,  как  сам  Оптимизирующий  компилятор,  так   и
компилятор Quick-C. Инструкции по выполнению программы SETUP вы  найдете
в   Главе   2   руководства   "Оптимизирующий   компилятор  Microsoft C.
Руководство пользователя."

              1.3.1. Установка пакета Quick-C на систему
                           с жестким диском.

    Следующие далее разделы 1.3.1.1-1.3.1.6 дают инструкции  поустановке
компилятора Quick-C на систему с жестким диском.

                1.3.1.1 Что делает программа SETUP на
                       системе с жестким диском.

    При  устаноке  пакета  Quick-C  на  жесткий  диск  программа   SETUP
выполняет следующие действия:

    - Копирует все необходимые файлы в каталоге или на диски, которые вы
зададите.

    -  Строит  автономную   библиотеку  для  каждой   комбинации  модель
памяти/математический пакет,  которую вы  определили в  командной строке
программы  SETUP.   Большинство  стандартных   библиотечных  СИ-процедур
встроены  в  программную  среду  Quick-C;  однако,  в некоторых случаях,
компилятор  Quick-C  просматривает  библиотеки,  построенные  программой
SETUP, чтобы найти процедуры, не найденные обычным путем. Эти библиотеки
также можно использовать,если  вы отлаживаете программы  вне Программной
среды пакета Quick-C.

    - Создает  пакетный файл  с именем  NEW-VARS.BAT, который  назначает
переменные операционной  среды DOS,  так что  компилятор Quick-C  всегда
может найти те файлы, которые ему требуются.

    -  Создает  файл  с  именем NEW-CONF.SYS, содержащий соответствующие
назначения для параметров files и buffers в вашем файле CONFIG.SYS.

               1.3.1.2 Запуск программы SETUP на системе
                           с жестким диском.

    Как только вы будете готовы установить вашу систему на жесткий диск,
вставьте рабочую копию дистрибутивного  диска Libraries#1 в дисковод  А.
Затем   введите   следующую   командную   строку   в   форме:

    SETUP H C:\dest{S!M!L}...{EM!87}...[GR][\bin][\incl][\lib]

---------------------------------------------------------------------

Предупреждение.

    Некоторые из аргументов программы SETUP - это имена каталогов.  Если
каталог,  который  вы  задали,  не  существует,  программа SETUP создает
каталог автоматически.

---------------------------------------------------------------------

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

    Каждый аргумент командной  строки программы SETUP,  показанной выше,
передает программе SETUP  информацию о том,  как должен быть  установлен
компилятор. Необязательные аргументы заключены в квадратные скобки. Если
вы  не  укажите  необязательные  аргументы,  программа  SETUP использует
соответствующие   стандартные.   Некоторые   необязательные    аргументы
позволяют вам для выбора стандартных набрать знак вопроса (?).

    Далее описаны аргументы, которые входят в командную строку программы
SETUP; для того, чтобы получить краткую информацию об аргументах  SETUP,
наберите SETUP без  аргументов, в то  время как в  дисководе А находится
дистрибутивный диск Program.

    Аргумент            Значение

     H                 Введите H для устаноки программного обеспече-
                       ния на жестком диске.
  C:\dest              Введите C, чтобы установить систему на диско-
                       вод C, за ним непосредственно следует имя це-
                       левого каталога (dest) для установки програм-
                       много обеспечения. SETUP предполагает, что
                       все остальные имена, заданные в командной
                       строке-это имена подкаталогов в данном катало-
                       ге.
  S, M, C, L           Одна или более из данных букв, разделенных про
                       белами, сообщает программе SETUP, какая модель
                       памяти будет использоваться. Введите M, пос-
                       кольку для Quick-C средняя модель памяти явля-
                       ется стандарной. Если вы будете разрабатывать
                       программы вне программной среды Quick-C, на-
                       пример с помощью команды QCL, описанной в Гла-
                       ве 9, наберите S, поскольку малая модель памя-
                       ти стандартна для команды QCL. Кроме того, ес-
                       ли вы будете работать с компактной или большой
                       моделью памяти, наберите C или L.
                       Программа SETUP использует аргументы модели
                       памяти и аргументы операций с плавающей точкой
                       (смотрите ниже) для того, чтобы построить тре-
                       буемые для вас библиотеки. Объединенные библио
                       теки ускоряют процесс создания программ; одна-
                       ко, поскольку объединенные библилтеки имеют
                       очень большой размер, вам следует задать толь-
                       ко те модули памяти, которые вы точно будете
                       использовать. (Если вы работаете больше чем с
                       одной моделью памяти, вы можете так же исполь-
                       зовать отдельные библиотеки, вместо того, что-
                       бы занимать дисковую память для объединенных
                       библиотек; за подробностями обратитесь к Раз-
                       делу 1.4).
   EM,87               Введите любой из двух или оба данных аргумен-
                       та, чтобы сообщить программе SETUP, каким об-
                       разом будут обрабатываться в ваших программах
                       операции с плавающей точкой.
                       Чтобы сообщить пакету Quick-C, что в первую
                       очередь будут использоваться процедуры эмуля-
                       ции операций с плавающей точкой, (а не сопро-
                       цессор 8087 или 80287), введите опцию EM.
                       (В разделе 9.3.5 вы найдете подробности об об-
                       работке в программах операций с плавающей точ-
                       кой).
                       Если вы разрабатываете программы, использующие
                       научные, математические или финансовые вычис-
                       ления с вещественными числими и всегда будете
                       работать на системе с математическими сопроце-
                       ссором, введите 87. В этом случае будет постро
                       ена дополнительная библиотека, которая требует
                       дополнительной дисковой памяти, но разработка
                       и выполнение программ с данной библиотекой бу-
                       дет производиться гораздо компактнее и быст-
                       рее.
    GR                 Если вы будете использовать графические функ-
                       ции пакета Quick-C, введите параметр GR (опи-
                       сание содержится в Главе 4 данного руководства
                       и в документе "Справочное руководство по биб-
                       лиотеке процедур Microsoft C." Эти функции бу-
                       дут добавлены в библиотеку, которую строит про
                       грамма SETUP. Данная опция делает библиотеку
                       приблизительно на 50К больше. Если данная оп-
                       ция не будет задана, графические функции не бу-
                       дут включены в библиотеку. Если ваша программа
                       использует графические функции, компилятор
                       Quick-C должен найти библиотеку GRAPHICS.LIB.
  \bin                 Введите имя подкаталога (bin) каталога dest, в
                       которую будут сброшены выполняемые файлы компи
                       лятора, в частности; компилятор, компоновщик и
                       утилиты. Если вы опискаете этот аргумент или
                       введете вместо его знак вопроса (?), программа
                       SETUP по умолчанию использует подкаталог \BIN.
  \incl                Введите имя подкаталога каталога dest, в кото-
                       рый будут установлены включаемые файлы. Если
                       вы опускаете данный аргумент или введете вмес-
                       то него знак вопроса (?), программа SETUP ис-
                       пользует по умолчанию подкаталог \INCLUDE.
  \lib                 Введете имя подкаталога каталога dest, в кото-
                       рую вы хотите установить библиотечные файлы.
                       Если вы опустите данный аргумент, или введете
                       вместо него знак вопроса (?), программа SETUP
                       использует по умолчанию подкаталог LIB.

    Программа SETUP автоматически создает следующие подкаталоги:

    - Подкаталог с именем \TMP, в который компилятор помещает  временные
файлы, создаваемые в процессе компиляции.

    - Подкаталог выполняемых файлов  \SAMPLE, в который программа  SETUP
помещает демонстративные программы.

      Примеры:

      SETUP H C:\MEM ???

    Данная командная  строка требует,  чтобы программа  SETUP установила
математическое   обеспечение   компилятора   в   стандартные подкаталоги
корневого каталога  на жестком  диске С.  Стандартными каталогами будут:
\BIN  для  выполняемых  файлов   компилятора  и  утилит,  \INCLUDE   для
включаемых  файлов  и  \LIB  для  библиотечных  файлов.  Программа SETUP
построит соответствующую библиотеку для  средней модели памяти и  пакета
математических  процедур  для  эмуляции  операций  с  плавающей точкой и
назовет данную библиотеку MLIBCE.LIB.

    SETUP H C:\QC SMCL EM GR 87\BINDER\INC\LIBS

    Указанная  командная  строка  указывает  программе  SETUP установить
математическое обеспечение компилятора  в заданные подкаталоги  каталога
\QC на жестком  диске С. Выполняемые  файлы будут сброшены  в подкаталог
\QC\BINDIR; включаемые файлы в подкаталог \QC\INC; библиотечные файлы  в
подкаталог    \QC\LIBS;    демонстрационные    файлы    в     подкаталог
\QC\BINDIR\SAMPLE.

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

               1.3.1.3. Построение библиотек на системе
                           с жестким диском.

    После того, как вы нажмете  ENTER, программа SETUP начнет строить  и
устанавливать библиотеки, причем SETUP сообщит вам, когда менять дискеты
в дисководе А.

    Программа SETUP  считывает аргументы  модели памяти  (S, M,  C, L) и
аргументы математики с плавающей точкой (EM и 87), заданные в  командной
строке,  и  строит  по   одной  библиотеке  на  каждое   сочетание  двух
параметров. Причем SETUP высвечивает по мере построения имена библиотек.

    Названия библиотек  составляются программой  SETUP в  зависимости от
используемой модели памяти  и пакета математических  подпрограмм. Каждое
стандартное имя библиотеки имеет следующую форму:

    {S|M|C|L}LIBC{E|7}.LIB

    Первый символ имени библиотеки совпадает с аргументом модели памяти:
S для малой (стандартной) модели памяти, M для средней модели памяти,  C
для компактной  модели памяти,  L для  большой модели  памяти. Последний
символ базового имени (часть имени перед расширением .LIB)  определяется
аргументом пакета математических подпрограмм: E, если задан аргумент EM,
или 7, если задан аргумент 87.

    Например, библиотека с именем MLIBCE.LIB поддерживает среднюю модель
памяти  и  пакет  эмуляции  математики  с  плавающей точкой-стандарт для
программной  среды  пакета  Quick-C.  Библиотека  с  именем   SLIBC7.LIB
поддерживает  малую  модель  памяти  и  пакет  процедур для сопроцессора
8087/8,287,  она   может  быть   использована  только   на  компьютерах,
оснащенных математическим сопроцессором.

---------------------------------------------------------------------

Примечание:

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

---------------------------------------------------------------------

                1.3.1.4 Удаление компонентов библиотек.

    Программа SETUP высвечивает следующее дополнительное сообщение:

    "Программе SETUP больше не требуются библиотечные компоненты, и  они
на понадобятся вам для компиляции и компановки программ. Хотите  удалить
их? [Y/N]"

    Если  вы  будете  пользоваться  моделями  памяти или математическими
пакета иными, чем  были заданы в  командной строке программы  SETUP, вам
следует  сохранить   отдельные  библиотеки.   Однако,  если   вы  будете
пользоваться  только   моделями  памяти   и  математическими   пакетами,
поддерживаемыми  вашими  объединенными  библиотеками,  вы можете удалить
отдельные  библиотеки.  Ответьте  Y  или  y,  чтобы  удалить   отдельные
библиотеки, или N или n, чтобы сохранить их.

             1.3.1.5 Завершение процесса установки пакета.

    Кроме прочего,  программа SETUP  выполняет некоторые  дополнительные
шаги, включая создание файлов NEW-VARS.BAT и NEW-CONF.SYS.

                  1.3.1.6 Установка на жестком диске
                        операционной среды DOS.

    Финальная часть процесса установки-это установка операционной  среды
DOS для ускорения поиска требуемых файлов.

    Программа  SETUP  автоматически  создает  пакетный  файл  с   именем
NEW-VARS.BAT. Этот файл можно использовать, чтобы установить  переменные
операционной среды для поиска нужных файлов.

    Можно также команды  SET из файла  NEW-VARS.BAT добавить в  ваш файл
AUTOEXEC.BAT   таким   образом,   что   среда   DOS   будет    корректно
устанавливаться всякий раз при загрузке системы.

    Кроме файла NEW-VARS.BAT программа SETUP создает файл  NEW-CONF.SYS.
Этот файл  устанавливает необходимые  для компилятора  Microsoft Quick-C
параметры files и buffers. Вы можете либо заменить ваш существующий файл
CONFIG.SYS на файл NEW-CONF.SYS, либо скопировать назначение  параметров
files  и  buffers  из   файла  NEW-CONF.SYS  в  ваш   существующий  файл
CONFIG.SYS.

    Программа SETUP  устанавливает файлы  NEW-VARS.BAT и  NEW-CONF.SYS в
тот подкаталог каталога dest, в который были сброшены выполняемые  файлы
пакета Quick-C (по умолчанию dest\BIN\SAMPLE).

               1.3.2 Установка пакета Quick-C на систему
                          с гибкими дисками.

    В разделах 1.3.2.1-1.3.2.4 описывается процесс установки компилятора
Quick-C на  систему с  гибкими дисками.  Заметим, что  данные инструкции
предполагают, что вы запускаете программу  SETUP с дисковода А; если  вы
предпочитаете запускать программу  SETUP с дисковода  В, то в  следующих
инструкциях  просто  замените  слова  "дисковод  А"  на  "дисковод  В" и
наоборот.

             1.3.2.1 Что программа SETUP делает на системе
                          с гибкими дисками.

    При установке пакета Quick-C на системе с гибкими дисками, программа
SETUP  строит  автономную  библиотеку  для  каждой заданной на командной
строке   комбинации   "модель   памяти/математический   пакет".   Многие
стандартные  процедуры  языка  СИ  встроены  в  программную среду пакета
Quick-C, однако,  в некоторых  случаях компилятор  Quick-C просматривает
библиотеки, построенные программой SETUP, чтобы найти процедуру, которая
не может быть найдена другим способом. Эти библиотеки также используются
для создания программ вне программной среды пакета Quick-C.

              1.3.2.2. Запуск программы SETUP на системе
                          с гибкими дисками.

    Перед  тем,,  как  запустить  программу  SETUP  на системе с гибкими
дисками,  вам  следует   определить,  сколько  вам   понадобится  чистых
отформатированных  дискет  для  того,  чтобы  разместить все библиотеки,
которые будут построены в процессе установки системы. Вам потребуется по
одной чистой отформатированной дискете для каждой модели памяти, которую
вы  будете  использовать  плюс  одна  рабочая  дискета;  если  вы будете
пользоваться  только  одной  стандартной  для  программной среды Quick-C
моделью  памяти  (средняя  модель),  вам  понадобятся всего две дискеты.
Программа  SETUP  разместит  каждую  построенную библиотеку на отдельном
гибком диске.

    После  того,  как  вы  отформатируете  требуемое  количество дискет,
вставьте  в  дисковод  А   вашу  рабочую  копию  дистрибутивного   диска
Libraries#1.

    Затем введите командную строку в следующей форме:

    SETUP F B:{S|M|C|L}...{EM|87}[GR]

    Каждый пункт (или аргумент) в командной строке программы SETUP  дает
программе информацию о том, каким образом установить компилятор Quick-C.
Необязательные  аргументы  заключены  в  квадратные  скобки [ ]. Если вы
опустите   необязательные   аргументы,   программа   SETUP    использует
соответствующие   стандартные.   Некоторые   необязательные    аргументы
позволяют для выбора стандартного значения ввести знак вопроса (?).

    Далее перечислены  аргументы, которые  вы можете  ввести в командный
строке программы SETUP; если  вы хотите получить краткую  информацию обо
всех аргументах  командной строки,  введите SETUP  без аргументов  (в то
время, как в дисководе А установлен дистрибутивный диск Program)

Аргумент               Значение

F                      Сообщает программе SETUP, что устанока произ-
                       водится на системе с гибкими дисками.
B:                     Наберите B:, чены к библиотеке. Если вы используете гра-
                       фические функции, компилятор должен находить
                       также и библиотеку GRAPHICS.LIB. Подробности
                       смотрите в Разделе 1.5.

      Пример:

      SETUP F B: M EM

      Приведенная командная строка требует, чтобы программа SETUP
построила соответствующую библиотеку для средней модели памяти и для

Аргумент               Значение

                       Если вы будете разрабатывать программы вне
                       программной среды пакета Quick-C (используя
                       команду QCL, описанную в Главе 9 "Компиляция
                       и компановка программ"), введите S, поскольку
                       малая модель памяти стандартна для команды
                       QCL. Кроме того, если вы будете применять ком-
                       пактную модель памяти или большую модель, вве-
                       дите C или L.
                       Программа SETUP использует задаваемые вами ар-
                       гументы модели памяти и математического пакета
                       (смотрите ниже) для построения библиотек. Объе
                       диненные библиотеки ускоряют процесс разработ-
                       ки программ; однако, поскольку для каждой по-
                       строенной библиотеки требуется отдельная дис-
                       кета, задавайте буквы только для тех моделей,
                       которыми вы точно будете пользоваться. (Если
                       вы используете более одной модели памяти, вам
                       могут понадобиться отдельные библиотеки, вмес-
                       то того, чтобы занимать дисковое пространство
                       для объединенных библиотек, подробности смот-
                       рите Раздел 1.4).
 EM,87                 Чтобы сообщить программе SETUP, как обрабаты-
                       вать операции с плавающей точкой с помощью
                       эмуляции сопроцессора 8087 или 80287 (EM),
                       или используя реальный сопроцессор (87). Обыч-
                       но, задаете EM, посколько программная среда
                       пакета Quick-C использует эмулятор.
                       Если вы разрабатываете программы, выполняющие
                       научные, математические или финансовые вычис-
                       ления с вещественными числами, и которые всег-
                       да будут работать на системах, имеющих матема-
                       тический сопроцессор, запускайте программу
                       SETUP с аргументом 87. При заданном аргумента
                       87 будет построена добавочная библиотека,
                       требующая дополнительного дискового простран-
                       ства, но написание программ с помощью этой биб
                       лиотеки сделает их компактнее и быстрее.
GR                     Введите GR, если вы хотите добавить в библио-
                       теки, создаваемые программой SETUP графические
                       функции пакета Quick-C (описанные в Главе 4
                       данного руководства и в документе "Справочное
                       руководство по библиотеке процедур
                       Microsoft C")
                       Использование данной опции сделает библиотеку
                       больше примерно на 50К. Если вы не зададите
                       эту опцию, графические функции не будут под-
                       ключены к библиотеке. Если вы используете гра-
                       фические функции, компилятор должен находить
                       также и библиотеку GRAPHICS.LIB. Подробности
                       смотрите в Разделе 1.5.

      Пример:

      SETUP F B: M EM

      Приведенная командная строка требует, чтобы программа SETUP
построила соответствующую библиотеку для средней модели памяти и для
процедур эмуляции операций с плавающей точкой с именем MLIBCE.LIB на
гибком диске в дисководе В.

                1.3.2.3 Построение библиотек на системе
                          с гибкими дисками.

    После того, как вы нажмите  ENTER, программа SETUP начнет строить  и
устанавливать  библиотеки.   SETUP  устанавливает  одну  библиотеку   на
дискету;  она  сообщает  вам  о  смене  дискет  в  устройствах  А  и  В-
дистрибутивных  дискет,  на  которых  расположены библиотеки, дискет, на
которые вы устанавливаете новые библиотеки и вашей рабочей дискеты.

    Программа SETUP считывает аргументы моделей памяти (S, M, C или L) и
аргументы математики с плавающей точкой (EM или 87), которые вы задали в
командной  строке  и  строит  по  одной  библиотеке  на каждую возможную
комбинацию этих двух параметров. В процессе построения, программа  SETUP
высвечивает  имена  строящихся  библиотек.   SETUP дает имена строящимся
библиотекам  в  зависимости  от  модели  памяти  и  пакета  математики с
плавающей точкой, которые вы выбрали. Каждое стандартное имя  библиотеки
имеет следующую форму:

    {S|M|C|L}LIBC{E|7}.LIB

    Первый символ имени библиотеки совпадает с аргументом модели памяти:
S для малой (стандартной) модели, M для средней модели, C для компактной
модели, L  для большой  модели памяти.  Последний символ  базового имени
(часть имени перед расширением .LIB) определяется аргументом  математики
с плавающей точкой: E для аргумента EM, 7 для аргумента 87.

    Например, библиотека с именем MLIBCE.LIB поддерживает среднюю модель
памяти и пакет  эмуляции операций с  плавающей точкой, стандарт  ной для
программной  среды  пакета  Quick-C.  Библиотека  с  именем   SLIBC7.LIB
поддерживает малую модель памяти  и пакет математики с  плавающей точкой
для сопроцессора 8087/80287,  данная библиотека может  быть использована
только в программах,  работающих на компьютерах,  имеющих математический
сопроцессор.

---------------------------------------------------------------------

    Примечание

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

---------------------------------------------------------------------

                1.3.2.4 Устанока операционной среды DOS
                     на системе с гибкими дисками.

    Финал процесса установки пакета-это установка операционной среды DOS
для облегчения поиска требуемых файлов. Введите следующие команды DOS:

      SET PATH=A:;
      SET LIB=A:;
      SET INCLUDE=A:\INCLUDE;

    Данные  команды  добавляют   пакет  Quick-C  искать   выполняемые  и
библиотечные  файлы  в  корневом  каталоге  дискеты  в  дисководе  А,  а
включаемые файлы в каталоге \INCLUDE на дискете в дисководе А.

    Данные  назначения   будут  работать   до  тех   пор,  пока   вы  не
перезагрузите  систему.   Вы  можете   добавить  эти   команды  в   файл
AUTOEXEC.BAT,  тогда  они  будут  выполняться  автоматически  при каждой
перезагрузке системы.

    Перед тем, как стартовать пакет Quick-C, добавьте следующие строки в
ваш файл конфигурации системы CONFIG.SYS, затем перезагрузите систему:

      files=15
      buffers=10

                1.4. Использование отдельных библиотек.

    Программа SETUP строит объединенные библиотеки, поскольку разработка
программ с использованием  отдельных библиотек занимает  больше времени.
Если вы используете много различных вариантов комбинаций моделей  памяти
и  математики  с  плавающей  точкой,  вам  может  показаться  чрезмерным
количество памяти, занимаемое различными комбинированными  библиотеками.
Вместо этого, вы можете пользоваться отдельными компонентами  библиотек.
Заметим, что применение отдельных библиотек имеет следующие недостатки:

    -Вы будете вынуждены набирать  слишком длинные командные строки  для
компиляции и компановки программ

    -Вы должны потребовать, чтобы редактор связей не использовал обычные
библиотеки и явно задать имена соответствующих отдельных библиотек.

    -Процесс компановки с отдельными библиотеками займет больше времени,
чем тот же процесс с комбинированными библиотеками.

    С компилятором Quick-C  поставляются следующие отдельные  библиотеки
(m означает соответствующую модель памяти).

 Библиотека            Применение

mLIBC.LIB              Стандартная библиотека процедур; содержит все
                       процедуры, входящие в библиотеку использующей
                       системыя Microsoft C, исключая математические
                       процедуры, поддерживающие операции с плавающей
                       точкой.
mLIBFP.LIB             Библиотека математики с плавающей точкой, тре-
                       буется, если ваша программа использует EM.LIB
                       или 87.LIB
EM.LIB                 Эмулятор операций с плавающей точкой, незави-
                       симый от используемой модели; применяется для
                       выполнения операций с плавающей точкой.
LIBH.LIB               "Помощник компилятора" независимый от исполь-
                       зуемой модели; применяется для обработки ком-
                       плексных операций, таких как 32-разрядное ум-
                       ножение и деление.
87.LIB                 Независимая от используемой модели библиотека
                       поддержки операций с плавающей точкой для со-
                       процессора 8087/80287; может быть использована
                       только на компьютерах, имеющих данный сопроце-
                       ссор.

    Следующий  ниже  список  показывает,  каким образом программой SETUP
строятся   комбинированные   библиотеки,   и   соотверствующие отдельные
библиотеки:

Комбинированные        Отдельные библиотеки
библиотеки

mLIBCE.LIB             mLIBC.LIB, mLIBFP.LIB, LIBH.LIB, EM.LIB
mLIBC7.LIB             mLIBC.LIB, mLIBFP.LIB, LIBH.LIB, 87.LIB

    Если вы предпочитаете использовать отдельные библиотеки,  скопируйте
требуемые вам  библиотеки с  ваших рабочих  копий дистрибутивных  дискет
Libraries#1, Libraries#2, Libraries#3  в подкаталог, который  вы создали
для  них  на  вашем  жестком  диске  (по  умолчанию,  dest\LIB). Если вы
запускаете пакет  с гибких  дисков, пользуйтесь  вашими рабочими копиями
дистрибутивных дисков.

    В следующем списке показано, где найти каждый тип библиотеки

Библиотеки             Дистрибутивная дискета

Независимые от модели  Libraries#1
памяти
Средняя и малая мо-    Libraries#2
дель памяти
Компактная и большая   Libraries#3
модели памяти

    В  разделе  9.4.2.3  вы  найдете  подробную  информацию  о специфике
отдельных библиотек.

        1.5. Использование графической библиотеки Microsoft C.

    Если вы  решили не  включать графические  функции в  комбинированные
библиотеки, строящиеся программой SETUP, но будете использовать  графику
в   ваших   программах,   пакет   Quick-C   должен   находить библиотеку
GRAPHICS.LIB, которая  содержит графические  функции. Данная  библиотека
находится на  дистрибутивном диске  Libraries#1. Если  вы устанавливаете
пакет Quick-C на систему с жестким диском, скопируйте данную  библиотеку
в подкаталог, в котором SETUP установил билиотеки.

    Если вы разрабатываете программу с графикой в среде пакета  Quick-C,
установите  для  программы  список,  как  описано в разделе 6.2.6. Затем
добавьте  в  программный  список  билиотеку  GRAPHICS.LIB, как описано в
разделе 6.2.7.

    Если вы разрабатываете  графическую программу вне  программной среды
пакета Quick-C, вам следует  подвязать библиотеку GRAPHICS.LIB явно.  Вы
можете выбрать из следующего:

    -Задать GRAPHICS.LIB в  командной строке команды  LINK или QCL,  как
описано в разделе 9.4.2.3.

    -Определить  библиотеку  GRAPHICS.LIB  в  переменной  среде  CL, как
описано в разделе 9.3 или в переменной среды LINK, как описано в разделе
9.5. Если  вы определите  библиотеку GRAPHICS.LIB  в операционной  среде
DOS, ваша программа будет подвязывать библиотеку автоматически.

                     1.6. Если у вас есть "мышь".

    Пакетом Quick-C можно пользоваться и без "мыши". Данное  руководство
описывает работу пакета как с  клавиатурой, так и с "мышью",  поэтому вы
можете всегда выбрать свой способ работы.

---------------------------------------------------------------------

Примечание

    Пакет  Microsoft   Quick-C  разработан   для  использования   "мыши"
Microsoft  Mouse.  Многие  производители  разрабатывают свои устройства,
совместимые с Microsoft  Mouse. Пакет Quick-C  может работать с  теми из
данных устройств,  которые полностью  совместимы, а  особенно, если  они
эмулируют функции Microsoft Mouse. За подробностями обратитесь к  вашему
поставщику.

---------------------------------------------------------------------

    В данном руководстве используются специальные термины для устройства
"мышь".

Термин                 Определение

Позиционировать        Перемещиние "мыши" до тех пор, пока указатель
 (point)               не установится на том месте, которое вам нуж-
                       но.
Нажать (press)         Нажать кнопку "мыши".
Быстро нажать и отпус- Быстро нажать и отпустить кнопку "мыши". Это
тить-щелкнуть          относится к левой кнопке, если не указано
(Click)                иначе.
Нажать и держать       Нажать левую кнопку "мыши" во время перемеще-
  (Drag)               ния ее по поверхности стола.
Двойное быстрое нажа-  Быстро нажать левую кнопку "мыши" дважды.
тие (Double click)

                  1.7. Работа с компилятором Quick-C.

    В  следующих  разделах  поясняется,  как  стартовать  и как выйти из
компилятора  Microsoft  Quick-C,  описываются  шаги  компиляции примера,
даются опции, задаваемые на  командной строке QC и  изменяющие поведение
компилятора.

                  1.7.1. Запуск компилятора Quick-C.

    После того, как вы установите математическое обеспечения компилятора
и назначите переменные программной среды DOS, вы готовы стартовать пакет
Quick-C. Какой из методов использовать зависит от того, работаете вы  на
жестком, или на гибких дисках:

      - На системе с жеским диском вы можете стартовать компилятор
      Quick из любого каталога, если у вас есть файл NEW-VARS.BAT, в
      котором установлена программная среда. В противном случае, вы-
      полните команду DOS CD, чтобы перейти в тот каталог, в кото-
      ром находится файл QC.EXE. Затем просто введите:
           QC

      - На системе с гибкими дисками, сделайте дисковод В текущим
      устройством. Установите в дисковод А вашу рабочую копию дис-
      трибутивной дискеты Product, а дискету, на которой будут раз-
      мещаться ваши программы, в дисковод В. Затем стартовать пакет
      Quick-C можно следующей командой:
           A:QC.

       Когда появится экран пакета Quick-C, замените дискету в диско-
      воде А на рабочую копию вашего дистрибутивного диска WORK.
      Чтобы загрузить одновременно со стартом пакета Quick-C и ваш
      исходный СИ-файл, наберите в командной строке после QC имя
      файла.

    Компилятор Quick-C  позволяет вам  также задать  в командной  строке
некоторые опции  и аргументы;  данные аргументы  описываются в следующем
разделе.

                          1.7.2. Кoманда QC.

    При  использовании  команды  QC  действиями  компилятора  Quick-C вы
модете управлять с помощью опций командной строки. Данные опции задаются
в  любом  порядке,  только  имя  исходного  файла,  которым  вы   хотите
загрузить,  должно  быть  последним  в  командной  строке. Ниже приведен
полный синтаксис команды QC:

      QC [[/b][/g][/h][/l quicklib][sourcefile]]

      Опции поясняются в следующей таблице:

Опция                  Действие

/b                     Стартует компилятор Microsoft Quick-C в черно-
                       -белом режиме. Если в вашей вычислительной
                       системе-монохромный монитор применяйте данную
                       опцию.
/g                     Применяйте данную опцию, если вы имеете цвет-
                       ной графический адаптер (CGA). Пакет Quick-C
                       автоматически регулирует экранный вывод в со-
                       ответствии с вашей аппаратурой. На некоторых
                       машинах возможна более быстрая регулировка эк-
                       рана, чем это делает пакет Quick-C стандартно
                       Опция /g позволит пакету Quick-C как можно
                       быстрее отрегулировать экранный вывод. Если вы
                       увидите "снег"(мерцание точек на экране), ког-
                       да вы изменяете на экране большой раздел (на-
                       пример с помощью PGUP), это значит, что ваша
                       аппаратура не может работать так быстро и вам
                       следует повторить старт пакета Quick-C с опци-
                       ей /g. Данная опция не оказывает влияния на
                       машинах, применяющих Усовершенствованный гра-
                       фический адаптер (EGA) или монохронный адаптер
                       (MA).
/h                     Стартует Quick-C с тем количеством строк, ка-
                       кое позволяет разрешение вашего видео-адапте-
                       ра. Например адаптер EGA, подсоединенный к
                       Усовершенствованному цветному монитору IBM
                       (ECD) может высвечивать 43 строки.
/l quicklib            Введите имя библиотеки Quick-C, если вам тре-
                       буется ее подзагрузить. Если в ваших програм-
                       мах используются библиотечные СИ-процедуры, не
                       встроенные в программную среду пакета Quick-C,
                       вы можете отладить их быстрее, если загрузите
                       библиотеку Quick, содержащую данные процедуры.
                       (В таблице 6.1 приведен список встроенных биб-
                       лиотечных процедур, а в разделе 10.1 приведена
                       информация о создании и использовании библио-
                       тек Quick).
sourcefile             Введите имя исходного СИ-файла, который вам
                       нужно загрузить для редактирования и компиля-
                       ции во время старта пакета Quick-C.

                    1.7.3. Выход из пакета Quick-C

    Чтобы выйти из  пакета Quick-C и  вернуться в операционную  систему,
проделайте следующие дествия:

    1.Нажмите Alt+F, чтобы высветить Меню файлов.

    2.Введите X, чтобы выполнить команду Exit.

    Другие способы выйти из пакета Quick-C описаны в Главе 6,  "Создание
и сохранение программ". Если вы выходите из Quick-C без записи программы
на диск, система спросит вас, хотите ли вы запомнить программу.  Введите
имя, которое вы хотите дать вашему файлу, затем нажмите ENTER.

                       1.7.4. Пример компиляции.

    Данный пример сеанса работы с пакетом дает вам небольшую практику. В
течение  этого  сеанса   вы  скомпилируете  демонстрационную   программу
CFLOW.C, которая  подготавливает вызовы  функций и  зависимости в  любом
исходном СИ-файле.

    Шаги, приведенные ниже, описывают процесс компиляции:

    1. Если вы работаете на системе с жестким диском, программа  CFLOW.C
находится  в  каталоге,  который  программа  SETUP  создает для примеров
программ.  (По умолчанию, dest\BIN\SAMPLE). Если вы работаете на системе
с  гибкими  дисками,  установите   в  дисковод  А  вашу   рабочую  копию
дистрибутивного  диска  Product,  а  в  дисковод  В  вашу  рабочую копию
дистрибутивного диска Libraries#2.

    2. Если вы запускаете систему на жестком диске, наберите:

                       qc cflow.c

    и нажмите ENTER для запуска пакета Quick-C и загрузки CFLOW.C.  Если
вы запускаете систему на гибких дисках, введите: a:qc cflow.c и  нажмите
ENTER

    3. Нажмите ALT+R для открытия Меню запуска.

    4. Нажмите C для выполнения команды Compile.

    5. Появится рамка  (называемая "диалоговая рамка")  команды Compile.
Теперь просто  нажмите ENTER.  Когда пакет  Quick-C закончит  компиляцию
ваших программ, рамка компиляции исчезнет с экрана.

    6. Снова нажмите ALT+R, чтобы открыть Меню запуска.

    7.  Нажмите  ALT+O  для  установки  опций  времени  выполнения  (или
выполнения команды SET Runtime Options.

    8.  Появится  диалоговая  рамка  команды  установки  опций   времени
выполнения.  В  командной  строке  текстовой  рамки  наберите  cflow.c и
нажмите ENTER.

    9. Снова нажмите ALT+R для открытия Меню запуска. 10. Нажмите S  для
запуска  вашей  программы.  Если  она  проработает  без  ошибок, Quick-C
высветит  следующее  сообщение:  Program  returned  (0).   Press any key
(Программа закончилась (0). Нажмите любой ключ).

    11. Нажмите любой ключ, чтобы вернуться в главное окно Quick-C.

    12. Нажмите ALT+R, чтобы снова открыть Меню файлов.

    13. Нажмите X,чтобы выйти из среды пакета Quick-C и вернуться в DOS

                        1.8. Опции сохранения:
                       Файл инициализации QC.INI

    Файл  QC.INI  представляет  собой  файл  иниализации,  который пакет
Quick-C  использует  для  записи  назначений  команды Options... из Меню
обзора  и  команды  Compile...  из  Меню  запуска.  Назначение   команды
Options... -определение цветов,  используемых для изображения  различных
частей текста, табуляции и автоматического размещения текста.

    Назначение   команды   Compile...   управляюи   различными аспектами
процесса компиляции. Если вы  изменили какое-либо из назначений  команды
Options...  или  Compile...,  и  затем  вышли  из  среды Quick-C, данные
изменения запишутся в файл с именем QC.INI. Файл QC.INI не  поставляется
ни на одной из дистрибутивных дискет. Он создается только при  изменении
назначений команды  Options... Если  вы пользуетесь  только стандартными
значениями, файл QC.INI не создается.

    При  старте  пакет  Quick-C  ищет  файл  QC.INI  сначала  в корневом
каталоге, затем в каталоге,  заданным с помощью переменной  операционной
среды PATH. Если  пакет Quick-C не  находит файла QC.INI,  он использует
стандартные  назначения  команды  Options...  из  Меню  обзора.  Если вы
изменили назначения  команды Options...,  Quick-C записывает  новый файл
QC.INI в каталог,  в котором он  был первоначально найден.  Заметим, что
если  вы  имеете  несколько  версий  файла QC.INI в отдельных каталогах,
пакет Quick-C использует версию того католога, из которого вы стартовали
пакет.


                             ГЛАВА 2.

            Введение в "Программную среду пакета Quick-C".

2.1.  Экран Quick-C.
2.2.  Использование меню Quick-C.
2.3.  Использование диалоговых рамок.
2.4.  Выборка текста.
2.5.  Прокрутка.
2.6.  Получение помощи: Меню помощи.

    Данная Глава знакомит вас  с программной средой пакета  Quick-C. Она
описывает  составные  части  данной  среды  и  показывает, как выполнять
наиболее  часто  употребляемые  операции,  такие  как:  отрытие  меню  и
диалоговых рамок; выбор команд и опций; выборка и прокрутка текста.

    Если вы хотите  начать работать с  программной средой до  детального
изучения отдельных меню и команд  в Части 2 данного руководства,  данная
Глава даст вам краткую информацию.

                          2.1. Экран Quick-C.

    Следующая таблица описывает компоненты экрана Quick-C.

Курсор                 Появляющееся на экране в месте ввода текста ми-
                       гающее подчеркивание или блок. Если пакет
                       Quick-C работает в режиме вставки-это мигающее
                       подчеркивание, если в режиме забоя-это ми-
                       гающий блок (за информацией о режиме забоя
                       обратитесь к разделу 7.1.2).
Указатель "мыши"       Маленький блок, появляющийся
                       в центре экрана, если у вас установлена "мышь"
Окно просмотра         Область экрана, в которой вы вводите и редак-
                       тируете программу в процессе отладки.
Строка меню            Полоса в верхней части экрана, содержащая име-
                       на командных меню Quick-C.
Заголовочная строка    Полоса экрана, ниже строки меню,
высвечивающая
                       имя файла, редактируемого в окне просмотра.
                       Если никакой файл не загружен, или если вы
                       работаете сновой программой, в заголовочной
                       строке появится: untitled.c.
Полосы прокрутки       Полосы между правой и нижней границами экрана,
                       показывающие относительную позицию в файле. Ес
                       ли вы имеете "мышь", полосы прокрутки также
                       обеспечивают для вас удобный путь перемещать в
                       окне просмотра текст вверх/вниз или вправо/вле
                       во. Полосы прокрутки можно включить или выклю-
                       чить с помощью опций просмотра в диалоговой
                       рамке.
Строка состояния       Последняя строка экрана, отображающая програм-
                       мный контекст и текущий программный список.
                       Если вы загрузили программный список, в стро
                       ке появится: "Program List:", за которым сле-
                       дует имя программного списка. В противном слу-
                       чае, за "Program List:" следует . (смот-
                       рите Главу 6, "Создание и сохранение прог-
                       рамм", в которой описывается программный спи-
                       сок). Если программа еще не была скомпилирова-
                       на, за "Context:" следует "Program not compi-
                       led." Если программа уже была скомпилирована,
                       по еще не выполнялась, за "Context:" следует
                       "Program not running". Если ваша программа вы-
                       полняется, после слова "Context:" высвечивает-
                       ся имя текущего исходного файла, за которым
                       следует имя выполняющейся в данный момент фун-
                       кции. С правого края высвечивается текущая по-
                       зиция курсора в виде комбинации номеров строки
                       и колонки. Слева от позиции курсора появляется
                       буква C, если нажат ключ CAPS LOCK, и N, ес-
                       ли нажат ключ NUM LOCK.
Окно данных            Окно появляется на экране, если только вы ис-
                       пользуете команду Add Watch... Смотрите в раз-
                       деле 8.2.3.1 подробности об окне данных и ко-
                       манде Add Watch...
Окно ошибок            Появляется на экране только в том случае, если
                       ваша программа имеет ошибки компиляции или пе-
                       риода выполнения. За подробностями обращай-
                       тесь к разделу 5.5.

                   2.2. Использование меню Quick-C.

    Команды Quick-C организованы в меню строки меню.

    Команды,  за  которыми  следуют  точки  (...)  требуют от вас при их
вызове  дополнительную  информацию.  Команды  без точек выполняются, как
только вы их вызовете.

                    2.2.1 Содержимое меню Quick-C.

    В следующем спике  описываются меню Quick-C  и команды, которые  они
содержат:

Меню     Действие команд

File     Создание, загрузка, слияние, печать и сохранение исходных
         файлов. Остальные команды в данном меню устанавливают или
         редактируют программный список, выходят в DOS, заканчивают
         сеанс работы с пакетом Quick-C.

Edit     Удаление, добавление или копирование текста в исходном файле

View     Адаптация программной среды пакета Quick-C и задание режимов
         изображения Quick-C.

Search   Поиск и замена текста в исходных файлах, поиск функций в про
         цессе отладки, высвечивание строк исходного файла, вызвавших
         ошибки компиляции.

Run      Компиляция и выполнение программ и установка опций компиля-
         ции и выполнения.

Debug    Управление средствами отладки, такими как выражения вывода
         данных, точки прерывания и подкачка экрана.

Calls    Не содержит команды, вместо этого изображается иерархия фун-
         кций, вызванных другими функциями, что позволяет вам переме-
         стить курсор на ту точку, откуда были вызваны высвечиваемые
         функции.

Help     Управление высвечиванием вспомогательной информации. Меню по
         мощи описано подробно в разделе 2.6 данного руководства "По-
         лучение помощи: Меню Help."

                     2.2.2. Выбор команд из меню.

    В  среде  Quick-C  имеется  несколько  способов  высвечивания меню и
выбора  команд.  Пользуйтесь  тем  методом,  который вы найдете наиболее
удобным.

    -Клавиатура

    Чтобы выбрать команду с помощью клавиатуры выполните следующие шаги:

1.    Нажмите ключ ALT плюс первую букву наименования меню. Меню бу-
      дет открыто.

2.    Нажмите ключ, соответствующий подсвеченной или подчеркнутой
      букве в наименовании команды. Если команда уже подсвечена, наж-
      мите ENTER, чтобы выбрать ее.

    Второй способ выбрать команду-следующий:

    1. Нажмите ALT.

    2. Переместите подсветку  на нужную команду  с помощью ключей  "up",
"down" и т.д.

    3. Нажмите ENTER,чтобы выполнить подсвеченную команду.

    Чтобы  отменить  любую  команду  перед  ее выполнением, нажмите ESC.
Заметим,  что  ключ  ALT  имеет  длительное  действие;  при  нажатии  он
устанавливает подсветку на  первый пункт строки  меню: File. Кроме  того
его можно включать и отключать, если вы нажмете ключ снова, его значение
станет  противоположным.  Таким  образом,  если  вы нажмете ALT+R, будет
открыто меню Run. Если сразу же  после этого вы нажмете снова ALT,  меню
Run исчезнет, и в строке меню останется подсвеченным пункт Run. Если  вы
нажмете ALT еще раз, подсветка исчезнет совсем.

    Если в меню  более одной команды  имеют одну и  ту же первую  букву,
одна  из  данных  команд  имеет  подсвеченной букву, отличную от первой.
Например, если в меню файлов имеются команды "Open...", так и "Open Last
File",  которые  обе  начинаются  на  букву "O". Чтобы выполнить команду
Open..., нажмите O, а чтобы выполнить команду Open Last File, нажмите L.
Нажатие клвиши ESC окончательно  выключит высвечивание меню, в  то время
как нажатие ALT только закрывает  его, но оставляет имя меню  выбранным.
Чтобы открыть меню, а затем  открыть другие меню, находящиеся в  строке,
откройте  сначала  одно  меню,  а  затем  перемещайтесь по строке меню с
помощью ключей  управления курсором  "LEFT" или  "RIGHT", чтобы  открыть
любое смежное меню.

    "-Мышь"

    Чтобы выбрать команду с  помощью "мыши", быстро нажмите  и отпустите
левую  кнопку  "мыши",  чтобы  выбрать  требуемое  имя меню, затем опять
щелкните левой кнопкой "мыши", чтобы выбрать команду.

    Чтобы снять команду с помощью "мыши", следует щелкнуть левой кнопкой
"мыши" на любом месте экрана, исключая меню.

                   2.2.3 Ключи быстрого реагирования
                           для команд меню.

    Справа   от   некоторых    команд   меню   высвечивается    название
соответствующего ключа. Это так называемые ключи быстрого  реагирования.
Этими   ключами   можно   пользоваться   чтобы   выполнять   команду без
предварительного  открытия  меню  и  выбора  команды.  Например,   чтобы
загрузить недавно редактируемый файл  без открытия меню, просто  нажмите
F2. В нижеследующей талице приведен список ключей быстрого  реагирования
пакетм Quick-C.

              Ключи быстрого реагирования пакета Quick-C.

Меню      Команда                                 Ключи

File      Открытие последнего файла              F2
         (Open Last File)
Edit     Undo (Отмена дествия)                   ALT+BACKSPACE
         Cut (Усечь)                             SHIFT+DEL
         Copy (Скопировать)                      CTRL+INL
         PASTE (Склеить)                         SHIFT+INS
         Clear (Очистить)                        DEL
View     Output Screen (Выводной экран)          F4
Search   Selected Text (Выбранный текст)         CTRL+\
         Repeat Last Find (Повторить последний   F3
         поиск)
         Next Error (Следующая ошибка)           SHIFT+F3
         Previons Error (Предыдущая ошибка)      SHIFT+F4
Run      Continue (Продолжить)                   F5
Debug    Delete Last Watch (Удалить последнее    SHIFT+F2
         окно данных)
         Toggle Breakpoint (Переключить точку    F9
         прерывания).

                 2.3. Использование диалоговых рамок.

    Пакет  Quick-C  высвечивает  диалоговую  рамку,  если  ему требуется
дополнительная информация, или он требует подтверждение вашего  действия
или вашего выбора.  Диалоговая рамка включает  в себя область  для ввода
информации, для выбора опций  команд, активизации выполнения или  снятия
команды. В  то время,  как пакет  Quick-C высвечивает  диалоговую рамку,
любая  информация,  вводимая  с  клавиатуры  влияет  на  любой   элемент
диалоговой рамки,  имеющий "фокус  ввода". На  элементе, имеющем  "фокус
ввода" появляется мигающее подчеркивание.

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

    При использовании  "мыши" щелкните  левой кнопкой  на нужном пункте,
независимо от того, где находится "фокус ввода".

    В данном  разделе для  иллюстрирования работы  с диалоговами рамками
используются диалоговае рамки Compile... и Open... .

    Диалоговые рамки содержат некоторые или все из следующих элементов:

Элемент                Описание

Текстовая рамка        Простанство для ааода информации по командам,
                       такой, например, как имя файла или текст, ко-
                       торый вы хотите найти.
                       Когда мигающее подчеркивание появляется в рам-
                       ке, текстовая рамка получает "фокус ввода".
                       Это означает, что в данную рамку вы можете
                       вводить или редактировать текст. Если вы вво-
                       дите текста больше, чем модет уместиться в рам-
                       ке, рамка сдвигается влево, освобождая дополни
                       тельное место для ввода текста.
                       Чтобы исправить ошибки ввода в текстовой рам-
                       ке, нажмите BACKSPACE или пользуйтесь ключами
                       редактирования Quick-C, описанными в разделе
                       7.1.1.
                       Для перемещения "фокуса ввода" с текстовой
                       рамки на следующий или предыдущий элемент диа-
                       логовой рамки, нажмите TAB или SHIFT+TAB соот-
                       ветственно.
                       Чтобы установить фокус ввода на любой элемент
                       диалоговой рамки, нажмите ALT и введите под-
                       свеченную букву имени элемента.
Рамка списка           Рамка, перечисляющая файлы, соответствующие
                       спецификации текстовой рамки. Рамка списка
                       обеспечивает для вас дополнительный способ вы-
                       борки файла для команды: вместо ввода имени
                       файла в текстовую рамку, вы можете выбрать его
                       из файлов, перечисленных в рамке списка.
                       Имя файла, имеющего "фокус ввода", появляется
                       в инверсном изображении. Данное имя это
                       выбранное в текущий момент имя файла.
                       Это имя появляется также в текстовой рамке.
                       Для того, чтобы переместить "фокус ввода" на
                       другое имя файла, нажимайте ключи управления
                       курсором, или нажмите первую букву имени фай-
                       ла. Для выполнения команды с данным выбранным
                       файлом нажмите ENTER.
Рамки проверки         Опции, которым предшествуют открывающие и зак-
                       рывающие скобки ([ ]), которые позволяют вам
                       выбрать одну или более опций из группы.
                       Для перемещения "фокуса ввода" вперед и назад
                       между рамками проверки, нажимайте ключи TAB и
                       SHIFT+TAB.
                       Чтобы включить или выключить "фокус ввода" в
                       рамке проверки, нажмите клавишу пробела. Когда
                       рамка проверки включена (то есть выбрана), в
                       рамке появляется символ X.
                       Для включения или выключения любой рамки про-
                       верки, нажмите ALT+подсвеченная буква наимено-
                       вания опции.
Кнопка команды         Квадратная рамка с меткой, которая обозначает,
                       что делает выбранная кнопка. Если командная
                       кнопка имеет "фокус ввода", она обведена двой-
                       ной рамкой. Командная кнопка с "фокусом ввода"
                       обозначает, что действие команды начнет выпол-
                       няться,как только вы нажмете ENTER или клавишу
                       пробела. Для того, чтобы переместить "фокус
                       ввода" с одной командной кнопки на другую, наж-
                       мите TAB или SHIFT+TAB, либо нажмите ALT и
                       введите букву, подсвеченную в командной рамке.
                       Для выполнения команды с опциями, выбранными в
                       диалоговой рамке, нажмите клавишу пробела или
                       ENTER. После выполнения команды диалоговая ра-
                       мка исчезает.
Круглые кнопки         Опции, которым предшествует открывающие и за-
                       крывающие круглые скобки (( )), которые обоз-
                       начают, что вы можете выбрать только одну оп-
                       цию из группы. Для перемещения "фокуса ввода"
                       вперед и назад по круглым кнопкам пользуйтесь
                       ключами "Up" и "Down".
                       Чтобы включить или выключить "фокус ввода" на
                       круглой кнопке, нажмите клавишу пробела. Если
                       круглая кнопка включена (выбрана), она ярко
                       подсвечивается.
                       Включение любой круглой кнопки достигается на-
                       жатием клавиши ALT плюс подсвеченной буквы из
                       имени опции. После того, как вы выбрали круг-
                       лую кнопку из группы круглых кнопок, нажмите
                       TAB или SHIFT+TAB для дальнейшего передвижения

    Очень часто диалоговая рамка  открывается с уже выбранными  опциями.
Обычно, это те опции, которые  были выбраны в предыдущий раз.  Например,
диалоговая рамка команды Options...  должна открываться с набором  опций
оставшихся после предыдущей работы с ней в течение данного сеанса.

    Для выбора  рамки проверки,  круглой кнопки  или командной  кнопки с
помощью "мыши", проделайте следующие два шага:

    1. Позиционируйте данную опцию.

    2. Щелкните левой кнопкой "мыши".

                         2.4. Выборка текста.

    Если вы работаете в среде пакета Quick-C, вам понадобиться "выбрать"
текст, с которым будет работать следующая команда.

    -Клавиатура.

    Чтобы  выбрать  текст  либо  в  рабочей  области  (например)  в окне
списка),  либо  в  текстовой  рамке,  держите  ключ SHIFT и одновременно
нажимайте  ключи   управления  курсором   для  перемещения   курсора  по
выбираемому тексту.  Чтобы выбрать  за раз  более одного  символа, можно
пользоваться   различными   ключевыми   комбинациями.   Данные  ключевые
комбинации приведены в Таблице 7.1.

    -"Мышь".

    Для  выбора  нужной  части  текса,  позиционируйтесь  на левую часть
текста и перемещайте "мышь" вдоль текста с одновременным нажатием  левой
кнопки.

                            2.5. Прокрутка.

    Очень часто  программа или  процедура имеет  слишком большой размер,
чтобы уместить целиком в окне просмотра. Чтобы увидеть оставшуюся  часть
текста, вам следует перемещать текст в окне вверх, вниз, вправо и влево.
Это называется "прокруткой".

    -Клавиатура.

    Для прокрутки текста с помощью клавиатуры вам следует, как только вы
достигните  последнего  символа  на  экране,  нажимать  ключи управления
курсором в том  направлении, в котором  вы хотите осуществить  прокрутку
текста.  Например,  чтобы  сделать  прокрутку  вправо,  переместитесь до
правой границы экрана и  продолжайте нажимать ключ RIGHT.  Для прокрутки
более  одного  символа  за  раз,  пользуйтесь  информацией  Таблицы 2.2.

Таблица 2.2  Прокрутка с помощью клавиатуры.

Прокрутка             Действие

На один экран вниз     PGDN
На один экран вверх    PGUP
На один экран влево    CTRL+PGUP
На один экран вправо   CTRL+PGDN

      -"Мышь".

    Если  у  вас  установлена  "мышь",  вы  можете  воспользоваться  для
прокрутки  текста  вверх,   вниз,  вправо,  влево   полосами  прокрутки,
находящимися на дне и на правой границе экрана.

    Для  прокрутки   с  помощью   "мыши",  позиционируйтесь   на  "рамку
прокрутки"  (темную  рамку  в  полосе  прокрутки)  и  двигайте  "мышь" с
одновременным нажатием левой кнопки к позиции на полосе, соответствующей
желаемому  местоположению.  Чтобы  осуществлять  прокрутку   страницами,
установите указатель "мыши"  между рамкой прокрутки  и верхом или  низом
полосы прокрутки и щелкните левой кнопкой "мыши". Для прокрутки по одной
строке или по одному символу  за один раз, щелкните кнопкой  на стрелках
любого конца полосы прокрутки.

                  2.6. Получение помощи: Меню помощи.

    Если вам  потребуется информация  о ключах  редактирования или  меню
Quick-C,  особенностях  языка  СИ,  библиотечных  функциях  СИ-вы всегда
можете получить помощь  от пакета Quick-C.  Вы можете попросить  Quick-C
выдать  для  вас  вспомогательную  информацию  в  окне просмотра о любом
ключевом   слове   языка   СИ   или   имени   функции-во  время процесса
редактирования вашего исходного файла. Или, если вы предпочитаете, можно
просмотреть список заголовков вспомогательной информации для того, чтобы
выбрать ту информацию, которая вам требуется.

    Чтобы вызвать вспомогательную информацию пакета Quick-C (в то время,
как никакая другая вспомогательная информация не высвечивается), нажмите
F1. Над окном просмотра появится первый экран вспомогательной информации
Quick-C-список   наиболее   часто   используемых   ключей редактирования
Quick-C.

    Команды в меню Help используются для просмотра информации о командах
клавиатуры Quick-C или о синтаксисе операторов и функций языка СИ.

      Команды в меню помощи описаны ниже:

Команда                Действие

General...             Высвечивает информацию об использовании Help и
                       о командах клавиатуры и меню Quick-C. Имеется
                       несколько экранов основной информации. Нажмите
                       N (следующий) или P(предыдущий) для перемещи-
                       ния между экранами.
Topic                  Высвечивает информацию о ключевом слове СИ или
                       функции СИ.
Close Help             Удаляет с экрана вспомогательную информацию.

    Вместо того, чтобы высвечивать вспомогательную информацию с  помощью
меню, используйте  ключи "быстрого  реагирования", что  дает вам большой
выигрыш в скорости. Ключи быстрого реагирования описаны в Таблице 2.3.

                                                 Таблица 2.3.

            Ключи быстрого реагирования для функции помощи.

Команды меню           Ключи быстрого реагирования

General                F1
Topic                  SHIFT+F1
Close Help             ESC

    Например, для  получения информации  о ключевом  слове языка  СИ или
функции, выполните следующие шаги:

    1. Поместите  курсор где-нибудь  на выбранном  слове (включая пробел
после последней буквы).

    2. Нажмите  SHIFT+F1 чтобы  высветить информацию  о данном  ключевом
слове.

    Если вы нажмете  SHIFT+F1, в то  время, как курсор  не установлен на
ключевом  слове  или  функции  СИ,  в  диалоговой  рамке появится список
заголовков (в верхнем регистре). Чтобы высветить информацию по одному из
перечисленных заголовков, проделайте следующее:

    1.  Пользуясь  ключами  управления  курсором, установитесь на нужном
заголовке.

    2. Нажмите  ENTER. Появится  список функций,  относящихся к  данному
заголовку; перейдите к шагу 3.

    3. Используйте, как описано в шаге 1 и 2 для высвечивания информации
о функции, находящейся под данным заголовком, ключи управления  курсором
и клавишу ENTER. Чтобы вернуться в вашу программу, нажмите ESC.


                                ГЛАВА 3

                     Быстрый старт пакета Quick-C.

3.1.  Структура программы на языке СИ.
3.2.  Описания.
3.3.  Директивы препроцессора и подключаемые файлы.
3.4.  Описания переменных.
3.5.  Операторы, выражения и операции.
3.6.  Описания функций и определения.
3.7.  Операторы цикла.
3.8.  Условные операторы и операторы перехода по условию.
3.9.  Массивы и строки.
3.10. Указатели.
3.11. Указатели на функции.
3.12. Структуры.
3.13. Использование функций ввода-вывода.
3.14. Использование функций ввода-вывода в файл.
3.15. Аргументы командной строки языка СИ.

    В данной Главе даются основы  программирования на языке СИ в  сжатой
форме.  Она  разработана  для  того,  чтобы  вы  как можно скорее начали
программировать на языке СИ.

    Предполагается, что  вы уже  знакомы с  программированием на  языках
Pascal   или   BASIC.   Если   вы   являетесь   абсолютным   новичком  в
программировании, для  изучения программирования  и языка  СИ вы  можете
одновременно   пользоваться   как   данной   Главой,   так   и  книгами,
перечисленными ниже.

    Для ускорения изучения каждый  раздел занимает только две  страницы.
Разделы представлены в порядке возрастания сложности и в порядке частоты
использования  в  программах  на  языке  СИ.  Например,  обзор  описаний
переменных предшествует обзору условных операторов.

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

                   Рекомендуемое изучение языка СИ.

    В дальнейшем,  вы можете  работать с  языком СИ  с помощью следующей
литературы:

    - Hagcock, Les, Morris Krieger.   "The C Primer, 2d ed."   New York:
McGraw-Hill,   1985   (Руководство   по   языку   СИ   для    начинающих
программистов).

    -  Kochan,  Stephen.   "Programming  in  C".  Hasbrouck Heights, NJ:
Hayden Book Company, Inc., 1983.  (Исчерпывающее руководство по языку СИ
с некоторым погружением в среду UNIX).

    - Plum,Thomas.   "Learning to  Program in  C". Cardiff,  New Jersey:
Plum Hall, Inc., 1983 (Широко известное руководство по  программированию
на языке СИ для колледжей).

    - Schildt,  Herbert.  "C  Made Easy".   Berkely, CA: Osborne/McGraw-
-Hill, 1985 (Хорошее введение в язык СИ для тех, кто уже знает BASIC).

    -  *Waite,  Mitchell,  Stephen  Prata  and Donald Martin.  "C Primer
Plus".   Indianopolis,  IN:  Howard  W.  Sams.  Inc., 1984 (Пользующееся
наибольшим спросом введение в язык СИ).
* Есть русский перевод в издательстве "Мир". Примечание переводчика.

                 3.1.Структура программы на языке СИ.

    Все  программы  на   языке  СИ  содержат   директивы  препроцессора,
описания, определения, выражения, операторы и функции.

    -Директива препроцессора.

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

    -Описания.

    Описание устанавливает имена и атрибуты переменных, функций и типов,
используемых в программе. Глобальные переменные описываются вне  функций
и  действуют  от  конца  описания  до  конца файла. Локальная переменная
описывается  внутри  функции  и  действует  от  конца  описания до конца
функции.

    -Определение.

    Определение   устанавливает   содержимое   переменной   или функции.
Опеределение также отводит память, требуемую для переменных и фунций.

    -Выражение.

    Выражение-это  комбинация  операций  и  операндов, которое принимает
единственное значение.

    -Оператор.

    Операторы управляют порядком выполнения программы на языке СИ.

    -Функция.

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

    -Функция main (главная).

    Все программы на языке СИ, там где начинается выполнение  программы,
имеют функцию с именем main.  Фигурные скобки, в которые заключено  тело
функции main, определяют начало и конец программы.

      -Пример: Основная структура СИ-программы.
                       /* директивы препроцессора */
#include      /* подключение стандартного заголовочного
                       файла СИ */
#define PI 3.14        /* определение символьной константы */
float area;            /* глобальное описание */
int square (int);      /* прототип функции */
main()

{                      /* начало функйии main и программы */
    int_radius squared; /* локальное описание */
    int radius = 3;    /* описание и инициализация */
    radius_squared = square (radius); /* передача значения функции */
    area = PI * radius_squared; /* оператор присваивания */
    printf ("area: %6.2f\n", area);
}                       /* конец функции main и программы */
square (r)              /* заголовок функции */
   int r_squared;       /* описания, известные только */
                        /* для функции square */
   r_squared = r * r;
   return (r_squared);  /* возврат значения в вызывающее выражение */
}

                             3.2 Описания.

    Описания  устанавливают  имена  и  типы  переменных,  а  также  типы
функций, определяемые где-либо.

    -Стандартные типы данных.

    Язык  СИ  имеет  стандартный   набор  типов  данных,  куда   входят:
символьные (char), целые (int) и с плавающей точкой (float).

    -Описания переменных и функций.

    Переменные следует  описать перед  использованием их  в программе на
языке СИ. Переменные не должны быть одинаково проинициализированы, но  в
операторах определения вы можете задать им начальные значения.

    Функции могут быть описаны  явно перед определением их  содержимого.
Функции, возвращающие данные типа, отличного от int, должны быть описаны
перед  использованием.  Без  явного  описания  первая  ссылка  на данную
функцию воспримет ее как int.

    -Создание новых наименований типов данных.

    Для создания  новых наименований  типов для  уже существующих  типов
данных используйте описание  typedef. Применение описаний  typedef может
сделать программы более мобильными и надежными.

    Определяемый тип может обозначать тип операции, разрешенной с данной
переменной (например, логической  операции). Испольщуйте ключевое  слово
typedef для защиты ваших программ в проблемах переносимости.  Применяйте
описание   typedef    для   тех    типов   данных,    которые   являются
машинно-зависимыми.  Тогда,  при  перемещении  программы будут требовать
изменения только описание  typedef. Наконец, typedef  можно использовать
для  лучшего  документирования  вашей  программы.  Например,  тип данных
"employee" (служащий) легче понять, чем что-то описанное в виде  сложной
структуры.  В  нижеследующей  таблице  приведены несколько типичных имен
typedef и соответствующие значения:

Имя typedef            Значение

ulong                  длинное целое без знака
bool                   целое (используемое для условий нуль/не нуль)
string                 указатель на символьное значение

      -Пример: Описания и определения типов в языке СИ.

#include
typedef unsigned long ulong; /* типы, определяемые программистом */
typedef unsigned short ushort;
typedef int bool;
typedef char *string;
/* typical function declaration:
   function name -- get_avg
   return value -- float
   expected parameters -- two integers
*/
float get_avg (int, int); /* прототип функции */
main()
{
   int matrix [3] [3]; /* описание 2-х мерной матрицы */
   struct date {   /* описание структуры */
        int month;
        int day;
        int year;
   };
   /* однажды созданные, имена typedef могут быть использованы в
      дальнейшем */
   bool true = 1;
   string example string;
   example_string = "text";
   printf ("string: %s\n",exampleestring);
   printf ("bool: %d\n",true);
}

            3.3 Директивы препроцессора и включаемые файлы.

    Тексты внешних файлов могут быть включены в СИ-программу посредством
директивы препроцессора #include. Препроцессор автоматически вызывает на
первом  шаге  компиляции.  Он  интерпретирует  директивы препроцессора и
затем посылает компилятору модифицированный СИ-файл.

    Директива #include требует, чтобы препроцессор подставил  содержимое
внешнего файла на место строки, содержащей директиву.

    -Заголовочные файлы языка СИ.

    Заголовочные СИ-файлы  обычно содержат  общие переменные  и описания
функций. Такие файлы  можно включить в  исходный текст программы,  чтобы
использовать содержащиеся в них  переменные или функции. Внешние  файлы,
подключаемые  директивой  #include  носят  также название "заголовочных"
файлов, которые для удобства имеют в операционной системе DOS расширение
.h.

    Директива #include-это команда  препроцессора. Символ #  должен быть
первым значащим символом в строке. Строка не должна заканчиваться точкой
с запятой.  Чаще всего  директива #include  ставится в  начале программы
перед функцией main.

    Используйте  заголовочный   файл,  чтобы   хранить  наиболее   часто
используемые определения и  описания, или машинно-зависимые  константы в
одном  месте.  Такой  файл  упрощает  задачу обработки набора описаний и
определений, используемых несколькими исходными программами.

    Библиотека СИ-процедур периода  выполнения также использует  внешние
файлы  для  определений  и  описаний.  Перед использованием библиотечной
функции  к  СИ-программе  должен  быть подключен соответствующий внешний
файл.

                Управление поиском подключаемого файла.

    Маршрут   поиска   определяется   форматом   в   директиве #include,
используемым для заголовочного файла.

    Разрешены три следующих формата:

    - Угловые скобки определяют, что в первую очередь поиск начина-
      ется в каталогах, заданных в командной строке компилятора и
      затем продолжается в стандартных каталогах, определенных в пе-
      ременной среды подключаемых файлов. Угловые скобки можно испо-
      льзовать для определения заголовочных файлов, поставляемых с
      компилятором.

    - Двойные кавычки обозначают, что поиск файлов начинается в ката-
      логе, в котором находится исходный файл, затем в каталогах, за-
      данных в командной строке компилятора, и наконец, в стандар-
      тных каталогах. Двойные кавычки употреблять для обозначения
      файлов, разработанных программистом.

    - Явное имя маршрута задается в любой форме (внутри двойных ка-
      вычек или угловых скобок), оно определяет единственный маршрут
      для поиска файлов.

      Пример: Подключение внешних файлов.

#include  /* стандартные заголовочные файлы процедур ввода-
                      -вывода из стандартного каталога */
#include   /* заголовояный файл математической функции */
#include  /* заголовочный файл графических процедур */
#include "local.h" /* локальный заголовочный файл ищется в том ката-
                      логе, в котором расположен исходный код */
#include "c:\test\math87.h" /* заданный файл ищется только на дис-
                    ководе C и только в подкаталоге "test" */
{
      /* тело СИ-программы */
}

                       3.4. Описания переменных.

    Все переменные перед использованием  следует описать. Они не  должны
быть предварительно проинициализированы. Неинициализированные переменные
содержат непредсказуемые значения.

    -Типы данных.

    Описания  содержат  спцификатор  типа,  за  которым  следует  список
переменных, данного типа. Переменные в списке должны отделяться друг  от
друга запятыми.

    -Область действия.

    Местоположение   описания   переменной   опеределяет   сферу влияния
переменной.

    Глобальные  переменные   описываются  вне   функций.  К   ним  можно
обращаться  из  любого  места  внутри  исходного  файла,  в  котором они
описаны.  Они  также  доступны  из  других  исходных модулей. Глобальные
переменные  обычно  описываются  в  начале  программного  текста   перед
функцией main и после директив #include.

    Локальные переменные описываются внутри функции и известны только  в
той функции, в которой они описаны.

    Локальные  переменные  всегда  описываются  в  начале  функции перед
выполняемыми операторами.

    -Требования к памяти.

    Ниже приведены требования к памяти для основных типов данных:

Тип            Память в байтах   Диапозон

char           1 байт             от -128 до 127
int
short          2 байта           от -32,768 до 32,767
long           4 байта           от -2,147,482,648 до 2,147,482,647
unsined char   1 байт            от 0 до 255
unsined
unsined short  2 байта           от 0 до 65,535
unsined long   4 байта           от 0 до 4,294,967,295
float          4 байта           от +3.4E-38 до 3.4E+38
double         8 байт            от +1.7E-308 до 1.7E+308

---------------------------------------------------------------------

Примечание: Если требования к памяти или диапозон не определены,
значит они зависят от конкретного применения.

---------------------------------------------------------------------

    Зависят  от   применения  типы   int  и   unsigned.  Для   семейства
микропроцессоров 8086  и 80286  тип int  эквивалентен типу  short, а тип
unsigned-типу unsigned short.

    -Регистровые переменные.

    Регистровые переменные-это целое или указатель, хранимые в  машинном
регистре.  Такая  память   ускоряет  выполнение  программы   посредством
увеличения скорости доступа к переменным.

    Если не имеется  свободных регистров, описания  е будет сделано,  но
регистр не будет использоваться для хранения.

      Пример: Описания переменных.
#include  /* стандартный заголовочный СИ-файл */
float pi=3.14159; /* глобальное описание и инициализация */
typedef unsigned short ushort /* unhort-это теперь синоним для типа
                                 unsigned short */
main()
{
    int i = 0; /* локальное описание и инициализация целого
                  (integer) */
    ushort limit; /* переменная limit имеет тип ushort, что эквива-
                     лентно unsigned short */
    register int j; /* хранение переменной j в машинном регистре */
/* тело функции main, следующее за описаниями */
}

function1()
{
     int x=47; /* описание и инициализация целого X известного
только
                  внутри функции function1 */
...тело функции function1, следующее за описаниями.

                 3.5. Операторы, выражения и операции.

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

    -Формат оператора.

    Все операторы заканчиваются точкой с запятой. На одной строке  могут
быть  размещены  два  или  более  операторов,  разделенных  двоеточиями.
Нулевой оператор состоит из одной точки с запятой.

    -Составные операторы.

    Составные операторы-это набор  нескольких операторов, заключенных  в
фигурные скобки { }. Составной  оператор может находиться там же,  где и
обычный оператор. После  фигурной скобки не  требуется точки с  запятой.
Составной оператор известен также под названием "блок".

    -Выражения.

    Выражения  состоят  из  операции  и  ее  операндов.  Выражение может
находиться  везде,  где  разрешено  появление значения. Любое выражение,
заканчивающееся точкой с запятой, является оператором.

    В языке СИ, присваивания считаются выражениями.

    -Операция присваивания.

    Операция  присваивания  определяет,  что  значение операнда с правой
стороны помещается  в память  по адресу,  задаваемому операндом  с левой
стороны.

    -Операции.

    Язык  СИ  поддерживает  более  40  операций,  начиная  от   основных
арифметических операций до  логических и поразрядных  операций. Операции
языка  СИ  дают  результат,  который  может  быть вложен внутрь большого
выражения. Операции также могут быть объединены с оператором  присвоения
(=)  для  формирования  составного  оператора  присваивания  в следующей
форме:

    X+=Y;

    -Преобразования типов.

    Явное  приведение  типов  может  быть  сделано  с  помощью  операции
приведения (cast), которая представляет собой тип, заключенный в скобки.

    В  нижеследующем  переменная  i  (предварительно описанная, как int)
преобразуется в тип float:

    (float)i

    -Операции приращения и уменьшения.

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

      Используйте эти операнды, как описано ниже:
      if (i-->0) /* i сравнивается с нулем, затем i уменьшается */
      printf ("сравнивается, затем уменьшается");
      if (--i>0) /* i уменьшается, затем сравнивается с нулем */
      printf ("уменьшается, затем сравнивается")

      -Примеры: Некомментированные СИ-выражения.
         while ((c=getchar())!=EOF)

    Пример, приведенный  выше, является  вложенным выражением,  вызывает
функцию getchar, которая возвращает целое. Затем, результат запоминается
в переменной C, и сравнивается  с переменной EOF, что дает  в результате
либо  "ложь",  либо  "истинну".  Данный  результат  определяет, будет ли
выполняться тело цикла while.

    a=b=7;

    В данном двойном операторе  присваивания, значение 7 запоминается  в
переменной  b,  затем  значение  b  (которое  равно  7)  запоминается  в
переменной a.

      x+=7;
      a<<=b;

    Первый  составной  оператор  увеличивает  x  на  7, второй составной
оператор сдвигает a влево на b разрядов.

                 3.6. Описание и определение функций.

    Описание  функции  устанавливает  такие  атрибуты  функции, как имя,
ожидемые  аргументы  и  тип  возвращаемого значения. Определение функции
определяет ее реальное содержимое.

    -Описание функции.

    Описание  функции  состоит  из  типа  возвращаемого  значения, имени
функции и необязательного  списка аргументов. Заголовок  функции состоит
из типа данных, возвращаемых функций,  за которым следует имя функции  и
список формальных параметров. Тело функции состоит из локальных описаний
и составного  оператора (или  "блока"), который  определяет, что  делает
данная функция.

    -Типы возвращаемых значений.

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

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

    -Список типов аргументов и прототипы функций.

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

    -Формальные параметры.

    Формальные  параметры  в  описании  функции  являются   переменными,
которые получают значения аргументов, переданные функции.

    -Передача аргументов функции.

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

      Пример: Описание и определение функции.
#include  /* описания стандартных функций */
#include  /* содержит описание прототипа atof */
typedef char *string;
main()
{
   string ascii_number;
   float float_number;
   ascii_number = "-6.02E-23";
   printf ("string: %s\n", ascii_number);
   /* следующая строка генерирует предупреждающее сообщение компиля-
      тора */
   float_number = atof(); /* слишком мало аргументов */
   float_number = atoy (ascii number); /* корректный вызов */
   printf ("number: %e'n", float_number);
}

      Приведенная выше СИ-программа показывает, как использлвание
прототипа функции может предупредить вас о некорректном вызове
функции. Функция atof преобразует символьную строку в число с
плавающей точкой. Прототип функции содержащийся в файле stdlib.h
определяет, что функция принимает один аргумент.

                         3.7. Операторы цикла.

    В  языке   СИ  операторы   for  и   while  обеспечивают  возможности
повтрорения выполняемых операторов.

    -Оператор for.

    Оператор for используется для  повторения какого либо оператора  или
составного оператора  определенное количество  раз. Он  состоит из  трех
частей:

    1. Выражение, стартующее цикл ( init-expr).

    2.  Текстовое  выражение   (cond-expr),  вычисляемое  перед   каждой
итерацией.

    3. Выражение цикла (loop-expr), выполняемое в конце каждой итерации.

    Формат оператора for приведен ниже:

      for([init-expr];[cond-expr];[loop-expr])statement

    Сначала  вычисляется  init-expr.  Затем,  пока вычисляемое выражение
cond-expr не равно нулю,  выполняется оператор statement. В  конце цикла
вычисляется выражение loop-expr. Как только выражение cond-expr получает
значение 0, управление передается на оператор, следующий за телом  цикла
for.

    Каждое выражение в операторе  цикла for может быть  любым корректным
выражением языка  СИ. Любое  из трех  или все  три выражения  могут быть
опущены.  Если  выражения  опущены,  точки  с запятой должны оставаться.
Несколько  выражений  могут  быть  помещены  в  оператор  for, но должны
отделяться  друг  от  друга  запятыми.  Типичный  пример   использования
одновременно нескольких операторов-это инициализация нескольких значений
в части init-expr цикла for, как показано ниже:

    for(i=1, j=1; i<=100; i++) /* инициализация i и j */

    -Оператор while.

    Оператор цикла  while состоит  из текстового  выражения (test-expr),
которое вычисляется перед телом  выполняемого цикла. Если test-expr  при
вычислении дает  "ложь", цикл  никогда не  выполняется. Формат оператора
while следующий:

      while ([test-expr])
      statement

      Тело цикла while состоит из оператора или составного
оператора. Если тестовое выражение дает при вычислении "истину",
тело цикла выполняется до тех пор, пока выражение не станет
"ложным".

    -Окончание работы операторов for и while.

    Обычно, операторы for и while завершают работу, как только  тестовое
выражение в цикле примет значение "ложь". Если необходимо прервать  цикл
раньше,  можно  воспользоваться  операторами  break,  goto  или  return.
Оператор continue  прерывает интерацию  без выхода  из цикла  и передает
контроль следующей итерации оператора for или while.

      Пример: Использование циклов for и while.
#include
main()
{
   int i, done;
   printf ("table of squres (every sixth number)\n");
   printf ("\nfor loop\n");
   printf ("number\t\tsquare\n");
   for (i=0; i<=20; i+=6)
      printf ("%d\t\t%d\n",i, i*i);
   printf ("nwhile loop\n");
   printf ("number\t\tsquare\n");
   i = 0;
   while (i <= 20) {
      printf ("%d\t\t%d\n",i, i*i);
      i += 6;
      }
   printf ("nwhile (nonzero test expression version)\n");
   printf ("number\t\tsquare\n");
   i = 0;
   done = 0;
   while (!done) {   /* будет выполняться пока done не получит
                        значение 1 */
      printf ("%d\t\t%d\n",i, i*i);
      i += 6;
      if (i > 20)
         done = 1;
   }
}

    Программа,  приведенная  выше  использует  циклы  for  и  while  для
вычисления таблицы квадратов для каждого 6-числа между 0 и 20.

       3.8. Условные операторы и операторы перехода по условию.

    В языке  СИ функции  условий и  переходов выполняют  операторы if  и
switch.

    -Оператор if.

    Если тестовое выражение в  операторе if получает значение  "истина",
выполняется   тело   оператора   if.   В   противном   случае, программа
продолжается  со  следующего  оператора.  Оператор  if может иметь также
операторную скобку else.  Однако, поскольку в  языке СИ нет  конструкции
"else if", для достижения  того же самого эффекта  используйте вложенные
операторы  if.  Без  явного  указания,  язык  СИ спаривает каждое else с
ближайшим предыдущим  if, которому  не хватает  else. Компилятору  будет
"яснее",  если  вы  заключите  группу  операторов  в  фигурные   скобки.
Нижеследующие примеры показывают типичные операторы if:

      if (x < 0)
         printf ("Square root operation invalid'n");
      if (x >= 0)
         {
         answer = sqrt (x);
         printf ("square root is: %6.2f\n", answer);
         }

    -Оператор switch.

    Оператор switch заменяет большое количество вложенных конструкций if
и else.

    Оператор switch  передает управление  оператору внутри  своего тела.
Управление  переходит  на  оператор,  для которого константное выражение
case  соответствует  (целая  либо  символьная константа, или константное
выражение)  значению  тестового  выражения  оператора switch. Выполнение
начинается с выбранного оператора и продолдается до конца тела оператора
switch, или до тех пор, пока какой-либо оператор не передает  управление
за  пределы  оператора  switch.  Для  прерывания выполнения определенной
ситуации  оператора  switch  используйте  оператор  break. Без оператора
break программа перейдет к следующей ситуации.

    Оператор  default  выполняется  в  том  случае,  если   соответствия
константного выражения  case и  тестового выражения  оператора switch не
существует.  Если  оператор  default  опущен,  и не найдено соответствия
константному  выражению  case,  ни  один  из операторов в теле оператора
switch не выполняются.

    Никакие две константы case в  одном операторе switch не могут  иметь
одинаковых  значений.  Ниже  приведен  пример  использования   оператора
switch.

      Пример:
switch (i) {
   case 1:
           printf ("number 1\n");
           break; /* продолжается после закрывающей фигурной
                     скобки  */
   case 2:
   case 4:

      printf ("even'n"); /* выполняется, если i==2 или i==4 */
      break; /* продолжается после закрывающей фигурной скобки */
   default:
           /* печатается, если i не равно 1,2 или 4 */
           printf ("number not in our test list'n");
   }

      -Пример: Использование операторов if и switch.

#include
#include  /* необходимо для функции преобразования
                       toupper */
main()
{
   char response [10];
   char test_char;
   printf ("Please enter your response (yes/no/quit): ");
   scanf ("%s" response); /* форматный ввод в строку */
   if (toupper(response[0]) == 'Q') { /* тест для q */
    printf ("program exit\n"); /* выполнить, если равно q */
    exit(1);
   }
   switch (response[0]) { /* переключатель по первому символу */
      case 'y': /* множественные метки case */
      case 'n':
         printf ("lowercase y or as first letter\n");
         break;
     default:
         printf ("not a lowercase y or n as first letter\n");

      break;
}
test_char = toupper(response[0]); /* преобразование в верхний
                                     регистр */
switch (test char) {
   case 'Y':
      printf ("Response is yes\n");
      break;
   case 'N':
      printf ("Response is no\n");
      break;
   default:
      printf ("Poease enter a yes or no\n");
  }
}

                        3.9. Массивы и строки.

    "Массив"-это  набор  элементов  данных  одиного  типа.  "Строка"-это
массив символов, оканчивающийся символьным нулем ('\0').

    -Типы массивов.

    Основной тип элементов массива определяет и тип массива. Тип массива
может  быть  любым,  разрешенным  в  языке  СИ,  включая, так называемые
"агрегатные" или составные типы, например структуры.

    -Размещение в памяти массивов.

    Элементы массива хранятся в последовательных областях памяти, причем
по  возрастанию  адресов  от  первого  элемента  к  последнему.  Массивы
хранятся  по  строкам.   (То  есть,  сначала хранятся все колонки первой
строки,  затем  все  колонки  второй  строки  и  т.д.).  Имя массива без
скобок-это  указатель  на  первый  элемент  массива.  Начальный  элемент
массива имеет номер 0.

    -Строки.

    В  языке  СИ  строка-это  массив  символов,  оканчивающийся   пустым
символом   ('\0').   Массивы,   представляющие   собой   строки   должны
резервировать память для хранения нулевого окончания.

      Пример: Использование массивов.
#include  /* стандартный заголовочный файл */
typedef char *string; /* переименование типа "char" в тип "string"
*/
int strlen (string); /* прототип функции */
/* описание и инициализация символьного массива test string */
char test string [] = "This is a C string";
main()
{
   int x;
   x = strlen1 (test string);
   printf ("length (array method): %d\n",x);
}
/* версия strlen (массива описателя) */

strlen1 (s)
char s[];
{
   int i = 0;
   while (s[i] != '\0')
      i++;
   return (i);
}

    Программа, приведенная выше,  вычисляет длину строки  путем подсчета
количества символов до нулевого окончания.

                           3.10. Указатели.

    Указатель-это переменная, содержащая  машинный адрес для  создания и
манипуляции структурами данных, динамического размещения памяти и вызова
функции посредством ссылки.

    -Создание указателей.

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

      Ниже приведены некоторые примеры описания указателей:
int*intptr; /* указатель на тип int */
char*name; /* указатель на тип char */

    -Требования к памяти для указателей.

    Количество памяти, требуемое для размещения указателя-это количество
байт,   требуемых   для   задания   машинного   адреса.   В    семействе
микропроцессоров  8086  "короткие"  указатели  требуют  16  разрядов,  а
"длинные" указатели-32 разряда.

    -Операторы для указателей.

    Символ звездочки  (*)-это оператор  косвенного обращения  к объекту,
который означает "указать на данные". Символ амперсенда (&)-это оператор
адресации. Если объекту  предшествует оператор адресации,  то это-адрес,
по которому хранится данный объект.

    -Указатели и функции.

    Указатели обеспечивают передачу  аргументов функции по  ссылке. Если
функции передаются массиву, передается только адрес начального элемента.

    -Действия с указателями.

    С  указателями  разрешается  производить  только некоторые действия:
сложение  указателя  и  целого  числа  (наращивание значения указателя);
вычитание из указателя целого  числа ( уменьшение указателя);  вычитание
двух указателей (вычитание  количества элементов между  ними); сравнение
двух указателей.

    Если указатель увеличивается или уменьшается на единицу целого типа,
язык СИ измеряет значение  этого целого по размеру  адресуемого объекта.
Это гарантирует то,  что увеличение на  единицу, например, всегда  будет
указывать на следующий элемент данных, независимо от размера элемента.

      -Пример: Функция измерения длины строки с
       использованием указателей.
/* версия strlen с увеличением указателя */
strlen1 (s)
char *s;
{
   int i;
   for (i=0; *s != '\0'; s++) /* увеличение указателя переменной s */
      i++;
   return (i);
}
/* версия strlen с вычитанием указателя */
strlen2 (s)
char *s;
{
   char *p = s; /* установка p для адресации первого символа s */
   while (*p != '\0')
     p++;   /* продвижение к следующему символу */
   return (p-s);
}

    Две  функции,  приведенные  выше,  могут  быть  подставлены на место
функции вычисления длины строки, описываемой в Разделе 3.9., "Массивы  и
строки".  Вместо  массива  для  вычисления  длины  строки,  передаваемой
функции, эти функции используют действия с указателем.

                      3.11. Указатели на функции.

    Указатель может быть описан  для адресации любого сложного  объекта,
включая  структуру  или  функцию.  Используйте  указатели на функции для
создания "родовых" функций, которые манипулируют данными любого типа.

    -Создание указателей на функции.

    Описывайте указатель на функцию, как показано ниже:

    int(*number compare) ();

    Тип  переменной  number  compare-это  "указатель на функцию, которая
вызвращает целое". Скобки вокруг  *number compare обязательны. Без  них,
язык СИ будет  использовать свои правила  порядка выполнение действий  и
интерпретирует строку, как  описание функции, возвращающей  указатель на
элемент типа int-что совсем не то же самое.

    -Использование указателей на функции.

    Наиболее принятое использование  указателей на функции-это  передача
их, как аргументов других функций. Например, библиотечная функция  qsort
выполняет "быструю сортировку" массива элементов данных. Данная функция,
как один из  своих аргументов, принимает  указатель на функцию,  которая
выполняет реальное сравнение элементов массива. Функция сравнения  может
содержать  операцию  сравнения  для  любого  типа  данных. В результате,
функция  qsort  может  быть  использована  для сортировки массива любого
типа. Реальное сравнение выполняет функция, заданная пользователем, а не
функция qsort.

    С  указателями  на  функцию  следует  использовать  только операторы
присвоения, сравнения и косвенного наименование (*); все другие операции
не определены.

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

#include
#include
main()
{
   int number_compare ();
   int string_compare ();
   char s1[80], s2[80];
   printf ("generic test for equality\n");
   printf ("enter first item:\n");
   gets (s1);
   printf ("enter second item:\n");

   gets (s2);
   if (isaipha (*s1))
      compare (s1, s2, string_compare); /* передача адреса */
   else
      compare (s1, s", number_compare); /* передача адреса */
}
compare a, b, compare_function)
char *a, *b;

/* указатель на функцию, возвращающую целое значение */
int 8*compare_function) ();
{
   /* использование оператора (*) для вызова конкретной функции

      сравнения */
   if ((*compare_function) (a,b))
      printf ("equal\n");
   else
      printf ("not equal\n");
}
number_compare (a,b)
char *a, *b;
{
   if (atoi (a) == atoi (b))
      return (1);
   else
      return (0);
}

string_compare (a,b)
char *a, *b;
{
if (stricmp(a,b))
   return (0);
else
   return (1);
}

                           3.12. Структуры.

    "Структура"-это набор логически связанных элементов данных различных
типов.

    -Создание структур.

    При  определении  данных  типа  "структура"  задаются элементы типов
данных  структуры  и  создается  сама  структура. Отдельные переменные в
структуре  называются   "члены",  а   имя  структуры   называется  "тэг"
структуры. Данные типа structure описываются в следующей форме:

    struct   structure-name    {   member-declarations    };   Структура
date,например, создается по следующему определению:

      struct date
         {
           int month;
           int day;
           int year;
         };
      После того, как структура определена, вы можете описать
переменную уже определенного типа. Тэг структуры должен следовать за
ключевым словом struct.

      Следующие ниже описания определяет переменную todayc date типа
struct date:

    struct date todays_date;

    -Переменные в структурах.

    Переменные,    являющиеся    элементом    типа    структуры,   могут
использоваться также, как и  любые другие переменные. Оператор  членства
(.) определяет  имя члена  структуры и  структуры, элементом  которой он
является. В приведенном ниже примере переменной month в структуре todays
date присваивается значение 12:

    todays date.month=12;

    -Структура и указатели.

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

    -Действия со структурами.

    Для  переменных-структур  разрешены  только  три операции: вы можете
получить ее адрес с помощью оператора адресации (&); вы можете  получить
доступ к одному из ее членов; вы можете присвоить одну структуру  другой
посредством операции присвоения.

      Пример: Использования структур.
#include
#include
main()
{
   struct ti *current_time;
   time_t long_time; /* значение времени*/
   time (&long time); /* получение количества секунд в long time */
   /* преобразование в структуру времени */
   current_time = localtime(&long_time);
   /* использование оператора выборки члена структуры для доступа
      к отдельному члену структуры */
   printf ("hour: %d'n", current_time->tm_hour);
}

    Приведенные  выше  программа   использует  оператор  выборки   члена
структуры  для  доступа  к  отдельным  элементам  структуры  tm, которая
содержит информацию о  времени. Затем распечатывается  значение текущего
часа. Функция localtime не  содержится в библиотеке процедур  Quick-C. В
результате,  вам  понадобится  для  компиляции  вашей  программы в среде
Quick-C воспользоваться  программным списком.  Использование программных
списков описывается в Разделе 6.1.

           3.13 Использование функций ввода/вывода языка СИ.

    Стандартая   библиотека   процедур   СИ   содержит   необходимый для
программиста на языке СИ полный набор функций ввода/вывода (I/O).

    -Функции ввод/вывод одного символа (getchar, putchar).

    Функция getchar получает следующий по порядку символ с клавиатуры  и
возвращает его в качесве  значения. Функция putchar выводит  один символ
на экран.

    -Форматный вывод (printf).

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

Управляющая последовательность       Символ

         \n                          сдвиг строки
         \t                          табуляция
         \'                          одинарная кавычка
         \''                         двойная кавычка
         \\                          обратный слэш

      -Форматный ввод - scanf.

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

    -Спецификации строки формата.

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

Спецификация           Значение
преобразования

%d                     десятичное целое
%u                     десятичное без знака
%o                     восьмиричное без знака
%x                     шестнадцатеричное без знака
%e                     экспонента
%f                     число с плавающей точкойа
%c                     один символ
%s                     строка символов

      -Пример: Использование функций ввода/вывода языка СИ.
#include
typedef char * string;
main()
{
   char c, j;
   int i;
   string item1[10], item2[10];
   float x;

   printf ("please enter a single character:\n");
   c = getchar();
   printf ("\tthe character just input was -- %c\n",c);
   printf ("nenter a digit, a string, a float, and a string: ");
   scanf ("%d %s %f %s", &i, item1, &x, item2);
   printf ("\n\ayou entered\n");
   printf ("%d\n%s\n%f\n%s", i, item2, x, item2);
   printf ("\n\nexample of conversion specifications:\n");
   printf ("decimal\toctal\thex\tcharacter\n");
   for (j = 65; j<=70; j++)
      printf ("%d\t%o\t%x\t%c\n", j,j,j,j);
}

            3.14 Использование функция ввода/вывода в файл.

    Стандартная  библиотека  языка  СИ  имеет  полный  набор необходимых
программисту функций ввода/вывода для файлов.

    -Структура FILE.

    Стандартный заголовочный файл процедур ввода/вывода stdio.h содержит
описание структуры FILE, которая определяет внутренний характер файла.

    -Открытие и закрытие файлов.

    Перед использованием файл должен  быть открыт с помощью  стандартной
библиотечной функции fopen. После использования файл должен быть  закрыт
посредством библиотечной функции fclose.

    Функция fopen принимает внешнее имя файла в системе DOS и возвращает
указатель   файла,   используемый   в   дальнейшем   в   вызовах функций
ввода/вывода. Указатель файла-это  адресный указатель на  структуру типа
FILE.  Функция  fopen  определяет  также  режим  работы с файлом:чтение,
запись добавление.

    Если вы делаете попытку открыть файл для записи или добавления в  то
время, как файл не существует, он по возможности будет создан. Если  при
открытии  файла  произошла  ошибка,  функция  fopen  возвращает  нулевой
указатель (со значением NULL).

    Для  лучшей  сохранности  файла  при  выходе из программы непременно
следует использовать финкцию fclose.

    -Односимвольный ввод/вывод в файл (fputchar, fgetchar).

    Функция fputchar помещает символ  в заданный файл. Функция  fgetchar
получает  символ  из  заданного  файла.  Значение возвращаемое функцией,
равное EOF, означает, что был достигнут конец файла.

    -Форматный ввод/вывод в файл (fprintf, fscanf).

    Функция fprintf  помещает отформатированный  вывод в  заданный файл.
Форматирование производится в  соответствии со строкой  формата, которая
действует аналогично тому, как было описано в функции printf.

    Функция   fscanf   считывает   информацию   из   заданного  файла, в
соответствии со строкой  формата, как и  в функции scanf.  Значение EOF,
возвращаемое функцией, означает, что была сделана попытка прочесть конец
файла.

      Пример: Использование ввода/вывода в файл.
#include
#include

main()
{
   FILE *fopen(), *fp_out;
   char fn_in[12], fn_out[12]; /* отводится память для filename.ext*/
   printf ("enter name of input file: ");
   scanf ("%s", fn_in);
   printf ("enter name of output file: ");
   scar ("%s", fn_out);
   fp_out = fopen (fn_out, "w");
   fp_in = fopen (fn,in,"r");
   /* проверка для несуществующего выодного файла; выход если вызов
      функции fopen потерпит неудачу */
   if (fp_in == NULL) {
      printf ("No input file %s'n",fn'in);
      exit (1);
   }
   /* если функция fopen завершилась удачно, выполнение оставщейся
      части программы*/
   convert_file(fp in,fp out);
   printf ("\nFile %s cleaned up\n",fp_in);
   printf ("Output in file: %s\n",fn_out);
   fclose (fp_in);
   fclose (fp_out);
   return (o);
}
convert_file (input, output)
FILE *input, *output;
{
   int c;

   /* получение символов до достижения конца файла (EOF) */
   while ((c = getc (input)) "= EOF){
      if (isupper(c)) /* преобразование регистра */
         c = tolower (c);
      else
         c = toupper (c);
   fputc(c,output); /* вывод в выходной файл */
   }
}
      Программа, приведенная выше, изменяет регистр всех символов в
файле.

                  3.15 Доступ к аргументам командной
                          строки в языке СИ.

    Аргументы командной строки в  языке СИ обеспечивают способ  передачи
аргументов к программе при ее выполнении.

    -Основные аргументы командной строки.

    В  операционной  системе  DOS  любая  информация, появляющаяся после
имени программы, воспринимается, как аргумент командной строки. Язык  СИ
обеспечивает  механизм  для  доступа  к  этим  аргументам.  Функция main
связывает  аргументы  командной  строки  с  двумя  параметрами.   Данные
аргументы кратко описываются ниже:

Аргумент               Описание

argc                   "Счетчик аргументов"-это количество аргументов
                       в командной строке. Завершающим аргументом
                       посредством argv[argc-1], поскольку массивы в
                       языке начинаются с нулевого элемента.
argv                   "Вектор аргументов"-это указатель на массив

                       символьных строк, содержащих аргументы команд-
                       ной строки, по одному в символьной строке.

    -Использование аргументов командной строки.

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

#include
main (argc,argv) /* функция main, использующая аргументы командной
                    строки */
char *argv[]; /* вектор аргументов */
int argc; /* счетчик аргументов */
{
   int i;
   printf ("argc: %d\n", argc); /* печать количества аргументов*/
   for (i = =; i < argc; i++) /* печать содержимого аргументов */
   printf ("argv [%d]: %s\n", i, argv[i]);
}

    Помните, что  несколько аргументов  ва командной  строке задаются  в
Меню Run с помощью пукта  меню: Set Runtime Options-во время  создания и
запуска вашей программа.

    Также, примите во  внимание, что в  операционной системе DOS  версии
3.0 значение arg[0] содержит строку "C", а не имя программы.

    -Использование символов-шаблонов DOS.

    При  обычной  компиляции,  программа,  полученная  в  результате, не
распознает имя файла DOS с символами-шаблонами (* и ?). Для того,  чтобы
иметь  возможность  использовать  шаблоны  DOS,  вам следует подвязать к
объектному модулю вашей программы соответствующий файл mSETARGV.OBJ (где
m означает соответствующий модуль памяти).

    При расширении имени файла  с шаблонами, все файлы,  соответствующие
данному  имени,  передаются  программе.  Если  такого  соответствия   не
найдено, аргумент передается литералом.

      -Пример: Обработка командной строки.
#include
#include
main(argc,argv)
char *argv[];
int argc;
{
   FILE +fopen(), *fp_in, *fp_out;
   /* проверка на корректное число аргументов */
   if (argc != 3) {
     printf ("correct usage is:\n");
     printf ("convcase input-file output-file\n");
     exit(0);
   }
   fp_out = fopen (argv[2], "w");
   fp_in = fopen (argv[1],"r");

   /* проверка на несоответствующий входной файл; выход если fopen
      закончилась неудачно */
   if (fp_in == NULL) {
      printf ("input file error : %s\n",argv[1]);
      exit (1);
   }
   /* если функция fopen завершилась удачно, выполняется оставшаяся
      часть программы */
   convert_file(fp in,fp out);
   printf ("\nFile %s converted\n",argv[1]);
   printf ("Output in file: %s\n",argv[2]);
   fclose (fp_in);
   fclose (fp_out);
   return (1);
}
convert_file (input,output)
{
/*
   The contents of the convert_file function
   are the same as in Section 3.14
*/
}

    Программа, приведенная выше, является модификацией примера программы
из  раздела  3.14,  "Использование  функций  ввода  вывода  в файл". Она
принимает имена файлов в  качестве аргументов командной строки,  где имя
входного файла предшествует имени выходного файла.


                             ГЛАВА 4.

                    Запуск графики пакета  Quick-C.

4.1   Структура графической программы.
4.2   Установка видео-режима.
4.3   Определение видео-конфигурации.
4.4   Использование цветных текстовых режимов.
4.5   Использование цветных графических режимов CGA.
4.6   Использование цветных графических режимов EGA.
4.7   Использование цветных графических режимов VGA.
4.8   Понятие о координатных системах.
4.9   Расстановка точек.
4.10  Вычерчивание линий.
4.11  Описание графических объектов.
4.12  Изображение графических объектов.
4.13  Заполнение фигур по шаблонам.
4.14  Вычерчивание и запоминание фигур.
4.15  Использование мультипликации.

    Данная Глава кратко описывает основы графического  программирования.
Она разработана таким образом,  чтобы наиболее быстрым способом  научить
вас решать любые графичечские задачи.

    Чтобы  ускорить  ваше  обучение,  каждая  тема располагается на двух
страницах.  Темы   представлены  в   порядке  вызрастания   сложности  и
приблизительно отвечая частоте появления в ваших программах.

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

---------------------------------------------------------------------

    Важное замечание:

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

    Кроме  того,  вам  следует  включить  в  программный  список   вашей
выполняемой СИ-программы графическую  библиотеку. Подробно этот  процесс
описан в Разделе 6.1.

---------------------------------------------------------------------

    -Дополнительные источники по изучению графики.

    Для  дальнейшего  погружения  в  микрокомпьютерную графику вы можете
воспользоваться некоторыми из приведенных ниже пособий:

    -Artwick, Bruce.  "Microcomputer Displays, Graphics and Animaition".
Englewood Cliffs.  NJ:Prentice-Hall, Inc., 1985 (Обзор  микрокомпютерной
графики и мультипликации создателем "flight Simulator").

    -Cockerham, John T. "Tne EGA Standart" PC Teeh Journal 4:10 (October
1986): 48-79 (Обзор стандарта EGA).

    Hummel,Robert L.  "Get the  Full EGA  Color Spectrum".   PC Magazine
(June 23,1987):311-328.  (Обзор цветных палитр EGA).

    -International  Business  Mashines.   "Enhanced  Graphics   Adapter"
(manual part # 6280131).  (Официальное техническое руководство  адаптера
EGA, выпущенное фирмой IBM, 1-800-426-7282).

    -Norton,Peter "The Peter Norton  Programmer's Guide to the  IBM PC".
Redmond, WA:Microsoft press,  1985.  (Стандартное руководство  "изнутри"
по семейству компьютеров IBM-PC. Несколько глав посвящены видео-режимам,
за исключением режимов EGA и VGA).

                 4.1 Структура графической программы.

    Разработка всех графических программ включает следующие пять шагов:

      1.Подключение графической библиотеки.

      2.Установка видео-режима.

      3.Определение параметров видео-конфигурации.

      4.Создание и манипуляции графическими фигурами.

      5.Восстановление первоначальной конфигурации перед выходом из
        программы.

    -Подключение графической библиотеки.

    Выключаемый   заголовочный   файл   graph.h   определяет    основные
переменные, прототипы  функций и  константы, используемые  в графическом
программировании.   Подключайте   данный   файл   ко   всем  программам,
использующим графические функции.

    -Установка видео-режима.

    Первым   шагом   в   графических   программах   является   установка
видео-режима,  который  разрешает  выполнение  графических  функций.   В
графической  библиотеке  СИ  поддерживается  10 графических режимов. Они
перечислены в Разделе 4.2.

    Процесс установки видео-режима описан ниже:

      1. Установите наивысший уровень видео-режима, требуемый для ва-
         шей программы. Проверьте возвращаемое значение на сбой.

      2. Если вы не можете установить первоначально заданный видео-
         -режим, продолжите попытку с более слабыми режимами до
         тех пор, пока режим не будет установлен, или до тех пор,
         пока не останется видео-режимов, удовлетворяющих вашей прог-
         рамме. Если не найдено корректного видео-режима, выйдете из
         функции и напечатайте сообщение об ошибке.

    -Определение видео-конфигурации.

    Для определения характеристик  видео-режима следует вызвать  функцию
getvideoconfig.   Полученная   информация   включает   такие   вещи, как
количество пикселов  x и  y для  каждого размера  и количество возможных
цветов.

    -Восстановление первоначальной конфигурации.

    Восстановите  систему  в  ее  первоначальный видео-режим посредством
вызова  функции  setvideomode  с  константой  DEFAULTMODE. Отказ системы
выполнить данные  действия приведут  к тому,  что при  запуске следующей
программы машина будет "заблокирована".

      -Пример: Скелет графической программы.
#include
#include  /* подключаемый файл графических функций */
int set mode (void); /* прототип */
struct videoconfig vc; /* данные конфигурации */
char error message [] = "This video mode is not supported";
main()
{
/* программа требует разрешения экрана 640x200 */
   if (!set mode()){ /* если set mode завершилась неудачно */
     printf ("%s\n", error message); /* печать сообщения об ошибке */
     exit (0); /* и выход */
   }
   _getvideoconfig (&vc); /* данные видео-конфигурации в VC */
              /* здесь выполняются графические операции */
   /* восстановление видео-режима */
   _setvideomode (_DEFAULTMODE);
}
   /* функция для установки режима; предполагается, что программа
      требует разрешения 640x200 */
int set_mode()
{
   if (_setvideomode (_HRES16COLOR)) /* VGA или EGA */
      return (_HRES16COLOR);

   if (_setvideomode(_HRESBW)) /* VGA, EGA или CGA */
      return (_HRESBW);
   esle
     return (0);
}

    Программа,приведенная выше, в общих чертах обрисовывает  графическую
программу.

                     4.2. Установка видео-режима.

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

    -Возможные режимы.

    Для установки видео-режимов используются приведенные ниже константы.
Размеры  даются  в  пикселах  для  графических  режимов,  и  в строках и
колонках для текстовых режимов.

Константа              Видео-режим                Текстовый или
                                                  графический

_DEFAULTMODE           Восстанавливает экран в   Оба
                       оригинальный режим
_TEXTBW40              40x25 текст, 16 серых     текстовый
_TEXTTC40              40x25 текст, 16/8 цветных текстовый
_TEXTBW80              80x25 текст, 16 серых     текстовый
_TEXTC80               80x25 текст, 16/8 цветных текстовый
_MRES4COLOR            320x200 ячеек, 4 цвета    графический
_MRESNOCOLOR           320x200 ячеек, 4 серых    графический
_HRESBW                640x200 ячеек, BW         графический
_TEXTMONO              80x25 текст, BW           текстовый
_MRES16COLOR           320x200 ячеек, 16 цветов  графический
_HRES16COLOR           640x200 ячеек, 16 цветов  графический
_ERESNOCOLOR           640x350 ячеек, BW         графический
_ERESCOLOR             640x350 ячеек,4/16 цветов графический
_VRES2COLOR            640x480 ячеек, 2 цвета    графический
_VRES16COLOR           640x480 ячеек, 16 цветов  графический
_MRES256COLOR          320x200 ячеек, 256 цветов графический

    -Выбор видео-режима.

    Выберете видео-режим  с требуемым  разрешением для  выполнения вашей
задачи.  Вам   нужно  сделать   выбор  между   повышениемем  разрешающей
способности экрана и количеством  цветов. Для установки режима  вызовите
функцию _setvideomode с одной из перечисленных выше констант.

    Возвращаемое  значение  0  обозначает,  что  ваше  оборудование   не
поддердивает  выбранный  видео-режим.  Сделайте  выход  из  программы  с
сообщением   о   том,   что   выбранный   видео-режим  не поддерживается
конфигурацией вашего оборудования.

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

    -Восстановление видео-режима.

    По окончанию программы  всегда следует восстанавливать  оригинальный
видео-режим  с  помощью   вызова  функции  _setvideomode   с  параметром
_DEFAULTMODE. Отказ системы восстановить оригинальный видео-режим  после
выполнения  графической  программы  приведет  к  тому,  что  при запуске
следующей программы машина будет "зблокирована".

      -Пример: Установка видео-режима.
#include
#include
int set mode (void);
struct videoconfig vc;
char error _message [] = "Данный видео-режим не поддерживается".
main()
{
   if (!set_mode()) {
      printf ("%s\n", error_message);
      exit(0);
   }
  _setvideoconfig (&vc); /* помещение данных конфигурации в VC */
           /* далее следует тело программы */
   _setvideomode (_DEFAULTMODE); /* восстановление видео-режима */

}
int set_mode()
{
/* предполагается, что программа требует разрешения 640x200 */
if (_setvideomode(_HRES16COLOR))
   return (_HRES16COLOR);
if (_setvideomode(_HRESBW))
   return (_HRESBW);
else
   return (0);
}

                 4.3. Определение видео-конфигурации.

    Вся  информация  о  видео-конфигурации  содержится  в структуре типа
videoconfig. Содержимое данной структуры определено в файле graph.h. При
установке видео-режима, предварительно должна быть задана информация для
видео-конфигурации.

    -Переменная-структура videoconfig.

    Для получения  информации о  видео-конфигурации вам  следует описать
переменную  типа  videoconfig.  Данная  структура будет использоваться в
вызове getvideoconfig в следующем формате:

struct videoconfig vc; /* описание переменной-структуры */
   .
   .
   .
_getvideoconfig (&vc); /* использование переменной-структуры */

      -Содержимое структуры videoconfig.

    Структура videoconfig определяется в графическом заголовочном  файле
graph.h, и содержит следующие элементы:

struct videoconfig {
   short numxpixels; /* количество пикселов по оси X */
   short numypixels; /* количество пикселов по оси Y */
   short numtextcols; /* количество возможных текстовых колонок */
   short numtextrows; /* количество возможных текстовых строк */
   short numcolors; /* количество реальных цветов */
   short bitsperpixel; /* количество разрядов на пиксел */
   short numvideopages; /* количество доступных видео-страниц */
};

    -Использование информации с видео-конфигурации.

    Информация    видео-конфигурации    применяется    для   определения
размерностей экрана.  В любом  графическом режиме  центр экрана задается
следующими координатами:

xcenter =  vc.numxpixels/2 -  1; /*  координата центра  по оси  X */
Ycenter = vc.numypixels/2 - 1; /* координата центра по оси Y */

    Переменная vc.vcnumxpixels-это число пикселов по оси X, а переменная
vc.vcnumypixels-это  количество   пикселов  по   оси  Y   в  в   текущем
видео-режиме.

      -Пример: Обращение к структуре видео-конфигурации.
#include
#include
#include
struct videoconfig vc; /* переменная vc типа videoconfig */

/* опеределение массива видео-режимов и наименований режимов, пос-
   кольку числа не последовательны */
int modes[12] = {_TEXTBW40, _TEXTC40, _TEXTBW80, _TEXTC80,
    _MRES4COLOR, _MRESNOCOLOR, _HRESBW, _TEXTMONO,
    _MMRES16COLOR, _HRES16COLOR, _ERESNOCOLOR, _ERESCOLOR};
char *modenames[] = {"TEXTBW40", "TEXTC40", "TEXTBW80",
                      "TEXTC80", "MRES¤COLOR", "MRESNOCOLOR",
                      "HRESBW", "TEXTMONO", "MRES16COLOR",
                      "HRES16COLOR", "ERESNOCOLOR", "ERESCOLOR"};
main()
{
   int i;
   /* проверка всех видео-режимов */
   for (i=0; i<=11; i++) {
        setvideodeomode (modes[i]);
        getvideoconfig (&vc);
       printf ("\n video mode:\t%s\n",modenames[i]);
       printf (" x pixels:\t%d\n",vc.numxpixels);
       printf (" y pixels:\t%d\n",vc.numypixels);
       printf (" text columns:\t%d\n",vc.numtextcols);
       printf (" text rows:\t%d\n",vc.numtextrows);
       printf (" # of colors:\t%d\n",vc.numcolors);
       printf (" bits/pixel:\t%d\n",vc.bitsperpixel);
       printf (" video pages:\t%d\n",vc.numvideopages);
       print (" Hit return for next video mode");
      _setcolor (2);
       _rectangle (_GBORDER,0,0,vc.numxpixels-5,

       vc.numypixels-5);
       getchar();
       _clearscreen (_GCLEARSCREEN);
   }
   _setvideomode (_DEFAULTMODE);
}

    Программа, приведенная выше, вызывает каждый возможный видео-режим и
распечатывает  информации  видео-конфигурации.  Данная  программа  также
вычерчивает по краям экрана прямоугольник.

             4.4. Использование цветных текстовых режимов.

    С  дисплеями  CGA,  EGA  и  VGA можно использовать цветные текстовые
режиме _TEXTC40  и _TEXTC80.  Данные режимы  предлагают 16  передних и 8
фоновых цветов.

    -Основы выбора цвета текста.

    В  текстовом  режиме  каждый  высвечиваемый  символ  требует 2 байта
видео-памяти. Первый байт содержит  код ASCII, представляющий символ,  а
второй байт  содержит атрибут  изображиния. В  цветном текстовом  режиме
CGA, байт-атрибут определяет цвет и наличие мерцания символа. Имеются 16
цветов: значения пикселов CGA и стандартные значения пикселов EGA и VGA.

    Поскольку  палитры  EGA  и  VGA  могут  быть перепланированы, данные
значения должны быть заданы таким образом, чтобы соответствовать  любому
набору  16  цветов  с  соответствующей  картой  палитры.   (Информацию о
перепланировании  значений  ячеек  EGA  и  VGA  смотрите  соответственно
разделы 4.6 и 4.7).

    -Использование цветов текста.

    Для того,чтобы найти значение соответствующего значения пиксела  для
текущего  цвета  текста,  используйте  функцию  _gettextcolor.  Значения
пикселов  в  пределах  от  0  до  15 интерпретируются как обычные цвета.
Значения пикселов от 16  до 31-это те же  самые цвета, что и  0-15, но с
мерцающие.

    Устанавливаются  цвета  для  текстовых  режимов  посредством функции
_settextcolor. Данная функция использует единственный аргумент,  который
задает  значение  пиксела  для  использования  в  текстовых   операциях.
Значение пиксела  0 приводит  к невидимому  выводу, поскольку  он всегда
представляет текущий цвет фона. Цвет  текста не влияет на обычный  вывод
языка  СИ.  Для  вывода  цветного  текста  следует  использовать функцию
_outtext.  Ниже  определяются  значения  ячеек  для  цветных   текстовых
режимов:

№   Цвет        №   Цвет         №   Цвет          №   Цвет

0   черный      4   красный      8   темно-серый   12  светло-красный
1   голубой     5   лиловый      9   светло-голу-  13  светло-лиловый
                    (фруксин)        бой
2   зеленый     6   коричневый   10  светло-зеле-  14  желтый
                                     ный
3   зеленовато- 7   белый        11  светло-зеле-  15  ярко-белый
    -голубой                         новато-голубой

      -Пример: Вывод цветного текста.
#include
#include
char buffer [225];

main()
{
   int i,j;
   long int delay;
   _setvideomode (_TEXTC80);
   for (j=0; j<= 7; j++) {
               _setbkcolor (j); /* фоновые цвета */
               _settextrosition (1,1);
               printf ("bkocolor: %d\n", j);
               for (i=0; i<= 15; i++) {
                  _settextcolor (i); /* цвета текста */
                  _settextrosition (5+i,i);
                  sprintf (buffer, "Color: %d\n", i9;
                  _outtext (buffer);
               }
                  /* пауза */
                 for (delay = 0; delay <=200000; delay++);
}
   _clearscreen (_GCLEARSCREEN);
   _setvideomode (_DEFAULTMODE);
}

    Приведенная выше  программа в  цикле проходит  через все  комбинации
цветов фона и текста.

          4.5. Использование цветных графических режимов CGA.

    Цветные графические режимы CGA  (то есть MRES4COLOR и  _MRESNOCOLOR)
высвечивают  4  цвета  (или  оттенки  серого),  выбираемые из нескольких
заданных палитр цветов. Они высвечивают цвета переднего плана на  цветах
фона, выбираемых из 16 возможных цветов.

    -Цветная графика CGA.

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

    Цвет фона может быть одним из имеющихся 16 цветов. Для  оборудования
CGA  палитра  цветов  переднего  плана  задана  заранее  и не может быть
изменена.  Номер  палитры-это  целое  число,  которое  выбирает  одну из
заданных палитр.

    -Использование палитр.

    В  видео-режиме  _MRES4COLOR  имеются  четыре палитры. Палитру можно
выбрать  с  помощью  функции  _selectpalette. Таблица, приведенная ниже,
показывает соответствие  между значениями  пикселов и  цветов для каждой
палитры. Фон может быть установлен одним из 16 возможных цветов.

Номер               Значение пиксела
палитры             1                  2                  3

0             зеленый          красный              коричневый
1             зеленовато-го-   лиловый              светло-серый
              лубой
2             светло-зеленый   светло-красный       желтый
3             светло-зелено-   светло-лиловый       белый
              вато-голубой

    Видео-режим _MRESNOCOLOR используется для черно-белого изображения с
помощью палитр, состоящих из оттенков серого цвета.

    Режим  _MRESNOCOLOR  может  также  воспроизводить  цвета  на цветном
дисплее.  Однако,  на  цветном  дисплее  имеются только две палитры. Для
выбора  одной  из   заранее  определенных  палитр   применяется  функция
_selectpalette.

    Приведенная ниже  палитра показывает  соответствие между  значениями
пикселов и цветами для каждой палитры:

Номер               Значение пиксела
палитры             1                  2                  3

0             голубой          красный              светло-серый
1             светло-голубой   светло-красный       белый

    Функцию _selectpalette  можно использовать  только с  видео-режимами
_MRES4COLOR и _MRESNOCOLOR.

      -Пример: Изображение цветов палитры.
#include
#include

long bkcolor[8] = {_BLACK, _BLUE, _GREEN, _CYAN,
                   _RED, _MAGENTA, _BROWN, _WHITE};
char *blcolor name [] = {"_BLACK", "_BLUE", "_GREEN",
    "_CYAN", "_RED", "_MAGENTA", "_BROWN", "_WHITE"};
main()
{
 int i, j, k, delay;
 _setvideomode (_MRES4COLOR); /* использование цветного режима CGA
*/
 for (k=0; k <= 7; k++) {
   _setbkcolor (bkcolor[k]);
   for (i=0; i<= 3; i++) {
     _selectpalette (i);
     for (j=0; j<=3; j++) {
       _settextposition (1,1);
       _setcolor (j);
       printf ("background color: %8s\n", bkcolor nameGk[);
       printf ("palette: %d\ncolor: %d\n",i,j);
       _rectangle (_GFILLINTERIOR,160,100,320,200);
       for (delay=0; delay<= 20000; velay++)
     }
   }
 }
 _setvideomode (_DEFAULTMODE);
}

    Данная  программа  устанавливает  видео-режим  _MRES4COLOR  и  затем
прокручивает все комбинации фона и цветов палитр.

     4.6. Использование цветных графических режимов EGA.

    Видео-режимы  _  MRES16COLOR,  _HRES16COLOR, _ERESCOLOR используются
для получения  уличщенной цветной  графики с  адаптером EGA.  Режимы CGA
также можно использовать с адаптером EGA, но на уровне разрешения CGA  и
с уменьшенным набором цветов.

    -Цветные графические режимы EGA.

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

    Палитра  цветов  доступна,  какой  бы  из графических режимов EGA не
использовался. Палитры EGA могут быть перепланированы и переопределены в
программе.  Стандартная  палитра  для  режимов  EGA  та  же самая, что и
палитра для цветных текстовых режимов.

    -Переопределение отдельных цветов.

    Для переопределения одного значения пиксела в заданный цвет (который
должен быть  обязательно цветом,  поддерживаемым текущим  видео-режимом)
используется функция _remappalette.  Например, приведенная ниже  функция
переопределяет  значение  ячейки  1  на  значение _RED. После выполнения
данного оператора голубой цвет будет везде появляться, как красный:

_remappalette (1, _RED); /* переназначение голубого на красный */

      -Переопределение набора цветов.

    Для переопределения всех значений пикселов одновременно используется
функция _remapallpalette. Аргумент  функции указывает на  массив номеров
цветов, отражающих  перепланировку. Первый  номер цвета  в списке станет
новым цветом, связанным со значением пиксела 0.

    Номер в вызове функции, устанавливающей цвет (такой, как  _setcolor)
является индексом  в имеющейся  палитре цветов.  В стандартной текстовой
палитре  индекс  1  означает  "голубой".  Если  палитра перепланируется,
порядок цветов в палитре  изменяется. В результате, цвет,  получаемый по
данному  значению  пиксела,  также  изменяется.  Количество  планируемых
цветов   зависит   от   количества   цветов,   поддерживаемых    текущим
видео-режимом.

    Функции _remappalette и  _remapallpalette работают во  всех режимах,
но  только  с  оборудованием  EGA  или  VGA.  Если  вы  сделаете попытку
выполнить данные  функции без  оборудования EGA  или VGA,  функции дадут
сбой и возвратят значение-1.

      -Пример: Перепланирование цветов палитры.
#include
#include

main()
{
   _setdideomode (_ERESCOLOR);
   _settextposition (1,1); /* обычная палитра */
   printf ("Normal palette");
   _setcolor (4); /* красный в стандартной палитре */
   _rectangle (_ GFILLINTERIOR, 50,50,200,200);
   getchar(); /* ожидание ключа ENTER */
   _remappalette (4. _BLUE); /* превращение красного в голубой */

   _settextposition (1,1);
   printf ("Remapped palette");
   _setcolor (4); /* голубой */
   _rectangle (_GFILLINTERIOR, 50,50,200,200);
   getchar(); /* ожидание ключа ENTER */
   _remappalette (4, _RED); /* восстановление */
   _settextposition (1,1);
   printf ("Restored palette");
   _setcolor (4); /* красный */
   _rectangle (_GFILLINTERIOR,50,50,200,200);
   getchar(); /* ожидание ключа ENTER */
   _clearscreen (_GCLEARSCREEN);
   _setvideomode (_DEFAULTMODE);
}

    Данная  программа  вычерчивает   прямоугольник  красного  цвета.   В
стандартной палитре EGA значение пиксела 4 означает красный цвет. Данное
назначение переопределяется в данной программе на _BLUE и  прямоугольник
перечерчивается.  В  конце  программы  значение пиксела переопределяется
назад в оригинальный цвет.

          4.7. Использование цветных графических режимов VGA.

    С дисплеем VGA используются видео-режимы _VRES2COLOR,  _VRES16COLOR,
_MRES256COLOR. С оборудованием VGA  могут использоваться также и  режимы
EGA и  CGA, но  с более  низкой разрешающей  способностью и ограниченным
набором цветов.

    -Цветные графические режимы VGA.

    В графическом режиме пиксел может быть представлена как одно-, двух-
или четырех-битовое значение, в зависимости от выбранного режима. Данное
представление известно, как "значение пиксела". Кроме того, в дополнение
к  значению  пиксела  существует  порядковое представление цвета. Каждый
цвет, высвечиваемый в определенном видео-режиме, представлен  уникальным
порядковым   значением.   Распределение   значений   ячеек   в  реальные
высвечиваемые цвета дает в результате "палитру" высвечиваемых цветов.

    Цветная  графика  VGA  оперирует  почти  с  262144 (эквивалент 256К)
цветами.   Режим   графики   _VRES2COLOR   высвечивает   2  цвета, режим
_VRES16COLOR высвечивает 16 цветов, режим _MRES256COLOR высвечивает  256
цветов из имеющихся в VGA.

    Большое  количество  возможных  цветов  в  режимах  VGA   становится
возможным  при  использовании  трех  байтов  информации,  представляющей
интенсивность красного, зеленого и голубого для каждой пикселе. В каждом
байте  два  старших  разряда  должны  равняться  нулю.  Оставшиеся шесть
разрядов  определяют   интенсивность  голубого,   зеленого  и   красного
(читается от  старшего байта  к младшему).  Три цвета,  каждый с  шестью
разрядами  интенсивности  дают  64**3  или  262144 оттенка.  (эквивалент
256К).  Например,   равные  значения   красного,  зеленого   и  голубого
используются  для  получения  белого  низкой  интенсивности, так что три
байта цвета должны содержать следующее:

голубой             зеленый            красный
00011111            00011111           00011111
старшие разряды-------------------->младшие разряды

    Поскольку номера цветов разделяются между байтами, номера цветов  не
являются последовательными (как и в случае CGA или EGA).

    16 цветов для стандартной  палитры режима _VRES16COLOR и  первый для
стандартной  палитры  режима  _MRES256COLOR  те  же  самые,  что  и  для
текстовых цветных режимов.

    -Переопределение отдельных цветов.

    Для  переопределения  одного  значения  пиксела  в определенный цвет
используется   функция    _remappalette.   Приведенная    ниже   функция
переопределяет  значение  пиксела  1  в  цвет,  заданный константой _RED
(которая представляет  красный цвет).  После того,  как данный  оператор
выполнится, цвет, заданный голубым, будет высвечиваться , как красный:

_remappalette (1, _RED); /* переназначение голубого в красный в
                           режиме VGA */

    -Переназначение набора цветов.

    Чтобы  переназначить  все  имеющиеся  в  наличии цвета одновременно,
воспользуйтель  функцией  _remapallpalette.  Аргумент  функции  адресует
массив номеров цветов, отражающих  переназначение. Первый номер цвета  в
списке станет новым цветом, соответствующим значению пиксела 0.

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

    Функции _remappalette и  _remapallpalette работают во  всех режамах,
но  только  на  оборудовании  EGA  или  VGA.  Если  вы  сделаете попытку
переназначить палитру без оборудования EGA или VGA, функции

_remappalette и _remapallpalette дадут сбой и возвратят значение -1.

    Описывающие константы для стандартных номеров цветов задаются  таким
образом, что переназначение  цветов для VGA  совместимо с режимами  EGA.
Имена данных  констант самодокументируемы.  Например, номера  цветов для
черного,  красного   и  светло-желтого   цветов  задаются   объявляющими
константами _BLACK, _RED, _LIGHTYELLOW.

    Все  режимы   VGA  действуют   с  любым   видео-монитором  VGA.  При
подсоединенном монохромном мониторе все цвета высвечиваются, как оттенки
серого.

      -Пример: Переназначение цветных палитр VGA.
long colors1 [16] = {_BLACK, _BLUE, _GREEN, _RED, _RED, _MAGENTA,
       _BROWN, _WHITE, _GRAY, _LIGHTBLUE, _LIGHTGREEN, _LIGHTRED,
       _LIGHTRED, _LIGHTMAGENTA, _LIGHTYELLOW, _BRIGHWHITE};

    Приведенный  выше  массив  номеров  цветов переназначает стандартную
палитру  VGA  таким  образом,  что  вместо  цветов зеленовато-голубого и
светло-зеленовато-голубого будут высвечиваться красный и светло-красный.

                 4.8. Понятие о координатной системе.

    "Координатная система" используется для идентификации местоположения
пиксела относительно горизонтальной  и вертикальной осей.  В графическом
режиме  каждый  пиксел  на  экране  может  быть  обозначен   посредством
уникальной пары координат.  Графическая библиотека функций  поддерживает
две координатные системы: физическую и логическую.

    -Физические координаты.

    "Физическая  координатная  система"  помещает  начало  отсчета  (или
координатную пару 0,0) в верхний левый угол экрана. Рост  положительного
значения  координаты  Х  происходит  слева  направо. Рост положительного
значения  координаты  У  происходит  сверху  вниз. Таким образом, правый
нижний угол экрана имеет  координату Х, равную максимальному  количеству
пикселов  по  оси  Х,  поддерживаемому данным видео-режимом. Аналогично,
нижний  правый  угол  экрана  имеет  координату  У, равную максимальному
количеству пикселов по оси У в данном видео-режиме.

    Физическая  координатная   система  содержит   только  положительные
значения: Х от 0 ( в верхнем левом углу) до количества пикселов по оси Х
(правая граница); У от 0 (верхний левый угол) до количества пикселов  по
оси У (низ экрана).

    Физическая   координатная   система   зависит   от   оборудования  и
конфигурации изображения и не может быть изменена.

    -Логические координаты.

    "Логическая  координатная  система"  создается  перемещением  начала
координат   в   более   "логическую"   позицию   относительно абсолютных
физических  координат.  Она  определяется  функцией  _setlogorg, которая
устанавливает   новое   логическое   начало   координат.  Первоначально,
логическая  координатная   система  идентична   физической  координатной
системе.

    После перенесения начала координат, координаты Х и У  придерживаются
данной  ориентации.  При  увеличении  Х  позиция пиксела перемещается по
экрану слева направо; при увеличении У, позиция пиксела перемещается  от
верхней границы к нижней границе экрана.

    -Перемещение начала координат.

    Сегмент программы, приведенный  ниже, перемещает начало  координат в
центр экрана:

_getvideoconfig (&vc);
_setlogorg (vc.numxpixels/2-1, vc.numypixels/2-1);

    Вызов функции _getvideoconfig помещает информацию видео-конфигурации
в  переменную-структуру  vc.  Структура  конфигурации  содержит данные о
размере экрана.  Это используется  (после соответствующего  деления) для
перемещения начала координат в центр экрана.

    -Возврат к физическим координатам.

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

 setlogorg (0,0);

    -Преобразование координат от одной координатной системы к другой.

    Для преобразования  физических координат  в логические  используется
функция  _getlogcoord.  Логические  координаты  помещаются  в  структуру
xycoord.  Для  преобразования  логических  координат заданного пиксела в
физические  координаты  используется  функция  _getphyscoord. Физические
координаты помещаются  в структуру  xycoord. Формат  двух данных  описан
ниже:

_getlogcoord (x,y);
_getphyscoord (x,y);
_getvideoconfig (&vc); /* получение информации видео-конфигурации */
x = vc.numxpixels/2 - 1; /* определение Х и У средних точек */
y = vc.numypixels/2 -1;
_setlogorg (x,y); /* перемещение начала координат */

    Данный   фрагмент   программы   находит   центр   экрана  для любого
видео-режима и устанавливает в нем начало координат.

                   4.9. Размещение отдельных точек.

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

    -Перемещение на заданную точку экрана.

    Текущую  графическую  позицию  можно  изменить  с  помощью   функции
_moveto.  Данная  функция  перемещает  текущую  позицию  (то есть ту, на
которой   закончилась   предыдущая   операция)   в   заданные логические
координаты. Формат данной функции следующий:

_moveto (10,10); /* сдвиг на 10 пикселов вправо и на 10 пикселов
                    вниз от логического начала координат */

    -Установка и очистка пикселов.

    Функция _setpixel используется для установки пиксела, расположенного
по заданным логическим координатам в текущий цвет. Ее формат следующий:

_setpixel (10,10); /* установка пиксела по координатам 10, 10 в
                      текущий цвет */

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

_setcolor (0); /* установка текущего цвета в цвет фона */
_setpixel (x,y); /* очистка пиксела */

    -Пример: Установка пикселов.  Программа hyppix.c, приведенная  ниже,
вычерчивает  гипоциклоид-  -фигуру,  полученную  вращением  одного круга
внутри другого. Подключается библиотека math.h (математических функций),
поскольку потребуются функции синус и косинус. Используется видео-режим,
совместимый с  CGA. Кривая  вычерчивается во  времы работы  цикла while,
который может  быть прерван  нажатием функциьнального  ключа. Для  того,
чтобы получить более интересные  рисунки, задайте circle ratio  большим,
чем  pen  position  и  не  используйте  чисто  целых  значений. Наиболее
интересный  рисунок  получается  при  circle  ratio,  равном  3.2  и ren
position, равном  1.6.  (Более  подробную информацию  о гипоциклоидах  и
других  циклоидах  можно  найти  в  журнале  "Byte",  May, 1987 в статье
"Математические построения").

/* hyppix.c-построение гипоциклода-точечное */
#include
#include
#include
#include
struct videoconfig vc;
char error_message [] = "This video mode is not supported";
main()
{
   if (_setvideomode(_MRES4COLOR) == 0) {

      printf ("%s\n", error_message);
      exit(0);
   }
   _getvideoconfig (&vc);
   hypcycle(); /* вызов функции рисования */
   _clearscreen(_GCLEARSCREEN);
   _setvideomode (_DEFAULTMODE); /* восстановление видео-режима */
}
hypcycle()
{
   float pi=3.14159; /* объявление и инциализация */
   float a,h,b,r,x0,y0,x,y, ang;
   int i;
   x0 = vc.numxpixels/2 -1;
   y0 = vc.numypixels/2 -1;
   printf ("circle ratio (>=1): ");
   schanf ("%f", &r);
   printf ("\npen position (>1): ");
   scanf ("%f",&h);
   _clearscreen(_GCLEARSCREEN);
   _setcolor (1);
   _moveto (x0,0); /* вычерчивание осей */
   _lineto (x0,vc.numypixels);
   _moveto (0,y0);
   _lineto (vc.numxpixels,y0);
    a = 0.5*r*vc.numypixels/(r+h-1);
   b = a/r;
   h = h*b;
   _setcolor (2);
   ang = 0;

   while (!kbhit()) { /* вычерчивание гипоциклоида */
       for (i=1; i<= 20; i++) {
          ang = ang + 2*pi/100;
          x = x0+(a-b)*cls(ang)+cos(ang*(a-b)/b);
          y = y0-(a-b)*sin(ang)+h*sin(ang*(a-b)/b);
           setpixel (x,y);
       }
   }
}

                        4.10. Рисование линий.

    Для рисования линий между двумя точками используются функция _moveto
и _lineto. Линия может быть вычерчена либо плотно (непрерывно), либо  по
образцу .

    -Перемещение в заданную позицию.

    Для перемещения  в заданную  логическими координатами  (парой чисел)
точку используется функция _moveto. Формат оператора _moveto  следующий:

_moveto (25,25); /* перемещение в точку с логическими координатами 25,25
*/

    -Вычерчивание линий.

    Для  того,  чтобы  прочертить  линию  от  текущей позиции курсора до
заданной в  функции конечной  точки, используется  функция _lineto. Если
линия была  успешно вычерчена,  текущая позиция  курсора перемещается на
координаты, указанные  в функции  _lineto .  Используемый цвет  является
текущим.  После  выполнение   описанной  выше  функции   _moveto(25,25),
приведенная ниже функция lineto  вычертит линию от точки  с координатами
(25,25) до точки (100,100), причем курсор установится в точке (100,100):

_lineto (100,100); /* вычерчивание линии от текущей позиции до точки
                      (100,100) */

    -Вычерчивание пунктирных линий либо линий определенного образца.

    Рисованием линии управляет  маска стиля. Маска-это  используемый для
рисования 16-разрядный шаблон. Каждый разряд в маске определяет пиксел в
линии. Если  разряд содержит  1, соответствующий  пиксел окрашивается  в
текущий цвет.  Если разряд  содержит 0-пиксел  устанавливается в фоновый
цвет. Стандартная маска-это непрерывная плотная линия (0хFFFF).

    Функция  _setlinestyle  устанавливает  стиль,  в котором вычерчивают
линии функции _lineto и _rectangle.

    Следующий пример изменяет  стиль линии на  пунктирный: _setlinestyle
(0xAAAA); /* стиль по шаблону 1010101010101010 */

      -Пример: Вычерчивание линий.
#include
#include
#include
struct videoconfig vc;
char error_message [] = "This video mode is not supported";
main()
{
   if (_setvideomode(_MRES4COLOR) == 0) {
      printf ("%s\n", error message);
      exit(0);
   }

   _getvideoconfig (&vc);
   _setlinestyle (0x0001);
   _moveto (0,0); /* вычерчивание фигуры */
   _lineto (0,150);
   _setlinestyle (0x0bb0);
   _lineto (150,150);
   _setlinestyle (0x0ff0);
   _lineto (150,0);
   _setlinestyle (0xffff);
   _lineto (0,0);
   getchar(); /* ожидание возврата */
   _clearscreen( GCLEARSCREEN); /* очистка содержимого экрана */
   _setvideomode ( DEFAULTMODE); /* восстановление видео-режима */
}

    Приведенная выше программа вычерчивает прямоугольник, причем  каждую
сторону в разном стиле.

                 4.11. Описание графических объектов.

    Данный  раздел  дает  основополагающие  концепции,  используемые при
описании графических объектов.

    -Ограничивающий прямоугольник.

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

    -Граница.

    Граница   кругового   объекта   вычерчивается   в   текущем  цвете и
непрерывной  линией.  Граница  прямоугольного  объекта  вычерчивается  в
текущем цвете и в любом стиле, заданном функцией _setlinestyle. Если для
вычерчивания границы не задано шаблона, используется стандартный  шаблон
(0xFFFF).

    -Флажок заполнения.

    Флажок заполнения используется для определения того, будет ли фигура
заполняться по текущей маске заполнения или останется пустой.  Константа
_GFILLINTERIOR  определяет,  каким  образом  будет заполняться объект, а
константа _GBORDER определяет, что будет вычерчиваться только граница.

    -Вектор начала и конца.

    Дуга или сектор начинаются в точке, где ограничивающий прямоугольник
пересекается  со  стартовым  вектором   и  заканчивается  там,  где   он
пересекается с заканчивающим вектором.

    -Коэффициент изображения.

    Коэффициент  изображения-это  количество  пикселов  на  вертикальной
линии, разделенное на количество пикселов по горизонтальной линии. Чтобы
вычертить квадрат или  окружность, вам следует  соизмерять их размеры  с
коэффициентом изображения.

    Коэффициент изображения зависит от двух факторов:

    1.  Горизонтальная  строка  имеет  больше пикселов, чем вертикальная
колонка той же самой физической длины-во всех режимах экра на, поскольку
на горизонтальной линии расстояние между точками меньше.

    2. Экран видео-дисплея шире, чем его высота, обычно с  коэффициентом
4:3.

    -Вычисление коэффициента изображения.

    Коэффициент  изображения  для  данного  видео-режима  вычисляется по
следующей формуле:

    коэф.изобр.=(ширина экрана/высота экрана)*(у-пиксел/х-пиксел),

    где "ширина экрана" и "высота экрана"-это физические размеры экрана,
а "у-пиксел"  и "х-пиксел"-это  текущее разрешение  экрана (измеряется в
пикселах).

      -Пример: Вычерчивание точно пропорциональных фигур.
#include
#include
#include
struct videoconfig vc;
char error_mesage [] = "this video mode is not supported";
main()
{
   float ar, x, y;
   if (_setvideomode(_MRES4COLOR == 0) {
      printf ("%s\n", error_message);
      exit(0);
   }
   _getvideoconfig (&vc);
   /* размеры экрана 10*6.6 дюймов */
   ar = (float) (10 * vc.numypixels) / (6.5 * vc.numhpixels);
   y = 100*ar;
   x = 100;
   _setlogorg (vc.numxpixels/2 - 1, vc.numypixels/2 - 1);
   _setcolor (1);
   _rectangle (_GFILIINTERIOR, -x, -y, x, y);
   _setcolor (3);

   _ellipse (_GFILLINTERIOR, -x, -y, x, y);
   getchar();
   _clearscreen(_GCLEARSCREEN);
   _setvideomode (_DEFAULTMODE); /* восстановление видео-режима*/
}

    Данная  программа  использует  коэффициент  изображения, для точного
вычерчивания квадрата и окружности.

    Круговая фигура освещает принцип ограничивающего прямоугольника.

                  4.12. Вычерчивание основных фигур.

    Основные фигуры, имеющиеся в стандартной библиотеке процедур  СИ-это
прямоугольник, эллипс, дуга и сектор.

    -Вычерчивание прямоугольников.

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

_rectangle (_GBORDER,0,0,25,25); /* вычерчивание только границ */
_restangle (_GFILLINTERIOR,25,25,0,0); /* закрашивание внутреннос-
                                          ти */

    -Вычерчивание окружностей и эллипсов.

    Для вычерчивания эллипсов  используется функция _ellipse.  Параметры
функции определяют противоположные углы ограничивающего  прямоугольника.
Центром  эллипса  является  центр  ограничивающего  прямоугольника. Если
ограничивающий    прямоугольник    является    квадратом-эллипс    будет
окружностью. Нижеприведенные команды  вычерчивают два эллипса  в верхний
левой части экрана:

_ellipse (_GBORDER,0,0,25,25); /* вычерчивание одних границ */
_ellipse (_GFILLINTERIOR,25,25,0,0); /* заполнение фигуры */
      Если принцип ограничивающего прямоугольника немного непонятен,
вы можете вызвать функцию _ellipse, используя только центр (х,у) и
радиус (r), как показано ниже.
_ellipse (_GBORDER,x-r,y-r,x+r,y+r); /* вычерчивание одних границ */

    -Изображение дуг и секторов.

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

/* ограничивающий прямоугольник определяется координатами: (,0) и
(50,50), вектор начала-центр ограничивающего прямоугольника &
(0,100); конечный вектор-центр ограничивающего прямоугольника
&(100,100) */
_arc (0, 0, 50, 50, 0, 100, 100, 100);
_pie (_GFILLINTERIOR, 0, 0, 50, 50, 0, 100, 100, 100);

      -Пример: Рисование фигур.
#include
#include
#include
struct videoconfig vc;
char error_message [] = "Данный видео-режим поддерживается";
main()
{
   int x = 50;
   int y = 40;
   if (_setvideomode(_MRES4COLOR) == 0) {
      printf ("%s\n", error_message);
      exit (0);
   }
   _getvideoconfig (&vc);
   _setlogorg (vc.numxpixels/2 - 1, vc.numypixels/2 - 1);
   _setcolor (1);
   _setlogorg (vc.numxpixels/2 - 2, vc.numypixels/2 - 1);
   _setlinestyle (0x5555);
   _rectangle (_GBORDER, -x, -y, x, y);
   _setcolor (2);
   _ellipse (_GFILLINTERIOR, -x, -y, x, y);
   _setcolor (3);

   _pie (_GFILLINTERIOR,-x, -y, x, y, -x-10, y+10, x+10, y-10);
   getchar();
   _clearscreen(_GCLEARSCREEN);
   _setdideomode (_DEFAULTMODE); /* восстановление видео-режима */
}

                  4.13. Заполнение фигур по шаблону.

    Для  заполнения  любой  замкнутой  фигуры  по  шаблону  используется
функция _floodfill. Замкнутая фигура-это  фигура, не имеющая разрывов  в
ограничивающей ее линии.

    -Заполнение фигур по шаблону.

    Функция _floodfill используется  для заполнения замкнутой  фигуры по
шаблону,  задаваемому  параметром  fillmask.   (маска заполнения). Маска
заполнения-это массив восьмиразрядных значений, в котором каждый  разряд
представляет  соответствующий  пиксел.  Если  разряд  содержит 0, пиксел
остается незаполненной. Если бит содержит 1, ячейка заполняется  текущим
цветом. Данная маска заполнения повторяется всюду на заполняемой площади
фигуры. Стандартная маска заполнения-это сплошное закрашивание.

    Маска заполнения действует в  явном режиме закрашивания. Если  бит в
маске равен нулю, пиксел остается незаполненным. Единица, содержащаяся в
маске  закрашивает  соответствующий  пиксел  в  текущий цвет. По-разному
раскрашенные  фигуры  могут  быть  созданы  с  помощью установки и смены
цветов  между  вызовами  функции  _floodfill.  Граница,  не   являющаяся
непрерывной   (шаблон   которой    не   равен   0хFFFF),    приведет   к
непредсказуемому  результату,  если  вы  сделаете  попытку  заполнения с
помощью  функции   _floodfill  (вероятно   к  переполнению   графической
области).

    Чтобы  вернуться  к  текущей  маске  заполнения, используйте функцию
_getfillmask.   Функция   _getfillmask   применяется   для   того, чтобы
установить текущую  маску заполнения  в заданное  значение. Ниже показан
формат функций задания маски заполнения:

_getfillmask (fillmask);
_setfillmask (fillmask);

      Маска заполнения NULL используется для переключения режима
заполнения фигуры в сплошное заполнение, как показано ниже:
_setfillmask (NULL); /* переключение маски на сплошное заполнение */

      -Создание маски заполнения.

    Маска заполнения представляет собой массив восьмиразрядных  значений
(определяемый, как обычный символьный массив). Создание маски заполнения
описывается ниже:

    1. Нарисуйте таблицу-шаблон с восемью колонками и восемью  строками,
заполненную нулями.  Поместите единицы  (1) в  каждую ячейку  которую вы
хотите закрасить.

    2.  Преобразуйте  8-разрядные  числа  в  каждой колонке в десятичные
целые.

    3. Создайте из этих значений массив, как показано ниже:

      /* маска заполнения для шаблона X
         двоичное          десятичное
         представление     представление

         10000001           129
         01000010            66
         00100100            36
         00011000            24
         00011000            24
         00100100            36
         01000010            66
         10000001           129 */

      char fill_mask [] = {129,66,36,24,24,36,66,129};

      4. Нарисуйте фигуру и закрасьте ее внутренность с помощью толь-
         ко что созданной маски.
_setfillmask (fill_mask);
_rectangle (_GFILLINTERIOR,50,50,25,25,100);

      -Пример: Заполнение фигур по образцам.
#include
#include
char mask1 [] = {0,66,36,24,24,36,36,66,0}; /* 2 маски заполнения */
char mask2 [] = {0,24,0,102,102,0,24,0};
char error_message [] = This video mode is not supported";
main()
{
   if (_setvideomode(_MRES4COLOR) == 0) {
      printf ("%s'n", error_message);
      exit(0);
   }
   _setfillmask (mask1);
   _setcolor (1); /* использование многоцветности */
   _rectangle (_GBORDER,0,0,150,150);
   _setcolor (2);
   _floodfill (100,100,1); /* стоп на границе цвета */
   _setcolor (3);
   _setfillmask (mask2);
   _floodfill (100,100,1);
   getchar(); /* ожидание возврата каретки */
   _clearsceen(_GCLEARSCREEN);
   _setvideomode (_DEFAULTMODE); /* восстановлени видео-режима */
}

                4.14. Вычерчивание и запоминание фигур.

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

    -Запоминание изображений.

    Размеры  сохраняемого  в  памяти  экранного  образа   ограничиваются
размерами ограничивающего  прямоугольника. Для  того, чтобы  скопировать
область  экрана,  находящуюся  внутри  ограничивающего прямоугольника, в
буферную память, используется функция _getimage, как показано ниже:

    _getimage (0,0,10,10,buffer);

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

    -Требования памяти для функции _getimage.

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

    Вывод изображений из памяти.

    Функция  _putimage  используется  для  вызова  образа   сохраненного
прямоугольника  на  экран,  причем  в  функции задаются координаты точки
верхнего  левого  угла  желаемого  появления  прямоугольника  на экране.
Функция, приведенная ниже, иллюстрирует  вывод изображения из памяти  на
экран  внутрь.  прямоугольника  с  координатами  в  левом  верхнем  углу
(50,50).    Последний    параметр-это    аргумент     "глагол-действия",
определяющий,  каким   образом  образ,   хранящийся  в   памяти,  должен
взаимодействовать с текущим экраном. _putimage (50,50,buffer,_GPSET);

    -Аргумент "глагол-действия функции _putimage.

    Глагол   действия   управляет   тем,   каким   образом изобрражение,
вызываемое из  памяти, будет  взаимодействовать с  тем, что  уже есть на
экране.  Описывающие  константы  данного  аргумента приводят к следующим
действиям:

 Константа             Действие

 _GPSET                Прямая пересылка.
 _GPRESET              Прямая пересылка, цвет инвертирован.
 _GAND                 Логическое AND вызванного образа и текущего
                       экрана образа.
 _GOR                  Наложение образа на существующий образ.
 _GXOR                 Инверсия экрана там, где в буфере существует
                       точка.

      -Пример: рисование и запоминание фигуры.
draw_and_store_figure()
{
   _setbkcolor (0);
   _setcolor (1);
   _rectangle (_GBORDER,0,0,10,10);
   _setcolor (2);
   _rectangle (_GFILLINTERIOR,1,1,9,9);
   _setcolor (3);
   _moveto (1,1);

   _lineto (9,9);
   _moveto (1,9);
   _lineto (9,1);
   buffer=(char far *)malloc((unsigned int)
          _imagesize(0,0,10,10));
   _getimage (0,0,10,10, buffer);
}

    Данная  функция  рисует  фигуру,  определяет  размер,  требуемый для
размещения изображения в памяти, затем помещает фигуру в память  (буфер)
для  дальнейшего  использования  ее  в  мультипликации.  (Данная функция
позднее  появляется  в  Разделе  4.15, "Использование мультипликации", в
полной программе на языке СИ.

                  4.15. Использование мультипликации.

    Простейшая мультипликация может быть создана, например, перемещением
фигуры в новую  позицию на экране  с удалением старого  изображения. Для
более  быстрой  и  эффективной  мультипликации  с помощью сложных фигур,
используйте функции _getimage и _ putimage.

    -Создание мультипликации.

    Создайте  изображение  на  экране,  используя  графические  функции,
сделайте  "снимок"  этого  изображения   в  память  с  помощью   функции
_getimage. Затем посредством  функции _putimage вы  можете воспроизвести
данное изображение где-нибудь на экране.

    Для  мультипликации  хорошо  подходят  два глагола-действия: _GXOR и
_GPSET. Мультипликация с помощью _GPSET работает быстрее, но  уничтожает
фон, напротив, мультипликация с  _GXOR работает медленнее, но  сохраняет
фон экрана.

    -Использование в мультипликации константы _GXOR.

    Мультипликация  с   применением  _GXOR   осуществляется  выполнением
следующих четырех шагов:

    1.Поместите объект на экран с помощью _GXOR.

    2.Вычислите новое положение объекта.

    3.Поместите  объект  на  экран  второй  раз  по  старой  позиции   с
константой GXOR-чтобы удалить старое изображение

    4.Перейдите  к  шагу  1,  но  на  этот раз поместите объект на новую
позицию.

    Перемещение  объекта,  выполненное  с  помощью данных четырех шагов,
оставляет  фон  неизменным  после  шага  3. От мигания изображения можно
избавиться посредством минимизации времени работы между шагами 4 и 1,  и
уверенности, что  между шагами  1 и  3 прошло  достаточно времени.  Если
перемещается более,  чем 1  объект, каждый  объект должен обрабатываться
отдельно, один шаг за один прием.

    -Использование в мультипликации константы _GPSET.

    Если  сохранение  фона  не  является  важным,  мультипликацию  можно
выпольнить  с  помощью   опции  _GPSET.  Если   граница  ограничивающего
прямоугольника  вокруг  изображения  такая  же  большая  или больше, чем
максимальное расстояние, на которое перемещается объект, то всякий  раз,
как образ будет помещаться в новую позицию, граница будет уничтожать все
следы образа в старой позиции.

      -Пример: Мультипликация с помощью запоминания образов.
   .
   .     previous includes from huppix.c
   .
#include qmalloc.h> /* требуется для использования буфера */
   .

   .     declarations from hyppix.c
   .
char far *buffer; /* используется с функциями _getimage и
                     _putimage */
main()
{  .
   .     body of program from hyppix.c
   .
}
hypcycle()
{  .
   .    declarations and initialization from hyppix.c
   .
   draw_and_store_figure(); /* помещение фигуры в буфер */
   _clearscreen (_GCLEARSCREEN);
   .
   .    drawing of axes as in hyppix.c
   .
   /* расстановка точек и помещение образа из буфера на экран */
   while (!kbhit()) {
        for (i=1; i<= 20; i++) {
           ang = ang + 2*pi/100;
           x = x=+(a-b)*cos(ang)+h*cos(ang*(a-b)/b);
           y = y0-(a-b)*sin(ang)+h*sin(ang*(a-b)/b);
           _putimage (x,y,buffer?GXOR);
           for (j=1; j<=6000; j++)
              ;
           _putimage (x,y,buffer,GXOR);

         }
  }
}
draw_and_store_figure()
{  .
   .   содержине функции из предыдущего раздела.
   .
}

    Программа   вычерчивания   гипоциклоида   из   Раздела   4.9    была
модифицирована с тем, чтобы вычерчивание кривой производилось с  помощью
запомненного    шаблона    и    поверх    фона    на    экране.  Функция
_draw_and_store_ligure взята из Раздела 4.14, она используется  функцией
_getimage для  сохранения всей  графической фигуры  в буферной  области.
Скелет  данной  программы  приведен  выше  с замечаниями о произведенных
изменениях.


                             ГЛАВА 5.

             Управление изображением: меню просмотра View.

5.1.  Просмотр программного списка:
      Команда Source...
5.2.  Просмотр включаемых файлов:
      Команда Include.
5.3.  Настройка дисплея:
      Команда Options...
5.4.  Просмотр программного вывода:
      Команда Output Screen.
5.5.  Открытие или закрытие окна ошибок:
      Команда Errors.

    Команды из меню просмотра View используются для:

    -Открытия окон.

    -Высвечивания программного вывода.

    -Настройка параметров вашего экрана.

    Команды из меню просмотра выполняют следующие действия:

Команда                Действие

Source...              Высвечивает текущий программный список.
Include                Высвечивает данный включаемый файл.
Options...             Настраивает цвета фона и переднего плана эк-
                       рана, устанавливает табуляцию и управляет по-
                       лосами прокрутки изображения.
Output Screen          Показывает вам выходной экран. Ключ быстрого
                       реагирования для данной команды F4.
Errors                 Открывает и закрывает окно ошибок и нижней
                       части экрана Quick-C.

    Следующие разделы описывают, как пользоваться меню просмотра.

                  5.1. Просмотр программного списка:
                           Команда Source...

    Команда  Source...  используется  для  просмотра любого программного
модуля из  текущего программного  списка. Данная  команда будет  активна
только в  том случае,  если вы  загрузили программный  список с  помощью
команды  Set  Program  List...  из  меню файла (File).  (смотрите Раздел
6.2.6, "Создание  и загрузка  программных списков:  Команда Set  Program
List...", в  котором описана  данная команда).  Эта команда обеспечивает
быстрый способ  перемещения между  программными модулями  без применения
команды Open. Использование  команды Source... проще,  чем использование
команды Open... поскольку:

    -  Команда  Source...   выводит  только  файлы,   являющиеся  частью
программного  списка;  Команда  Open...может  перечислить  слишком много
файлов.

    - Команда Source... перечисляет файлы программного списка из  разных
каталогов;  Команда  Open...   перечисляет  только  файлы   из  текущего
каталога.

    Как только вы выберете команду Source..., появится диалоговая рамка,
в которой  указаны: имя  текущего программного  списка и  имена файлов в
текущем программном списке.

    Высвечиваются все модули из данного программного списка,  независимо
от того, на каком устройстве  или в каком каталоге они  расположены. Для
выбора  модуля,   который  вы   хотите  посмотреть,   используйте  ключи
управления курсором. Затем нажмите ENTER,чтобы высветить модуль.

                  5.2. Просмотр подключаемых файлов:
                           Команда Include.

    Команда  Include  используется  для  высвечивания включаемых файлов.
Высветить включаемые файлы можно двумя способами:

  1.  Двигайте курсор с помощью ключей управления до тех пор, пока
      он не установится на той же строке, что и директива #include;
      Затем выбирайте команду Include, чтобы, высветить данный
      включаемый файл.

  2.  Выберите команду Include и нажмите ENTER. Появится диалоговая
      рамка. Стандартная спецификация в текстовой рамке File следую-
      щая за *.h. Выберите включаемый файл из списка, затем выберите
      командную кнопку ОК.

    После  просмотра  включаемого  файла,  нажмите  F2 для возвращения в
редактируемый файл.

                      5.3. Настройка изображения:
                          Команда Options...

    Команда Options...  позволит вам  изменить стиль  экрана Quick-C.  С
помощью команды Options... вы можете изменить цвета переднего и  заднего
плана,  изменить  порядок  высвечивания  программных  строк, переместить
полосы прокрутки или изменить табуляцию.

    Как  только  в  меню  File  вы выберете команду Options..., появится
диалоговая   рамка.   В   рамке   атрибутов   дисплея  содержится опции,
управляющие цветами экрана:

Опция                  Использование

Обычный текст          Определяет цвета, используемые для высвечива-
(Normal Text)          ния операторов программы. Фоновый цвет, выбран
                       ный вами, устанавливает цвет заднего плана для
                       экрана редактирования.
Текущий оператор       Определяет цвета, используемые для высвечива-
(Current Statement)    ния текущего выполняемого оператора.
Строки прерываний      Определяет цвета, используемые для высвечива-
(Breakpoint Lines)     ния точек прерывания (программных строк, в ко-
                       торых вы временно приостанавливаете выполнение
                       программы в процессе отладки.)

    Опция  "Normal  Text"  может  быть  установлена таким образом, чтобы
программный  текст  высвечивался  с  повышенной яркостью. Опции "Current
Statement" и "Breakpoint  Lines" могут быть  установлены в режиме  яркой
подсветки,  мигания  или  подчеркивания  или  в  любой  комбинации  этих
возможностей.  (Подчеркивание возможно только на системах с  монохромным
адаптером).

    Выбрать цвета для опций Обычного текста, Текущего оператора и  Строк
прерывания можно одним из следующих методов:

   -  Если опция выбрана, введите первую букву желаемого цвета. Обра-
      тите внимание, что буква "В" представляет оба цвета, как "чер-
      ный" (black), так и "голубой" (blue).

   -  Если опция выбрана, используйте ключи "up" и "dowн" для прок-
      рутки списка цветов, до тех пор, пока в рамке не появится нуж-
      ный вам цвет.

    Выбор цветов  возможен только  на цветном  мониторе. На  монохромном
мониторе в списке  цветов заднего плана  имеются только черный  и белый.
Если вы выберете для фона белый цвет, вместо черного, изображение  будет
инвертированным.

    Опции высвечивания управляют высвечиванием следующих элементов:

Опция                  Использование

Полосы прокрутки       Включает или выключает высвечивание полос про-
                       крутки в окне просмотра. Полосы прокрутки бу-
                       дут вам полезны только, если вы имеете устрой-
                       ство "мышь". Если у вас нет мыши, выключите
                       полосы прокрутки, это дает вам больше места
                       для текста.
Табуляция              Устанавливает количество колонок между позици-
                       ями табуляции. Стандартное значение 8.

    По умолчанию все опции  высвечивания включены. Рамка контроля  перед
записью файла проверяет, сохранил  ли Quick-C автоматически изменения  в
файле  с  которым  вы  работаете,  если  вы  делаете  что-то, что можете
потерять сделанные  изменения (например,  создаете или  загружаете новый
файл). Если  данная рамка  контроля выбрана,  пакет Quick-C  высвечивает
сообщение,  запрашивающее   вас,  хотите   ли  вы   сохранить  сделанные
изменения;  чтобы  сохранить  изменения,  вам  следует выбрать командную
кнопку Yes; чтобы их уничтожить-командную кнопку No. Если рамка контроля
не выбрана, Quick-C автоматически запоминает изменения без  высвечивания
сообщения.

                5.4. Высвечивание программного вывода:
                        Команда Output Screen.

    Команда Output  Screen дает  пакету Quick-C  указание вместо  экрана
редактирования высвечивать экран вывода программы. Данная команда обычно
используется для просмотра вывода программы в процессе отладки.

    После того, как  вы выбрали данную  команду, нажмите любой  ключ для
возврата к экрану редактирования.

    Команда быстрого реагирования выполняется для экрана вывода по ключу
F4.

                5.5. Открытые или закрытые окна ошибок:
                            Команда Error.

    Если во время компиляции произошли ошибки, пакет Quick-C  открывавет
на  дне  экрана  окно  ошибок,  В  котором  данные ошибки высвечиваются.
Команда Error приказывает пакету  Quick-C закрыть окно ошибок,  если оно
открыто в  данный момент  и, наоборот,  открыть его,  если оно  в данный
момент закрыто. Когда  окно открыто, вслед  за командой в  меню появится
контрольная метка.

    В  Разделе  7.3.4  "Выявление  программных ошибок: Команда Следующая
ошибка и  Предыдущая ошибка"  вы найдете  более подробную  информацию об
обработке ошибок компиляции.


                             ГЛАВА 6.

                    Создание и сохранение программ.

6.1.  Программы и модули:
      Программный список
      6.1.1. Одно-модульные программы.
      6.1.2. Много-модульные программы.
      6.1.3. Работа с программными списками.
      6.1.4. Как пакет Quick-C использует программные
             списки.
      6.1.5. Общие вопросы о встроенных программах и
             программных списках.
6.2.  Обработка исходных файлов:
      Меню File
      6.2.1. Создание новых программ.
             Команда New.
      6.2.2. Загрузка файлов для редактирования:
             Команда Open...
             6.2.2.1. Загрузка файлов с помощью команды
                      Open...
             6.2.2.2. Распечатка файлов с помощью команды
                      Open...
      6.2.3. Открытие последнего редактируемого файла:
             Команда Open Last File.
      6.2.4. Слияние файлов: Команда Merge...
      6.2.5. Сохранение файлов: Команда Save и
             Команда save As...
      6.2.6. Создание и загрузка программного списка:
             Команда Set Program List.
      6.2.7. Очистка текущего программного списка:
             Команда Clear Program List.
      6.2.8. Редактирование программного списка:
             Команда Edit Program List.
      6.2.9. Печать файлов: Команда Print.
      6.2.10.Временный выход в DOS:
             Команда DOS Shell.
      6.2.11.Выход из пакета Quick-C:
             Команда Exit.

    В данной Главе  объясняется, как создавать  и сохранять программы  с
помощью компилятора Microsoft Quick-C. Во-первых, в ней  рассказывается,
как модули  объединяются и  формируют программу,  и описывается  понятие
"программного списка", который поддерживается каждой программой. Затем в
данной Главе  показывается, как  использовать команды  из меню  File для
создания, сохранения и респечатки исходных файлов Quick-C.

             6.1. Программы и модули: программный список.

    Программа Quick-C  состоит из  одного или  более исходных  файлов на
языке  СИ,  иначе  "модулей".  Программа,  построенная  из одного модуля
называется "одномодульная программа".  Программа, построенная из  более,
чем  одного  модуля,  называется  "многомодульной программой". Вы можете
подготовить список модулей, из которых состоит программа на языке СИ,  в
файле,  называемой  "программный   список".  Пакет  Quick-C   использует
программный  список  для  повторного  построения программы при изменении
одного из  модулей. Данный  механизм гарантирует,  что программа  всегда
перестраивается, используя наиболее "свежую" версию модулей.

                   6.1.1. Одно-модульные программы.

    Одно-модульные  программы  создать  легче  всего.  Обычный   процесс
написания одномодульных программ состоит в следующем:

      1. Выберите команду New (Раздел 6.2.1) из меню File для созда-
         ния нового исходного СИ-файла, или команду Open... (Раздел
         6.2.2) из меню File для открытия существующего исходного
         файла.

      2. Введите текст программы, используя ключи редактирования и
         команды, описанные в Главе 7.

      3. Скомпилируйте, выполните и отладьте программу с помощью
         команд, описанных в Главе 8.

    Для  одномодульной  программы  не  требуется  создавать  программный
список. Если  вы не  создали программный  список, программа  создается в
памяти, причем выполняемый файл не записывается на диск.

    Если программа вызывает стандартные библиотечные процедуры на  языке
СИ, большинство определений данных процедур встроены в программную среду
пакета  Quick-C.   Таблица  6.1   перечисляет  библиотечные   процедуры,
встроенные  в   среду  Quick-C,   которые  известны,   как  "оперативная
библиотека" Quick-C.

                                                 Таблица 6.1.

      Библиотека процедур на языке СИ, определенная в файле QC.EXE.

abort        _fmalloc      Itoa         rmdir         strncat
access       _fmsize       malloc       rmtmp         strncmp
atexit       fopen         memavl       sbrk          strnepy
atof         fprintf       memccpy      scanf         strnset
atoi         fputc         memchr       segread       strpbrk
atol         fputs         memcmp       setbuf        strrchr
bdos         fread         memcpy       setjmp        strrev
brk          free          _memmax      setmode       strset
calloc       _freect       memmove      setvbuf       strspn
chdir        fscanf        memset       signal        strstr
chmod        fseek         mkdir        sopen         strtok
clearerr     fstat         movedata     spawnl2       strupr
close        ftell         _msize       spawnl2       system
cputs        fwrite        _nfree       spawnlp2      tell
creat        getch         _nheapchk    spawnlge2     time
dosexterr    getche        _nheapset    spawnv2       tmpfile
eof          getcwd        _nheapwalk   spawnvpe2     tmpnam
_exit        _getdate      _nmalloc     sprintf       tolower
exit         getenv        _nmsize      sscanf        toupper
_expand      gets          onexit       stackavail    tzset
fclose       gettime       open         strcat        ultoa
fflush       int86         printf       strchr        ungetc
_ffree       int86x        putch        strcmp        unlink
fgets        intdosx       puts         strcmpi       vfprintf
_fheapchk    isatty        raise        strcpy        vprintf
_fheapset    itoa          read         strcspn       vsprintf
_fheapwalk   kbhit         realloc      strdup        write
filelength   longjmp       remove       stricmp
flushall     lseek         rewind       strlwr

    1. Семейство функций halloc, hfree и exec определены в файле QC.EXE,
но не могут быть вызваны программами, работающими в среде Quick-C.

    2.  Данные  функции  не  могут  быть  вызваны  с  флагом  P  OVERLAY
программами  ,  работающими  в  среде  программирования  Quick-C.   Если
программа вызывает стандартные библиотечные функции, не перечисленные  в
Таблице 6.1, вы  должны выполнить один  из следующих шагов  для гарантии
того, что определения для данных функций будут найдены:

    1. Создайте  библиотеку Quick-C,  содержащие функции,  не вошедшие в
список  (смотрите  разделы  10.1.1  и  1.1.3).  Затем  загрузите  данную
библиотеку  во  время  старта  пакета  Quick-C (Раздел 10.1.2). В данном
случае,  недостающие  определения  функций  будут  найдены  в библиотеке
Quick-C.

    2. Выберите команду Set Program List (Раздел 6.2.6) из меню File для
создания программного  списка. Затем  выберетекоманду Edit  Program List
...  (Редактирование программного  списка, Раздел 6.2.8)  чтобы добавить
программный модуль к новому программному списку и сохранить  программный
список. В данном случае недостающие определения функций будут найдены  в
комбинированной библиотеке  средней модели  памяти MLIBCE.LIB  на диске;
смотрите  раздел  6.1.4  для  более  подробной  информации  о  том,  как
используются программные списки Quick-C.

                   6.1.2. Многомодульные программы.

    Для   многомодульных   программ   вам   обязательно   нужно  создать
программный список для того, чтобы компилятор Quick-C знал, какие модули
использовать  при  создании  программы.  Для  построения  многомодульной
программы проделайте следующие шаги:

      1. Для создания, компиляции и отладки исходных файлов, из кото-
      рых состоит программа, применяются следующие действия:

        а)Выберите команду New (Раздел 6.2.1) из меню File для созда-
        ния нового исходного файла, или команду Open...(Раздел 6.2.2)
        из меню File, чтобы открыть существующий исходный файл для
        редактирования.

        в)Введите текст для исходного файла, используя ключи редакти-
        рования и команды, описанные в Главе 7.
        Выберите команду Compile... (Раздел 8.1.4) из меню Run для
        компиляции исходного файла и проверки на синтаксические ошиб-
        ки.

    2.  Выберите  команду  Set  Program  List...  (Раздел 6.2.6) из меню
File, чтобы  создать программный  список или  загрузить существующий для
редактирования.

    3. Выберите команду Edit  Program List...  (Раздел 6.2.8)  для того,
чтобы  добавить  или  убрать  модули  из  программного  списка  и  затем
запомнить программный список. Обратите внимание, что вы можете  добавить
в программный  список также  объектные файлы  или автономные  библиотеки
(библиотеки с расширениями .LIB).

    4. Повторяйте шаги 1-3, для новых программных модулей.

    5.  Компилируйте,  запускайте  и  отлаживайте  программу,  с помощью
команд, описанных в Главе 8.

    При  компиляции  многомодульной  программы,  пакет Quick-C проверяет
программный  список,  чтобы  определить,  были  ли  какие-нибудь  модули
изменены со времени последней компиляции программы. Если изменения были,
измененные модули перекомпилируются  перед повторной сборкой  программы.
Такой механизм гарантирует, что программа всегда соответствует последним
изменениям ее компонентов.

    Компилятор  записывает  программный  список  на  диск с тем же самым
базовым именем,  что и  программа с  расширением .MAK.  Вне среды пакета
Quick-C, вы можете дать расширение .MAK входному файлу утилиты MAKE  при
редактировании  программы.  Смотрите  Раздел  11.5  для  более подробной
информации о файлах .MAK.

---------------------------------------------------------------------

    Замечание.

    Не удаляйте  файл .MAK  для программы,  имеющий программный  список.
Если  вы  копируете  программу,  имеющую  программный  список  в  другой
каталог, вам нужно также скопировать файл .MAK в новый каталог.

---------------------------------------------------------------------

                6.1.3. Работа с программными списками.

    Компилятор Quick-C делает легким прогцесс создания и  редактирования
программных списков. В следующей таблице приведены операции, которые  вы
можете выполнить над программным  списком, и команды, которые  вы можете
использовать для выполнения данных операций:

Операции               Меню/Команды

Создать программный    File/Set Program List... (Раздел 6.2.6)
список
Открытие существующего File/Set Program List... (Раздел 6.2.6)
программного списка
для редактирования
Высвечивание содержи-  File/Set Program List... (6.2.6) или
мого программного спи- View/Source... (Раздел 5.1)
ска
Высвечивание или реда- View/Source... (Раздел 5.1)
ктирование модуля в
программном списке
Редактирование и сох-  File/Edit Program List... (Раздел 6.2.8)
ранение программного
списка
Очистка текущего прог- File/New (Razdel 6.2.1),
раммного списка из     File/Clear Program List (Раздел 6.2.7), или
памяти                 File/Edit Program List... с командной кнопкой
                       Clear List (Раздел 6.2.8).

    Если вы  потеряете след  программного списка,  имеющегося в  памяти,
запомните, что имя программного списка (без расширения .MAK)  появляется
после программного списка (Program List): индикатор на строке  состояния
на дне экрана пакета Quick-C.

        6.1.4. Как пакет Quick-C использует программный список.

    Компилятор Quick-C выполняет при компиляции одномодульной  программы
с  программным   списком  или   перестройкой  многомодульной   программы
следующие шаги:

      1. Перекомпилирует любые модули из программного списка, ко-
      торые получили изменения со времени последней компиляции. Этот
      процесс создает измененные объектные файлы на диске.

      2. Создает файл для компановщика с тем же самым именем, что
      и программа с расширением .LNK.

      3. Вызывает компановщик LINK.EXE. Компановщик связывает
      объектные файлы, созданные на шаге 1 со всеми объектными фай-
      лами, созданными из программных модулей и все объектные файлы и
      автономные библиотеки, заданные в программном списке, создавая
      на диске выполняемые файлы. Редактор связей ищет определение
      стандартных СИ-процедур в следующих местах:

        -Оперативная память, встроенная в программную среду Quick-C.

        -Библиотека Quick, если она загружена в данный момент.

        -Автономная библиотека MLIBCE.LIB на диске.

    Если компановщик  не может  найти какую-либо  из данных  процедур, в
результате будет выдана ошибка, и программа прекратит выпол- нение.

      4. Компилятор перезагрузит заново созданный выполняемый файл в
      среду Quick-C, где программа может быть выполнена.

    Обратите внимание, что объектные файлы создаются на шаге 1, файл для
компановщика создается на шаге 2,  а выполняемый файл создается на  шаге
3, причем записывается на диск.  Остальные файлы могут быть записаны  на
диск, в  зависимости от  опций, используемых  при компиляции  программы.
Например, если вы включаете в программу отладочную информацию  (смотрите
в Разделе  8.1.4.3 информацию  по опции  Debug), на  диск будет  записан
также файл карты распределения памяти.

    Чтобы управлять действиями редактора связей на шаге 2, в файле  .MAK
вы  можете   задать  опции   редактора  связей,   описанные  в   Разделе
9.5.1-9.5.14. За инструкциями обратитесь к Разделу 11.5.3.

              6.1.5. Общие вопросы о встроенных в память
                   программах и программных списках.

    Вопросы и ответы в данном разделе освещают информацию о встроенных в
память программах, программных списках и библиотеках Quick.

    Вопрос:  Я   получил  неразрешенные   внешние  ссылки   при  попытке
компиляции программы в среде Quick-C. Как я могу разрешить эту проблему?

    Ответ: Наиболее вероятная  причина неразрешенных внешних  ссылок для
встроенных в память программ-это то, что программа вызывает  стандартные
библиотечные процедуры СИ, не  содержащиеся во встроенной в  программную
среду библиотеке Quick-C (смотрите Таблицу 6.1).

    Если ваша программа  использует стандартные библиотечные  процедуры,
не  содержащиеся  в  Таблице  6.1,  воспользуйтесь  одним  из  следующих
методов:

      -Создайте одномодульный программный список, который включает
      в себя имя текущей программы (смотрите Раздел 6.2.6-6.2.8). В
      данном случае, редактор связей разрешит внешние ссылки, испо-
      льзуя комбинированную библиотеку средней модели памяти
      MLIBCE.LIB,находящуюся на диске.

      -Построить и загрузить библиотеку Quick, содержащую недостающие
      процедуры (смотрите Разделы 10.1.1-10.1.3). В данном случае,
      внешние ссылки разрешаются с помощью функций из библиотеки
      Quick.

    Вопрос: Если  моя программа  использует функции,  не перечисленные в
Таблице  6.1,  что  лучше?  Создать  и  загрузить программный список или
создать и загрузить библиотеку Quick?

    Ответ: Если вы работаете на  системе с жестким диском, обычно  легче
создать программный список, поскольку этот метод избавляет вас от  забот
по построению библиотеки Quick.  Кроме того, компилятор должен  вызывать
редактор  связей  и  обращаться  к  диску,  чтобы  искать  функции,   не
содержащиеся  в  оперативной  памяти.  Жесткий  диск минимизирует время,
требуемое для данного процесса.

    Если   вы   запускаете   пакет   на   системе   с   гибкими дисками.
предпочтительнее  создать  и  загрузить  библиотеку  Quick,   содержащую
недостающие  функции.  Это  удобнее,  поскольку  все  функции, требуемые
программе, могут быть найдены  в памяти, либо во  встроенной библиотеке,
либо в библиотеке Quick, и не требуется обращений к диску.

    Вопрос: Как мне создать новый программный список?

    Ответ: Выберете команду Set Program List...  (Раздел 6.2.6) из  меню
File и задайте имя, которое вы выбрали для нового программного списка  в
текстовой  рамке  File  Name.  Обычно,  это  базовое  имя  программы   с
расширением .MAK. Если данный программный список не существует,  Quick-C
спрашивает вас, хотите ли вы его создать; выберите командную кнопку Yes.
Пакет  Quick-C  автоматически  выполняет  команду  Edit  Program List...
(Раздел 6.2.8), то  есть вы можете  добавить модули в  новый программный
список. После того, как  вы закончите добавление модулей  к программному
списку,  выберите  командную  кнопку  Save  List,  чтобы сохранить новый
список.

    Вопрос: Как я могу  легко перемещаться между модулями  в программном
списке?

    Ответ: Выберите  команду Source  из меню  View и  модуль, который вы
хотите редактировать.

    Вопрос: Как мне  удалить программный список  из памяти, если  он уже
загружен?

    Ответ: Выберите команду Clear Program List из меню File.

    Вопрос: Как мне создать библиотеку Quick?

    Ответ: Посмотрите  инструкции в  Разделе 10.1.1.  Основная процедура
состоит в следующем:

      1. Создайте программу main, которая вызывает функции, помеща-
      емые вами в библиотеку Quick.

      2. Скомпилируйте данную программу с опциями компилятора /c и
      /AM .

      3. Свяжите результирующий файл с объектным файлом QUICKLIB.OBJ
      и опцией редактора связей /QU.

    Вопрос:  Как  я  могу  подключить  существующий  объектный  файл или
автономную библиотеку к программе, находящейся в памяти?

    Ответ:  Создайте  программный  список  (Раздел  6.2.6)  и   добавьте
объектные  файлы  или  билиотеки  в  программный  список (Раздел 6.2.8).
Заметим,  что  когда  вы  помещаете  в  программный  список   автономную
библиотеку,  редактор  связей  помещает  в  программу  полное содержимое
библиотеки.

    Вопрос: Поскольку  редактор связывает  модули в  программном списке,
существует ли способ  определить опции, управляющие  действием редактора
связей?

    Ответ:  Определите  опции  редактора  связей (Раздел 9.5.1-9.5.14) с
помощью  макрокоманды  с  именем   LDFLAGS  в  файле  .MAK,   содержащем
программный список. За указаниеми обратитесь а Разделу 11.5.3.

                    6.2. Обработка исходных файлов:
                              Меню File.

    Команды в меню File используются для создания новых файлов, загрузки
существующих   файлов   для   редактирования,   создания   и  сохранения
программных списков, сохранения редактируемых файлов, объединения файлов
и печати файлов.

    Как только  вы выберете  File, на  полосе меню  появится меню файлов
(File), которое будет открыто для работы:

    Команды из меню File выполняют следующие действия:

Команда                Действие

New                    Создает новый файл
Open...                Загружает существующий файл для редактирова-
                       ния.
Open Last File         Загружает недавно редактируемый файл и возмож-
                       но сохраняет текущий файл, если он был изменен
                       Ключ быстрого реагирования для данной команды
                       F2.
Merge...               Копируется с диска в текущий файл после стро-
                       ки, на которой установлен в данный момент кур-
                       сор.
Save                   Сохраняет отредактированный файл под его теку-
                       щим именем.
Save As...             Сохраняет отредактированный файл под другим
                       именем.
Set Program List...    Создает новый программный список или загружает
                       существующий программный список в среду
                       Quick-C.
Clear Program List     Удаляет текущий программный список из памяти.
Edit Program List...   Добавляет модули или удаляет модули из текуще-
                       го программного списка.
Print...               Печатает выбранный текст или содержимое теку-
                       щего файла.
Dos Shell              Временный выход в DOS и затем возвращение в
                       среду Quick-C.
Exit                   Заканчивает сеанс работы с Quick-C и выходит
                       в DOS.

    В разделах  6.2.1-6.2.11 описывается,  как пользоваться  командами в
меню File.

                    6.2.1. Создание новых программ:
                             Команда New.

    Команда New  создает новый  файл в  памяти. Данный  файл может  быть
любого типа,  включая исходный  СИ-файл, включаемый  файл или  документ.
Назначьте имя файлу при сохранении  его с помощью команды Save  или Save
As... .

    Команда  New  также  очищает  из  памяти текущий программный список.
Чтобы  создать  программный  список  для  новой  программы,  используйте
команду Set Program List...  (Раздел 6.2.6).

              6.2.2. Загрузка файлов для редактирования:
                            Команда Open...

    Команда Open... загружает  существующий файл для  редактирования. Вы
можете  также  использовать   команду  Open...  для   просмотра  файлов,
находящийся в вашей системе в различных каталогах.

    Как  только  вы  выберите  из  меню  File команду Open..., на экране
появится диалоговая рамка.

    Используйте опции  из диалоговой  рамки и  перечисленные ниже, чтобы
описать файл, который вы хотите открыть:

Опция                  Использование

Имя файла              Введите имя файла, который вы хотите открыть.
                       Если вы хотите просто выбрать данный файл из
                       списка, введите спецификацию для файлов, кото-
                       рые вы хотите увидеть в списке. Чтобы получить
                       информацию, обратитесь к Разделам 6.2.2.1.
                       "Загрузка файлов с помощью Open... ", 6.2.2.2
                       "Распечатка файлов с помощью команды Open...".
Спецификация маршрута  Текущая спецификация маршрута появится между
                       текстовой рамкой File Name и рамкой списка
                       файлов.
Рамка списка файлов    В текстовой рамке File Name появятся файлы,
                       соответствующие спецификации файлов и маршру-
                       та, которые вы ввели
                       Имена файлов и каталогов высвечиваются по ко-
                       лонкам в алфавитном порядке. Имена каталогов
                       подсвечиваются и выводятся в верхнем регистре;
                       имена файлов появляются в нижнем регистре.
                       Если имена файлов не умещаются в рамке, нажми-
                       те ключи управления курсором RIGHT и LEFТ для
                       того, чтобы переместить реверсную подсветку
                       на край рамки и прокрутить список. Если вы
                       применяете мышь, пользуйтесь полосой прокрутки
                       на дне рамки списка файлов для прокрутки спис-
                       ка направо или налево. Для более подробной ин-
                       формации смотрите Разделы 6.2.2.1. "Загрузка
                       файлов с помощью команды Open..." и 6.2.2.2.
                       "Высвечивание файлов с  помощью команды
                       Open...".
OK                     Используйте данную командную кнопку для того,
                       чтобы открыть выбранный файл.
Cansel                 Используйте данную командную кнопку для снятия
                       команды Open...

    Когда диалоговая  рамка Open...  появляется первый  раз, в текстовой
рамке появляется ярко подсвеченная  спецификация файла *.C. Все  файлы в
текущем каталоге, имеющие расширение .C появятся в рамке списка файлов.

          6.2.2.1. Загрузка файлов с помощью команды Open...

    Вы можете  определить файл,  который вам  нужно загрузить  с помощью
одного из следующих шагов:

      1. Введите имя файла, затем нажмите ENTER. Пакет Quick-C пред-
      полагает расширение .C для всех имен файлов без расширений.
      Если вы хотите загрузить файл, не имеющий расширения, введите
      точку (.) непосредственно после имени файла.

      2. Нажмите ключ TAB, чтобы переместить фокус ввода на рамку спи
      ска файлов и пользуйтесь ключами управленич курсором, чтобы пе-
      ремещаться по списку файлов до тех пор, пока файл, который вы
      хотите загрузить не подсветится. Затем нажмите ENTER, чтобы за-
      грузить файл.
      Вы можете также ввести первую букву имени файла, который вы хо-
      тите загрузить. Это действие автоматически переместит подсветку
      на перво имя файла или каталога в списке, которое начинается на
      данную букву. Например, если вы ищете файл PROG1.C, ввод буквы
      P переместит фокус ввода на первое имя файла, начинающееся с
      буквы "Р".

      3. При использовании мыши быстро нажмите два раза имя файла в
      рамке списка.

            6.2.2.2. Вывод файлов с помощью команды Open...

    Чтобы  высветить  на  экране  содержимое  любого  каталога  в  вашей
системе, вы можете воспользоваться  текстовой рамкой в диалоговой  рамке
команды Open...

    В рамке  списка файлов  имена файлов  выводятся в  нижнем регистре а
имена каталогов в подсвеченном верхнем регистре. Символы ".." в  верхнем
левом углу рамки списка файлов представляют каталог, являющийся текущим.
Когда вы введете имя каталога в текстовую рамку или выберете каталог  из
рамки списка файлов, Quick-C  перечислит файлы в данном  каталоге.(Когда
вы выберете или введете имя  файла, он загружается в память).  Вы можете
использовать  символы  шаблонов  DOS  (?  и *), чтобы перечислить группы
файлов.

           6.2.3. Открытие последнего редактируемого файла:
                        Команда Open Last File.

    Команда Open Last  File загружает файл,  редактировавшийся последний
раз. Если вы не сохраните изменений текущего файла, Quick-C спросит вас,
хотите  ли  вы  сохранить  их  перед  загрузкой нового файла. Если вы не
редактировали  других  файлов,  с  тех  пор,  как вы стартовали Quick-C,
нового файла не загружается.

    Если  вы  редактируете  два  исходных  файла,  данная команда делает
простым  перемещение  между  двумя  этими  файлами.  После  того, как вы
запомнили  один  исходный  файл  и  загрузили  второй  исходный файл для
редактирования,    первый    исходный    файл    становится  "последним"
редактируемым   файлом.   Чтобы   перезагрузить   этот    предварительно
запомненный файл для редактирования,  просто выберете команду Open  Last
File или нажмите ключ F2 снова.

                6.2.4. Слияние файлов: Команда Merge...

    Команда Merge...  вставляет файл,  после строки,  на которой  курсор
установлен в окне редактирования. Когда вы выберете

    из меню File команду Merge..., на экране появится диалоговая  рамка,
открытая для работы.

    Опции диалоговой  рамки команды  Merge... те  же самые,  что и опции
диалоговой рамки команды Open... Для более подробной информации смотрите
Раздел 6.2.2.

                      6.2.5. Сохранение файлов:
                       Команды Save и Save As...

    Команды Save  и Save  As... записывают  редактируемый файл  на диск.
Команда Save  используется, чтобы  сохранить файл  под его  оригинальным
именем, а команда Save As..., чтобы изменить имя данного файла. Если  вы
записываете новый  файл, не  имеющий пока  имени, можно  применить любую
команду для задания  имени файла. Если  вы выберете команду  Save As...,
появится диалоговая рамка, открытая для работы.

    Диалоговая рамка Save As... имеет следующие опции:

Опция                  Использование

Имя файла              Если вы записываете новый, не названный файл,
                       введите имя файла в текстовой рамке. Если вы
                       сохраняете файл, уже имеющий имя, имя файла по
                       является в текстовой рамке. Если вы используе-
                       те то же самое имя файла, просто нажмите
                       ENTER; чтобы изменить имя файла, введите его.
                       Новое имя заменит старое.
Спецификация маршрута  Между текстовой рамкой имени файла и командной
                       кнопкой появится текущая спецификация марш-
                       рута.
OK                     Данную командную кнопку следует выбрать, чтобы
                       сохранить файл с именем, заданным в текстовой
                       рамке.
Cancel                 Данная командная кнопка выбирается для снятия
                       команды Save As... и возвращения в редактор.

            6.2.6. Создание и загрузка программных списков:
                      Команда Set Program List...

    Команда Set  Program List...  создает новый  программный список  или
загружает существующий программный список в программную среду Quick-C.

    Если вы  выбрали команду  Set Program  List..., появится  диалоговая
рамка,  аналогичная  диалоговой  рамке  команды  Open..., за исключением
того, что  спецификацией файла  в рамке  списка имен  файлов будет .MAK.
(Программные списки сохраняются в файлах с расширениеми .MAK). Вы можете
выбрать  файлы  .MAK  для  редактирования  или  высвечивания  из  любого
каталога  на  вашей  системе,  так  же,  как в команде Open...; смотрите
Разделы   6.2.2.1-6.2.2.2.   Если   вы   выбираете   для  редактирования
существующий файл  .MAK, для  выполнения изменений  в файлах используйте
команду Edit Program List...

    Если  вы  зададите  имя  несуществующего  файла  .MAK, пакет Quick-C
спросит вас, хотите  ли вы создать  файл. Если вы  ответите "Yes", пакет
Quick-C  автоматически  открывает  диалоговую  рамку  для  команды  Edit
Program List..., теперь вы можете добавлять модули к новому программному
списку.

    После того,  как вы  загрузите программный  список, имя программного
списка появится после слов Program List: (на строке состояния).

    При компиляции программ,  командные кнопки Build  Program (Построить
программу) и Rebuild All (Перестроить все) действуют только на модули  в
данном  программном  списке,   а  не  на   исходный  файл,  который   вы
редактируете.

             6.2.7. Очистка текущего программного списка:
                      Команда Clear Program List.

    Команда Clear  Program List  удаляет текущий  программный список  из
памяти.  Индикатор  на  строке  состояния  Program  List:  изменяется на
, чтобы обозначить, что в памяти в данный момент нет  программного
списка. До тех пор, пока вы  не загрузите с помощью команды Set  Program
List... новый программный  список, компилятор Quick-C  предполагает, что
любые  компилируемые  файлы  являются  одномодульными  программами,   не
являющиеся частью программного списка.

              6.2.8. Редактирование программного списка:
                      Команда Edit Program List.

    Команда Edit  Program List  обрабатывает список  модулей, из которых
состоит программа.

    Когда вы  выберете команду  Edit Program  List... из  меню File, или
после того, как вы создадите новый программный список с помощью  команды
Set Program List..., на экране появится открытая диалоговая рамка.

    Чтобы  задать  программный  список  для  редактирования  и   сделать
желаемые изменения, используйте следующие опции диалоговой рамки команды
Edit Program List...:

Опция                  Использование

Имя файла              Введите имя файла .MAK, содержащего программ-
                       ный список, который вы хотите редактировать,
                       или введите спецификацию для тех файлов, кото-
                       рые вы хотите вывести в рамке списка файлов.
                       Для вывода списка файлов текущего устройства
                       или текущего каталога команда Edit Program
                       List...используется аналогично команде
                       Open...; За подробностями обратитесь к Разде-
                       лам 6.2.2.1 "Загрузка файлов с помощью команды
                       Open..." и 6.2.2.2 "Вывод списка файлов с по-
                       мощью команды Open...".
Спецификация маршрута  Между текстовой рамкой имени файла и командны-
                       ми кнопками появляется текущая спецификация
                       маршрута.
Файлы                  Данная рамка списка файлов выводит все диско-
                       вые файлы, соответствующие спецификации марш-
                       рута, заданной в текстовой рамке имени файла.
                       Как только вы выберете имя файла из рамки спи-
                       ска файлов, воспользуйтесь командной кнопкой
                       Add/Remove для добавления или удаления файлов
                       из программного списка. Вы можете выбрать фай-
                       лы из рамки списка файлов или высветить файлы
                       из различных каталогов, как вы делали это для
                       команды Open... меню File. Подробные инструк-
                       ции смотрите в Разделах 6.2.2.1 "Загрузка фай-
                       лов с помощью команды Open..." и 6.2.2.2 "Вы-
                       вод списка файлов с помощью команды Open...".
Программный список     Данная списковая рамка выводит все файлы, свя-
                       занные с загруженным в данный момент программ-
                       ным списком. Выбирайте файлы для удаления из
                       программного списка аналогично тому, как вы
                       выбирали файлы для команды Open...; смотрите
                       Раздел 6.2.2.1 "Загрузка файлов с помощью ко-
                       манды Open...".
Add/Remove             Используйте данную командную кнопку для того,
(добавить/удалить)     чтобы добавить выбранный файл к программному
                       списку или удалить его из списка. Если файл
                       еще не находится в программном списке, он до-
                       бавляется в него. Если файл уже находится в
                       программном списке, он удаляется из него. Про-
                       граммный список реально не изменяется до тех
                       пор, пока вы не воспользуетесь командной кноп-
                       кой Save List.
Clear List             Данная командная кнопка используется для того,
(Очистить список)      чтобы удалить из текущего программного списка
                       все модули. Обратите внимание, что командная
                       кнопка Clear List удаляет все модули из прог-
                       раммного списка независимо от того, была или
                       нет "нажата" командная кнопка Save List; ко
                       манда Cancel не восстанавливает оригинальный
                       программный список.
Save List              Данная командная кнопка используется для сох-
                       ранения всех изменений программного списка в
                       файле .MAK.
Cancel (Снять)         Данная командная кнопка используется для сня-
                       тия команды Edit Program List...

    Для  редактирования   программного  списка   используется  следующая
процедура:

    1. Выберете команду Edit Program List из меню File.

    2.  Выберете  директорию,  из  которой  вы  хотите  добавить файлы в
программный список. Смотрите Раздел  6.2.2.1 "Загрузка файлов с  помощью
команды Open..." и Раздел  6.2.2.2 "Распечатка файлов с  помощью команды
Open...".

    3. Выберете файл для удаления или добавления в программный список из
рамки списка файлов.

    4. Нажмите Enter. Если файла,  который вы выбрали нет в  программном
списке,  пакет  Quick-C  добавит  его.  Если  он  уже  находится в рамке
программного  списка,  Quick-C  удалит  его  из списка. Диалоговая рамка
останется на экране.

    5. Повторяйте шаги 4-5 до тех пор, пока программный список не  будет
содержать файлы, которые вам требуются.

    6. Введите  ALT+S для  сохранения программного  списка и  обновления
файла  .MAK,  либо  наберите  ALT+C  для  очистки  программного  списка.
Диалоговая  рамка  исчезнет  с  экрана.  Чтобы  прервать  в  любое время
выполнение  команды  Edit  Program  List...,  нажмите  ESC  или выберете
командную кнопку Cancel.

                       6.2.9. Распечатка файлов:
                           Команда Print...

    Команда Print... распечатывает  либо файл, который  вы редактируете,
либо выбранный  текст из  файла. Файлы  распечатываются без  разрывов на
страницы и без заголовков.

    Если  вы  применяете  данную   команду,  ваш  принтер  должен   быть
подсоединен к LPT1 (либо вы можете использовать команду DOS MODE,что  бы
переадресовать LPT1 в COM1).

    Как  только  вы  выберете  из  меню  File команду Print..., появится
диалоговая рамка, открытая для работы.

    Вы можете выбрать одну из следующих опций:

Опция                  Использование

Print File             Распечатывает содержимое редактируемого
файла.
(печать файла)
Print Selected Text    Распечатывает только выбранный в окне обзора
(распечатка выбран-    текст (подсвеченный)
ного текста)

    В  то  время,  как  текст  распечатывается,  на  экране   появляется
диалоговая  рамка  с  командной  кнопкой  Cancel. Чтобы прервать печать,
нажмите просто ESC или клавишу пробела.

                    6.2.10. Временный выход в DOS:
                          Команда DOS Shell.

    Команда DOS  Shell позволяет  вам временно  выйти на  уровень команд
операционной системы DOS, где  вы можете выполнить другие  программы или
команды DOS, причем  Quick-C остается в  памяти. Обратите внимание,  что
вам не  нужно удалять  перед возвратом  в Quick-C  файлы .MAK,  исходные
файлы СИ или текущий программный список.

    Чтобы  выполнить  команду  DOS  Shell,  пакет  Quick-C  должен иметь
возможность найти файл COMMAND.COM.  В первую очередь Quick-C  ищет этот
файл в директории , заданной в переменной среды COMSPEC, затем в текущей
директории. Обратитесь за подробной  информацией о файлах COMMAND.Com  и
COMSPEC к документации об использовании операционной системы DOS.

    Для возврата в пакет Quick-C с командного уровня DOS введите команду
DOS EXIT.

                   6.2.11. Выход из пакета Quick-C:
                             Команда EXIT.

    Команда EXIT удаляет пакет Quick-C из памяти и возвращает вас в DOS.

    Если  вы  редактировали  файл,  но  не  сохранили  его,  специальное
сообщение  опросит  вас,  хотите  ли  вы сохранить данную программу. Для
сохранения программы, нажмите ENTER, либо нажмите командную кнопку Yes с
помощью мыши. Если программа  не имеет имени, появится  диалоговая рамка
Save As...

    Чтобы  вернуться  в  системы  без  сохранения  файла, введите h, или
нажмите с помощью мыши командную кнопку No.


                              ГЛАВА 7.

                    Редактирование исходных файлов.

7.1.  Редактирование с помощью клавиатуры  и с помощью
      мыши.
      7.1.1. Использование ключей редактирования пакета
             Quick-C.
      7.1.2. Использование режимов вставки и перезаписи.
      7.1.3. Использование текстовых маркеров.
      7.1.4. Соответствие скобок
      7.1.5. Редактирование с помощью мыши.
2.2.  Команды редактирования: Меню Edit.
      7.2.1. Отмена выполненного редактирования:
             Команда Undo.
      7.2.2. Удаление и вставка текста:
             Команды Cut, Copy, Paste, Clear.
      7.2.3. Установка режима "только-чтение":
             Команда Read Only.
7.3.  Поиск и замена текста:
      Меню Search.
      7.3.1. Поиск текста: Команды Find...,
             Selected tText, Repeat Last Find.
        7.3.1.1. Команда Find.
        7.3.1.2. Поиск выбранного текста:
                 Команда Selected Text.
        7.3.1.3. Команда Repeat Last Find.
        7.3.1.4. Специальные символы и
                 регулярные выражения.
      7.3.2. Замена текста:
             Команда Change...
      7.3.3. Поиск функций:
             Команда Function.
      7.3.4. Поиск программных ошибок: Команды
             Next Error и  Previous Error.

    Редактор  программ,  встроенный  в  среду  программирования   пакета
Quick-C,  является  мощным  и  гибким  набором  команд  клавиатуры   для
редактирования  исходных  файлов.  Большинство  операций  редактирования
Quick-C требуют только одно нажатие ключа или последовательность нажатий
одного  ключа  плюс  клавиши  АLT,  CTRL  или SHIFT. С помощью редактора
Quick-C вы  можете быстро  выполнить операции  редактирования, такие как
перемещение курсора;  выборка, вставка,  копирование и  удаление текста;
открытие новых строк в исходном файле.

---------------------------------------------------------------------

    Примечание:

    Если  вы  когда-либо  пользовались  программой MicroPro Wordstar, вы
обнаружите,  что  большинство  команд  редактирования Quick-C аналогичны
WordStar.

---------------------------------------------------------------------

    В данном Разделе описывается, каким образом вводить и  редактировать
программный текст  с помощью  команда редактора  Quick-C и  меню Edit  и
Shearch.

    -  Раздел   7.1  представляет   команды  редактирования   с  помощью
клавиатуры и мыши.

    - Разделы 7.3  и 7.3 описывают  команды в двух  меню редактирования:
Edit и Shearch.

           7.1. Редактирование с помощью клавиатуры и мыши.

    Если вы хотите отредактировать текст, выполните следующие шаги:

    1.  Передвиньте   курсор  на   начало  текста,   который  вы  хотите
редактировать.

    2. Выберете  текст, который  вы хотите  редактировать. Нажмите  ключ
SHIFT плюс любой ключ управления курсором для выборки текста.

    3. Редактирование выбранного текста.

          7.1.1. Использование ключей редактирования Quick-C

    Таблица  7.1  описывает  команды  клавиатуры,  передвигающие курсор,
выбирающие текст и выполняющие функции редактирования.

                                                 Таблица 7.1.
      Ключи редактирования Quick-C.

Чтобы переместить кусор:          Нажмите:

Вверх/вниз на одну строку         UP или CTRL+E/DOWN или CTRL+X
Вправо/влево на 1 символ          RIGHT или CTRL+D/LEFT или CTRL+S
Влево на 1 символ (с удалением    BACKSPACE или CTRL+H
символа
Вправо/влево на одно слово        CTRL+RIGHT или CTRL+F/CTRL+LEFT
                                  или CTRL+A
На начало/на конец строки         HOME или CTRL+QS/END или CTRL+QD
На верх/дно экрана                CTRL+QE/CTRL+QX
На начало/конец файла             CTRL+HOME или CTRL+QR/CTRL+END или
                                  CTRL+QC
На следующую ошибку               SHIFT+F3
На предыдущую ошибку              SHIFT+F4

Прокрутить:                       Нажмите:

Вверх/вниз одну строку            CTRL+W/CTRL+Z
Вверх/вниз одно окно              PGUP или CTRL+R/PGDN или CTRL+C
Налево/направо одно окно          CTRL+PGUP/CTRL+PGDN

Выбрать текст:                    Нажать:

Символ                            SHIFT+LEFT/SHIFT+RIGHT
Текущую строку и строку выше/ниже SHIFT+UP/SHIFT+DOWN
Слово                             SHIFT+CTRL+LEFT/SHIFT+CTRL+RIGHT
Экран                             SHIFT+PGUP/SHIFT+PGDN
До начала/конца файла             SHIFT+STRL+HOME/SHIFT+CTRL+END

Вставить:                          Нажать:

Текст из выбранного шаблона       SHIFT+INS
(см. Раздел 7.2.)
Строку над текущей строкой        CTRL+N
Табуляцию на текущей позиции      TAB или CTRL+I
курсора
Табуляцию на начало каждой выб-   TAB
панной строки (когда выбираются
одна или более строк)
Управляющий символ                CTRL+P, следующий за символом CTRL

Удалить:                          Нажать:

Символ, на котором установлен     DEL или CTRL+G
курсор
Слово                             CTRL+T
Текущую строку, запомненную в вы- CTRL+Y
резанной части текста (смотрите
Раздел 7.2).
На конец строки                   CTRL+QY
Выбранный текст                   SHIFT+DEL
Выбранный текст, не запомненный   DEL
в блоке
Символ слева от курсора           BACKSPACE или CTRL+H

Скопировать:                      Нажать:

Выбранный текст, запомненный в    CTRL+INS
блоке (смотрите Раздел 7.2)

Установить табуляцию:             Нажать:

Всего выбранного текста           TAB/SHIFT+TAB
(справа/слева)

Прервать строку:                  Нажать:

На текущей позиции                ENTER

          7.1.2. Использование режимов вставки и перезаписи.

    Редактор Quick-C работает в двух режимах: режиме вставки или  режиме
перезаписи. Когда редактор работает в режиме "вставки", вводимые символы
вставляются  слева   от  курсора.   Если  редактор   работает  в  режиме
"перезаписи",  вводимые  символы  записываются  поверх  существующих  на
текущей строке.  Для переключения  редактора из  режима вставки  в режим
перезаписи  и  обратно  используйте  ключи  INS  или  CTRL+V. Если режим
перезаписи включен, курсор становится блоком.

    В  режиме  вставки,  редактор  вставляет  вводимый символ на позицию
курсора. В  режиме перезаписи  редактор заменяет  символ, находящийся на
позиции  курсора  на  символ  который  ввели.  Режим вставки-стандартный
режим.

               7.1.3. Использование текстовых маркеров.

    Если  вы  работаете  с  различными  частями  большого  файла   можно
установить  на  различных  частях  файла  маркеры,  чтобы  затем   легко
перемещаться от одного маркера к другому - то есть от одной части  файла
к  другой.  Разрешается  установить  в  любом  исходном файле до четырех
текстовых  маркеров,  пронумерованный  от  0  до  3-х.  Для   размещения
текстовых маркеров:

    - Нажмите CTRL+K n, для установки текстового маркера номер n.

    - Нажмите CTRL+Q n, чтобы установить курсор на маркер номер n.

                      7.1.4. Соответствие скобок.

    Редактор Quick-C разрешает наиболее часто встречающуюся в  СИ-файлах
проблему: поиск  соответствующей левой  или правой  фигурной скобки  {},
квадратные  скобки  [],  угловой  скобки  <>,  круглой  скобки (). Чтобы
отыскать  соответсвующую  фигурную,  квадратную,  угловую  или   круглую
скобку, выполните следующие шаги:

    1.   Установите   курсор   на   скобке,   который   вы  хотите найти
соответствие.

    2. Нажмите CTRL+] или CTRL+[.

                 7.1.5. Редактирование с помощью мыши.

    Если  у  вас  есть  мышь,  с  ее помощью вы можете быстро перемещать
курсор и выбирать текст, а затем использовать клавиатуру для  выполнения
желаемых функций редактирования.

    Чтобы переместить  курсор с  помощью мыши,  позиционируйте на нужное
место указатель мыши и быстро нажмите и отпустите левую кнопку.

    В Таблице 7.2 описаны способы быстрой выборки текста с помощью мыши.

                                                 Таблица 7.2.
      Выборка текста с помощью мыши.

Чтобы выбрать:         Выполните следующее:

Символ                 Установитесь на символ справа от того символа,
                       который вы хотите выбрать, нажмите левую кноп-
                       ку и держите ее нажатой, перемещая указатель
                       мыши влево над символами, которые вы хотите
                       выбрать. Перемещения мыши вправо выберет сим-
                       вол, на котором установлен курсор.
Слово                  Выполните на данном слове двойное нажатие ле-
                       вой кнопки.
Строку                 Установитесь на первую колонку строки, нажмите
                       левую кнопку, не отпуская кнопки переместите
                       подсветку вниз на одну строку и отпустите кно-
                       пку. Будет выбрана строка над курсором.
Несколько строк        Укажите первую выбранную строку, затем нажмите
                       левую кнопку и, не отпуская продвиньте подсвет
                       ку по всем строкам (вверх или вниз), которые
                       вы хотите выбрать.

    Если вы сделали при выборке  текста ошибку, нажмите левую кнопку  на
выбранном тексте, чтобы отменить команду.

                     7.2. Команды редактирования:
                              Меню Edit.

    Команды из меню Edit  позволяют вам удалять, перемещать,  копировать
текст из вашей программы, либо отменять модификации текущей строки.

    Следующие  команды  из  меню  Edit  используются  для редактирования
содержимого исходного файла:

Команда                Действие

Undo                   Отменяет все изменения, выполненные на теку-
                       щей строке. Последовательность ключей для вы-
                       полнения данной команды: ALT+BACKSPACE
Cut                    Удаляет выбранный текст и помещает его во вре-
                       менный блок. Данный блок представляет собой
                       временную область, которую редактор Quick-C
                       использует для хранения копии удаляемого тек-
                       ста. Ключ быстрого реагирования данной коман-
                       ды: SHIFT+DEL
Copy                   Копирует выбранный текст и помещает его в
                       блок, оставляя скопированный текст на его пре-
                       жнем месте. Ключевая последовательность для
                       данной команды: CTRL+INS.
Paste                  Вставляет текст из временного блока в редак-
                       тируемый файл. Ключ для данной команды:
                       SHIFT+INS.
Clear                  Удаляет выбранный текст. но не помещает его во
                       временный блок. Ключ для данной команды: DEL.
Read Only              Устанавливает редактор в режим "только-чтение"
                       и предохраняет таким образом текущий файл от
                       изменений.

      Разделы 7.2.1-7.2.3 описывают подробно команды из меню Edit.

                       7.2.1. Отмена изменений:
                             Команда Undo.

    Команда  Undo  отменяет  изменения  на  текущей  строке. Пока курсор
находится на строке, вы можете  ее восстановить. Если же вы  передвинете
курсор со строки, изменения на ней остаются постоянными.

    Пока   текущая   строка   неизменялась,   команда   Undo   считается
выключенной. Если данная  команда выключена, в  имени команды в  меню не
подсвечивается ни одна буква. Если вы выберете команду Undo в то  время,
как она выключена, ничего не произойдет.

    Команду Undo нельзя использовать для восстановления строк, удаленных
с помощью ключевой  последовательности CTRL+Y. Вместо  этого используйте
последовательность CTRL+QL или QTRL+INS.

                   7.2.2. Удаление и вставка текста:
                   Команда Cut, Copy, Paste, Clear.

    Используйте  команды  Cut,  Copy,  Paste,  Clear  для   перемещения,
копирования, удаления и вставки текста в редактируемый файл.

    Все команда (Cut,  Copy, Clear) влияют  только на текущий  выбранный
текст.  Комбинации  данных  команд  используются  для  различных   задая
редактирования:

    - Команда Cut вместе с командой Paste (смотрите ниже)

---------------------------------------------------------------------

    Примечание:

    Если вы перемещаете текст на  новое место в файле. безопаснее  будет
использовать команду  Paste непосредственно  после команд  Cut или Copy.
Это гарантирует вам, что вы не потеряете текст, находящийся во воеменном
блоке.

---------------------------------------------------------------------

    Пока текст не выбран, команды  Cut, Copy и Clear выключены;  ни одна
буква на имени команды в меню не подсвечивается. Если вы выберете  любую
из данных команд в то время, как она выключена, ничего не произойдет.

    Команда Paste вставляет текст  из временного блока. В  основном, эта
команда используется для замены  текста, выбранного вами в  окне обзора:
когда  вы  выбираете  команду  Paste,  выбранный  текст  замещает текст,
содержащийся  во  временном  блоке.  Если  никакого  текста  не выбрано,
команда Paste  вставляет содержимое  временного блока  слева от  текущей
позиции курсора. Вы можете вставлять одно и то же содержимое  временного
блока столько раз, сколько вам нужно. Если во временном блоке данных  не
содержится, команда Paste выключена.

    Чтобы вставить текст из временного блока, выполните следующие шаги:

    1.  Установите  курсор  на  то  место,  в которое вы хотите вставить
текст. Текст будет вставляться слева от курсора. Если вы хотите заменить
текст  содержимым  временного  блока,  выберете  текст,  который   будет
заменен.

    2. Выберете из меню Edit команду Paste.

    Текст остается во временном блоке  до тех пор, пока вы  не закончите
сеанс  работы  с  пакетом  Quick-C  (Команды  New  и  Open... не очищают
временный  блок).  Если  во  время  компиляции  вам  не  хватает памяти,
очистьте  временный  блок  путем  копирования  в  него  очень маленького
объекта, такого как один символ.

               7.2.3. Установка режима "только-чтение":
                          Команда Read Only.

    Команда Read Only включает и выключает режим "только-чтение".  Когда
редактор работает  в режиме  "только-чтение", в  текущем файле  не могут
быть сделаны  никакие изменения;  на строке  состояния появляется  буква
"R",  а   в  меню   редактирования  Edit   появится  специальная   метка
(контрольная метка).

    Данная команда бывает  полезна в процессе  отладки. Обычно, если  вы
случайно измените файл в процессе отладки, специальное сообщение спросит
вас,  хотите  ли  вы  перекомпилировать  программу  перед   выполнением.
Установка режима "только-чтение" предохранит вас от случайных  изменений
файла.

              7.3. Поиск и замена текста: Команда Search.

    Используя команды меню Search вы можете легко находить  определенные
части вашей программы.

    Команды меню Search выполняют следующие действия:

Команда                Действие

Find...                Находит первое появление заданного текста.
                       Ключевая последовательность вызова данной ко-
                       манды: CTRL+\ или CTRL+QF.
Selected Text          Находит текст, который вы выбрали в окне про-
                       смотра. Ключевая последовательность: CTRL+\.
Repeat Last Find       Находит следующее появление текста, который вы
                       задали для предыдущей команды поиска. Ключ дан
                       ной команды F3, Ключевая последовательность:
                       CTRL+L.
Charge...              Находит заданный текст и заменяет его на дру-
                       гой. Ключевая последовательность для данной
                       команды: SHIFT+QA.
Функция                Находит в процессе отладки заданную функцию.
Следующая ошибка       Находит строку в исходном файле, содержащим
                       следующую ошибку. Ключевая последовательность
                       для данной команды: SHIFT+F3.
Предыдущая ошибка      Находит строку исходного файла, содержащую
                       предыдущую ошибку. Ключевая последовательность
                       для данной команды: SHIFT+F4

    Поиск начинается с позиции курсора и прокручивается через верх  окна
просмотра до начальной точки поиска. Все команды меню Search ищут текст,
заданный предыдущей командой поиска, если не определено иначе.

    Следующие Разделы подробно описывают команды меню Search.

                 7.3.1. Поиск текста: Команды Find...,
                   Selected Text, Repeat Last Find.

    Редактор Quick-C обеспечивает следующие способы поиска текста:

    - Выберете команду Find... и задайте текст, который вы ищете.

    -  Выберете  текст  в  окне  обзора  и  ищите  его с помощью команды
Selected Text.

    - Ищите следующее вхождение того же самого текста с помощью  команды
Repeat Last Find. В Разделах 7.3.1.1-7.3.1.4 описываются данные команды.

    Команда  Find...  используется  для  поиска  символа,  слова, группы
символов  или  слов  вашей  программы.  Ключевая  последовательность для
данной команды CTRL+QF; в случае,  если в данный момент никакого  текста
не выбрано, используется другая ключевая последовательность: CTRL+\.

    Если   вы   выберете   команду   Find...,   на   экране   появляется
соответствующая диалоговая рамка.

    В  следующем  списке  разъясняются  опции  диалоговой  рамки команды
Find...

Опции                  Использование

Find What              Эту текстовую рамку следует выбрать для под-
(Что найти)            светки текста предыдущего поиска. Если вы те-
                       перь ищете другой текст, введите новый текст в
                       рамку.
Whole Word             Выбирайте данную текстовую рамку для поиска
(Целое слово)          заданного текста только в том случае, если он
                       окружен пробелами, знаками пунктуации или дру-
                       гими символами, не считающимися частями слова.
                       Символы считаются частями слова, если это бук-
                       вы верхнего регистра (A-Z), буквы нижнего ре-
                       гистра (a-z), цифры (0-9) и знак подчеркивания
                       ( ), который используется при объявлении пере-
                       менных. Например, если заданный текст define,
                       опция Whole Word установит вас на #define, но
                       не define terms.
Match Upper/Lowercase  Данную контрольную рамку можно выбрать, если
                       вы хотите найти только те входимости заданного
                       текста, которые имеют точное соответствие.
                       Например, если данный текст DEFINE, опция
                       Match Upper/Lowercase найдет в исходном тексте
                       фразу DEFINE, но не define.
Regular Expression     Данную контрольную рамку выбирайте, если вы
(регулярное выражение) хотите для задания текста поиска употребить
                       специальные символы. Смотрите Раздел 7.3.1.4
                       "Специальные символы в регулярных выражениях",
                       в нем вы найдете список регулярных выражений.
ОК                     Данная командная кнопка используется для за-
                       пуска поиска следующего вхождения заданного
                       текста.
Cancel (снять)         Данная командная кнопка используется для сня-
                       тия искомого текста из диалоговой рамки
                       Find... и возвращения в окно просмотра.

    Если текст не был найден, в рамке появляется текст "Match Not Found"
(Соответствие не достигнуто). Чтобы удалить рамку и продолжить,  нажмите
либо ENTER, либо SPACEBAR, либо выберете с помощью мыши командную кнопку
ОК.

                   7.3.1.2. Поиск выбранного текста:
                        Команда Selected Text.

    Другим  способом  найти  текст  в  программе  является использование
команды Selected Text. Вместо ввода текста, который вам нужно найти,  вы
можете просто подсветить нужный вам текст в окне обзора. Для  выполнения
команды Selected Text выполните следующую команду:

    1. Выберите текст, который  вы хотите найти. Выбрайный  текст должен
быть на одной строке. контрольную рамку Regular Expressions, для  поиска
текста в строке вы  можете определить следующие специальные  символы для
задания шаблонов:

Символ                 Значение

Точка (.)              Соответствует любому одиночному символу
Знак вставки ( )       Соответствует тексту, появляющемуся в начале
                       строки.
Знак доллара ($)       Соответствует тексту, который появляется в ко-
                       нце строки. Знак доллара должен стоять в конце
                       искомого текста.
Звездочка (*)          Соответствует нулевому или более повторением
                       символа, стоящего перед звездочкой. Например,
                        * находит любую последовательность одного
                       или нескольких подчеркиваний.
Квадратные скобки []   Соответствует набору символов, заданному внут-
                       ри квадратных скобок. Чтобы найти соответствие
                       символу правой скобки, введите его непосредст-
                       венно за левой скобкой, ограничивающей набор
                       символов.
                        Внутри скобки могут использоваться следующие
                        специальные символы:
                       Символ   Использользование

                       Знак     Соответствует любому символу, кроме
                       вставки  заданных внутри скобок. Чтобы трак-
                        ( )     товаться специальным символом, должен
                                быть первым символом внутри скобок.
                       Тире (-) Соответствует символом по порядку ко-
                                дов ASCII между символами по обоим
                                сторонам знака тире, включая ограни-
                                чители.
Обратный слэш          Символы, предществующие обратному слэшу, теря-
                       ют свое специальное значение и трактируются,
                       как литералы. Например, чтобы использовать
                       знак доллара именно в смысле знака $, а не в
                       смысле конца строки, введите \$.

    Примеры:

    Приведенные  далее  примеры  иллюстрируют  использование специальных
символов в регулярных выражениях:

    I*J
    I\*J

    в  приведенных  примерах  первое  регулярное  выражение соответсвует
такой  комбинации,  как  IJ,  IIJ,  IIIJ.  Второе  регулярное  выражение
соответствует  только  I*J.  Обратный  слэш  необходим  здесь,  так  как
звездочка является специальным в регулярных выражениях символом.

    x[-+/*]y

    в данном примере, регулярное  выражение соответсвует x+y, x-y,  x*y,
но не x=y или xzy.

    [A-Za-z]

    Приведенное  выше  регулярное  выражение  соответствует  любой букве
верхнего регистра, букве нижнего регистра или пробела.

    [ 0-9]

    Данное регулярное выражение (приведенное выше), соответствует любому
символу, кроме цифры.

    []#![@%]

    Регулярное выражение, заданное выше, соответствует либо левой,  либо
правой  скобке,  либо  любому  из  символов,  ограниченных  первой левой
скобкой и последней правой скобкой. Первая правая скобка не  трактуется,
как специальный символ, поскольку  она появляется сразу за  первой левой
скобкой.

    \[[0-9]*\]

    В данном примере  регулярное выражение соответствует  строкам чисел,
находящихся внутри скобок.

                         7.3.2. Замена текста:
                           Команда Change...

    Команда Change... используется для поиска текста и замены его другим
текстом. Ключевая  последовательность для  данной команды:  CTRL+QA. При
выборе  из  меню  команды  Change,  появится  соответствующая диалоговая
рамка.

    Опции  Find  What,   Whole  Word,  Match   Upper/Lowercase,  Regular
Expressions  и  Cancel-те  же  самые,  что  и в команде Find...;смотрите
Раздел 7.3.1.1.  "Команда Find..." и Раздел 7.3.1.4 "Специальные символы
в  регулярных  выражениях."  В  следующем  списке описываются оставщиеся
опции диалоговой рамки Change...:

Опция                  Использование

Change to              В данную текстовую рамку следует ввести текст
(изменить на)          для замены.
Find and Verify        Выбирайте данную командную кнопку, если вы хо-
(найти и сверить)      тите подтверждать каждое изменение, прежде,
                       чем редактор Quick-C его выполнит. Когда вы
                       выберете данную командную кнопку, редактор най-
                       дет текст и затем высветит еще три командные
                       кнопки: Change (изменить), Skip (пропустить),
                       Cancel (снять). Данные командные кнопки изоб-
                       ражены ниже:

                              Change     Skip     Cansel

                       Чтобы выполнить изменения, выбирайте команд-
                       ную кнопку Change; командную кнопку Skip сле-
                       дует выбрать, если вы хотите перейти к следую-
                       щему появлению искомого текста, а с данным по-
                       явлением никаких действий не производить; ко-
                       мандную кнопку Cancel выбирайте для прекраще-
                       ния поиска и возврата в окно обзора.
Change All             Данная командная кнопка выбирается, если вы
(изменить все)         хотите заменить все вхождения искомого текста
                       без подтверждения на каждое изменение.

---------------------------------------------------------------------

    Примечание:

    Если вы используете команду Change для замены текста, вы не  сможете
отменить сделанные изменения с помощью команды Undo из меню Edit.

---------------------------------------------------------------------

                         7.3.3. Поиск функций:
                           Команда Function.

    Команда   Function   находит   точку   входа   заданной   функции  в
редактируемом файле. Перед тем, как применять данную команду,  выполните
компиляцию исходного файла с опцией Debug.

    При  выборе  команды  Function  появляется соответсвующая диалоговая
рамка.

    В  текстовую  рамку  команды  Function введите наименование функции.
Если  вы  выбрали  имя  функции,  данное  имя автоматически появляется в
текстовой  рамке.  Затем  выберите  командную  кнопку  ОК для выполнения
операции  поиска  заданной  функции,  либо  "нажмите"  командную  кнопку
Cancel, чтобы снять выполнение команды.

                 7.3.4. Выявление программных ошибок:
                 Команды Next Error и Previous Error.

    Команды Next Error и Previous Error используются для быстрого поиска
и   исправления   синтаксических   ошибок   вашей   программы.  Ключевая
последовательность  для  команды  Next  Error:  SHIFT+F3;  для   команды
Previous Error: SHIFT+F4.

    Если ваша программа имеет  ошибки компиляции, пакет Quick-C  создает
список данных ошибок в порядке их возникновения и открывает окно на  дне
экрана для  высвечивания этих  ошибок. Для  каждой высвечиваемой ошибки,
Quick-C  показывает,  сколько  ошибок  в  списке,  и где в нем находится
данная ошибка.  Например, если  программа сгенерировала  шесть ошибок, и
четвертая  из  них  высвечивается  в  данный  момент, после сообщения об
ошибке появляется следующее сообщение (4 из 6).

    Если вы выбрали  команду Next Error,  в то время,  как пакет Quick-C
высвечивает последнюю  в списке  ошибку, звуковой  сигнал подскажет вам,
что вы находитесь в конце списка. Если при этом вы еще раз выберете Next
Error, Quick-C  высветить первую  ошибку в  списке. Аналогично,  если вы
заказываете  предыдущую  ошибку,  а  уже  находитесь  на первой ошибке в
списке,  звуковой  сигнал  покажет  вам,  что  вы в начале списка; выбор
команды Previus Error  второй раз перенесет  вас на последнюю  команду в
списке.

    Команда  Next  Error  перемещает  курсор  на  ту строку в программе,
которая вызвала данную ошибку и высветит соответсвующее сообщение в окне
ошибок. Аналогично, команды Previus Error установит курсор


                 8.1.4.2. Выбор формата вывода файла:
                             Опции вывода.

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

Опции                  Использование

Obj                    Создает объектный файл на диске с тем же базо-
                       вым именем, что и исходный файл плюс расшире-
                       ние .OBJ.
Memory                 Создает программу, которая может выполняться
                       в среде Quick-C. Если вы не выбрали никакой из
                       выводных опций, опция Memory является стандар-
                       тной.
Exe                    Создает выполняемый файл на диске, с тем же
                       самым именем, что и текущая программа плюс ра-
                       сширение .EXE. Данный выполняемый файл не мо-
                       жет работать в среде Quick-C, но может быть
                       запущен, как любая другая программа в среде
                       DOS.
Syntax Check Only      Проверяет синтаксис программы и высвечивает
                       диагностические сообщения для любых найденных
                       ошибок, но не создает объектный или выполняе-
                       мый файл.

                    8.1.4.3. Подготовка к отладке:
                             Опция Debug.

    Выбирайте контрольную  рамку Debug,  если вы  хотите отлаживать вашу
программу  в  среде  Quick-C.  Опция  Debug строит программу, содержащую
полную информацию для символической отладки в среде Quick-C.

    Если  вы  выбрали  данную  опцию,  а затем "нажали" командные кнопки
Build  Program  или  Rebuild  All  (смотрите  Раздел 8.1.4.10), редактор
связей  создает  на  диске  файл  карты распределения памяти, содержащий
отладочную  информацию.  Данный  файл  имеет  то  же  самое  имя,  что и
программа, но с расширением .MAP.  В разделе 9.5.10 вы найдете  описания
файлов типа .MAP и их форматы.

    Если вы выберете опцию вывода EXE вместе с опцией Debug, выполняемый
файл,  который  вы  создадите,  можно  будет отлаживать с использованием
полноэкранного отладчика Microsoft Code View.

            8.1.4.4. Использование "корректных указателей":
                         Опция Pointer Check.

    Контрольная рамка  Pointer Check  защищает вашу  программу от  часто
встречающихся  ошибок  указателей,  которые  могут  привести  к  ошибкам
периода выполнения.  Если вы  выберете опцию  Pointer Check,  компилятор
Quick-C   сгенерирует   выполняемый   код,   который   проверит    перед
использованием  указателей,  какие  данные  программы  адресуют   данные
указатели.

    Если нет в окне ошибок, пакет Quick-C высветит ошибки указателей  во
время выполнения программы.

    Проверка  указателей  может  предотвратить  ошибки,  которые   могут
перезаписать код или данные Quick-C или DOS и тем самым вызвать  останов
работы пакета  Quick-C или  системы DOS.  В результате,  мы настоятельно
рекомендуем пользоваться данной опцией во время разработки программ.

    Заметим,  что  опция  Pointer  Check  может  значительно   замедлить
выполнение программы. В альтернативу этому можем вам предложить включать
или  выключать  проверку  только  для  отдельных  указателей,   оставляя
стандартный  режим  для  остальных  указателей  модуля.  Если  вы хотите
включить  проверку  указателей  поместите  перед  описаниемем указателя,
который вы хотите проверить следующую строку:

    #pragma check pointer(on)

    Данная строка включит проверку для всех указателей, следующих за ней
в данном исходном файле, а не только находящихся в данной строке.  Чтобы
выключить проверку на указатели, введите следующую строку:

    #pragma check pointer(off)

    Если  для  директивы  pragma  check  pointer  не  задается  никакого
аргумента,  проверка  указателей  возвращается  к  поведению,  заданному
опцией  Pointer  Check:  включена,  если  включена опция Pointer Check;и
выключена  в  противном  случае.  Взаимодействие  директивы pragma check
pointer и опции Pointer Check подробно описано в Таблице 8.1.

                                                 Таблица 8.1.

             Использование директивы pragma check pointer.

Синтаксис              Компиляция   Действие

#pragma check pointer()   да        Включает проверку на указатели,
                                    следующие далее.
#pragma check pointer()   нет       Выключает проверку на указатели,
                                    следующие далее.
#pragma check pointer(on)     да или нет  Включает проверку на ука-
                                          затели, следующие далее.
#pragma check pointer(off)    да или нет  Выключает проверку на ука-
                                          затели, следующие далее.

               8.1.4.5. Проверка на переполнение стэка:
                          Опция Stack Check.

    Выберите  контрольную  рамку  Stack  Check,  если  вы  хотите, чтобы
Quick-C проверял, достаточно  ли стековой памяти  для вашей программы  и
выдавал диагностические сообщения, если недостаточно.

    Проверка  стека  выполняется  процедурами,  известными  как   "stack
probes" (контроль стека). Процедуры контроля стека вызываются из функции
для  проверки  достаточно  ли  места  в программном стеке для размещения
локальных  переменных  требуемых   функции.  Процедуры  контроля   стека
вызываются  при  каждом  вызове  функции  из  программы.  Они генерируют
сообщения  о   переполнении  стека   в  случае,   если  стековой  памяти
недостаточно. Поскольку проверка стека отлавливает ошибки, которые могут
привести к  сбою выполнения  операций Quick-C  или DOS,  мы настоятельно
рекомендуем применять при разработке программ опцию Stack Check.

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

    Однако, программы,  не включающие  в себя  процедуры контроля стека,
меньше по объему и работают быстрее.

    Если  вы  хотите  включить  или  выключить проверку стека только для
некоторых  процедур  в  программе,  пользуйтесь  директивой pragma check
stack.  Для  функции,  в  которой  вы  хотите  включить  проверку стека,
поместите перед определением функции следующую строку:

    #pragma check stack(on)

    Данная строка  включает контроль  стека для  всех процедур следующих
далее в исходном  файле, а не  только для процедур  на следующей строке.
Для выключения проверки стека введите следующую строку:

    #pragma check stack(off)

    Если в директиве  pragma check stack  не задано никакого  аргумента,
контроль стека работает так, как было определено опцией Stack Check:  то
есть включен, если  опция Stack Check  включена, и выключен,  если опция
Stack Check выключена.

    Взаимодействие  директивы  pragma  check  stack  и опции Stack Check
подробно описано в Таблице 8.2.

                                                 Таблица 8.2.

              Использование директивы pragma check stack.

                             Компиляция с

Синтаксис                 опцией         Действие

                             Stack Check?

#pragma check stack()    Да              Включает контроль стека для
                                         процедур, следующих далее.
#pragma check stack()    Нет             Выключает контроль стека для
                                         процедур, следующих далее.
#pragma check stack(on)  Да или нет      Включает контроль стека для
                                         процедур, следующих далее.
#pragma check stack(off) Да или нет      Выключает контроль стека для
                                         процедур, следующих далее.

    Вам следует задавать опцию Stack Check до тех пор, пока вы не будете
уверены, что  в вашей  программе достаточно  стековой памяти.  Например,
данная опция может  совсем не понадобиться  вам для программы,  делающей
всего несколько вызовов функций, которые имеют умеренные запросы  памяти
для локальных переменных и не имеют рекурсий.

       8.1.4.6. Использование расширений Microsoft C к языку СИ:
                      Опция Language Extensions.

    Контрольная рамка  Language Extensions  применяется, если  вы хотите
использовать  в  программе  расширение  к  стандарту  языка СИ "ANSI C",
предлагаемые компилятором Microsoft Quick-C.

    - ключевые слова cdecl , far , fortran , near , pascal;

    - для получения значений  long используется приведение типов,  как в
следующем примере:

      int *p;
      ((long*)p)++;

    - использование хвостовой  запятой (,), а  не запятой с  многоточием
(,...) в описании функции для обозначения переменного списка аргументов,
как например:

    int printf(char *,);

    -  переопределение  typedef  разрешаеются  в  той  же  самой области
действия, как в следующем примере:

      typedef int INT;
      typedef int INT;

    -  В  инициализации  разрешается  применять  смешанные  строковые  и
символьные константы, как в следующем примере:

    char arr[6]= {'a', 'b', "cde"};

    - Использование битовых полей с базовыми типами данных, отличных  от
unsigned int, либо signed int.

---------------------------------------------------------------------

    Примечание:

    Ключевое слово far не может быть использовано для определения данных
в программах, работающих в памяти, даже если используется опция Language
Extensions. Однако, оно может быть использовано для описании  указателей
на данные.

---------------------------------------------------------------------

    Не   применяйте   опцию   Language   Extensions,   если   вы  будете
компилировать  вашу  программу  с  помощью компиляторов, не распознающих
расширения к языку СИ, имеющиеся в Microsoft Quick-C. Если вы  выключите
данную опцию, расширенные ключевые слова будут трактоваться, как простые
идентификаторы,  а  остальные  расширения,  приведенные  в списке, будут
восприниматься, как недопустимые конструкции.

    Если  языковые  расширения  не  разрешены,  компилятор автоматически
определяет идентификатор NO_EXT_KEYS. Во включаемых файлах, поставляемых
вместе  с  библиотекой  процедур,  данный  идентификатор  используется с
директивой препроцессора #ifndef для управления применения в  прототипах
библиотечных функций ключевого слова cdecl.

    Примером  данной  условной  компиляции  является  включаемый  файл с
именем stdio.h.

                  8.1.4.7. Создание быстрых программ:
                         Опция Optimizations.

    Данная  контрольная  рамка  оптимизирует  вашу программу по скорости
выполнения.  Оптимизация   выполняется  с   помощью  свертки   констант,
автоматического   управления   регистрами,   автоматической    генерации
инструкций микропроцессора 80286.

    Программы, скомпилированные с данной опцией, могут быть  значительно
больше, чем программы, без данной опции, но они работают быстрее.

                   8.1.4.8. Поиск включаемых файлов:
                       Текстовая рамка Include.

    Если вы хотите искать включаемые файлы в каталогах, отличных от тех,
что заданы в переменной  программной среды INCLUDE, введите  в текстовой
рамке INCLUDE один или более маршрутов поиска, отделенных друг от  друга
запятыми (,). Копилятор будет искать каталог или каталоги в том порядке,
в котором вы их введете,  причем до того, как он  просмотрит стандартные
места, заданные в  переменной INCLUDE. Каталоги  ищутся в заданном  вами
порядке.

    Если компилятор Quick-C не может найти включаемый фвйл в  каталогах,
заданных вами в текстовой рамке, или в каталогах, заданных в  переменной
INCLUDE, компилятор высвечивает сообщение об ошибке и прекращает работу.
В  этом  случае,  вам  следует  посторить  компиляцию программы, сообщив
Quick-C, где искать  недостающий включаемый файл,  воспользовавшись либо
переменной INCLUDE, либо текстовой рамкой INCLUDE.

             8.1.4.9. Определение констант и макрокоманд:
                        Текстовая рамка Define.

    Используйте  текстовую  рамку  Define  для определения константы или
макрокоманды вашего исходного файла. Введите одну или более констант или
макроопределений в следующей форме, отделенные запятыми (,):

    identifier=string

    В каждом определении, identifier-это имя константы или макрокоманды,
а string-ее значение или содержание. Если вы опустите и знак  равенства,
и string, считается, что данная  константа уже определена и ее  значение
равно 1. Например, Set-достаточно определить макрокоманду с именем Set и
значением 1.

    Опция define особенно  полезна, если вы  применяете директивы #if  и
#ifdef для выполнения условной компиляции исходных файлов.

    Если вы зададите  знак равенства с  пустой строкой данная  константа
или макрокоманда  считается определенной  и равна  пустой строке.  Такое
определение   может   эффективно   вычистить   все   появления   данного
идентификатора из исходного файла. Например, чтобы удалить все появления
идентификатора REGISTER, используйте следующую опцию:

    REGISTER=

    Заметим,   что   идентификатор   register   считается  определенным,
поскольку имена, заданные большими и малыми буквами рррррррр

    Макроопределения или  определения констат  в текстовой  рамке Define
имеют то  же самое  действие, что  и директива  препроцессора #define  в
начале вашего  исходного файла,  или опция  /D в  командной строке  QCL.
Идентификатор, определенный в  исходном файле, будет  компилироваться до
тех пор,  пока директива  #undef не  отменит определение,  либо не будет
достигнут конец файла.

    Если   идентификатор,   определенный   в   текстовой   рамке Define,
определяется также и в  исходном файле, определение, данное  в текстовой
рамке,   используется   до   тех   пор,   пока   идентификатор  не будет
переопределен в исходном файле.

      Пример:
#if !defined(RELEASE)
       _nheapchk();
#endif

    Данный  пример  вызывает  функцию  для проверки ближней динамической
области, до тех  пор, пока не  будет определена константа  RELEASE. Пока
программа  находится  в  стадии  разработки,  вы можете оставить RELEASE
неопределенным и выполнять  проверку динамической области  для выявления
сбоев.  Затем,  когда  вы  исправите  все  ошибки  в  вашей   программе,
определите RELEASE, и программа будет работать быстрее.

                 8.1.4.10. Командные кнопки диалоговой
                             рамки Compile.

    Командные  кнопки  в  диалоговой  рамке Compile сообщают компилятору
Quick-C, компилировать ли исходный файл, который вы редактировали,  либо
модули  из  текущего  программного  списка.  Выберите  одну из следующих
командных кнопок:

Командная кнопка       Использование

Build Program          Перекомпилирует все модули текущего программ-
                       ного списка, которые были обновлены со време-
                       ни последней перестройки програмы; затем прог-
                       рамма перестраивается. Детально данная проце-
                       дура описывается в Разделе 6.1.4. Результирую-
                       щие объектные файлы, файл для редактора свя-
                       зей, выполняемый файл, и (если включена опция
                       Debug) файл карты распределения памяти записы-
                       ваются на диск. Если не имеется программного
                       списка, компилируется исходный файл, который
                       вы редактировали.
Compile File           Компилируется редактируемый в данный момент
                       исходный файл.
Rebuild All            Перекомпилируются все модули из текущего прог-
                       раммного списка, независимо от того, изменя-
                       лись ли они со времени последней перестройки
                       программы; затем программа заново строится.
                       Подробно данная процедура описывается в Разде-
                       ле 6.1.4. Результирующие объектные файлы, файл
                       для редактора связей, выполняемый файл, и (ес-
                       ли включена опция Debug) файл карты распреде-
                       ления памяти записываются на диск. Если не су-
                       ществует программного списка, компилируется
                       редактирумый в данный момент исходный файл.
Cancel                 Снимает компиляцию и возвращает вас в окно об-
                       зора.

       8.1.5. Опции, управляющие процессом выполнения программ:
                    Команда Set Runtime Options...

    Команда  Set  Runtime  Options...  управляет  различными   аспектами
поведения программы во времы выполнения. Данные опции будут  действовать
и в следующий раз, когда программа будет запущена.

    Когда вы выберете  команду Set Runtime  Options... из меню  File, на
экране появится соответствующая диалоговая рамка, открытая для работы.

    В  следующем  списке  описаны  опции  диалоговой  рамки  Set Runtime
Options...:

Опция                  Использование

Command Line           Введите аргументы, которые бы вы набрали в
                       командной строке после имени программы, если
                       бы программа запускалась с помощью командной
                       строки DOS. Данные аргументы передаются прог-
                       рамме с помощью стандартных аргументов argv и
                       argc функции Main исходного текста СИ-програм-
                       мы.
Near Data              Чтобы уменьшить количество памяти, отведенной
                       для стандартного сегмента данных (по умолча-
                       нию 64К), введите количество отводимых байтов
                       (в десятичном виде). Стандартный сегмент со-
                       держит все инициализированные глобальные
                       данные и данные типа static, исключая данные
                       явно описанныеые с ключевым словом far. Вам
                       может понадобиться уменьшить размер данного
                       сегмента, если ваша программа не использует
                       большое количество данных, входящих в стандар-
                       тный сегмент, но использует большие по размеру
                       данные (как, например большие массивы), разме-
                       щаемые в других сегментах данных. Подробную
                       информацию о размещении данных вы можете найти
                       в Приложении В "Работа с моделями памяти
                       Quick-C". Подробности о стандартном сегменте
                       данных и других сегментах, используемых компи-
                       лятором Microsoft Quick-C, вы найдете в Прило-
                       жении С "Интерфейс между языком СИ и языком
                       Ассемблер".
Stack                  Чтобы использовать стек размером, отличный от
                       стандартного (2К), введите количество байтов
                       (в десятичном виде) в текстовой рамке Stack.
                       Наибольший размер стека, который вы можете
                       потребовать-64К. Вы можете увеличить размер
                       стэка, если ваша программа выдает диагности-
                       ческие сообщения о переполнении стека. И на-
                       оборот, если ваша программа использует очень
                       маленький стек, вам может понадобиться умень-
                       шить размер программы путем уменьшения размера
                       стека.

                        8.2. Отладка программ.

    Компилятор  Microsoft   Quick-C  имеет   мощные  средства   отладки,
облегчающие  процесс  выявления  ошибок  в программной логике. Например,
отладчик  можно  использовать  для  трассировки  и пошагового выполнения
программы, установки точек прерывания  и проверки значений переменных  и
выражений.

                  8.2.1. Основная процедура отладки.

      Для отладки программы в среде Quick-C используйте следующую
основную процедуру:

    1. Скомпилируйте программу с  включенной опцией Debug в  диалого вой
рамке Compile.

    2. Включите какие-либо средства отладки, такие как точки прерывания,
выражений  просмотра   или  прокрутка   экрана-либо  с   помощью  команд
клавиатуры, либо с помощью команд меню Debug, описанных в Разделе 8.2.3.

    3.  Запустите  вашу  программу   на  выполнение  с  помощью   команд
клавиатуры, описанных  в Разделе  8.2.2, либо  с помощью  команд из меню
Run:  Start,  Restart,  Continue.  Наблюдайте  при этом, в каком порядке
выполняются функции и операторы, какие изменения претерпели  переменные,
данные, выводимые программой.

    4. Отредактируйте вашу программу, чтобы исправить ошибки, выявленные
на  шаге  3.  Затем  перекомпилируйте  вашу программу снова выбрав опцию
Debug из меню Compile.

    5.  Если  вам  требуется  изменить какую-либо отладочную информацию,
вернитесь  к  шагу  2.  В   противном  случае  вернитесь  к  шагу   3  и
перезапустите вашу программу.

    6. Повторяйте  шаги 3-5  до тех  пор, пока  ваша программа  не будет
выполняться корректно.

               8.2.1.1. Добавление выражений просмотра.

    Если  вы  добавите   выражения  просмотра,  Quick-C   откроет  окно,
называемое  "окном   просмотра"-в  верхней   части  экрана,   где  будут
высвечиваться значения выражений просмотра.

    Во время  выполнения программы  пакет Quick-C  постоянно высвечивает
значения  выражений  просмотра,  изменяя  их,  в  зависимости  от  смены
значений  соответствующих  программных  переменных.  Не   прогнозируемые
значения выражений просмотра могут означать ошибки в программе.

    Для добавления выражения просмотра пользуйтесь командой Add Watch из
меню Debug.  Для удаления  только что  добавленного выражения  просмотра
пользуйтесь  командой  Delete  Last  Watch  из  меню Debug. Обеими этими
командами рекомендуется  пользоваться, если  вы просматриваете  значения
локальных переменных во  время прохода через  функции, в которых  данные
переменные  определены,  а  затем,  после  выхода  из  функции  удаляете
выражения просмотра для данных переменных.

    Чтобы  удалить  ВСЕ  выражения  просмотра, следует применить команду
Delete All Watch из меню Debug.

                 8.2.1.2. Установка точек прерывания.

    "Точки   прерывания"   устанавливаются   на   определенных   строках
программы.   Точка   прерывания   заставляет   пакет   Quick-C  временно
приостановить  выполнение  программы  в  данной строке. Точки прерывания
часто  используются  вместе  с  выражениями  просмотра: установите точки
прерывания  в  тех  строках  программы,  где  вы  ожидаете  сбой,  затем
проверьте значения выражений просмотра в данной точке.

    Чтобы включить или выключить точку прерывания, установите курсор  на
строку, где вы хотите переключить  данную точку. Затем либо нажмите  F9,
либо выберите команду Toggle Breakpoint из меню Debug.

    Для  удаления  всех  точек  прерывания,  выберете  команду Clear All
Breakpoints из меню Debug (Смотрите Раздел 8.2.3.5.  "Управление точками
прерывания" для получения более подробной информации о команде Clear All
Breakpoints).

              8.2.2. Отладка с помощью команд клавиатуры.

    Quick-C поддерживает следующие  команды, вызываемые нажатием  одного
ключа:

Команда для:                                      Ключ

Выполнение следующего оператора программы;        F8
трассировка функции.
Выполнение следующего программного оператора;     F10
трассировка в обход функции.
Выполнение программы до текущей позиции курсора.  F7
Высвечивание выводного экрана                     F4

    Для  выполнения  программы  до  строки,  в  которой   позиционирован
указатель мыши, щелкните на данной строки правой кнопкой мыши.

                  8.2.3. Команды отладки: Меню Debug.

    Команды из меню Debug выполняют следующие действия:

Команда                Действие

Add Watch              Добавляет в окно просмотра одно или более вы-
                       ражений просмотра.
Delete Last Watch      Удаляет из окна просмотра выражение просмотра,
                       добавленное последним. Ключевая последователь-
                       ность для данной команды SHIFT+F2.
Delete All Watch       Удаляет из окна просмотра все выражения про-
                       смотра.
Trace On               Включает, либо выключает трассировку программы
Scceen Swapping On     Включает, либо выключает прокрутку экрана.
Toggle Breakpoint      Включает или выключает точку прерывания на
                       строке в текущей позиции курсора. Ключ быстро-
                       го реагирования для данной команды F9.
Clear All Breakpoints  Очищает все точки прерывания из данной про-
                       граммы.

    В Разделах 8.2.3.1-8.2.3.5. описываются команды из меню Debug.

               8.2.3.1. Добавление выражений просмотра:
                         Команда Add Watch...

    Команда Add Watch... используется для добавления в окно просмотра  в
верхней части экрана одного или более выражений просмотра.

    Как только вы выберете команду Add Watch... из меню Debug, на экране
появится открытая диалоговая рамка.

    Введите в текстовую рамку  одно или более выражений  просмотра. Если
вы вводите  более одного  выражения, в  конце каждого  выражения вводите
точку с запятой.

    Выражение просмотра может быть одним из следующих:

    - переменная;

    - Си-выражение, состоящее из переменных, объедененных в скобки (()),
квадратные  скобки   ([]),  оператором   выбора  члена   структуры  (.),
оператором-указателем  на  структуру  (->),  либо  оператором косвенного
наименования (*);

    - содержимое структуры или массива

    Заметим,  что  в  выражениях  просмотра  математические операторы не
допускаются.

    Чтобы  высветить  значение  просматриваемой  переменной,   используя
различные формат вывода, введите после имени просматриваемой  переменной
запятую, за  которой следует  символ формата.  В Таблице  8.3 приводится
список  символов  формата  вместе  с  примерами  вывода  для   значений,
хранящихся в памяти.

                                                 Таблица 8.3.

         Спецификации формата для просматриваемых переменных.

Символ  Формат вывода          Просматриваемое   Высвечиваемое зна-

                               значение            чение

d      десятичное целое со     40000                 40000
        знаком
i      десятичное целое со     40000                 40000
        знаком
u      десятичное целое        40000                 40000
        без знака
o      восьмиричное целое      40000                 116100
       без знака
x      шестнадцатеричное целое 40000                  9с40
f      значение со знаком с    3./2.                  1.500000
       плавающей точкой в де-
       сятичном формате с 6-ю
       знаками после запятой.
e      число со знаком в фор-  3./2.                  1.500000е+000
       мате с плавающей точ-
       кой (экспонинциальном)
       до 6-и знаков после
       запятой (хвостовые нули
       и десятичная точка
       отбрасываются)
g      число со знаком с пла-  3./2.                   1.5
       вающей точкой в деся-
       тичном формате (f), ли-
       бо в экспонинциальном
       формате (е)-то что более
       компактно.
c      один символ             65                        А
s      символы, печатаемые до  "String"                  String
       первого пустого сим-
       вола.

    Если  не  задано  никакого  формата,  отладчик  Quick-C   использует
стандартную  спецификацию  формата  для  данного  типа   просматриваемой
переменной.   В   структурах   каждое   поле   высвечивается  в формате,
стандартном  для  типа  данного  поля.  Дейтсвительные  числа  простой и
двойной точности высвечиваются в формате g.

    Для обозначения двухбайтового  целого со спецификациями  формата (d,
o, u, x) используется префикс h. С теми же самыми типами префикс l может
использоваться для идентификации четырехбайтового целого.

    Например,   если   значение   просматриваемой   переменной   100000,
спецификация ld  дает 100000.  Однако, спецификация  hd вычисляет только
два старших байта и дает в выводе -31072.

    Спецификаторы формата для просматриваемых переменных работают тем же
самым способом, что и  спецификаторы формата для семейства  библиотечных
функций printf. Поэтому,  если вы определите  просматриваемую переменную
одного типа,  а спецификатор  формата другого  типа, неявное  приведение
типа просматриваемой  переменной к  типу спецификатора  формата не будет
произведено.  Вместо  этого,  битовый  шаблон  в  памяти, представляемый
просматриваемой  переменной,  появляется  в  таком  виде, как если бы он
представлялся элементом того же самого типа, что и спецификатор формата.
Например,  если  переменная  типа  int  имеет  значение  4,  и  если  вы
высвечиваете  ее  в  формате  f,  высвечиваться  будет  "0.00000'  а  не
'4.00000".  Данное  значение   высвечивается,  поскольку  в   формате  с
плавающей точкой битовый шаблон формата "00000100" представляет число  с
такой маленькой степенью, что она почти равна нулю.

    Вы  не   ограничены  в   высвечивании  содержимого   просматриваемой
переменной. Если вы после имени просматриваемой переменной введете более
одного символа формата, каждый символ формата будет представлять область
памяти,  находящуюся   после  области   памяти  данной   просматриваемой
переменной. Отладчик Quick-C высвечивает значение, хранимое в каждой  из
этих областей памяти, используя формат заданный данным символом формата.

    После того, как  вы введете в  текстовую рамку выражения  просмотра,
"нажмите" командную  кнопку ОК  для добавления  данных выражений  в окно
просмотра, либо командную кнопку Cancel для снятия команды Add Watch...

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

    Примеры:

    watchvar,f

    Пример,  приведенный  выше,  высвечивает  значение   просматриваемой
переменной watchvar  в десятичном  формате с  плавающей точкой  и шестью
десятичными знаками.

    watchavar,dulx10c

    Второй  пример   высвечивает  значение   просматриваемой  переменной
watchvar  в  десятичном  формате  со  знаком.  Кроме того, высвечиваются
значение  12  областей  памяти,   адреса  которых  следуют  за   адресом
watchavar, в форматах, приведенных ниже:

      - десятичное число без знака;
      - длинное шестнадцатеричное число;
      - десять символов.

        8.2.3.2. Удаление просматриваемых переменных: Команды
                     Delete Last Watch/All Watch.

    Команда Delete Last Watch удаляет из окна просмотра недавно  (только
что) добавленное выражение  просмотра. Если вы  с помощью одной  команды
Add Watch... добавили более одного выражения просмотра, удаляется только
последнее   выражение,   находящееся   в   текстовой   рамке.   Ключевая
последовательность для данной команды SHIFT+F2.

    Команда Delete All Watch удаляет все выражения просмотра и закрывает
окно просмотра.

                   8.2.3.3. Управление трассировкой:
                           Команда Trace On.

    Команда  Trace  On  включает,  либо выключает трассировку программы.
Если  данная  команда  включена,  в  меню  Debug  появляется контрольный
маркер. Если при включенной трассировке, вы вызовете из меню Run команды
Start  или  Continue,  программа  будет  выполняться  до следующей точки
прерывания, причем  текущий выполняемый  оператор будет  подсвечиваться.
Если следующий  выполняемый оператор  находится в  другом модуле, данный
модуль высвечивается в окне просмотра.

    Если   трассировка   включена,   текущий   выполняемый   оператор не
подсвечивается. Выполнение продолжается непосредственно до первой  точки
прерывания, которой является первый подсвеченный оператор.

                8.2.3.4. Управление прокруткой экрана:
                      Команда Screen Swapping On.

    Команда  Screen  Swapping  On  включает,  либо  выключает  прокрутку
экрана.  После  выполнения  команды  в  меню  Debug появится контрольная
метка, обозначающая включенную прокрутку экрана.

    Если прокрутка экрана включена, экран Quick,C исчезает и  заменяется
экраном  программного  вывода  по  каждому  шагу  выполнения  программы,
последовательно, с постоянным мерцанием.

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

            8.2.3.5. Управление точками прерываний: Команды
              Toggle Breakpoint и Clear All Breakpoints.

    Команда  Toggle  Breakpoint   и  Clear  All   Breakpoints  управляют
использованием в процессе отладки точками прерываний.

    Команда Toggle Breakpoint включает, либо выключает точку  прерываний
в  строке,  в  которой  в  данный  момент  установлен курсор. Если точка
прерывания уже установлена, команда  выключит ее; если точка  прерывания
не установлена,  команда Toggle  Breakpoint установит  ее. Ключ быстрого
реагирования для данной команды F9.

    Строки, в которых установлены точки прерывания, имеют цвета и другие
атрибуты, заданные опцией Breakpoint Lines в диалоговой рамке Options...
меню View.

    Команда  Clear  All  Breakpoints  удаляет  все  точки  прерывания из
отлаживаемой программы.

                  8.2.4. Перемещение между функциями:
                              Меню Calls.

    Меню Calls высвечивает список вызываемых функций. Этот список  можно
использовать   для   высвечивания   функций.   Кроме   того,   вы можете
использовать  список   данных  функций   для  выполнения   программы  до
определенной функции.

    Пока список  Calls высвечивается,  вы можете  использовать мышь  или
ключи управления курсором и ключ ENTER для выбора одной из функций.

    Пакет  Quick-C  высветит  функцию  и  поместит  курсор  на следующий
оператор,  который  будет  выполняться,  когда  управление  вернется   к
вызывающей функции.

    Если  вы  последовательно  проходите  через  функцию и хотите из нее
выйти, выполните следующие шаги:

    1. Откройте меню Calls.

    2. Воспользуйтесь  ключами управления  курсором для  подсветки имени
функции, из которой  вы вызвали функцию,  которую вы проходите  в данный
момент, и нажмите ENTER.

    3. Нажмите F7.

    Отладчик Quick-C возвратит вас в точку, непосредственно следующую за
той, из которой вы вызвали функцию.


                               ЧАСТЬ 3.

             Набор инструментальных средств пакета Quick-C

      Главы:

      9. Компиляция и компановка программ.
      10.Создание библиотек Quick-C и автономных
         библиотек.
      11.Автоматизированная разработка программ с
         помощью утилиты MAKE.

    Компилятор Microsoft Quick-C  имеет не только  интегрированную среду
разработки  программ;  он  также   включает  в  себя  несколько   мощных
программных средств, дополняющих интегрированную среду. Настоящий Раздел
показывает, как применять данные средства, которые включают:

    -  Компилятор  QCL,  создающий  из  исходных  СИ-файлов  объектные и
выполняемые файлы на диске.

    - Оверлейный  редактор связей  LINK, объединяющий  объектные файлы и
автономные библиотеки в выполняемые файлы или библиотеки Quick.

    - Утилита LIB, объединяющая объектные файлы в автономные библиотеки.

    -  Утилита  поддержки   программ  MAKE,  автоматически   обновляющая
программу, при изменении какого-либо из ее составных модулей.

                               ГЛАВА 9.

                   Компиляция и компановка программ.

9.1.  Процесс компиляции и редактирования связей.
      9.1.1. Использование только командной строки QCL.
      9.1.2. Использование команд QCL и LINK.
9.2.  Одношаговая компиляция и компановка:
      Команда QCL.
9.3.  Управление компиляцией с помощью опции QCL.
      9.3.1. Опции программной среды.
      9.3.2. Опции, управляющие редактированием
             связей.
      9.3.3. Распечатка опций компилятора (/HELP).
      9.3.4. Задание имени объектного файла (/FO).
      9.3.5. Модель памяти (/A) и опции операций
             с плавающей точкой (/FP).
      9.3.6. Использование процессоров 8086 или 80286
             (/G0, /G2).
      9.3.7. Управление препроцессором.
      9.3.8. Подготовка к отладке (/Zi, /Zd).
      9.3.9. Упаковка членов структуры (/Zp).
      9.3.10.Подавление выбора стандартной библио-
             теки (/ZI).
      9.3.11.Управление соглашениями о связях (/Gc).
      9.3.12.Установка границы данных.
      9.3.13.Оптимизация циклов (/Ol).
9.4.  Раздельные компиляция и редактирование связей:
      QCL и LINK.
      9.4.1. Редактирование связей посредством команды QCL.
      9.4.2. Редактирование связей посредством команды LINK.
9.5.  Использование опций компановщика.
      9.5.1. Высвечивание списка опций (/HE).
      9.5.2. Паузы в процессе компановки (/PAU).
      9.5.3. Высвечивание информации о процессе
             компановки (/I).
      9.5.4. Запрет на сообщения компановщика (/B).
      9.5.5. Создание библиотек Quick (/Q).
      9.5.6. Упаковка выполняемых файлов (/E).
      9.5.7. Отказ от стандартных библиотек (/NOD).
      9.5.8. Установка максимального количества
             сегментов (/SE).
      9.5.9. Установка максимального размера
             памяти (/CP).
      9.5.10.Создание файла карты распределения
             памяти (/M, /LI).
      9.5.11.Управление размером стека (/ST).
      9.5.12.Трансляция "длинных" вызовов (/F, /NOF).
      9.5.13.Упаковка последовательных сегментов
             (/PAC, /NOP).
      9.5.14.Прочие опции компановщика LINK.
9.6.  Управление стеком и динамическим распределением
      памяти.
9.7.  Использование оверлейных структур.
      9.7.1. Ограничения на оверлейные структуры.
      9.7.2. Запросы диспетчера оверлейных структур.

    Как только вы освоите программирование в интегрированной программной
среде  Quick-C,  вам  может  понадобиться  умение  управлять   процессом
компиляции и  компановки программ  вне интегрированной  среды. Вам может
это понадобиться по следующим причинам:

    -  Вы  создаете  исходный  текст  программы  на  своем   собственном
редакторе текстов.

    - Вы компилируете программы, которые не могут быть скомпилированы  в
программной среде Quick-C.

    - Программа, которую вы создаете использует различные модели памяти.

    - Вы хотите изменить стандартные соглашения о наименовании и  вызове
функций из ваших программ.

    - Во  время компиляции  вашей программы  вы генерируете  специальные
команды для процессора 80286.

    - Вам  требуется листинг  либо содержащий  вывод препроцессора языка
СИ, либо программные сегменты, в порядке появления.

    Компилятор Microsoft Quick-C имеет  программу с именем QCL,  которая
компилирует и компанует  вашу программу вне  среды Quick-C. В  следующей
Главе   показывается,   как   использовать   команду   QCL  и оверлейный
компановщик Microsoft, называемый  LINK. Она организована,  как показано
ниже:

Разделы       Содержание

9.1-9.1.2.    Описывается процесс компиляции и компановки. Прочтите
              данный раздел, если вы незнакомы с языковой продукцией
              фирмы Microsoft Inc.; в противном случае перейдите к
              Разделу 9.2.
9.2-9.3.      Объясняется, как компилировать и компановать программы
              с помощью одной строки команды QCL , и описывает файлы
              и опции, которые поступают на ввод команде QCL.
9.4-9.7.      Объясняется, как компилировать и компановать программы
              в два приема: с помощью компиляции посредством QCL и
              компановки посредством LINK. В данных Разделах описыва-
              ется информация, которую QCL передает программе LINK,
              кроме того список файлов и опции, которые вы можете за-
              дать на входе команды LINK

           9.1. Процесс компиляции и редактирования связей.

    Создание автономной программы из исходного СИ-файла вне  программной
среды Quick-C описывает следующая процедура:

    1.  Каждый  исходный   файл  в  программе   компилируется,  создавая
объектный файл.

    2.  Объектные  файлы  связываются  с  одной  или  более   автономных
библиотек (Библиотеки с расширением .LIB) для формирования  выполняемого
файла. Перед созданием выполняемого файла компановщик разрешает  внешние
ссылки в объектных файлах.  (То есть, гарантируется то, что все функции,
вызываемые в объектных файлах, соответствуют функциям в библиотеках  или
в других объектных файлах).

    В Разделах 9.1.1. и 9.1.2. описываются два метода, которые вы можете
использовать для компиляции и компановки программ.

    Рисунок 9.1 иллюстрирует данные методы.

    Рисунок 9.1. Компиляция и компановка программ.

           9.1.1. Использование одной командной строки QCL.

    Компилировать  и  компановать   программу  можно  используя   только
командную  строку  QCL.  То  есть  может  быть использована одна и та же
командная строка, чтобы задать исходные файлы для компиляции,  об'ектные
файлы и библиотеки для  компановки, опции для управления  компилятором и
компановщиком.   QCL  скомпилирует   все  исходные  файлы,   которые  вы
зададите, затем передаст компановщику все имена об'ектных файлов,  имена
библиотек и опции компановщика, который затем соединит об'ектные файлы и
библиотеки, создав тем самым выполняемый файл.

                9.1.2. Использование команд QCL и LINK.

    В качестве  альтернативы вышеописанному  способу, вы  можете сначала
выполнить  компиляцию  с  помощью  QCL  с опцией /c, затем использоывать
команду  LINK  для  прямого  вызова  компановщика. Преимуществом данного
метода является  то, что  вам не  потребуется в  одной командной строке,
задавать компановщику всю необходимую информацию; команда LINK  запросит
у вас всю информацию, которую вы не задали. Инструкции по  использованию
команды LINK смотрите в Разделах 9.4.2.1-9.4.2.4.

             9.2. Одношаговая компиляция и редактирование:
                             Команда QCL.

    Для  компиляции  и  компановки  посредством  команды QCL, ваша опера
ционная среда DOS должна быть установлена так, как описано ниже:

    Полное описание смотрите в Разделе 1.3.1.6 (для пользователей систем
с жестким диском)  или в Разделе  1.3.2.4.  (для пользователей  систем с
гибкими дисками).

    - Если вы являетесь пользователем системы с жестким диском, сделайте
каталог с вашим исходным файлом текущим с помощью команды DOS CD.

    - Если вы пользуетесь системой с гибкими дисками, установите дискету
с вашей исходной программой в дисковод В, а копию дистрибутивной дискеты
PRODUCT в дисковод А. Сделайте дисковод В рабочим. При запуске программы
QCL  введите  имя  дисковода  А:  непосредственно перед командой QCL без
разделяющих пробелов. Во  время процесса компиляции/компановки,  система
будет  просить  вас  установливать  в  дисковод  А  вашу  рабочую  копию
дистрибутивной  дискеты  Work  и  дискету,  содержащую   соответствующую
автономную библиотеку.

    Команда QCL имеет следующий формат:

    QCL[[option]]...file...[[option|file]]...[[/link[[lib...link-opt.
..]]]]

    Информация, вводимая в командной строке QCL объясняется в  следующем
списке:

Содержимое             Значение

option                 Опция QCL; смотрите Разделы 9.3.1-9.3.13, опи-
                       сывающие опции. Чтобы получить краткий обзор
                       наиболее часто используемых опций, введите:
                       QCL/HELP и нажмите ENTER.
file                   Имя исходного или объектного файла, передава-
                       емого для обработки; либо имя библиотеки, пе-
                       даваемой редактору связи для обработки. Вам
                       следует задать хотя бы одно имя файла. О за-
                       дании имен файлов в команде QCL смотрите Раз-
                       делы 9.2.1.1-9.2.1.3.
lib                    Имя автономной библиотеки, передаваемой ком-
                       пановщику для обработки. Подробную информацию
                       о задании автономных библиотек смотрите в Раз-
                       деле 9.4.2.3.
link-opt               Одна или более опций компановщика, описанных в
                       Разделах 9.5.1-9.5.14; Команда QCL передает
                       данные опции компановщику. Обычно, вам не нуж-
                       но задавать опции компановщика, если вы не хо-
                       тите, чтобы компановщик выполнял специальные
                       операции, такие как подвязывание специальной
                       библиотеки, изменение размера программного
                       стека, создание файла распределения памяти,
                       либо включение в выполняемый файл отладочной
                       информации.

    В командной строке QCL вы можете задать любое количество опций, имен
файлов и автономных библиотек, но учтите, что командная строка не должна
превышать 128 символов.

                      9.2.1. Задание имен файлов.

    Команда  QCL  имеет  некоторые  правила  для  задания  имен  файлов,
основывающиеся на именах маршрутов и расширений, которые вы  используете
для  данных  файлов.  Следующие  Разделы  описывают  правила, которым вы
должны следовать при задании имен файлов для QCL.

              9.2.1.1. Буквы нижнего и верхнего регистра.

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

                   9.2.1.2. Расширения имен файлов.

    Имя  файла  в  операционной  системе  DOS  состоит  из  двух частей:
"базовое  имя",  то  что  стоит  перед  точкой,  и "расширение", которое
состоит   из   точки(.)   и   трех   символов   после  точки. Расширение
идентифицирует тип файла.

    Команда  QCL  использует  расширение  каждого  имени файла для опре-
деления  способа  обработки  соответствующего  файла,  как об'ясняется в
следующей таблице:

Расширение    Обработка

.C            QCL предполагает, что данный файл является исходным
              СИ-файлом, и компилирует его.
.OBJ          QCL предполагает, что файл является об'ектным, и передает
              его редактору связей для компановки.
.LIB          QCK предполагает,что файл является автономной библиоте-
              кой и передает ее редактору связей для компановки вместе
              со сгенерированными об'ектными файлами, заданными в ко-
              мандной строке.
Любые другие  QCL предполагает,что файл является об'ектным и передает
расширения    его компановщику.
или без расши-
рения.

    -Пример:

    Командная строка:

    QCL A.C B.C C.OBJ D

    компилирует файлы A.C и B.C,создает объектные файлы с именами  A.OBJ
и B.OBJ. Данные  объектные файлы затем  компануются вместе с  объектными
файлами C.OBJ и D.OBJ для формирования выполняемого файла с именем A.EXE
(поскольку базовое  имя первого  файла в  командной строке  А). Обратите
внимание, что для  файла D предполагается  расширение .OBJ, поскольку  в
командной строке для него не задано никакого расширения.

                   9.2.1.3. Наименование маршрутов.

    Любой  файл  может  содержать  полное  или  частичное   наименование
маршрута.  Полное  имя  маршрута  начинается  со спецификации дисковода;
частичное имя маршрута имеет одно или более имен каталогов перед  именем
файла, но не содержит имя дисковода.

    Задание  наименования  маршрута  позволяет  вам  задавать  на   вход
программе QCL файлы, содержащиеся в различных каталогах, создавать файлы
на различных дисководах или в различных каталогах текущего устройства.

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

    Если вы не зададите полное или частичное наименование маршрута,

    QCL предполагает, что определенные вам исходный или объектный  файлы
находятся в текущем каталоге, где будут создаваться все выходные файлы.

           9.3. Управление компиляцией с помощью опций QCL.

    Опции команды QCL представляют собой либо слэш (/), либо дефис  (-),
за которыми следует одна или более букв.

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

---------------------------------------------------------------------

    Важное замечание:

    Опции  QCL  чувствительны  к  использованию  больших  и  малых букв.
Например, /W и /w являются различными опциями.

---------------------------------------------------------------------

    Опции могут  быть расположены  в любом  месте командной  строки QCL.
Если не оговорено  иначе, опция QCL  применяется к файлам,  следующим за
ней  в  командной  строке,  и  не  влияет  на файлы, предшествующие ей в
командной строке.

    Все  опции  QCL  совместимы  с  опциями  оптимизирующего компилятора
Microsoft C версии 5.0.

    -Объединение опций в переменной программной среды CL.

    Если вы перекомпилируете данный набор файлов более одного раза,  или
вы  используете  при  компиляции  тот  же  самый набор опций, переменная
программной среды CL может спасти вас от повторного ввода файлов и опций
в командной строке при каждой компиляции. Для определения переменной  CL
используйте, как показано ниже, команду DOS SET:

    SET CL=[[option|file]...[/link[link-libinfo]]]

    Данная  переменная  также  бывает  полезна,  если  при компиляции вы
обычно используете большое количество файлов и опций, поскольку файлы  и
опции,  которые  вы  определяете  в  данной  переменной,  не умещаются в
128-символьный  лимит  командной  строки;  те  файлы и опции, которые вы
часто используете, можно определить в переменной CL, а остальные файлы и
опции, нужные вам для специальных целей, задавать в командной строке.

    Информация,   которую   вы   определяете   в   переменной  CL, будет
трактоваться так, как  если бы она  находилась в командной  строке перед
информацией,  заданной  в  командной  строке  QCL.  Например,  если   вы
используете командную последовательность в форме:

    SET CL=/ Fm TEST1:C /link LIB1.LIB /PAC
    QCL /Zi TEST2.C /link LIB2.LIB /STOxCOO

    эффект будет тот же, как если бы вы ввели в командной строке:

    QCL /Fm TEST1.C /Zi TEST2.C /link LIB1.LIB /PAC
    LIB2.LIB /STOxCOO

    Обратите внимание, что если вы  определили файл или опцию с  помощью
CL,  вы  не  сможете  отменить  ее  в  командной строке. Вам будет нужно
переназначить  переменную  программной  среды  CL  и пропустить файл или
опцию, которую вы не хотите использовать.

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

    -Опции QCL и объектные файлы.

    Большинство опций QCL  применимы только к  процессу компиляции и  не
влияют на объектные файлы, заданные на командной строке.

    Таблица  9.2  в  Разделе  9.3.2.  приводит список опций, влияющих на
процесс компановки.

    -Примеры:

    SET CL=FILE1.C FILE2.C
    QCL FILE3.OBJ

    В приведенном  выше примере  переменная среды  CL просит  компилятор
скомпилировать и  скомпановать исходные  файлы FILE1.C  и FILE2.C. Тогда
команда QCL

    QCL FILE1.C FILE2.C FILE3.OBJ

    будет иметь тот же самый эффект, что и первая командная строка.

    SET CL=/Za
    QCL FILE1.C/Ze FILE2.C

    Пример, приведенный выше,  рассказывает как отменить  действие опции
CL.  В  данном  примере  переменной  среды  CL  присваивается опция /Za,
описанная  в  Разделе  9.3.1,  указывающая,  что  компилятор  не  должен
распознать расширения к  языку СИ фирмы  Microsoft. При действии  данной
опции ключевые слова, специфичные для Microsoft-C будут трактоваться как
обычные идентификаторы.

    Команда  QCL  определяет  обратную  опцию  /Ze, при действии которой
компилятор трактует  языковые расширения,  как зарезервированные  слова.
Поскольку компиляция с помощью командной строки, приведенной ниже та  же
самая:

    QCL /Za FILE1.C /Ze FILE2.C,

    файл FILE1.C компилируется с выключенными языковыми расширениями,  а
файл FILE2.C скомпилируется с распознаванием языковых расширений.

                    9.3.1. Опции программной среды.

    Опции командной строки QCL имеют то же самое действие, что и  опции,
задаваемые в  диалоговой рамке  Compile. В  Таблице 9.1  показаны данные
опции  QCL,  соответствующие  опциям  рамки  Compile, разделы, в которых
описываются данные функции и действие каждой опции.

                                                 Таблица 9.1.
              Опции QCL и опции диалоговой рамки Compile.

Опции QCL                Опции Compile             Действие

/C                       OBJ кнопка включена     Создает объектный
                                                 файл на диске.
/D identifier[=[string]] Define text box         Определяет символи-
                                                 ческие константы или
                                                 макрокоманды. Опция
                                                 /D разрешает давать
                                                 до 16 определений,
                                                 если языковые расши-
                                                 рения выключены (оп-
                                                 ция компилятора /Za
                                                 или круглая кнопка в
                                                 интегрированной сре-
                                                 де), и до 17 опреде-
                                                 лений, если языковые
                                                 расширения разрешены
/Cs                      Контрольная рамка       Отменяет контроль на
                         Stack Check выключена   стековые операции.
                         (8.1.4.5.)
/Idirectory              Текстовая рамка Include Сообщает комплятору,
                         (8.1.4.8)               по каким маршрутам
                                                 искать включаемые
                                                 файлы. Каждая опция
                                                 /I определяет различ
                                                 ные каталогиию.
/Ot                      Контрольная рамка опти  Оптимизация времени
                         мизации (8.1.4.7.)      выполнения за счет
                                                 размера программного
                                                 кода.
/Ox                      Контрольная рамка опти  Выполняет максимум
                         мизации (8.1.4.7.) и    оптимизации програм-
                         контрольная рамка Stack мы. Данная опция
                         Check (8.1.4.5.)        включает также опти-
                                                 мизацию по циклам.
                                                 (Подробную информа-
                                                 цию об оптимизации
                                                 по циклам смотрите в
                                                 Разделе 9.3.13.
/W[{0|1|2|3}]            Включение кнопки        Устанавливает уро-
                         Warning Level (8.1.4.1) вень для предупреж-
                                                 дающих сообщений.
/Za                      Выключение контрольной  Устанавливает зап-
                         рамки Language          рет на расширения
                         Extensions (8.1.4.6)    Microsoft-C к стан-
                                                 дарту ANSIC.
/Zd                      Включение контрольной   Получает объектный
                         рамки отладочной инфор- файл, содержащий но-
                         мации (Debug) (8.1.4.3) мера строк записей,
                                                 соответствующие номе
                                                 рам строк в исходном
                                                 файле. Бывает полез-
                                                 на, если вы хотите
                                                 передать объектый
                                                 файл символическому
                                                 отладчику SYMDEB.
                                                 Данный отладчик ис-
                                                 пользует эти номера
                                                 для определения мес-
                                                 тоположения в прог-
                                                 рамме внешних симво-
                                                 лических имен, одна-
                                                 ко, он не может это-
                                                 го сделать для лока-
                                                 льных символических
                                                 имен.
/Zi                      Включение контрольной   Помещает в объектный
                         рамки Debug (8.1.4.3.)  файл информацию, тре
                                                 буемую для отладки;
                                                 позволяет использо-
                                                 вать данный файл для
                                                 отладчика Quick-C,
                                                 либо для символичес-
                                                 кого отладчика
                                                 Microsoft Code View.
                                                 Для использования
                                                 программы отладчиком
                                                 Quick-C, опция /Zi
                                                 должна быть задана
                                                 вместе с опциями /Zd
                                                 и /Zq.
/Zq                      Включение контрольной   Генерирует прерыва-
                         рамки Debug (8.1.4.3.)  ния, требуемые для
                                                 отладки Quick-C.
/Zr                      Включение контрольной   Производит проверку
                         рамки Pointer Check     на нулевые указате-
                         (проверка указателей)   ли, выходящие за до-
                         (8.1.4.4.)              пустимые пределы.
/Zs                      Включение кнопки        Только проверка син-
                         Syntax Check Only       таксиса программы.
                         (8.1.4.2.)              Объектный файл не
                                                 создается.

    Подробно действия данных опций описываются в Разделе 8.1.4.

                9.3.2. Опции, управляющие компановкой.

    Несколько опций QCL влияют  на процесс компановки, а  не компиляции.
Данные опции имеют  то же самое  действие, что и  запросы поля командной
строки  или  опции  команды  LINK.   В  Таблице  9.2  даны  опции   QCL,
соответствующие средствам команды LINK и их действию.

                                                 Таблица 9.2.

                           Опции QCL и LINK.

Опция QCL     Опция LINK     Действие

/F hexnum     /STACK:number  Устанавливает размер стека для программы
                             (смотрите Раздел 9.5.11).
/Fe[exefile]  Запрос Run     Именует выполняемый файл (смотрите Раз-
              File или поле  дел 9.4.2.2).
              exefile
/Fm[mapfile]  Запрос         Создает файл карты распределения памяти,
              List File или  содержащий описания, расположенных по
              опция /MAP     порядку программных сегментов (смотрите
                             Раздел 9.5.10). Опция /Fm позволяет вам,
                             по желанию, переименовать файл карты рас-
                             пределения памяти.

             9.3.3. Распечатка опций компилятора (/HELP).

    -Опция.

    /HELP
    /help

    Данная  опция  выводит  список  наиболее  часто  используемых  опций
компилятора.  Команда   QCL  обрабатывает   всю  информацию   в  строке,
содержащей опцию /help и высвечивает информацию о команде.

    Данная опция не чувствительна  к использованию больших и  малых букв
принимается любая комбинация букв верхнего и нижнего регистра. Например,
/HELP также является корректной формой данной опции.

             9.3.4. Задание имени объектного файла (/Fo).

    -Опция.

    /Foobjfile.

    Опция /Fo присваивает объектным  файлам различные имена, либо,  если
вы определите маршрут, создает их в другом каталоге.

    Применяя данную опцию, помните следующие правила:

    - Аргумент  objfile должен  стоять непостредственно  за опцией,  без
разделяющих пробелов.

    -  Каждая  опция  /Fo  применяется  к исходному файлу, следующему за
данной опцией в командной строке.

    Для файла  objfile вы  можете задать  любое имя  и любое расширение.
Однако, рекомендуется использовать  принятое расширение .OBJ,  поскольку
компановщик  и  программа  управления  библиотеками  LIB  при  обработке
объектных файлов пользуются стандартным расширением .OBJ.

    Если в  опции /Fo  вы не  задали полного  имени объектного файла (то
есть, если вы не задали имя объектного файла с базой и расширением, либо
вы задали имя маршрута без имени файла), программа QCL назовет объектный
файл соответственно следующим правилам:

    - Если вы задали имя объектного файла без расширения (как, например,
TEST), программа QCL автоматически добавит расширение .OBJ.

    - Если  вы задали  имя объектного  файла с  пустым расширением (как,
например TEST.), QCL оставит расширение пустым.

    - Если вы  зададите маршрут без  имени файла, QCL  создает объектный
файл   в   каталоге   с   данным   маршрутом,   дает   ему  базовое имя,
соответствующее  имени  первого  исходного  файла  в командной строке, и
прибавит расширение .OBJ.

    В данном случае, имя  маршрута должно заканчиваться обратным  слэшем
(\),  чтобы  программа  QCL  не  спутала  наименование маршрута с именем
файла.

    -Примеры:

    QCL /Fob:\OBJECT\ FILE1.C

    В примере,  приведенном выше,  компилируется исходный  файл FILE1.C;
результирующий   объектный   файл   именуется   FILE1.OBJ  (стандартно).
Спецификация каталога B:\OBJECT сообщает  QCL, что файл FILE1.OBJ  нужно
создать в каталоге \OBJECT на устройстве B.

    QCL /Fo\OBJECT\FILE1.C FILE2.C/Fo\SRC\NEWFILE3.OBJ FILE3.C

    В  приведенном  выше  примере,  первая  опция  /Fo просит компилятор
создать  в  каталоге  \OBJECT  объектные  файлы  FILE1.OBJ (получаемый в
результате  компиляции  FILE1.C)  и  FILE2.OBJ  (получаемой в результате
компиляции  FILE2.C).  Вторая   опция  /Fo  сообщает   компилятору,  что
объектный файл с именем NEWFILE3.OBJ (полученный в результате компиляции
FILE3.C) следует создать в каталоге \SRC.

                   9.3.5. Опции модели памяти (/A) и
                  операций с плавающей точкой (/FP).

    В команде QCL существуют две следующих важных опции:

    1. Модель памяти, используемая вашей программой.

    2. Способ,  каким ваша  программа обрабатывает  операции с плавающей
точкой.

    Модель памяти определяет правила, по которым компилятор формирует  в
памяти  программный  код  и  сегменты  данных.  QCL предлагает следующие
модели памяти, описанные в Таблице 9.3.

                                                 Таблица 9.3.

                            Модели памяти.

Опция CL  Модель памяти  Сегменты данных        Сегмент кода

/AS       малая          один                   один
/AM       средняя        один                   один сегмент кода
                                                для каждого модуля.
/AC      компактная    несколько сегментов дан- один
                       ных; элементы данных дол-
                       жны быть меньше, чем 64К
/AL      большая       несколько сегментов дан- один сегмент кода для
                       ных;элементы данных дол- модуля
                       жны быть меньше, чем 64К.

    ОБычно, модели памяти с  несколькими сегментами кода могут  давать в
результате программы большие, чем модели памяти с одним сегментом  кода;
а также модели  памяти с несколькими  сегментами данных могут  создавать
программы со значительно большим количеством данных, чем модели памяти с
одним сегментом данных. Однако, программы с несколькими сегментами  кода
или данных обычно  работают медленнее, чем  программы с одним  сегментом
кода или данных.

    По   умолчанию   компилятор   Microsoft   Quick-C   для    программ,
компилируемых в среде Quick-C, использует среднюю модель памяти, и малую
модель памяти, для программ, компилируемых с помощью команды QCL. (Более
подробную информацию  об использовании  и регулировании  моделей памяти,
смотрите в Приложении В "Работа с моделями памяти пакета Quick-C").

    Команда QCL имеет следующие  опции, позволяющие вам выбрать  способ,
каким  компилируемая  вами  программа  будет обрабатывать математические
операции с плавающей точкой:

Опция  Действие

/FPi   Обрабатывает операции с плавающей точкой  с помощью програм-
       ного обеспечения, эмулирующего работу математического сопро-
       цессора 8087 или 80287. Чтобы выполнять программы с данной оп-
       цией, вам не нуже реальный математический сопроцессор, хотя
       такая программа будет успешно работать и на системах с сопро-
       цессором.Данная опция стандартна.
/FPi87 Обрабатывает математические операции с плавающей точкой с по-
       мощью генерации инструкций для математического сопроцессора
       8087 или 80287. Использование данной опции сокращает размер
       программы, но программа всегда будет работать только на систе-
       мах, имеющих сопроцессор.

    Выбранные вами  опции операций  с плавающей  точкой и  модели памяти
определяют  автономную  библиотеку,  подсоединяемую  программой  QCL   к
создаваемому  объектному   файлу.  Если   вы  хотели   подвязать  даннюу
библиотеку в процесс компановки,  вам не нужно задавать  компановщику ее
имя. В Таблице  9.4 изображены все  комбинации модели и  соответствующие
этим комбинациям имена библиотек,  вставляемые командой QCL в  объектный
файл.

                                                 Таблица 9.4.

                  Опции QCL и стандартные библиотеки.

Опция операции с пла-  Опция модели памяти       Стандартная библио-
вающей точкой                                       тека

/FPi87                 /AS                       SLIBC7.LIB
                       /AM                       MLIBC7.LIB
                       /AC                       CLIBC7.LIB
                       /AL                       LLIBC7.LIB
/FPi                   /AS                       SLIBCE.LIB
                       /AM                       MLIBCE.LIB
                       /AC                       CLIBCE.LIB
                       /AL                       LLIBCE.LIB

                   9.3.6. Применение процессора 8086
                        или 808286 (/G0, /G2).

    -Опции:

/G0   Устанавливает набор инструкций для процессора 8086/8088 (стан-
      дартно).
/G2   Устанавливает набор инструкций для процессора 80286.

    Если вы пользуетесь микропроцессором 80286, вы можете указать  опцию
/G2-чтобы  установить  для  вашей  программы  набор 80286. По умолчанию,
компилятор   Microsoft   Quick-C   использует   набор   инструкций   для
микропроцессора  8086/8088.  Хотя  на  машине  с  микропроцессором 80286
желательно компилировать с опцией /G2, вам это не обязательно, поскольку
программы, скомпилированные с опцией /G2, не смогут работать на  машинах
с микропроцессорами  8088 или  8086. Однако,  программы, скопилированные
без опции /G2, либо программы, явно скомпилированые с опцией /G0,  могут
работать на машинах с микропроцессором 80286.

                   9.3.7. Управление препроцессором.

    Команда   QCL   имеет   несколько   опций   управляющих    действием
препроцессора  языка  СИ.  В  командной  строкЕ  вы  можете   определять
макрокоманды  и  символические  константы,  изменять  маршрут поиска для
включаемых  файлов,  либо  остановить  работу компиляции исходного файла
после стадии работы препроцессора для получения листинга препроцессора.

               9.3.7.1. Удаление определений стандартно
              предопределенных идентификаторов (/U, /u).

    -Опции

/U identifier Удаляет определение стандартно заданного идентификато-
              ра identifier.
/u            Удаляет определвние ВСЕХ стандартно заданных иденти-
              фикатор.

    Компилятор  Microsoft  Quick-C  определяет  четыре   идентификатора,
являющихся  полезными  при   написании  переносимых  программ.   Данными
идентификаторами следует пользоваться  для компиляции частей  программы,
зависящих  от  используемых  процессора,  операционной  системы,  модели
памяти. Стандартно определенные  идентификаторы и их  значения приведены
ниже:

Идентификатор          Функция

MSDOS                  Всегда определен. Идентифицирует операционную
                       систему, как DOS.
M_186                  Всегда определен. Идентифицирует машину, как
                       относящуюся к семейству микропроцессоров 8086.
M_186mM                Всегда определен. Идентифицирует модель памя-
                       ти, где m-это либо S (малая модель), C (ком-
                       пактная модель), M (средняя модель), L (боль-
                       шая модель). Использование моделей памяти под-
                       робно обсуждается в Приложении В "Работа с мо-
                       делями памяти пакета Quick-C".
NO_EXT_KEYS            Определяется, только если языковые расширения
                       не разрешены (то есть если программы компили-
                       руются с выключенной круглой кнопкой Language
                       Extensions, либо с опцией компилятора /Za.

    Опция  /U  (отменить  определение)  выключает  определение   данного
стандартно  заданного  идентификатора.  Опцию  /U  и параметр identifier
могут отделять один или более  пробелов. В одной командной строке  можно
задать более одной опции /U. Опция /u выключает все четыре определения.

    Удалить   определения   стандартных   идентификаторов   вам    может
понадобиться в следующих случаях:

    - Если вы  хотите задать в  командной строке более,  чем максимально
разрешенное  число  определений.  Если  языковые расширения отменены, вы
можете задать 16 определений, и 17 определений в противном случае.

    - Если вы хотите, чтобы в вашей программе стандартный  идентификатор
обозначал что-нибудь другое.

    Взамен каждого  удаленного стандартного  идентификатора вы  можете в
командной  строке  подставить  определение  своего собственного. Если вы
удалите определения всех четырех стандартных идентификаторов, вы  можете
определить до двадцати  определений командной строки.  Однако, поскольку
DOS ограничивает количество символов,  которые можно задать в  командной
строке, количество определений, которые  вы можете задать ,  на практике
значительно меньше, меньше 20.

    -Пример:

    QCL /UMSDOS /UM_186 WORK.C

    Данный пример удаляет определения двух стандартных  идентификаторов.
Заметим, что для выполнения этого опция /U должна быть задана дважды.

                 9.3.7.2. Вывод листинга препроцессора
                            (/P, /E, /EP).

    -Опции:

/P    Записывает вывод препроцессора в файл.
/E    Направляет вывод препроцессора в стандартный выходной поток;
      подключает директивы #line.
/EP   Записывает вывод препроцессора в файл и в стандартный выходной
      поток.

    Опции   /P,/E   и   /EP   выводят   листинг   файла  после обработки
препроцессором. Использование данных опций позволяет вам проверить вывод
препроцессора  языка   СИ.  Все   три  опции   подавляют  компиляию;  не
производится ни  объектного файла,  ни карты  распределения памяти, даже
если в командной строке QCL будут заданы опции /Fo или /Fm.

    Листинг препроцессора  идентичен оригинальному  исходному файлу,  за
исключением  того,  что  все  директивы препроцессора выполняются, также
расширяются все макрокоманды, а комментарии удаляются.

    В следующей Таблице вы увидите, как каждая из опций влияет на  вывод
препроцессора:

Опция  Вывод препроцессора

/P    Записывает вывод препроцессора в файл с тем же самым базовым
      именем, что и исходный файл, но с расширением .I.
/E    Копирует листинг препроцессора на стандартное выводное устройс-
      тво (обычно ваш терминал); для записи листинга в файл на диск
      вы можете использовать переадресацию DOS. Также данная опция
      помещает директивы #line в начало и конец каждого включаемого
      файла и вокруг строк, удаленных директивами препроцессора, за-
      дающими условную компиляцию. Данная опция бывает полезна, если
      вы перед компиляцией хотите промотреть листинг препроцессора.
      Директивы #line перенумеровывают строки файла, полученного пос-
      ле работы препроцессора, поэтому ошибки, сгенерированные на бо-
      лее поздних стадиях обработки, относятся к оригинальному исход-
      ному файлу, а не к файлу, полученному после обработки препроце-
      ссором.
/EP   Объединяет действие опций /E и /P: помещает листинг препроцес-
      сора в файл и копирует его на стандартное устройство вывода, но
      не добавляет директивы #line.

      -Примеры:

    QCL /P MAIN.C

    Данный пример создает листинг препроцессора MAIN.I и помещает в файл
на диске с исходным файлом MAIN.C.

    QCL /E ADD.C >PREADD.C

    Приведенная выше команда создает препроцессорный файл с  включенными
директивами #line из исходного файла ADD.C. Вывод переадресуется в  файл
PREADD.C.

    QCL /EP ADD.C

    Данная команда производит тот же самый препроцессорный вывод, что  и
во втором примере, но без директив #line. Вывод появляется на экране.

                9.3.7.3. Соxранение комментариев (/C).

    -Опция:

    /C

    Опция /C  ("комментарий") сохраняет  комментарии во  время обработки
файла препроцессором.

    Если данная опция не задана, препроцессор "вырезает" комментарии  из
исходного  файла,   поскольку  они   не  нужны   на  позднейших  стадиях
компиляции.

    Данная опция действует  только, если одновременно  используется одна
из опций /E,/P, или /EP.

    -Пример:

    QCL /P /C SAMPLE.C

    Данный  пример  производит  листинг  с именем SAMPLE.I. Файл-листинг
содержит  оригинальный  исходный  файл,  включая  комментарии,  со всеми
директивами препроцессора, расширенными, либо замененными.

                9.3.7.4. Поиск включаемых файлов (/X).

    -Опция:

    /X

    Опция /X просит компилятор не искать включаемые файлы в "стандартных
местах", определяемых переменной операционной среды DOS INCLUDE.

    Данная опция  позволяет вам  изменить порядок,  в котором компилятор
ищет включаемые файлы без изменения среды компилятора, используемой вами
обычно.

    Опция  /X  часто  используется  обычно  вместе  с опцией /I, которая
сообщает  компилятору,  где,  если   не  в  стандарных  местах,   искать
включаемые   файлы.   Информацию   о   задании   каталогов,  отличных от
стандартных мест, в которых  обычно находятся включаемые файлы,  ищите в
Разделе  8.1.4.1,  "Подавление  сообщений  компилятора:  Опции   уровней
предупреждений" и Разделе 9.3.1, "Опции программной среды".

    -Пример:

    QCL /X MAIN.C

    В  приведенном  выше  примере  компилятор  ищет подключаемые файлы в
текущем рабочем каталоге, поскольку опция /X сообщает программе QCL, что
список обычных стандартных мест пуст.

                9.3.8. Подготовка к отладке (/Zi, /Zd).

    -Опции:

/Zi Создание объектного файла для отладки в программной  среде/отла-
    дчик Code View.
/Zd Создание объектного файла с  ограниченной отладочной
    информаци- ей.

    Опция  /Zi  производит  объектный  файл,  содержищий  информацию для
отладки в символических адресах-для использования встроенным  отладчиком
в программной  среде Quick-C,  либо символическим  отладчиком Code View.
Данный объектный  файл содержит  полную таблицу  символических адресов и
номера строк.

    Опция  /Zd  производит  объектный  файл,  содержащий  номера  строк,
соответствующие номерам строк исходного  файла. Опция /Zd полезна  в тех
случаях, когда вы хотите уменьшить размер выполняемого файла, который вы
будете  отлаживать  с  помощью  отладчика  Code  View,  и вам в процессе
отладки не понадобится использовать вычисление выражений.

    -Пример:

    QCL /Zi TEST.C

    Данная команда производит объектный файл с именем TEST.OBJ,  который
содержит номера строк, соответствующие номером строк файла TEST.C.

                9.3.9. Упаковка членов структуры (/Zp).

    -Опции:

    /Zp[{1|2|4}]
    #pragma pack ([{1|2|4}])

    При размещении  структуры в  памяти, члены  структур обычно зранятся
следующим образом:

    - Элементы  типа char  или unsigned  char, либо  массивы, содержащие
элементы данных типов, выравниваются на границу байта.

    -  Структуры  выравниваются  на  границу  слова; структуры нечетного
размера дополняются до четного количества байтов.

    - Все остальные типы членов структур выравнивабтся на границу слова.

    Для экономии памяти вам  может понадобиться хранить структуры  более
или менее стандартно. Опция /Zp  и директива pragma pack управляют  тем,
как данные структуры "упаковываются" в памяти. Заметим, что на некоторых
процессорах, опции  /Zp может  замедлить выполнение  программ, поскольку
требуется время при доступе к структурам для их распаковки.Например,  на
микропроцессоре  8086  данная  опция  может  снизить эффективность, если
члены структур типов int или long упаковываются таким способом, что  они
начинаются на границе нечетного байта.

    Пользуйтесь опцией  /Zp, чтобы  определить аналогичную  упаковку для
всех структур в модуле. Если вы зададите опцию /Zp[n], где n-это 1,2 или
4, каждый член структуры после первого хранится на границе n-ого байта в
зависимости от выбранной вами опции.  Если вы используете опцию /Zp  без
аргумента, члены структур упаковываются на 1-байтовой границе.

    Используйте  директиву  pragma  pack,  если  вы  хотите   определить
упаковку  иную,  чем  упаковка,  определенная  в  командной  строке  для
определенных  структур.  Задайте  pragma  pack(n)  где n-это 1,2, или 4,
перед  описанием  структур,   которые  вы  хотите   упаковать  различным
способом.  Чтобы  восстановить  упаковку,  заданную  в командной строке,
задайте pragma pack() без аргументов.

    Таблица 9.5  показывает взаимодействиеопции  /Zp и  директивы pragma
pack. Таблица 9.5.

                 Использование директивы pragma pack.

Синтаксис              Компиляция с опцией /Zp   Действие

#pragma pack()         да                        Возвращает к упаков-
                                                 ке заданной в коман
                                                 дной строке для сле-
                                                 дующих за ней струк-
                                                 тур.
#pragma pack()         нет                       Возвращает к стандар
                                                 тной упаковке для
                                                 структур, следующих
                                                 за ней.
#pragma pack(n)        да или нет                Упаковывает следую-
                                                 щие далее структуры
                                                 по заданной байтовой
                                                 границе до тех пор,
                                                 пока не будет изме-
                                                 нений или выключе-
                                                 ний.

    -Пример:

    QCL /Zp PROG.C

    По данной команде все  структуры в программе PROG.C  будут храниться
без дополнительного места для выравнивания ее членов по границе int.

        9.3.10. Подавление выбора стандартной библиотеки (/Zl).

    -Опция:

    /Zl

    Обычно,  программа  QCL  помещает  в  объектный файл имя стандартной
библиотеки  SLIBCE.LIB.  Данный  механизм  позволяет  редактору   связей
автоматически  находить  соответствующую  библиотеку  и подвязывать ее к
объектному файлу.При заданной опции  /Zl компилятор не будет  помещать в
объектный файл имя стандартной библиотеки. В результате, объектный  файл
будет значительно меньше.

    Опция  /Zl  бывает  полезна,   когда  вы  используете  утилиту   LIB
(описанную в Разделе 10.2) для построения автономной библиотеки.

    Вы  можете  скомпилировать   объектные  файлы,  помещаемые   вами  в
библиотеку, с опцией /Zl, для того, чтобы удалить имена библиотек  перед
их объединением.  Кроме того,  опция /Zl  сэкономит небольшое количество
памяти  для  каждого  объектного  файла,  значительно большое количество
памяти  будет  сэкономлено  в  библиотеке,  содержащей  много  объектных
модулей.

    -Пример:

    QCL ONE.C /Zl TWO.C

    Пример, приведенный выше создает следующие два объектных файла:

    - Объектный файл ONE.OBJ, содержащий имя СИ-библиотеки SLIBCE.LIB.

    - Объектный  файл TWOO.OBJ,  не содержащий  стандартной информации о
библиотеках.

    При компановке  файлов ONE.OBJ  и TWO.OBJ,  информация о стандартной
библиотеке в файле ONE.OBJ приведет к тому, что данная библиотека  будет
использована для разрешения любый  внешних ссылок в файле  ONE.OBJ, либо
TWO.OBJ.

            9.3.11. Управление соглашениями о связях (/Gc).

    -Опция:

      /Gc
      fortran
      pascal
      cdecl

    Ключевые слова fortran, pascal, cdecl вместе с опцией /Gc  управляют
соглашениями  о  вызове  и  наименовании  функций,  используемые  вашими
программами  для  того,  чтобы  они  могли  вызывать или могли сами быть
вызваны  функциями,  написанными  на  языке  Pascal,  FORTRAN,  BASIC  с
использование средств фирмы Microsoft.

                   9.3.12. Установка границы данных.

    -Опция:

    /Gt[number]

    При использовании  опции /Gt,  все элементы  данных, размер  которых
больше  или  равен  number  байтов,  будут  размещаться в новом сегменте
данных. Если число number  задано, оно должно непосредственно  следовать
за опцией /GT,  без каких-либо разделяющих  пробелов. Если число  number
опущено, стандартное  пороговое значение  256. Если  опция /Gt  опущена,
стандартное пороговое значение 32767.

---------------------------------------------------------------------

    Примечание:

    Опцию /Gt можно использовать  только для программы, разработанной  в
компактной или большой  модели памяти, поскольку  программы в малой  или
средней модели памяти имеют только один сегмент данных.

---------------------------------------------------------------------

                   9.3.13. Оптимизация циклов (/Ol).

    -Опция:

    /Ol

    Опция /Ol требует компилятор  выполнять оптимизацию по циклам.  Если
вы  выберете  данную  опцию,  компилятор  автоматически  поместит  часто
используемые  переменные  цикла  в  регистры,  для  того. чтобы ускорить
выполнение программы.

    Данная  опция  будет  неявно  включена,  если вы будете использовать
опцию /Ox (максимально возможная оптимизация).

               9.4. Раздельная компиляция и компановка:
                          Команды QCL и LINK.

    С  помощью  компилятора  Microsoft  Quick-C  вы  можете осуществлять
компановку несколькими различными способами. Данные методы описываются в
Разделах 9.4.1-9.4.2. Для каждого из методов вы задаете редактору связей
следующую информацию:

    - Объектные файлы, которые вы компануете.

    - Имена библиотек, которые  вы подвязываете, если они  отличаются от
стандартных.

    - Имя  выполняемого файла,  если вы  хотите переименовать  его, либо
использовать расширение, отличное от .EXE.

    - Наименование файла карты распределения памяти, если вы хотите  его
создать.

    -  Опции  компановщика,  если  они  имеются,  управляющие  процессом
компановки.

    Для того, чтобы осуществлять компиляцию в и компановку два отдельных
шага,  используйте  команду  QCL  для  компиляции  исходных  файлов  без
компановки  результирующих  объектных  файлов.  В  командной  строке QCL
задайте опцию /c и имена исходных файлов.. Затем скомпануйте в отдельном
шаге  результирующие  объектные  файлы  с соответствующими библиотеками,
применив нужные опции редактирования связей.

               9.4.1. Компановка с помощью команды QCL.

    Для компановки  с использованием  команды QCL  используйте следующий
синтаксис:

    QCL[option...]objfile...[lib...]/link link-option...lib...

    Как описано в Разделе 9.2,  команда QCL, если вы в  командной строке
задайте только  имена объектных  файлов, пропустит  компиляцию и вызовет
компановщик. Команда QCL  передаст компановщику имена  объектных файлов,
имена библиотек и опции компановщика.

               9.4.2. Компановка с помощью команды LINK.

    Если  вы  осуществляете  компановку  отдельным  шагом,  альтенативой
использования   команды    QCL   является    вызов   редактора    связей
непосредственно  командой  LINK.  Это  можно  сделать  после  компиляции
посредством команды QCL с опцией /c.

    Для  компановки  посредством  команды  LINK,  операционная среда DOS
должна быть установлена так, как описано ниже. Полное описание  смотрите
в Разделе 1.3.1.6 (для пользователей жесткого диска) или Раздел  1.3.2.4
(для пользователей гибких дисков.).

    -  Если  вы  запускаете  команду  LINK  на системе с жестким диском,
воспользуйтесь  командой  DOS  CD  для  того,  чтобы  сделать  каталог с
объектными файлами, предназначенными для компановки, текущей.

    - Если вы работаете с программой LINK на системе с гибкими  дисками,
диск,  содержащий  ваши  объектные  файлы,  должен  быть  устиновлен   в
дисководе B, а рабочая копия вашего дистрибутивного диска в дисководе A.
Сделайте дисковод B текущим. Когда вы запускаете программу LINK, введите
спецификацию  дисковода  А:  непосредственно  перед  командой  LINK  без
каких-либо промежуточных пробелов. Во время процесса компановки  система
будет предупреждать  вас о  замене в  дисководе A  рабочей копии  вашего
дистрибутивного  диска  на  диск,  содержащий соответствующую автономную
библиотеку.

    Вход  для  программы  LINK  вы  можете  задать  одним  из  следующих
способов:

Метод                  Инструкции

Задание входной инфор- Используйте командную строку в следующей фор-
мации в командной      ме:
строке.                LINK objfile[,[exefile] [,[mapfile][,[lib]...
                       ]]][link-opt]...[;]
                       Командная строка не может быть длиннее 128 сим
                       волов.
Ответ на запросы       Введите:
                       LINK
                       и ответьте на следующие запросы:
                       Object Modules [.OBJ]: -объектные модули
                       Run File [basename.EXE]: -исполняемые файлы
                       List File [NUL.MAP]: -листинг памяти
                       Libraries [.LIB]: -библиотеки
                       Чтобы задать больше файлов для одного запроса,
                       введите в конце строки знак +. Запрос снова
                       появится на следующей строке и вы можете про-
                       должить ввод для следующего запроса.
Создание файла         Создайте файл с ответами на запросы команды
ответов                LINK, известный под названием "файл ответов",
                       затем введите команду LINK в следующей форме:
                       LINK @ filename  , где
                       filename-это имя файла ответов. К любому отве-
                       ту вы можете добавить опции компановщика, либо
                       задать их в одной или более отдельных стро-
                       ках. Ответы вы должны задавать в том же поря-
                       дке,что и запросы LINK, описанные выше. Вы мо-
                       жете также ввести наименование файла ответов
                       после любого запроса компановщика, либо в лю-
                       бой позиции командной строки LINK.

    В Таблице  9.6 приведены  примеры входной  информации, задаваемой  в
командной строке LINK, либо ответы на запросы команды LINK.

                                                 Таблица 9.6.

                 Входная информация для команды LINK.

Поле     Запрос        Входная информация

objfile  Object        Один или более объектных файлов, которые вы
         Modules       связываете, отделяются знаком плюс или пробе-
                       лами. В данном поле вы также можете определить
                       библиотеки; в данном случае, все объектные мо-
                       дули в библиотеке связываются с остальными
                       объектными модулями, заданными в данном поле.
exefile Run File       Имя создаваемого вами выполняемого файла, если
                       вы хотите дать ему имя или расширение, отлич-
                       ное от стандартного. Вам всегда следует исполь-
                       зовать файлы, имеющие данное расширение.
mapfile  List File     Имя файла, содержащее листинг символических
                       адресов (карту распределения памяти), если вы
                       ее используете. Кроме того, вы можете задать
                       одно из следующих адресов устройств, поддержи-
                       ваемых DOS-для того, чтобы направить данный
                       файл на  одно из этих устройств: AUX-для до-
                       полнительного устройтсва, CON для консоли (те-
                       рминала), PRN для принтера, NUL (нет устройст-
                       ва), то есть файл карты не создается. В Раз-
                       деле 9.5.10. приведен пример карты распределе-
                       ния памяти и дается информация о ее содержа-
                       нии. (Файл карты вы можете создать с помощью
                       опции команды QCL/Fm (Раздел 9.3.2), либо с
                       помощью опции /MAP команды LINK.
lib       Libraries    Одна или более автономных библиотек, либо ка-
                       талогов, в которых будут искаться автономные
                       библиотеки, отделенные друг от друга знаками
                       плюс или пробелами. Вы можете задать до 32 биб-
                       лиотек в ответе на запрос о библиотеках; все
                       остальные дополнительные библиотеки игнориру-
                       ются. В Разделе 9.4.2.3 заданы правила для за-
                       дания имен библиотек при компановке.
link-opt  Задавайте    Любые из опций компановщика, описанные в Раз-
         опции после   лах 9.5.1-9.5.14. Опции можно задать в любом
         любого отве-  месте командной строки.

          9.4.2.1. Стандартная информация для программы LINK.

    Стандартную информацию для команды  LINK вы можете выбрать  одним из
следующих способов:

Тип стандартной        Как выбрать
информации

Командная строка       Опустите имя файла либо имена перед местами
                       для входной информации и введите только тре-
                       буемые запятые. Исключение составляет только
                       стандарт для входной информации mapfile: если
                       вы поставите вместо входной информации запя-
                       тую, команда LINK наоборот создает файл карты
                       распределения памяти.
Запрос                 Просто нажмите ENTER.
Вся оставшаяся вход-   Введите точку с запятой после
соответствующего
ная информация         входа, либо запроса. (Заметьте, что вам нужно
                       задать по крайней мере имя одного объектного
                       файла.)

    В следующей Таблице показаны стандарты имен, которые программа  LINK
использует для  выполняемых файлов,  файлов карт  распределения памяти и
библиотек:

Тип файла              Стандарт

Выполняемый            Дается базовое имя первого объектного файла
                       плюс расширение .EXE. Чтобы переименовать вы-
                       полняемый файл, задайте только новое базовое
                       имя; если вы зададите имя файла без расшире-
                       ния, программа LINK автоматически добавит рас-
                       ширение .EXE.
Файл распределения     Специальный файл с именем NUL.MAP, который со-
памяти                 общает команде LINK, что файл распределения
                       памяти создавать не нужно. Для создания файла
                       распределения памяти задайте только базовое
                       имя; если вы зададите имя файла без расшире-
                       ния, программа LINK автоматически добавит рас-
                       ширение .MAP.
Библиотеки             Имена библиотек задаются в объектных файлах.
                       Имена библиотек, помещаемые в объектные файлы,
                       зависят от опций плавающей точки и модели па-
                       мяти, заданных при компиляции исходных файлов;
                       список стандартных имен библиотек приведен в
                       Таблице 9.4. Если вы хотите определить имя
                       библиотеки, отличное от стандартного, задайте
                       только базовое имя; если вы зададите имя биб-
                       лиотеки без расширения, программа LINK автома-
                       тически добавит расширение .LIB. В Разделе
                       9.4.2.3 вы найдете подробную информацию об оп-
                       ределении библиотек, отличных от стандартных.

    -Примеры:

    STDEV SQROOT EXP
    /PAUSE /MAP
    STDVLST
    MATHFN.LIB

    Данный файл ответов сообщает  программе LINK, что следует  загрузить
три объектных модуля STDEV, SQROOT и EXP. Будут созданы выполняемый файл
STDEV.EXE  и  файл  карты  STDVLST.MAP.  Опция  /PAUSE  указывает,   что
программа LINK должна прервать работу перед созданием выполняемого файла
для того, чтобы вы могли, если необходимо, сменить гибкий диск.

    Опция  /MAP  сообщает  компановщику,  что  следует  включить  в файл
распределения памяти внешние символические  имена и адреса типа  PUBLIC.
Кроме того, программа LINK подвязывает из библиотечного файла MATHFN.LIB
все требуемые  процедуры. Опция  /PAUSE подробно  описывается в  Разделе
9.5.2, а опция /MAP в Разделе 9.5.10.

    LINK STDEV+SQROOT+EXP, ,STDVLIST, MATHFN.LIB

    В  приведенном  выше  примере  программа  LINK загружает и связывает
объектные модули STDEV.OBJ,  SQROOT.OBJ и EXP.OBJ,  причем неразрешенные
ссылки ищет в библиотечном  файле MATHFN.LIB. По умолчанию,  выполняемый
файл получит  имя STDEV.EXE.  Будет создан  файл распределения  памяти с
именем STDVLIST.MAP.

    LINK.
    Object Modules [.OBJ]: STDEV SQROOT EXP INP+
    Object Modules [.OBJ]: READDATA+GRAPH+PRINT+
    Object Modules [.OBJ]: REPORT
    Run File [STDEV.EXE]: ;

    Данный пример показывает, как  продолжить любое сообщение с  помощью
ввода в конце ответа плюса (+). В данном примере связываются все  данные
объектные  файлы  и  создается  выполняемый  файл.  Поскольку в качестве
ответа  на  запрос  Run  File  была  введена  просто  точка  с  запятой,
выполняемому  файлу  будет  присвоено  по  умолчанию базовое имя первого
объектного  файла  (STDEV)  плюс  расширение  .EXE. Стандартные значения
используются также и для  остальных запросов: то есть  файл распеделения
памяти  не  создается,  и  для  компановки будут взяты стандартные имена
библиотек в объектных файлах.

              9.4.2.2. Задание файлов для программы LINK.

    Большинство правил для задания имен файлов программе LINK  совпадают
с  правилами  задания  имен  файлов  для  QCL:  буква верхнего и нижнего
регистра  могут  быть  использованы  попеременно,  имена  файлов   могут
содержать полное имя маршрута,  чтобы указать компановщику, где  искать,
либо где создать данные файлы. Тем не менее, команда LINK не  распознает
в именах файлов символы-шаблоны.

            9.4.2.3. Задание библиотек для программы LINK.

    Обычно,   задавать   компановщику   имя   автономной   библиотеки не
требуется. Когда  команда QCL  создает объектные  файлы, она  помещает в
каждый объектный  файл имя  подходящей для  него автономной  библиотеки.
QCL определяет имя соответствующей библиотеки по опциям модели памяти  и
плавающей точки, заданных в командной строке QCL, как описано в  Таблице
9.4 (Раздел 9.3.5). Как  только объектный файл передается  компановщику,
компановщик ищет библиотеку с  именем, совпадающим с именем  в объектном
файле, и автоматически  связывает ее с  объектным файлом. Чтобы  связать
объектные файлы  с библиотеками,  отличными от  стандартных, вам следует
сообщать  компановщику,  какие  библиотки  вы  хотите  подвязать.  Имена
библиотек вы можете задать в любом из следующих мест:

    - В командной  строке QCL. Имена  библиотек, стоящие перед  ключевым
словом  /link  должны  иметь  расширения  .LIB; имена библиотек, стоящие
после /link могут совсем не иметь расширений.

    - В четвертом поле командной строки LINK.

    - В ответе на запрос Libraries команды LINK.

    Для разрешения внешних ссылок компановщик сначала ищет заданные вами
библиотеки, а затем стандартные библиотеки.

    Вам может понадобиться подвязать автономную библиотеку, отличную  от
стандартной в следующих случаях:

    -  Если  вы  хотите  подвязать дополнительные автономные библиотеки.
Например,  если  вы  не  включили  при  построении  библиотек  с помощью
программы  SETUP  графические  функции,  вам следует связать графические
программы   с   автономной   графической   библиотекой   GRAPHICS.LIB, в
дополнение к стандартным библиотекам.

    -  Вам  требуется   подвязать  библиотеки,  находящиеся   по  разным
маршрутам.  Если  вы  зададите  для  библиотеки  полное  имя   маршрута,
компановщик  будет  искать  библиотеку  только  по  данному  маршруту. В
противном  случае,  компановщик  ищет  библиотеку  в  других  местах   в
следующем порядке:

    1. Текущий рабочий каталог.

    2. Любые маршруты или  дисководы, которые вы задаете,  когда обычным
способом задаете  имена библиотек.  Данные маршруты  или дисководы могут
быть заданы после опции /link  в командной строке QCL, либо  в четвертом
поле командной строки  LINK, либо в  ответе на запрос  Libraries команды
LINK.

    3. Местоположение, заданное переменной программной среды LIB.

    - Вы хотите проигнорировать библиотеку, названную в объектном файле;
например, если вы хотите  подвязать отдельные библиотеки, как  описано в
Разделе 1.4.  В данном  случае вам  в дополнение  к заданной библиотеки,
которую вы хотите  использовать для компановки,  следует задать и  опцию
компановщика /NOD. Подробности об использовании опции /NOD вы найдете  в
Разделе 9.5.7.

    -Пример:

    QCL STDEV SQROTT EXP /link C:\TESTLIB\NEWLIBV3

    Данный   пример   связывает   три   объектных   модуля  для создания
результирующего выполняемого файла STDEV.EXE. Перед поиском  стандартных
библиотек  для  разрешения  внешних  ссылок,  компановщик ищет, в первую
очередь   NEWLIBV3.LIB.   Чтобы   обнаружить   местоположение библиотеки
NEWLIBV3.LIB, компановщик сначала просматривает текущий рабочий каталог,
затем каталог C:\TESTLIB\, и, наконец, по маршрутам, заданным переменной
программной среды LIB.

             9.4.2.4. Требования к памяти программы LINK.

    Для сеанса редактирования связей программа LINK использует доступную
память. Если файлы, связываемые для создания выходного файла,  превышает
имеющуюся оперативную  память, программа  LINK создает  временный файл в
каталоге,  заданном  с  помощью  переменной  среды  TMP.  Например, если
переменная TMP установлена, как  C:\TEMPDIR, то программа LINK  помещает
временный  файл  в  каталог  C:\TEMPDIR.  Если  переменная  среды TMP не
задана,  либо,  если  каталог,  заданный  с  помощью  переменной  TMP не
существует, программа  LINK поместит  временный файл  в текущий  рабочий
каталог.

    В зависимости  от версии  операционной системы  DOS, временный  файл
обрабатывается одним из следующих способов:

    1.При  запуске  операционной  системы  DOS  версии  3.0  или   выше,
программа LINK  использует системный  вызов DOS  для создания временного
файла с уникальным именем.

    2.При работе с помощью версии  DOS ниже 3.0, программа LINK  создает
временный файл с именем VM.TMP.

    При создании временного файла программа LINK выводит сообщение:

    Temporary file tempfile has been created
    Do not change diskette in drive letter,

    где tempfile-это  ".\", за  которым следует  либо VM.TMP,  либо имя,
сгенерированное системой DOS,  а letter-это спецификация  устройства, на
котором создан временный файл.

    Если  устройство  со  спецификацией  letter  является дисководом для
гибких дисков, появится также сообщение "Do not change diskette in drive
letter." Если оно появилось, не вынимайте дискету из данного устройства,
пока не окончится сеанс редактирования связей.

    Если   вы   вынете   дискету,   действия   компановщика   могут быть
непредсказуемыми, и вы можете увидеть следующее сообщение:

    L1087: unexpected end-of-file on scratch file

    (Неожиданный конец удаляемого файла)

    Если  вы  увидите  такое  сообщение  ,стартуйте  компановщик заново.
Временный  файл,  создаваемый  программой  LINK-это только рабочий файл.
LINK удаляет его в конце сеанса работы.

                9.5. Использование опций компановщика.

    Все  опции  компановщика  начинаются  со  знака  опции (/). В опциях
компановщика буквенный  регистр не  играет существенной  роли; например,
/NOI и /noi эквивалентны.

    Чтобы сократить место и  вашу работу сокращайте опции  компановщика.
Однако,  удостоверьтесь,  что  ваше  сокращение уникально, и компановщик
сможет  распознать,  какую  опцию   вы  имеете  в  виду.    (Минимальная
аббревиатура  каждой  опции  определяется  ее  синтаксисом).   Например,
некоторые опции начинаются с  буквенного сочетания "NO"; таким  образом,
чтобы быть  уникальной, аббревиатура  данной опции  должна быть длиннее,
чем   "NO".   Вам   нельзя   использовать   сокращение   "NO"  для опции
"/NOIGNORECASE",  поскольку  компилятор  не  сможет распознать, какую из
опций, начинающихся  на "NO",  вы имеете  в виду.  Кратчайшая корректная
аббревиатура для данной опции будет "/NOI".

    Аббревиатура  должна  начинаться  с  первой  буквы  опции  и  должна
продолжаться до последней введенной буквы. Никакие искажения и  пропуски
не допускаются.

    Некоторые из опций  компановщика имеют числовые  аргументы. Числовой
аргумент может быть одним из следующих:

    - Десятичное число в пределах от 0 до 65535 (обратите внимание,  что
запятые не должны стоять в числовых аргументах.)

    - Восьмеричное число  от 0 до  0177777. Число интерпретируется,  как
восьмеричное,  если  оно  начинается  с  "0".  Например,  число   10-это
десятичное число, а 010-восьмеричное число, эквивалентное 8 в десятичной
системе.

    -  Шестнадцатеричное  число  в  пределах  от  0  до  0хFFFF.   Число
интерпретируется, как шестнадцатиричное, если оно начинается с "0x"  или
"0X".  Например,  0x10-это  шестнадцатиричное  число, эквивалентное 16 в
десятичной системе.

    Опции компановщика  оказывают влияние  на все  файлы, участвующие  в
процессе редактирования, связей независимо от того, где они заданы.

                  9.5.1. Просмотр списка опций (/HE).

    -Опция

    /HE[LP]

    Опция /HE используется для высвечивания списка всех возможных  опций
компановщика.

         9.5.2. Останов (пауза) в процессе компановки (/PAU).

    -Опция

    /PAU[SE]

    Опция /PAU вынуждает  компановщик остановить работу  перед созданием
на диске выполняемого файла (.EXE) и высветить сообщение. Это  позволяет
вам установить новую дискету,  чтобы записать выполняемый файл.  Если вы
зададите  опцию  /PAU,  программа  LINK  перед созданием выходного файла
высветит следующее сообщение:

    About to generate .EXE file
    Change diskette in drive "letter" and press
    ("Предстоит генерация файла .EXE

    Смените дискету в дисководе letter и нажмите ".)   Letter-это
спецификация текущего  дисковода. Программа  LINK продолжит  выполнение,
после того, как вы нажмете клавишу ENTER.

---------------------------------------------------------------------

    Примечание:

    Не   удаляйте   диск,   содержащий   заново   созданный   файл карты
распределения памяти, либо диск, используемый для временного файла. Если
временный  файл  создается  на  диске,  который  вы  планируете сменить,
нажмите  CTRL+C,  чтобы  закончить  сеанс компановки. Реорганизуйте свои
файлы таким образом, чтобы временный файл и выполняемый файл могли  быть
записаны на один и тот же диск. Затем возобновите процесс компановки.

---------------------------------------------------------------------

              9.5.3. Высвечивание информации, освещающей
                       процесс компановки (/I).

    -Опция

    /I[NFORMATION]

    Данная опция может быть для вас полезной, если вы хотите  определить
местополежение связываемых  объектных файлов  и порядок,  в котором  они
компануются.  По  данной  опции  высвечивается  информация  о   процессе
компановки, включая каждую фазу компановки и имена связываемых объектных
файлов.

    -Пример:

    **** PASS ONE ****
    NTOI.OBJ(htoi.c)
    **** LIBRARY SEARCH ****
    c:\lib\MLIBCE.LIB(chkstk)
    c:\lib\MLIBCE.LIB(crto)
    c:\lib\MLIBCE.LIB(printf)

    c:\libMLIBCE.LIB(scanf)
    .
    .
    .
    **** ASSIGN ADDRESSES ****
    **** PASS TWO ****
    HTOI.OBJ(htoi.c)
    c:\lib\MLIBCE.LIB(chkstk)
    c:\lib\MLIBCE.LIB(crto)
    c:\lib\MLIBCE.LIB(printf)
    c:\lib\MLIBCE.LIB(scanf)
    .
    .
    .
    **** WRITING EXECUTABLE ****
    Segments 25
    Groups 1
    Bytes in symbol table 16400

    Приведенный  выше  пример  показывает  сеанс работы компановщика при
заданной опции /I.

              9.5.4. Запрет на запросы компановщика (/B).

    -Опция:

    /B[ATCH]

    Опция  /B  запрещает  компановщику  запрашивать у пользователя новый
маршрут, если  он не  может найти  требуемую библиотеку,  либо требуемые
объектные файлы.

    Если  используется  данная  опция,  компановщик  просто   продолжает
выполнение без запрашиваемого файла.

    Использование  опции  /B  может  привести  к  неразрешенным  внешним
ссылкам.  Данную  опцию  следует  использовать,  в  основном,  тем,  кто
использует пакетную обработку, либо утилиту MAKE, связывает много файлов
в одной команде,  и не хочет  прерывать процесс компановки  из-за одного
ненайденного файла.

    Данная  опция,   однако,  не   запрещает  компановщику   запрашивать
аргументы, не заданные в командной строке LINK.

                 9.5.5. Создание библиотек Quick (/Q).

    -Опция:

    /Q[UICKLIB]

    Опция  /Q  сообщает  компилятору,  что  следует  объединить заданные
объектные файлы и библиотеки в библиотеку Quick. Библиотеки Quick  имеют
расширение .QLB, а не .EXE,  для того, чтобы отличить их  от выполняемых
файлов. Когда  вы стартуете  Quick-C, в  командной строке  QC вы  можете
задать опцию /l и загрузить таким образом библиотеку Quick.

    При создании  библиотеки Quick  имя файла  QUICKLIB.OBJ должно  быть
первым  в  списке  имен  объектных  файлов  для  компановки.   Подробную
информацию о создании и загрузке  библиотек Quick вы найдете в  Главе 10
"Создание библиотек Quick и автономных библиотек".

               9.5.6. Упаковка выполняемых файлов (/E).

    -Опция:

    /E[XEPACK]

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

    Выполняемые файлы, скомпакнованные с данной опцией могут быть меньше
и загружаться быстрее, чем  файлы, полученные без данной  опции. Однако,
вы  не  сможете  отлаживать  упакованные  программы с помощью отладчика,
встроенного в  программую среду  Quick-C, либо  с помощью  многооконного
отладчика Microsoft Code View.

          9.5.7. Игнорирование стандартных библиотек (/NOD).

    -Опция:

    /NOD[EFAULTLIBRARYSEARCH]

    Опция  /NOD  требует,  чтобы  компановщик  не  искал  для разрешения
внешних ссылок ни одной библиотеки, заданной в объектном файле.

    Обычно, программа Quick-C не могут работать корректно без автономных
библиотек, построенных  с помощью  программы SETUP.  Таким образом,  при
использовании  опции  /NOD,  вам  следует  явно  задать  имя   требуемой
автономной библиотеки.

         9.5.8. Установка максимального числа сегментов (/SE).

    -Опция:

    /SE[GMENTS]:number

    Опция /SE управляет числом сегментов, которые компановщик  позволяет
иметь программе.  Стандартное число  сементов 128,  но вы  можете задать
свое  число  number  (десятичное,  восьмеричное,  шестнадцатеричное)   в
пределах от 1 до 3,72. Для каждого сегмента компановщик должен  выделить
место  для  хранения  сегментной  информации.  Если  вы  зададите  число
сегментов,  большее   128,  компановщик,   соответсвенно,  отведет   для
сегментной информации больше места. Для программ с количеством сегментов
меньшим,  чем  128,  вы  можете  уменьшить  количество памяти, требуемое
компановшику,  задав  число  number,  равное  действительному количеству
сегментов в  программе. Компановщик  высветит сообщение  об ошибке, если
данное число слишком велико для памяти, предоставленной компановщику.

               9.5.9. Установка максимального количества
                        отводимой памяти (/CP).

    -Опция:

    /CP[ARMAXALLOC]:number

    Опция /CP установливает  максимальное число 16-байтовых  параграфов,
требуемых  для  программы  при  загрузке  в  оперативную  память, равным
number-целое  число   в  пределах   от  1-65535.   Операционная  система
использует  данное  значение  для  распределения  памяти  при   загрузке
программы. Стартовый  модуль Microsoft-C  усекает память  соответственно
большему из следующих двух значений:

    - 64К

    - Количествопамяти, заданное с помощью опции /CP.

    Для  программ  с  ограниченным  количеством  данных  типа  static  и
динамическим   распределением   памяти,   данная   опция   не   является
необходимой.

              9.5.10. Создание файла карты распределения
                           памяти (/M, /LI).

    -Опция:

    /M[AP][:number]

    /LI[NENUMBERS]

    Опции  /M  и  /LI  создают  файл  карты  распределения  памяти. Файл
распределения памяти  содержит список  сегментов программы  в порядке их
появления в загруженном модуле. Пример такого файла приведен ниже:

Start   Stop   Length Name               Class
00000H  01E9FH 01EAOH  TEXT              CODE
01EAOH  01EAOH 00000H C ETEXT            ENDCODE

.
.
.

    Информация  в  колонках  Start  и  Stop-это  20-разрядный  адрес  (в
шестнадцатеричной   системе)   каждого   сегмента   относительно  начала
загрузочного модуля. Загрузочный модуль  начинается с адреса 0.  Колонка
Length-это  длина  сегмента  в  байтах.  Колонка  Name-это имя сегмента,
колонка  Class-это  информация  о  типе  сегмента. О группах, сегментах,
классах читайте документацию для программистов DOS.

    После списка  сегментов появляется  информация о  группах: стартовый
адрес и имя каждой группы. Пример списка группы приведен ниже:

Origin       Group
01EA:0       DGROUP

    В приведенном выше примере DGROUP-это имя группы данных.  DGROUP-это
единственная  группа,  используемая  программами,  скомпилированными   с
помощью компилятора MicrosoftQuick-C.

    Если  вы  производите  компановку  с  помощью  опции /LI, файл карты
распределения  памяти  содержит   также  номера  строк   вашей  исходной
программы и адреса, соответствующие каждому номеру строки, как  показано
в приведенном ниже примере:

Line number for HTOI.OBJ(htoi.c) segment  TEXT
     2 0000:0020    4 0000:0019    5 0000:0023    6 0000:0031
     7 0000:0047   10 0000:004B   12 0000:0054   13 0000:005A
    14 0000:005F   16 0000:0067   17 0000:0070   18 0000:0078
    19 0000:007D   20 0000:008A   21 0000:008D   22 0000:008F
    23 0000:0095   25 0000:009A   26 0000:009D   28 0000:00A5
    29 0000:00C2   30 0000:00C5   32 0000:00CA   33 0000:00D2
    36 0000:00D6   38 0000:00DF   40 0000:00E9   42 0000:0107
    43 0000:010F

    Если вы выполняете компановку с помощью опции /M, файл распределения
памяти  содержит  два  списка  глобальных  символических  имен:   первый
отсортированный по именам  (по возрастанию символов  ASCII) и второй  по
возрастанию  адресов.  Примечание  Abs  появляется  рядом  с абсолютными
символическими  именами.   (Имена,  содержащие  16-разрядные  константы,
значения которых не связаны с программными адресами.)

    Каждый  список  может  содержить  максимально  2048  отсортированных
символических имен. В опции /M можно задать число number, если вы хотите
выдать список из большего  числа символических имен, отсортированных  по
адресам. Аргумент number может быть любым десятичным, восьмеричным, либо
шестнадцатеричным  числом  от  0  до  65535  (десятичное), включительно;
однако, на практике число отсортированных символических имен  ограничено
количеством ближней динамической области памяти.

    Если вы зададите аргумент number, в файле распределения памяти будет
отсутствовать список "Publics by Name" (Внешних имен).

Address           Publics by Name
01EA:0096         STKHQQ
0000:1D86         _brikctl
01EA:04B0         _edata
01EA:0910         _end
.
.
.
01EA:00EC         __abrkp
01EA:009C         __abrktb
01EA:00EC         __abrktbe
0000:9876  Abs    __acrtmsq
0000:9876  Abs    __acrtused
.
.
.

01EA:0240           ___argc
01EA:0242           ___argv

Address           Publics by Value
0000:0010         _main
0000:0047         _htoi
0000:00DA         _exp16
0000:0113         __jhkstk
0000:0129         __astart
0000:01C5         __cintDIV
.
.
.

    Большинство  глобальных  символических  имен,  появляющихся  в файле
карты распределения памяти, являются символическими именами, внутренними
для  компилятора  Microsoft  Quick-C.  Данные символические имена обычно
начинаются с одного или  более лидирующих подчеркиваний и  заканчиваются
на QQ.

    Адреса  внешних   имен  записываются   в  формате   фрейм:-смещение,
показывающем местоположение имени относительно нуля (начала загрузочного
модуля).

    Обе опции /LI и /M включают в файл распределения памяти точку  входа
в программу, как показано в следующем примере:

    Program entry point at 0000:0129

    Файл распределения  памяти можно  также создать,  задав опцию  /Fm в
командной строке  QCL, заданием  имени такого  файла в  командной строке
LINK, либо заданием  имени данного файла  в ответе на  запрос List File.
Однако эти  методы не  позволят вам  увеличить количество  символических
имен, отсортированных по адресам.

               9.5.11. Управление размером стэка (/ST).

    -Опция:

    /ST[ACK]:number

    Опция  /ST  определяет  размер   стека  для  вашей  программы,   где
number-это   любое   положительное   десятичное,   восьмеричное,    либо
шестнадцатеричное значение  до 65535  (десятичное), являющееся  размером
стека  в  байтах.  Восьмеричные  или  шестнадцатеричные значение следует
задавать в формате, принятом в языке СИ: восьмеричные числа начинаются с
нуля, а шестнадцатеричные числа начинаются с "0x".

    Если вы не зададите данную опцию, стартовая программа из  автономной
СИ-библиотеки устанавливает стандартный размер стека 2К.

    Если  вы  получили  сообщение  о  переполнении  стека,  вам  следует
увеличить его размер.  И обратно, если  ваша программа использует  очень
маленький стек, вы можете уменьшить его размер.

    Данная опция имеет то  же самое действие, что  и опция /F в  команде
QCL.

    -Пример:

    LINK FACT.OBJ EXP.OBJ,,, /STACK:0xC00

    Данный  пример  устанавливает  размер  стека  C00  (то  есть 3К) для
программы, созданной компановкой объектных модулей FACT.OBJ и EXP.OBJ.

           9.5.12. Трансляция "длинных" вызовов (/F, /NOF).

    -Опции:

    /F[ARCALLTRANSLATION]
    /NOF[ARCALLTRANSLATION]

    Опция /F  компановщика просит  компановщик оптимизировать  "длинные"
вызовы процедур,  лежащих в  том же  самом сегменте,  что и  вызывающая.
Данная  опция   производит  значительно   более  быстрые   и  компактные
программы.

    Когда вы  зададите опцию  компановщика /F,  компановщик оптимизирует
32-битовые  вызовы  процедур,  лежащих  в  том  же самом сегменте, что и
вызывающая процедура.  Поскольку адреса  сегмента, как  и для вызванных,
так  и  вызывающих  процедур  те  же  самые, требуется только 16-битовый
вызов.  Если  задана  опция  /F,  компановщик удаляет "длинные" вызовы и
заменяет их на код, который сначала помещает в стек содержимое  регистра
CS,  а  зтем  делает  "короткий"  вызов.  Вызванная  процедура  все   же
возвращается  с  "длинной"  (32-битовой)  инструкцией  возврата. Однако,
поскольку и сегмент кода (хранящийся в CS) и "короткий" адрес  находятся
в  стеке,  "длинной"  возврат  выполняется  корректно.Компановщик  также
добавляет  инструкцию  последовательно,  пяти  байтовый  "длинный" вызов
заменяется  пятью  байтами  инструкций.  Хотя  компановщик не использует
преобразования "длинных" вызовов, если вы его явно не попросите об этом,
вы  можете  применить  опцию  /NOF  для  выключения трансляции "длинных"
вызовов, если вы,  например, задали опцию  компановщика /F в  переменной
программной среды CL.

              9.5.13. Упаковка последовательных сегментов
                             (/PAC, /NOP).

    -Опции:

    /PAC[KCODE][:number]
    /NOP[ACKCODE]

    Опция /PAC просит компановщик сгруппировать соседние сегменты  кода.
Сегменты кода  в одной  и той  же группе  разделяют один  и тот же самой
адрес сегмента;  все адреса  смещений, если  требуется, регулируются  по
верхнему. В результате, многие инструкции, которые могли бы в  противном
случае иметь  различные сегментные  адреса, будут  иметь один  и тот  же
сегментный адрес.

    Используемая совместно с опцией компановщика /F (описанной в Разделе
9.5.12),  опция  /PAC  может  сократить  размер и улучшить эффективность
программ средней модели памяти.

    Если задано, число number-это предельный размер групп, формируемых с
помощью /PAC.  Компановщик перестает  добавлять сегменты  к определенной
группе, как  только добавление  следующего сегмента  превысит предельный
размер  группы.  В  данном  случае  компановщик  из оставщихся сегментов
формирует новую группу. Если  число number не задано,  стандартное число
65530.

    Хотя  компановщик  не  упаковывает  соседние  сегменты,  если  вы не
попросите  его  об  этом  явно,  вы  можете  применить  опцию  /NOP  для
выключения упаковки сегментов,  если вы, например,  задали опцию /PAC  в
переменной среды CL.

                9.5.14. Остальные опции программы LINK.

    Не все  опции команды  LINK подходят  для использования  программами
Quick-C. Перечисленные ниже  опции компановщика могут  быть использованы
для программ Microsoft  Quick-C, но они,  обычно, никогда не  требуются,
поскольку,  требуемые  действия  команда  QCL, либо компилятор Microsoft
Quick-C выполняет автоматически:

    /CO[DEVIEW]

    Подготавливает выполняемый файл  к отладке в  среде Quick-C, либо  к
использованию многооконным  отладчиком и  компановке отдельными  шагами,
данная опция имеет влияние,  только если вы компануете  объектные файлы,
скомпилированные с опцией /Zi.

    /LI[NENUMBERS]

    Создает   файл   распределения   памяти,   включая   номера  строк и
соответствующие  им  адреса  исходной  программы.  Если вы осуществляете
компиляцию и  компановку отдельными  этапами, данная  опция будет  иметь
эффект, только  если вы  компануете объектные  файлы, скомпилированные с
опцией /Zd.

    /NOI[GNORECASE]

    Просит компилятор делать различие  между буквами верхнего и  нижнего
регистра;  например,  компановщик  будет  считать  ABC,  abc и Abc тремя
различными именами.  Если вы  хотите осуществлять  компановку без  опции
/NOI, вам следует выполнить компановку отдельным шагом-с помощью команды
LINK.

    /DO[SSEG]

    Для  сегментов  будет  соблюдаться  порядок, принятый стандартно для
высоко-уровневых языковых продуктов  фирмы Microsoft. Программы  Quick-C
всегда используют такой сегментный порядок по умолчанию.

    Следующие опции не нужно применять при компановке объектных  файлов,
скомпилированных с помощью  компилятора Microsoft Quick-C.  Они подходят
только    для    объектных    файлов,    скомпилированных    посредством
Макроассемблера Microsoft (MASM).

    /DS[ALLOCATE]

    Загружает  все  данные,  начиная  со  старших  адресов  стандартного
сегмента данных.

    /HI[GH]

    Помещает  выполняемый  файл  в  память  по  возможно  более  старшим
адресам.

    /NOG[ROUPASSOCIATION]

    Просит  компановщик  игнорировать  групповые  связи  при  назначении
адресов элементам кода и данных.

    /O[VERLAYINTERRUPT]:number

    Определяет  номер  прерывания   больший,  чем  0x3F,   для  передачи
управления "оверлеям".

                 9.6. Управление размещением стека и
                     динамической области памяти.

    Программы,   скомпилированные   и   скомпанованные   под управлением
Microsoft-C, работают с фиксированным размером стека (стандартный размер
2048 байтов).

    Стек располагается над данными  типа static, а динамическая  область
использует  память,  оставшуюся   над  стеком.  Однако,   для  некоторых
программ, модель с фиксированным  размером стека не является  идеальной;
модель, в которой стэк и динамическая область делят между собой  память,
была бы более подходящей

    Подвязывание  объектных  файлов  типа  mVARSTCK.OBJ  дает  вам такую
модель:  если  динамическая  область  выходит  за  пределы  памяти,  она
пытается использовать  для себя  свободную стековую  память до  тех пор,
пока  на  дойдет  до  вершины  стека.  Как только занятая в стеке память
освобождается, она снова становится  доступной для стека. Заметьте,  что
размер стека  не может  вырасти сверх  последнего размещенного  элемента
динамической  области  в  стеке,   либо  если  в  стеке   нет  элементов
динамической области,  сверх размера,  заданного в  процессе компановки.
Кроме  того,  обратите  внимание,  что  хотя  динамическая область может
занимать память, отведенную под стек, обратное невозможмно-стек не может
занимать  память,  выделенную   под  динамическую  область.   С  помощью
связывания вашей программы с одним из объектных файлов типа mVARSTCK.OBJ
(где m-первая  буква используемой  вами библиотеки),  вы можете изменить
модель, используемую для  размещения динамической области.  Данные файлы
являются  версиями  процедур  для  малой,  средней,  компактной, большой
модели памяти, которые позволяют функциям распределения памяти  (malloc,
calloc, _expand, _fmalloc, _nmalloc, realloc) размещать элементы  данных
динамической области в неисопользованной области стекового пространства,
если они выходят за пределы памяти.

    Когда вы связываете вашу  программу с одним из  файлов mVARSTCK.OBJ,
не подавляйте контроль за переполнением стэка с помощью директивы pragma
check_stack, либо  с помощью  опций /Gs  или /Ox.  В программах с данной
опцией  переполнение  стека  может  произойти  вероятнее, вызвав ошибки,
которые затем будет трудно обнаружить.

    -Пример:

    QCL TEST.C SVARSTCK

    Данная командная строка компилирует  файл TEST.C, а затем  связывает
результирующий объектный модуль  с файлом SVARTSCK.OBJ-объектным  файлом
переменного размера стэка для малой модели памяти.

                9.7. Использование оверлейных структур.

    Если вы не уверены, что  программа уместится в имеющуюся память,  вы
можете указать  программе LINK,  что следует  создать оверлейную  версию
вашей  программы.  В  оверлейной  версии  программы,  отдельные ее части
(известные под  названием "оверлей")  загружаются только  в том  случае,
когда они  требуются. Данные  части разделяют  между собой  одну и ту же
область памяти.  Оверлейным может  быть только  программный код,  данные
никогда  не  бывают  оверлейными.  Программы,  использующие   оверлейнче
структуры,  обычно  требуют  меньше  памяти,  но они работают медленнее,
поскольку  требуется  дополнительное  время  для считывания программного
кода с диска в память.

    Оверлейные части определяются посредством заключения их в скобки при
задании  списка  объектных  файлов  для  компановщика. Каждый модуль или
комбинация  модулей  в  скобках  обозначают  один "оверлей". Например, в
командной строке LINK вы модете в поле objfiles задать следующий  список
объектных файлов:

    a + (b+c) + (e+f) + g + (i)

    В данном примере модули (w+c), (e+f) и (i) являются "оверлеями".

    Как только управление передается на данные модули, они считываются с
диска  в  память.  Модули  a  и  g,  а  также  любые модули из библиотек
составляют "резидентную часть" (или "корень") вашей программы.

    "Оверлеи" загружаются  в один  и тот  же раздел  памяти, так,  что в
отдельный   момент   времени    резидентным   является   только    один,
модуль.Дублирующиеся  имена  в  различных  "оверлеях" не поддерживаются,
поэтому каждый модуль может появиться в программе только однажды.

    Компановщик передает вызовы  из корня в  оверлей и вызовы  из одного
оверлея  в  другой  оверлей  с  помощью  прерывания  (за которым следует
идентификатор модуля и смещение). По умолчанию номер прерывания 63(3F  в
шестнадцатеричной системе).  Для изменения  номера прерывания  вы можете
воспользоваться опцией компановщика /O.

    Опция  /O  должна  применяться  только  в  программах,  использующих
оверлейные  структуры,  и  порождающих  другие  программы,  использующие
оверлейные   структуры.   В   данном   случае   каждая  программа должна
использовать  отдельный  номер  оверлейного  прерывания, означающий, что
хотя бы одна программа должна быть скомпанована с данной опцией.

                    9.7.1. Ограничения на оверлеи.

    Вы  можете  сделать  оверлейными  только  те  модули,  управления на
которые  передается  и  возвращается  с помощью стандартного 32-битового
вызова  или  возврата.  Однако,  вызовы  функций,  определяемые ключевым
словом  near,  являются  16-битовыми.  Это  означает,  что  вы не можете
сделать оверлейными модули, содержащие "ближние" функции, если остальные
модули вызывают данные процедуры.

            9.7.2. Запросы диспетчера оверлейных структур.

    Диспетчер  оверлейных  структур-это  часть  стандартных   библиотек,
поставляемых с  компилятором Microsoft  Quick-C. Если  во время процесса
компановки  вы  объявите  "оверлеи",  код диспетчера автоматически будет
связан с остальными модулями вышей программы

    Во время работы выполняемого  файла оверлейный диспетчер ищет  файл,
который требует загрузить другой оверлей. Он ищет данный файл сначала  в
текущем  рабочем  каталоге,  затем,  если  файл  не  найден,   диспетчер
просматривает каталоги, заданные  в переменной операционной  среды PATH.
Как  только  диспетчер  найдет  файл,  он  извлечет  оверлейные  модули,
заданные корневой программой. Если  оверлейный диспетчер не может  найти
требуемый оверлейный файл, он запрашивает пользователя ввести имя файла.

    Даже при использовании  оверлейных структур, компановщик  производит
только один  файл .EXE.  Даннай файл  открывается снова  и снова, до тех
пор,  пока  диспетчер  не  потребует  извлечь  новые  оверлейные модули.
Например,  предположим,  что   выполняемая  программа  вызывающая   файл
PAYROLL.EXE,  который  не  существует  ни  в  текущем  каталоге,  ни   в
каталогах,   заданных   переменной   PATH,   использует   оверлеи.  Если
пользователь  запускает  ее  с  помощью  полной  спецификации  маршрута,
оверлейный  диспетчер  высвечивает   следующее  сообщение  при   попытке
загрузить оверлейные файлы:

    Cannot find PAYROLL.EXE
    Please enter new program spec:
    (Невозможно найти файл PAYROLL.EXE
    Пожалуйста введите новую программную спецификацию:)

    Пользователь может затем  ввести спецификацию дисковода  или каталог
(либо и то и другое), определяющие местоположение программы PAYROLL.EXE.
Например, если файл расположен на дисководе В в каталоге \EMPLOYEE\DATA,
пользователь   должен   ввести   либо   B:\EMPLOYEE\DATA,   либо  просто
\EMPLOYEE\DATA, если дисковод В является текущим.

    Если пользователь позже удалит  диск из устройства В,  и оверлейному
диспетчеру  потребуется  снова  доспуп  к  оверлею,  он  не  найдет файл
PAYROLL.EXE. Высветится следующее сообщение:

    Please insert discette containing B:'EMPLOYEE\DATA\PAYROLL.EXE
    in drive B: and strike any key when ready
    (Пожалуйста вставьте дискету, содержащую файл
    B:\EMPLOYEE\DATA\PAYROLL.EXE в дисковод В: и при готовности нажмите
    любой ключ)

    После того, как оверлейный  файл будет прочитан с  диска, оверлейный
дистетчер высветит следующее сообщение:

    Please restore the original diskette.
    Strike any key when ready

    (Пожалуйста  установите   первоначальную  дискету.   При  готовности
нажмите любой ключ).


                               ГЛАВА 10.

                 Создание библиотек Quick и автономных
                              библиотек.

10.1. Библиотeки Quick.
      10.1.1. Создание библиотек Quick.
      10.1.2. Загрузка библиотек Quick.
      10.1.3. Стандартные библиотечные процедуры
              в библиотеках Quick.
10.2. Управление автономными библиотеками:
      Утилита LIB.
      10.2.1. Запуск утилиты LIB.
      10.2.2. Стандартная информация для утилиты LIB.
      10.2.3. Командные символы.
      10.2.4. Файлы-листинги перекрестных ссылок.
      10.2.5. Установка размера страниц для библиотек.

    Библиотека-это собрание  процедур, которые  были скомпилированы  или
ассемблированы  для  получения  набора  объектных модулей, которые затем
могут быть использованы программами Quick-C. Пакет Quick-C  обеспечивает
инструментальные средства для создания и обработки двух типов  бибиотек,
легко различающиеся по их характерному расширению:

Расши-           Значение
рение

.QLB  Обычно обозначает библиотеку "Quick", это тип библиотеки, соз-
      даваемый утилитой LINK, и используемый программами компилируе-
      мыми и выполняемыми в среде разработки программ Quick-C.
.LIB  Расширение .LIB характеризует библиотеку, созданную библиотеч-
      ным диспетчером LIB. Данные библиотеки называются обычно "авто-
      номными" и имеют тот же самый формат, что и библиотеки, приме-
      няемые в других языковых высокоуровневых продуктах фирмы
      Microsoft.

                        10.1. Библиотеки Quick.

    Библиотеки  Quick   используются  в   программах,  компилируемых   и
выполняемых  в  программной  среде  Quick-C.  Бибилиотеку  Quick следует
загрузить,   если   вы   хотите   получить   полный   список стандартных
библиотечных процедур СИ, встроенных в программную среду Quick-C.

                   10.1.1. Создание библиотек Quick.

    В  библиотеку  Quick  можно  объединить  объектные файлы, автономные
библиотеки, либо любую их комбинацию. Когда вы подключаете к  библиотеке
Quick  автономную  библиотеку,  все  модули данной библиотеки становятся
частью библиотеки Quick.

    Библиотеку Quick можно создать с помощью следующих шагов:

    1. Скомпилируйте  исходные файлы  СИ, которые  вы хотите  включить в
библиотеку.  Поскольку  модули  в  библиотеке  Quick должны использовать
среднюю модель памят, компиляцию выполняйте либо с выходной опцией obj в
программной среде Quick-C, либо с опцией /AM в командной строке QCL.

    2. Вызовите компановщик,  либо из командной  строки, либо с  помощью
программы LINK. Задайте QUCKLIB.OBJ в качестве первого имени  объектного
файла в командной строке, либо  в ответе на запрос Object  Files.  (Файл
QUICKLIB.OBJ  находится  на  дистрибутивном  диске  Libraries#1   пакета
Quick-C). Затем задайте имена  объектных файлов и автономных  библиотек,
которые вы объединяете. Задайте имя библиотеки Quick в командной  строке
в качестве имени выполняемого файла,  либо в ответе на запрос  Run File.
Чтобы создать библиотеку Quick задайте опцию компановщика /Q.

    -Пример:

    QCL QUICKLIB /AM CRCL.C ELPS.C LINE.C CRV.C /FeSHAPES.QLB /link /Q

    Командная строка QCL, приведенная  выше, создает библиотеку Quick  с
именем SHAPES.QLB из исходных файлов CRCL.C, ELPS.C, LINE.C и CRV.C.

                   10.1.2. Загрузка библиотек Quick.

    Чтобы  загрузить  библиотеку   Quick  при  старте   пакета  Quick-C,
используйте командную строку в следующей форме:

    QC/lqlibname

    В  данной  командной  строке  qlibname-это  базовое  имя  библиотеки
Quick(имя без расширения .QLB).

    Если библиотека  Quick имеет  другое расширение,  вам следует задать
имя файла  с расширением.  Библиотеки Quick,  если используются,  должны
быть загружены при старте среды  Quick-C. Каждый раз при старте  Quick-C
вы можете загрузить только одну из библиотек Quick.

    Quick-C  ищет  библиотеки  Quick  в  следующих  местах и в следующем
порядке:

    1.  По  маршруту,  определенному  в  имени библиотеки Quick, если он
задан.

    2. В текущем каталоге.

    3.  По  маршруту,  заданному  в  переменной среды LIB. (Информацию о
переменных операционной среды вы  найдете в руководстве пользователя  по
операционной системе DOS).

    -Пример:

    QC /lGRAPHICS.QLB

    Команда,  приведенная  выше,  загружает  библиотеку  Quick  с именем
GRAPHICS.QLB,  которая  содержит  графические  функции Quick-C.  (Данная
библиотека Quick поставляется, как часть пакета Quick-C).

             10.1.3. Стандартные библиотечные процедуры в
                          библиотеках Quick.

    В таблице  6.1. Разделе  6.1.1.  "Одномодульные  программы" приведен
список стандартных процедур  СИ, встроенных в  среду Quick-C. Вы  можете
вызвать эти процедуры из ваших программ без загрузки библиотеки Quick.

    Как вы можете увидеть из Таблице 6.1, многие из функций  стандартных
библиотек СИ определены в  программной среде Quick-C. Однако,  если ваша
программа  использует  стандартные  библиотечные  процедуры,  которые не
определены в программной  среде Quick-C, у  вас есть на  выбор несколько
средств.

    Если  ваша  программа  использует  библиотечные  процедуры (например
getchar()),  которые  работают   как  макрокоманды,  просто   скопируйте
директиву  #include  для  соответствующего  заголовочного  файла  в  ваш
исходный файл.

    Если  ваша  программа  вызывает  библиотечные  функции,  используйте
следующие процедуры для создания и загрузки библиотеки Quick, содержащей
данные функции:

    1.  Создайте  исходный  файл,  содержащий  программу  main,  которая
состоит  только  из  вызовов  данных  библиотечных  процедур, которые вы
хотите  иметь  в  библиотеке  Quick.  Например,  если  вы хотите создать
библиотеку Quick, содержащую процедуры из библиотеки исполняющей системы
Microsoft-C,  для  интерфейса  к  системе  BIOS,  вам  следует   создать
следующий исходный файл с именем BIOS.C.

         #include
         main()
         {

             _bios_serialcom();
             _bios_disk();
             _bios_equiplist();
             _bios_keybrd();
             _bios_memsize();
             _bios_printer();
             _bios_timeofday();
         }

    Заметьте, что компилятор может высветить предупреждения, пос  кольку
реальные аргументы, передаваемые функциям в программе отсутсвуют.

    2. Скомпилируйте и скомпануйте исходный файл, как описано в  Разделе
10.1.1.  В  данном  примере  вы  можете  использовать команды QCL и LINK
нижеследующим образом:

    QCL /C /AM BIOS.C

    LINK QUICKLIB.OBJ + BIOS.OBJ, BIOS.QLB, , /Q;

    3. Загрузите, как обычно, результирующую библиотеку Quick. В  данном
примере используйте следующую команду:

    QC /lBIOS

              10.2. Управление автономными библиотеками:
                             Утилита LIB.

    Администратор библиотек LIB  используется для управления  содержимым
автономных  библиотек.  Автономная  библиотека  состоит  из   "объектных
модулей"-то есть объектных файлов, объединенных в библиотеку. В  отличие
от  объектных  файлов,  объектные  модули  не  существуют  отдельно   от
бибилиотек,  к  которым  они  принадлежат,  и  не  имеют ни наименования
маршрута, ни расширения.

    Утилита LIB используется:

    1. Для объединения объектных файлов в новую библиотеку.

    2. Для добавления объектных файлов к существующей библиотеке.

    3. Для удаления и замены объектных файлов в существующей библиотеке.

    4. Для  извлечения объектных  модулей из  существующей библиотеки  и
помещения в отдельные объектные файлы.

    5. Для  объединения содержимого  двух существующих  библиотек в одну
новую библиотеку.

    Для  формирования  автономной   библиотеки  могут  быть   объединены
объектные  файлы,  автономные  библиотеки,  библиотеки идеологии Intel и
архива XENIX, причем в любом сочетании.

    Автономные  библиотеки  обычно  распознаются  по их расширению .LIB,
хотя допустимы и другие расширения.

    При  обновлении  существующей  библиотеки  утилита LIB выполняет все
операции с копией библиотеки. Данный механизм гарантирует, что вы всегда
будете иметь резервную копию обновляемой библиотеки.

                      10.2.1. Запуск утилиты LIB.

    Если  вы  работаете  с  утилитой  LIB  на  системе с жестким диском,
выполните  сначала  команду  DOS  CD,  чтобы  сделать текущим каталог, в
котормй находятся  нужные вам  объектные файлы  или библиотеки.  Если вы
запускаете LIB  на системе  с гибкими  дисками, установите  в дисковод А
рабочую  копию  вашей  дистрибутивной  дискеты  Libraries#1,  а дискету,
содержащую ваши объектные файлы или библиотеки в дисковод В.

    Входную информацию для утилиты  LIB можно задать одним  из следующих
способов:

    -Заданием входной информации в командной строке в следующей форме:

    LIB oldlib[/P[ANESIZE]:number][command][,[listfile][,[newlib]]][;]

    Командная строка не может превышать 128 символов.

    -Вводом:

    LIB

    и ответом на следующие запросы:

    Library name: (имя библиотек)
    Operations: (действие)
    List file: (файл перекрстных ссылок)
    Output library: (выходная библиотека)

    Чтобы задать в ответ на  один запрос больше файлов, введите  в конце
строки амперсэнд (&).  Запрос снова появится  на следующей строке,  и вы
можете продолжить ввод ответа на запрос.

    -Созданием файла с  ответом на запросы  команды LIB, известного  под
названием "файл ответов", затем вводом команды LIB в следующей форме:

    LIB @ filename ,

    где filename-имя  файла ответов.  Ответы должны  быть даны  в том же
порядке, что и на запросы команды LIB, описанные выше. Имя файла ответов
можно также ввести  и после запроса  компановщика, либо в  любой позиции
командной строки LIB.

    В  Таблице  10.1  приведена  входная  информация,  задаваемая вами в
командной строке LIB, либо в ответе на каждое сообщение.

                                                 Таблица 10.1.
                    Входная информация команды LIB.

Поле       Запрос      Входная информация

oldlib    Library name Имя библиотеки, которую вы изменяете , либо
                       создаете. Если данная библиотека не существу-
                       ет, LIB просит вас ее создать. Введите Y для
                       создания новой библиотеки, либо N-для прерыва-
                       ния работы LIB. Данное сообщение подавляется,
                       если вы введёте командные символы, запятую,
                       либо точку с запятой вслед за именем библиоте-
                       ки. При точке с запятой утилита LIB выполняет
                       контроль библиотеки, высвечивая сообщение при
                       обнаружении ошибок в любом библиотечном модуле
/P:number /P:number    Устанавливает для библиотеки размер страницы в
          в ответе на  number байтов, где number-это целое число, яв-
          запрос "Lib- ляющееся степенью двойки до 16 степени, 32768
          rary name"   включительно. Подробную информацию о размере
                       библиотечной страницы ищите в Разделе 10.2.5.
Commands  Operations   Символы команд и объектные файлы, сообщающие
                       программе LIB, какие изменения сделать в биб-
                       лиотеке.
listfile  List file    Имя файла перекрестных ссылок. Если вы не за-
                       дадите имя, листинг не будет создан.
newlib  Output library Имя измененной библиотеки, создаваемой в резу-
                       льтате работы утилиты LIB. Если вы не задади-
                       те новое имя библиотеки, оригинальная неизмен-
                       ная библиотека будет записана в библиотечном
                       файле с тем же именем, но расширением .BAK,
                       вместо расширения .LIB.

            10.2.2. Стандартная информация для утилиты LIB.

    Стандартную входную информацию для  утилиты LIB можно выбрать  одним
из следующих способов:

    - Чтобы выбрать стандартную  информацию для любой позиции  командной
строки, опустите имя  файла либо имена  перед позицией и  введите только
требуемую запятую. Исключение составляет только параметр Listfile:  если
вы   вместо   входной   информации   введите   пятую,   программа    LIB
напротив-создает файл перекрестных ссылок.

    - Чтобы выбрать стандарт для любого запроса, нажмите просто ENTER

    -  Чтобы  выбрать  стандарт  для  всех  оставшихся позиций командной
строки, либо для всех оставшихся запросов, введите после данной  позиции
точку с запятой (;).

    В  Следующей  Таблице  описаны  значения  по умолчанию, используемые
утилитой LIB для файла перекрестных ссылок и выходных библиотек:

Файл                   Стандарт

листинг перекрестных   Специальный файл с именем NUL просит утилиту
ссылок                 LINK не создавать файл перекрестных ссылок.
выходная библиотека    Позиция oldlib,либо ответ на запрос "Library
                       name".

                      10.2.3. Командные символы.

    Чтобы  сообщить  утилите  LIB,  какие  изменения вы хотите сделать с
библиотекой,  введите  командные  символы  (такие  как  +, -, -+, *, -*)
непосредственно после имени модуля,  имени объектного файла, либо  имени
библиотеки. Задать можно более одного действия, причем в любом порядке.

    В  следующей  Таблице  приводится  список  всех  командных  символов
утилиты LIB, тип имени файла, к которому применяется данная операция,  и
действия, выполняемые по данному командному символу:

Команда                Значение

+{objfile|lib}         При употреблении данного символа с именем объ-
                       ектного файла знак плюс (+) добавляет объект-
                       ный файл к входной библиотеке, причем данный
                       объектный файл становится последним модулем в
                       библиотеке. Для задания имени объектного фай-
                       ла вы можете использовать спецификацию маршру-
                       та. Поскольку утилита LIB автоматически предпо
                       лагает расширение .OBJ, вы можете опустить рас
                       ширение в имени объектного файла. Если знак
                       (+) употребляется с именем библиотеки, содер-
                       жимое данной библиотеки добавляется к входной
                       библиотеке. Имя библиотеки должно иметь расши-
                       рание .LIB.
-module                Удаляет данный модуль из входной библиотеки.
                       Имя модуля не имеет ни имени маршрута, ни рас-
                       ширения имени.
-+module               Заменяет во входной библиотеке данный модуль.
                       Имена модулей не имеют ни наименований маршру-
                       тов, ни расширений. Утилита LIB удаляет данный
                       модуль, затем добавляет объектный файл, имею-
                       щий то же самое, что и модуль, имя. Объектный
                       файл стандартно имеет расширение .OBJ и распо-
                       лагается в текущем рабочем каталоге.
*module                Копирует данный модуль из библиотеки в объект-
                       ный файл в текущем рабочем каталоге. Модуль
                       остается в библиотечном файле. При копировании
                       модуля в объектный файл, утилита LIB добавля-
                       ет расширение .OBJ. Вам нельзя пренебрегать
                       расширением .OBJ, спецификацией дисковода,
                       либо наименованием маршрута для данного объек-
                       тного файла. Однако, позднее вы можете пере-
                       именовать файл, либо скопировать его в любое
                       по вашему желанию место.
-*module               Перемещает данный объектный модуль из библио-
                       теки в объектный файл. Данная операция эквива-
                       лентна копированию модуля в объектный файл,
                       как описано выше, затем происходит удаление
                       модуля из библиотеки.

---------------------------------------------------------------------

    Предупреждение:

    Библиотечные  модули  могут  содержать  вызовы  других  библиотечных
модулей. Если вы извлекаете библиотечные модули, которые сами вызы- вают
другие библиотечные модули, вызываемые модули не извлекаются.

---------------------------------------------------------------------

    -Примеры:

    LIB LANG -+HEAP;

    Приведенный выше пример использует командный символ замены (-+)  для
замены с помощью утилиты LIB модуля HEAP в библиотеке LANG.LIB.  Утилита
LIB удаляет модуль  HEAP из библиотеки,  затем добавляет объектный  файл
HEAP.OBJ в качестве нового файла  в библиотеку. Точка с запятой  в конце
командной строки просит программу LIB на оставшиеся запросы использовать
стандартные  ответы.  Это  значит,  что  файл-листинг не будет создан, а
данные изменения записываются  в оригинальный библиотечный  файл, вместо
нового библиотечного файла.

    LIB LANG-HEAP+HEAP;
    LIB LANG+HEAP-HEAP;

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

    LIB FOR;

    В  данном  примере  утилита  LIB  последовательно выполняет контроль
библиотечного  файла  FOR.LIB.  Никаких  других  действий не происходит.
Утилита   LIB   последовательно   высвечивает   обнаруженные   ошибки  и
возвращается на уровень операционной системы.

    LIB LANG,LCROSS.PUB

    В  данном  примере  утилита  LIB  последовательно выполняет контроль
библиотечного файла LANG.LIB и затем создает файл перекрестных ссылок  с
именем LCROSS.PUB.

    LIB FIRST -*STUFF *MORE, ,SECOND

    В данном примере утилита  LIB перемещает модуль STUFF  из библиотеки
FIRST.LIB в объектный файл с  именем STUFF.OBJ. В процессе модуль  STUFF
удаляется  из  библиотеки.  Модуль  MORE  копируется  из  библиотеки   в
объектный  файл  с  именем  MORE.OBJ;  модуль  остается  в   библиотеке.
Исправленная библиотека получает имя SECOND.LIB. Она содержит все модули
из FIRST.LIB, исключая  STUFF, который был  удален с помощью  командного
символа (-*). Оригинальная библиотека FIRST.LIB остается неизменной.

    LIBFOR
    +CURSOR+HEAP-HEAP*FOIBLES
    CROSSLST

    Содержимое  приведенного  выше  фвйла  ответов  просит  утилиту  LIB
удалить модуль HEAP из  библиотеки LIBFOR.LIB, извлечь модуль  FOIBLES и
поместить его в объектный файл с именем FOIBLES.OBJ, добавить  объектные
файлы  CURSOR.OBJ  и  HEAP.OBJ  в  качестве  двух  последних  модулей  в
библиотеку.  Наконец,  утилита  LIB  создает  файл перекрестных ссылок с
именем CROSSLST.

                  10.2.4. Файлы перекрестных ссылок.

    Файл перекрестных ссылок содержит следующие два списка:

    1. Алфавитный список всех  внешних символических имен в  библиотеке.
За каждым символическим именем следует имя модуля, в котором встретилась
ссылка.

    2. Список модулей в  библиотеке. Под каждым именем  модуля находится
алфавитный список внешних имен, определенных в данном модуле.

    -Пример:

    Приведенный здесь пример изображает части файла перекрестных  ссылок
для стандартной  библиотеки СИ  MLIBCE.LIB. В  части, следующей  ниже, в
первой и третьей колонке даны внешние символические имена из библиотеки,
а во второй  и четвертой колонке-  имена модулей, в  которых встречаются
ссылки на данные имена:

$$OVDINIT         ovlm61       $i4_m10           ixtomx
$i8_implicit_exp  emfin        $i8_inpbas        emfin
$i8_input         emfin        $i8_input_ws      emfin
$i8_m8            ixtomx       $m4_i10           ixtomx
$m8_i8            ixtomx       DOSCREATECSALIAS  apisim
DOSDEVCONFIG      apisim       DOSFREESEG        apisim
DOSGETMACHINEMODE  apisim      DOSSETVEC         apisim
       .             .              .                .
       .             .              .                .
       .             .              .                .

    Во  второй  части  листинга,  приведенной  далее,  за именем каждого
модуля из библиотеки следует список внешних имен, встречающихся в каждом
модуле:

afhdiff                  Offset:00000010H  Code and data size: 41H
  __aFahdiff
anhdiff                  Offset: 000000d0H Code and data size: 3dH
  __aNahdiff
3_file                   Offset: 00000190H Code and data size: 11aH
  __iob                    __iob2           __lastiob
access                   Offset: 000002f0H Code and data size: 1fH
__access

           10.2.5. Установка размера страниц для библиотеки.

    Размер страниц библиотеки влияет на выравнивание модулей, хранимых в
библиотеке. Модули в библиотеке всегда выравниваются по позиции, кратной
размеру страницы (в байтах) от начала файла. Стандартный размер  страниц
для заново созданной библиотеки 16 байтов.

    Установить  другой  размер  страниц  для  библиотеки  во  время   ее
создания, либо изменить размер страниц для существующей библиотеки можно
с помощью добавления к командной строке утилиты LIB после пункта oldlib,
либо после имени, которое вы  введете в ответ на запрос  "Library name",
следующей опции:

    /P[AGESIZE]:number

    Число number определяет новый размер страницы. Оно должно быть целым
числом, являющимся степенью двойки в пределах до 16 степени или 32768.

    Библиотечный размер страницы определяет число модулей, которое может
содержать библиотека; то есть, увеличение размера страниц позволяет  вам
включить  в  библиотеку  больще  модулей.  Однако,  чем  больше   размер
страницы, тем большее количество  памяти затрачивается на библиотеку  (в
среднем, pagesihe/2 байтов на модуль). В большинстве случаев вам следует
использовать небольшой размер страницы (если ваша библиотека не является
очень большой).

    Размер  страницы,   кроме  того,   определяет  максимальный   размер
библиотеки.  Пределом  является  число  number*65536.  Например, если вы
зададите /P:16, библиотека должна быть меньше одного мегабайта (16*65536
байтов).


                              ГЛАВА 11.

               Автоматизированная разработка программ с
                        помощью утитлиты MAKE.

11.1. "Сердце" утитилиты MAKE:
      Файлы описания.
      11.1.1. Построение файла описания утилиты MAKE.
      11.1.2. Блоки описания.
11.2. Запуск утилиты MAKE.
11.3. Использование в утилите MAKE макро-
      определений.
      11.3.1. Определение и задание макрокоманд.
      11.3.2. Использование макрокоманд в макро-
              определениях.
      11.3.3. Использование специальных макрокоманд.
11.4. Определение правил вывода.
11.5. Использование файлов типа .MAK.
      11.5.1. Использование файлов типа .MAK с
              утилитой MAKE.
      11.5.2. Включение зависимостей файлов.
      11.5.3. Задание опций компановщика.

    Утилита разработки программ MAKE поможет вам в разработке  программ,
содержащих  более  одного  модуля.  Утилита MAKE автоматически обновляет
файл, устаревший по дате по сравнению с другими родственнами файлами,  и
бывает полезна в следующих ситуациях:

    -При разработке программ утилита MAKE может автоматически  обновлять
выполняемый  файл,  как  только  изменится  любой исходный или объектный
файл.

    -При  управлении  библиотеками  утилита  MAKE  может   автоматически
перестроить библиотеку, как только изменится один из модулей библиотеки.

    -В  сетевой  среде   утилита  MAKE  может   автоматически  обновлять
локальную  копию  программы  или  файла,  хранимых  в  сети,  как только
основная копия будет изменена.

    При запуске утилиты  MAKE вы должны  задать имя файла.  Данный файл,
известный  под   названием  "файл   описаний  утилиты   MAKE",  содержит
инструкции, сообщающие утилите MAKE, какие файлы следует обновить, какие
файлы должны измениться перед обновлением, какой тип обновления  следует
выполнить.

    Файл описаний может содержать следующие данные:

    TEST.EXE: TEST.C TEST2.C
    QCL TEST.C TEST2.C

    В данном  примере TEST.EXE-это  файл, который  должен быть обновлен,
если  какой-либо  из  исходных  файлов  TEST.C  или  TEST2.C   претерпит
изменения.Реальное  обновление  выполняется  с  помощью  команды  QCL на
следующей строке.  Подробности о  файлах описаний  вы найдете  в Разделе
11.1.

    Если вы компилируете ваши  программы в среде Quick-C,  файл описаний
для ваших программ строится автоматически.

    В  Разделе  11.2  описывается  информация,  которую следует задать в
командной строке утилиты  MAKE вместе с  именем файла описаний,  включая
опции   программы   MAKE.   В   Разделах   11.3-11.4  описываются другие
осбоенности утилиты MAKE.

                     11.1 "Сердце" программы MAKE:
                            Файлы описаний.

    Утилита MAKE использует "файлы описаний" для того, чтобы определить,
какие файлы следует  обновлять, когда их  обновлять и какие  следует для
этого выполнить операции. Файл  описаний утилиты MAKE состоит  из одного
или  более  "блоков  описаний",  каждый  из  которых задает описание для
одного файла.

    В Разделе 11.1.1 рассказывается, как создать простой файл  описаний,
состоящий из единственного блока описаний.

    В Разделах 11.1.1-11.1.2 разъясняется формат блока описаний, правила
для  их  установки  и  знаки  для  обозначения  отдельных блоков в файле
описаний.

    В  Разделе  11.1.2  рассматриваются  файлы  описаний программы MAKE,
которые строит Quick-C при разработке программ в среде Quick-C.

          11.1.1. Построение файла описаний для утилиты MAKE.

    В этом  разделе для  иллюстрации работы  утилиты MAKE  показано, как
построить простейший  файл описаний  для программы  MAKE. Поскольку файл
описаний  утилиты  MAKE-это  текстовый  файл,  для  его  создания  можно
воспользоваться любым редактором текстов.

    В нашем  примере, предположим,  что вы  хотите обновить  выполняемый
файл с именем UPDATE.EXE, как только изменится один из исходных  файлов.
Предположим далее,  что имена  исходных файлов  GETINPUT.C, FINDREC.C  и
UPDATE.C. Для создания файла  описания утилиты MAKE, с  помощью которого
автоматически   обновляется   файл   UPDATE.EXE,   используйте следующую
процедуру:

    1.С помощьюя  текстового редактора,  создайте файл  с именем UPDATE.
Хотя файл описаний утилиты MAKE  может иметь любое имя, может  оказаться
полезным присвоение файлу описаний то же самое имя, что и обрабатываемый
файл (без расширения).

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

    UPDATE.EXE:

    3.Далее за двоеточием введите имена файлов, изменение которых  может
привести  к  изменению  выходного  файла.  В  нашем  примере,  вы должны
обновить  файл   UPDATE.EXE,  как   только  изменится   один  из  файлов
GETINPUT.C, FINDREC.C, UPDATE.C; строка  файла описания в данном  случае
будет выглядеть следующим образом:

    UPDATE.EXE: UPDATE.C GETINPUT.C FINDREC.C

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

    4.Если  вы  хотите  добавить  комментарий  к  любой  из  строк файла
описаний утилиты MAKE,  введите знак (#)  Программа MAKE игнорирует  все
символы  между  этим  знаком  (#)  и  символом перехода на новую строку.
Например, вы можете задать следующий комментарий:

    UPDATE.EXE: UPDATE.C GETINPUT.C FINDREC.C #UPDATE ROUTINE

    5.Если любой их входный файлов изменяется, введите команду,  которую
вы  хотите  выполнить.  В  данном  примере предполагается, что вы хотите
перекомпилировать  и  перекомпановать  все  входные файлы. В результате,
файл описаний будет выглядеть следующим образом:

    UPDATE.EXE:UPDATE.C GETINP.C FINDREC.C #UPDATE ROUTINE
    QCL UPDATE.C GETINPUT.C FINDREC.C

    Если вы хотите добавить  комментарий до или после  командной строки,
комментарий, как показано ниже, должен начинаться в ко- лонке 1:

    UPDATE.EXE:UPDATE.C GETINPUT.C FINDREC.C #UPDATE ROUTINE
    # RECOMPILE AND RELINK
    QCL UPDATE.C GETINPUT.C FINDREC.C

    6.При выходе  из редактора  текстов сохраните  файл описаний.  Затем
введите: MAKE

    за  которым  следует  имя  файла  описаний  и нажмите ENTER. В нашем
примере вам следует ввести:

    MAKE UPDATE

    7.Утилита  MAKE  сравнивает  даты  последней  модификации каждого из
входных файлов  с датой  выходного файла.  Если все  даты входных файлов
"старее", чем дата выходного  файла, утилита MAKE не  производит никаких
действий. Если же какой-либо входной файл "новее" по дате, чем  выходной
файл,  утилита  MAKE  распознает,  по  отношению к какому входному файлу
"устарел" выходной файл и, таким образом, выполняет команду, назначенную
вами. В данном примере  программа MAKE перекомпилирует исходные  файлы и
перекомпанует соответсвующие объектные  файлы для создания  нового файла
UPDATE.EXE.

                        11.1.2. Блоки описаний.

    Блок описаний имеет следующую основную форму:

    outfile:[infile]...[#comment]

  [#comment]
      command
      [command]
         .
         .
         .

    В  следующей  Таблице  приведено  описание  составных  частей  блока
описаний:

Поле                   Значение

ontfile                Имя обновляемого файла; может включать специфи-
                       кацию дивковода или маршрута. Допускается толь
                       ко один выходной файл.
infile                 Имена файлов, которые при изменении приведут к
                       изменению выходного файла; могут включать спе-
                       цификации дисковода или маршрута. Одно имя вхо
                       дного файла от другого должно отделяться по
                       крайней мере одним пробелом. Если у вас файлов
                       больше, чем может уместиться на одной строке,
                       введите обратный слэш (\), нажмите ENTER и за-
                       тем продолжите ввод на следующей строке. Если
                       не задано ни одного входного файла, утилита
                       MAKE выполняет все команды в блоке автомати-
                       чески.
command                Команда, которая будет выполняться автомати-
                       чески, если выходной файл устарел по дате по
                       отношению к входному файлу. Командами в данном
                       случае могут быть программы, пакетные команды,
                       либо команды DOS. Команд может быть любое чис-
                       ло, но каждая должна начинаться с новой строки
                       и ей должен предшествовать хотя бы один пробел
                       или знак табуляции.
comment                Символ комментария (#), за которым следует
                       один или более символов. Программа MAKE игно-
                       рирует все символы, которые в данной строке
                       следуют за символом комментария. Поэтому, если
                       вы хотите разместить комментарий на той же
                       строке, что и имя выходного файла, вы должны
                       ввести его после имен входных файлов. Если ко-
                       мментарий появляется в строке, в которой ожи-
                       дается команда, символ комментария должен быть
                       первым символом в строке, причем лидирующие
                       пробелы не допускаются.

---------------------------------------------------------------------

    Примечание:

    Хороший  способ  запомнить  формат  файла описанний утилиты MAKE-это
представить его в форме "если, то": "если выходной файл устарел по  дате
по сравнению с  входным файлом, либо  если выходной файл  не существует,
выполняются команды".

---------------------------------------------------------------------

    В файле описаний вы можете задать любое количество блоков  описаний.
Между  последней  строкой  одного   блока  описаний  и  первой   строкой
следующего  блока  описаний  должна  быть  строка.  Когда  вы запускаете
утилиту  MAKE,  она  считывает  строку  в первом блоке описаний, которая
именует  входные  и  выходные  файлы  и затем проверяет даты модификации
данных  файлов.  Если  дата  модификации  для какого-либо входного файла
"старее"  даты  модификации  выходного  файла,  если  выходной  файл  не
существует,либо если входные файлы  не заданы, утилита MAKE  высвечивает
команды, заданные в блоке.

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

    Если утилита  MAKE не  может найти  входной файл,  выходной файл или
команду,  она  высвечивает  диагностическое  сообщение. Если пропущенный
файл является  выходным, утилита  MAKE проджолжает  работать, так  как в
большинстве   случаев,   недостающие   файлы   создаются  нижеследующими
командами.  Если  файл-входной  либо  командный-утилита  MAKE прекращает
работу.

    Утилита  MAKE,  кроме  того,  прекращает  работу  и  высвечивает код
прерывания  если  хотя  бы  одна  команда  возвращает  ошибку. Поскольку
утилита MAKE обрабатывает  блоки описаний в  том порядке, в  котором они
расположены  в  файле  описаний,   важно,  чтобы  блоки  описаний   были
расположены в требуемом порядке.

    -Пример:

MOD1.OBJ:      MOD1.C
        QCL /c MOD1.C
MOD2.OBJ:      MOD2.C
        QCL /c MOD2.C
EXAMPLE.EXE:   MOD1.OBJ MOD2.OBJ
        LINK MOD2+MOD2,EXAMPLE,EXAMPLE;

    В приведенном выше примере блоки описаний находятся в том порядке, в
котором  обновляются  или  создаются  выходные  файлы.  Таким   образом,
программа MAKE  обновляет файлы  MOD1.OBJ и  MOD2.OBJ (либо  создает их,
если  необходимо)  до   того,  как  будет   обновлен  или  создан   файл
EXAMPLE.EXE. После работы утилиты MAKE любые изменения в исходных файлах
будут отражены в файле EXAMPLE.EXE.

                     11.2. Запуск программа MAKE.

    -Синтаксис:

    MAKE [опции] [макроопределения] имя файла

    Если  вы  запускаете  утилиту  MAKE  на  системе  с  жестким диском,
используйье  команду  DOS  CD  для  того, чтобы сделать рабочим каталог,
содержащий файл  описаний и  ваши рабочие  файлы. Если  вы работаете  на
системе с гибкими дисками, установите в дискавод А рабочую копию  вашего
дистрибутивного диска  Libraries#1, а  диск, содержащий  файл описаний и
ваши рабочие файлы в дисковод В..

    Командная строка утилиты  MAKE позволяет вам  вместе с именем  файла
задать  дополнительную  информацию.  В  следующей  таблице   описывается
информация, которую вы можете задать в командной строке утилиты MAKE.

Поле    Значение

опции   Одна или более опций утилиты MAKE.
макро-  Одно или более макроопределений утилиты MAKE.
опреде-
ления
имя     Имя файла описаний утилиты MAKE. Обычно, это имя обрабатыва-
файла   емой программы без расширения. Если вы обновляете программу с
        именем PROGRAM.C, созданную в среде Quick-C, имя файла будет

        PROGRAM.MAK.

    В следующем списке описывается каждая опция, используемая с утилитой
MAKE и ее действия:

Опция   Действие

/D      Высвечивает последнюю дату модификации для каждого обрабаты-
        ваемого файла.
/I      Игнорирует коды завершения (называемые также кодами по уровню
        ошибок), возвращаемые программами, вызываемыми из файла опи-
        саний утилиты MAKE.
/N      "без выполнения" высвечивает команды из файла описаний, но не
        выполняет их. Данная опция бывает полезна для отладки файла
        описаний утилиты MAKE.
/S      "Режим молчания" строки во времы выполнения не высвечиваются.
/X имя  Переадресует сообщение об ошибках утилиты MAKE или любой дру-
файла   гой программы, вызываемой утилитой MAKE в данный файл. Если
        вместо имени файла стоит дефис (-), сообщения об ошибках на-
        правляются на стандартное устройство вывода. Если данная оп-
        ция не определена, сообщения об ошибках направляются на стан
        дартное устройство для вывода сообщений об ошибках вообще.

                 11.3. Использование макроопределений
                           для утилиты MAKE.

    Один  из  способов  упростить  файлы  определений-это   использовать
макрокоманды.  Макрокоманда-это  просто  имя,  которое  затем  в   файле
описаний утилиты MAKE вы можете заменить на любой текст. Если вы  хотите
изменить текст,  подставляемой на  место имени  макрокоманды, вы  можете
просто изменить  его в  макроопределении. Текст  автоматически обновится
повсюду, где используется имя данной макрокоманды.

    Макрокоманды могут вам понадобиться:

    -В качестве базовых имен исходных, объектных и выполняемых  файлов в
процессе разработки.  Если имя  программы меняется,  вы можете  изменить
базовое имя макроопределения; тогда базовое имя автоматически  изменится
для  исходного,  объектного  и  выполняемого  файла,  заданного  в файле
описания.

    -Для задания определенного  набора опций таких  команд, как QCL  или
LINK.  Если  опция  изменяется,  вы  можете  поменять  их  во всем файле
описаний путем простого изменения макроопределения.

              11.3.1. Определение и задание макрокоманд.

    Макроопределение имеет следующую основную форму:

    name=text

    После того, как вы  определите макрокоманду, вы можете  использовать
ее в файле описаний следующим способом ниже:

    $(name)

    Как только шаблон $(name)  появится в файле описаний,  данный шаблон
заменяется  на  text.  Имя  name  преобразуется  к  верхнему   регистру;
например,  имена  flags  и  FLAGS  эквивалентны.  Если вы определите имя
макрокоманды,  но  text  оставите  пустым,  либо если вы используете имя
макрокоманды, которое  не определено,  text будет  нулевой строкой.  Для
имени name можно также использовать любую переменную операционной среды,
определенную  в  текущей  среде.  Например,  если  переменная среды PATH
определена  в  текущей  среде,  значение  PATH  заменит  все   вхождения
макрокоманды $(PATH) в файле описаний.  (Заметим, что применение  данной
макрокоманды не переопределит значение переменной PATH в текущей среде).

    Макроопределения вы можете задать в одном из следующих мест:

    -Перед любым блоком описаний  в файле описаний утилиты  MAKE. Каждое
макроопределение должно быть расположено на отдельной строке. Все  знаки
табуляции или пробелы между name  и знаком равенства, либо между  знаком
равенства  и  text-игнорируются.  Все  табуляции  или  пробелы считаются
частью текста text.

    -В командной строке утилиты MAKE.

    Для   того,   чтобы   включить   знаки   табуляции   или   пробелы в
макроопределение в командной строке, заключите содержимое определения  в
двойные кавычки ('' '').

    Если одно и то же имя name определено более одного раза, соблюдается
следующий приоритет:

    1. Определение командной строки.

    2. Определение файла описаний.

    3. Определение операционной среды.

    Например,  если  PATH  определена  в  среде  DOS и в файле описаний,
утилита MAKE использует определение, находящееся в файле описаний.  Если
она определена также в командной строке утилиты MAKE, данное определение
подавляет оба других определения.

    -Пример:

    Предположим, что существует следующий  файл описаний утилиты MAKE  с
именем COMPILE:

base = ABC
debug = "/Zi"
$(base).EXE:         $(base).C
       QCL $(debug)$(base).C

    В  данном  файле  описаний  макроопределения  заданы для имен base и
debug.

    Макрокоманда base определяет  базовое имя объектного  и выполняемого
файлов, которые будут обрабатываться. Утилита MAKE заменит соответсвенно
все вхождения $(base)  на текст ABC.  Если имя программы  изменится, вам
будет  нужно  только  заменить  ABC  в  макроопределении  на  новое  имя
программы, и базовые имена двух файлов будут изменены автоматически.

    Макрокоманда debug просит команду  QCL создать выполняемый файл  для
отладчика Quick-C, либо отладчика Code View.

    Если  вы  хотите  отменить  одно  из макроопределений, находящихся в
файле описаний, вы можете задать  в командной строке утилиты MAKE  новое
макроопределение, как описано в следующем примере:

    MAKE base = DEF compile

    Данное  определение  макрокоманды  base  отменяет определение base в
файле описаний. В результате, base  заменяется на DEF, вместо ABC.  Если
вы  не   хотите  создавать   выполняемый  файл,   содержащий  отладочную
информацию,  вы  можете  запускать  утилиту  MAKE  с  помощью  следующей
командной строки:

    MAKE debug = compile

    Поскольку  макрокоманды,  определенные  в  командной  строке,  имеют
приоритет выше, чем те  же макрокоманды, определенные в  файле описаний,
утилита MAKE использует для макрокоманды $(debug) определения  командной
строки  (нулевую  строку;  обратите  внимание  на  пробел  между  знаком
равенства  и  именем  файла   описаний  утилиты  MAKE).  В   результате,
переключатель /Zi в командной строке QCL не появится, и выполняемый файл
не будет включать информацию для отладки.

                   11.3.2. Использование макрокоманд
                         в макроопределениях.

    Макрокоманды  могут  быть  использованы  внутри  других макрокоманд.
Например,  в  файле  описаний  утилиты  MAKE  PICTURE  вы  можете  иметь
следующее макроопределение:

    LIBS=$(DLIB)\MLIBCE.LIB $(DLIB)\GRAPHICS.LIB

    Вы  можете  затем  запустить  утилиту  MAKE и задать определение для
макрокоманды  с  именем  $(DLIB)  в  командной  строке,  как  показано в
следующем примере:

    MAKE DLIB = C:\LIB PICTURE

    В данном случае, каждое вхождение макрокоманды $(DLIB) будет в файле
описаний расширено до  C:\LIB; соответственно, определение  макрокоманды
LIBS в файле описаний будет расширено до следующего:

    LIBS=C:\LIB\MLIBCE.LIB C:\LIB\GRAPHICS.LIB

    Будьте осторожны, избегайте  рекурсивного вложения макрокоманд,  как
например, в следующем случае:

A= $(B)
B= $(C)
C= $(A)

    В  приведенном  выше  примере,   если  макрокоманда  $(B)  не   была
определена перед выполнением строки A= $(B), все остальные  макрокоманды
также не будут определены.

            11.3.3. Использование специальных макрокоманд.

    Утилита MAKE  имеет возможность  распознавать следующие  специальные
имена макрокоманд и автоматически подставляет для каждой соответствующий
текст:

Имя   Подставляемый текст

$*    Базовое имя выходного файла
$@    Полное имя выходного файла.
$**   Полный список имен входных файлов.

    -Пример:

TEST.EXE: MOD1.OBJ MOD2.OBJ MOD3.OBJ
          LINK $**, $@;
          $*

    В  приведенном  выше  примере  команды  LINK,  $**  представляет все
входные файлы, соответствующие выходному файлу TEST.EXE, а $@ определяет
полное имя TEST.EXE, как имя выполняемого файла в командной строке LINK.
Последняя строка  использует символы  $* для  определения базового имени
файла TEST.EXE,  то есть  TEST-как следующую  выполняемую команду. Таким
образом, приведенный выше пример эквивалентен следующему:

TEST.EXE: MOD1.OBJ MOD2.OBJ MOD3.OBJ
          LINK MOD1.OBJ MOD2.OBJ MOD3.OBJ, TEST.EXE;
          TEST

                   11.4. Определение правил вывода.

    Часто, утилита MAKE используется  для обновления файлов одного  типа
при  изменении  файлов  другого  типа.  Например, часто следует обновить
объектные файлы при изменении исходных файлов, либо обновить выполняемые
файлы или библиотеки при изменении исходных или объектных файлов.

    В  таких  случаях  вы  можете  задать  специальные "правила вывода",
которым будет следовать в  работе утилита MAKE. Данные  правила позволят
вам задать  единственную команду  MAKE для  преобразования всех выходных
файлов  с  данным  расширением  в  файлы с другим расширением. Например,
можно применить  правила вывода  для задания  единстнвенной команды QCL,
которая  превратит  все  файлы  (то  есть  файлы  с  расширением  .C)  в
выполняемые  файлы  (которые  имеют  расширение .EXE). Поскольку утилита
MAKE ищет соответствующие правила вывода, как только в блоке описаний не
окажется  команд,  вам  не  нужно  включать  команду QCL во все блоки, в
которых вы компилируете и компануете файл.

    Правила вывода имеют следующую основную форму:

.inextension.outextension:
    command
    [command]
    .
    .
    .

    В  данном  формате,  command  определяет  одну из команд, которую вы
должны использовать для преобразования файлов с расширением  inextension
в файлы с расширением outextension.

    Если мы рассмотрим приведенный ранее пример преобразования  исходных
файлов  в  выполняемые  файлы,  вам  следует определить для компиляции и
компановки  всех  исходных  файлов  текущего  каталога в объектные файлы
следующие правила вывода:

.C.EXE:
   QCL $*.C

    Задание  правил  вывода  без   команд  имеет  действие  снятия   уже
определенных ранее правил.

    Если утилита MAKE находит  блок описания без каких-либо  команд, она
ищет правила вывода, подходящие как для расширения выходного файла,  так
и для  расширения входного  файла. Если  такое правило  найдено, утилита
MAKE выполняет все команды, заданные в данном правиле.

    Правила вывода вы можете разместить в одном из следующих мест:

    -В файле описаний утилиты MAKE.

    -В  файле  с  именем  TOOLS.INI.  Данный файл известен под названием
"инструментальный стартовый  файл". Строка,  начинающаяся с  тэга [make]
должна стоять в файле TOOLS.INI перед всеми правилами зависимостей.

    Утилита MAKE ищет правила зависимостей в следующем порядке:

    1.В текущем файле описаний.

    2.В файле TOOLS.INI в текущем каталоге и на текущем устройстве. Если
она  не  может  найти  данный  файл,  то файл TOOLS.INI будет искаться в
каталоге, определенном  переменной операционной  среды INIT.  Как только
утилита MAKE находит  файл TOOLS.INI, она  просматривает файл в  поисках
строки, начинающейся с тэга  [make]. Затем она применяет  все подходящие
правила вывода, следующие за данной строкой.

    -Пример:

    Предположим, что файл TOOLS.INI содержит следующее:

[make]
.OBJ.LIB:
       LIB TEST.LIB +$*.OBJ;

    Теперь, предположим, что вы имеете следующий файл описаний:

EXAMPLE1.LIB: EXAMPLE1.OBJ
EXAMPLE2.EXE: EXAMPLE2.OBJ
       LINK /C0 EXAMPLE2,,,LIBV3.LIB

    Файл TOOLS.INI определяет правила вывода, которые выполняют  команду
LIB  в  файле  описаний,  чтобы  обновить  библиотеку,  как только будут
сделаны изменения в соответствующем объектном файле. Имя файла в правиле
вывода определяется специальной макрокомандой $*, так что данное правило
будет применяться к любому файлу с расширением .OBJ.

    Как только утилита MAKE встречает строку, содержащую выходной файл и
один или  более входных  файлов, сначала  она ищет  команды в  следующей
строке.  Если  никаких  команд  не  найдено,  утилита MAKE ищет правило,
которое  она  может  применить;  в  данном случае будет найдено правило,
определенное в  файле TOOLS.INI.  Утилита MAKE  применит данное правило,
заменив  при  выполнении  данной  команды  макрокоманду  $* на EXAMPLE1.
Соответственно, команда LIB будет выглядеть:

    LIB TEST.LIB +EXAPLE1.OBJ

    Когда  утилита  MAKE  достигает  строки,  содержащей  выходной  файл
EXAMPLE2.EXE, она  не ищет  правило зависимости,  поскольку для  данного
соотношения между входным и  выходным файлом команда задана  явно. Таким
образом, в  данном случае,для  создания выполняемого  файла утилита MAKE
скомпанует объектный  файл EXAMPLE2.OBJ  с библиотекой  LIBV3.LIB вместо
добавления файла EXAPMLE2.OBJ к библиотеке TEST.LIB.

                   11.5. Использование файлов .MAK.

    Если вы создаете программный  список для программы в  среде Quick-C,
Quick-C автоматически  строит файл  описания для  данной программы. Файл
описания  имеет  то  же  самое  базовое  имя,  что  и  программа,  но  с
расширением    .MAK.    Файл    описания    позволяет    пакету  Quick-C
перекомпилировать и перекомпановать все модули, составляющие  программу,
если какой-либо модуль в программе, либо подключаемый файл, определенный
в программном модуле, претерпел изменения.

                11.5.1. Использование файлов типа .MAK
                           с утилитой MAKE.

    При  незначительных  изменениях  утилиту  MAKE  и  файл  .MAK  можно
использовать вне программной среды  Quick-C. Если вы создаете  программу
вне среды Quick-C в файле .MAK должен присутствовать вызов библиотеки  с
расширением .LIB. Если же во время компиляции программы в среде  Quick-C
была загружена  библиотека Quick,  файл .MAK  будет содержать библиотеки
Quick.

    При  обновлении  программы  вне  среды Quick-C пользуйтесь следующей
процедурой:

    1.Создайте копию файла .MAK с другим именем, для того, чтобы Quick-C
мог продолжать использовать оригинал.

    2.Отредактируйте   данную   копию,   подставив   имя соответствующей
автономной   библиотеки   в   строку   комментария,   показывающую какая
библиотека будет использоваться.

    3.Запустите  утилиту  MAKE  и  задайте  имя измененного файла .MAK в
качестве программного входа. Утилита MAKE автоматически  перекомпилирует
и перекомпанует программу, которая может быть загружена в среду Quick-C,
как обычно.

                11.5.2. Зависимости включаемых файлов.

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

    Чтобы  иметь  гарантию  того,  что  программа  будет   автоматически
обновляться при изменении любого из подключаемых файлов,  удостоверьтесь
что вы  задали включаемые  файлы в  качестве входных  файлов файла .MAK.
Хотя  компилятор  Quick-C  не  помещает  включаемые  файлы  в  файл .MAK
автоматически, он сохранит все включаемые файлы, которые вы поместите  в
файл .MAK с  помощью редактора текстов.  Когда вы загрузите  программный
список  в  среду  Quick-C  с  помощью  команды  Set  Program  LIst,  все
включаемые файлы,  заданные в  файле .MAK  будут включены  в программный
список. Компилятор Quick-C использует включаемые файлы тем же  способом,
что и  остальные файлы  в программном  списке, если  включаемый файл был
обновлен  со  времени  последней  компиляции  программы, программа будет
перекомпилирована.

    -Пример:

    Предположим, что  каждый модуль  программы с  именем Lexer  содержит
включаемый файл  с именем  globals.h, который  располагается в  каталоге
\INCLUDE. Предположим также, что первые несколько строк файла  lexer.mak
следующие:

#
# Program: Lexer
#
        qcl -c -WO -Zq -AM $*.c
lexer.obj : C:\SRC\lexer.c
gettoken.obj : C:\SRC\gettoken.c
       .
       .
       .

    Вы  можете  изменить  файл  lexer.mak,  как показано ниже- для того,
чтобы  иметь  уверенность,  что  программа  Lexer  будет  обновлена  при
изменении файла globals.h:

#
# Program: Lexer
#
        qcl -c -WO -Zq -AM $*.c
lexer.obj : C:\SRC\lexer.c C:\INCLUDE\globals.h
gettoken.obj : C:\SRC\gettoken.c C:\INCLUDE\globals.h
       .
       .

                  11.5.3. Задание опций компановщика.

    Когда   компилятор   Quick-C   компилирует   программу   с   помощью
программного списка, сначала он компилирует модули в программном списке,
а затем связывает  результирующие объектные файлы.  Процессом компановки
можно  управлять  с  помощью  задания  специальных условий в файле .MAK,
содержащем программный список.

    Можно просто определить макрокоманду с именем LDFLAGS, как  показано
ниже:

    LDFLAGS= link-opt...

    Макрокоманда LDFLAGS автоматически помещается в строку команды  LINK
файла  .MAK.Ваше  определение  должно  следовать  правилам,  описанным в
Разделе 11.3.1.

    Опции программы  LINK, определенные  вами, используются  каждый раз,
как только вы перекомпилируете  и перекомпануете модули из  программного
списка; они действуют до тех пор, пока вы не измените значение LDFLAGS в
файле .MAK.


                           ПРИЛОЖЕНИЕ В.

                   Работа с моделями памяти QUICK-C.

В.1   Ближняя и дальняя адресация.
В.2   Использование стандартных моделей памяти.
      В.2.1. Создание программ для малой модели памяти.
      В.2.2. Создание программ для средней модели памяти.
      В.2.3. Создание программ для компактной модели памяти.
      В.2.4. Создание программ для большой модели памяти.
В.3   Использование ключевых слов "near" и "far".
      В.3.1. Поддержка библиотек для "ближней" и "дальней"
             памяти.
      В.3.2. Описание данных для "near" и "far".
      В.3.3. Описание функций с ключевыми словами
             "near" и "far".
      В.3.4. Преобразования указателей.
В.4   Установка порога данных.
В.5 Наименование текстового сегмента.

    В пакете  Quick-C вы  можете управлять  использованием памяти  вашей
программой, посредством определения для программы моделей памяти. Обычно
определять модели памяти не требуется, за исключением следующих случаев:

    -Программа, компилируемая в среде Quick-C имеет данные типа  STATIC,
занимающие больше 64К.

    -Программа,  компилируемая   с  помощью   команды  QCL   имеет  код,
превышающий 64К и данные типа STATIC, превышающие 64К.

    В данных случаях вы имеете следующие возможности:

    1.Если вы  выполняете компиляцию  с помощью  команды QCL,  вы можете
выбрать  одну  из  стандартных  моделей  памяти (средняя, компактная или
большая), используя опции /A.

    2.Можно  создать  программу,  использующую  смешанную модель памяти,
применяя ключевые слова near и far.

    3.Можно объединить метод 2 и метод 1.

                 В.1 "Ближняя" и "дальняя" адресация.

    Термины  "near"  и  "far"  (ближний  и дальний)-являются решающими в
понимании  концепции  моделей  памяти.  Данные термины обозначают, каким
образом  осуществляется  доступ   к  данным  в   сегментной  архитектуре
семейства микропроцессоров 8086 (8086, 80186, 80286).

    Операционная  система  DOS  загружает  код  и данные, распределенные
вашей программой  в сегменты  (физическую память).  Каждый сегмент имеет
длину 64К. Поскольку  для программного кода  и данных всегда  выделяются
разные сегменты, минимальное число сегментов, выделенных для  программы,
это  два.  Поскольку  эти  два  сегмента требуются каждой программе, они
называются  стандартными  (используемыми  по  умолчанию).  Малая  модель
памяти использует  только два  этих сегмента.  Остальные модели  памяти,
описанные в данной  Главе, используют либо  более одного сегмента  кода,
либо более одного сегмента данных, либо и то, и другое.

    В семействе микропроцессоров 8086, адресация памяти состоит из  двух
частей:

    1.16-ти битовое число,  представляющее собой базовый  адрес сегмента
памяти.

    2.Второе  16-битовое  число,  которое  задает  смещение  в  пределах
данного сегмента.

    Архитектура  микропроцессора  8086  такова,  что  доступ  к данным в
стандартном  сегменте   кода  или   данных  осуществляется   посредством
16-битового   значения   смещения.   Это   возможно,   поскольку  адреса
стандартных сегментов  всегда известны.  Данное 16-разрядное  смещение и
называется  "ближний"   адрес;  к   нему  можно   обратиться  с  помощью
"короткого" указателя. Так как для доступа к "ближней" памяти  требуется
только  16-разрядная  арифметика,  "короткие"  ссылки  на код или данные
всегда меньше и более эффективны.

    Когда данные или код  лежат вне стандартных сегментов,  адрес должен
использовать  как  значение  сегмента,  так  и  значение смещения. Такие
адреса называются "дальними"  адресами; в программе  СИ к таким  адресам
обращаться  можно  с  помощью  "длинных"  указателей.  Доступ  к данным,
которые  можно  назвать  "дальними",  стоит  дороже,  в смысле размера и
скорости  программ,  зато  это  средство  позволяет  вам  адресовать всю
память,  а  не  только  часть  в  64К.  Оставшаяся  часть  данной  Главы
рассматривает  различные  методы,  которые  вы  можете  использовать для
управления в вашей программе "ближней" и "дальней" адресацией.

            В.2. Использование стандартных моделей памяти.

    Библиотеки,  построенные  с  помощью  программы  SETUP  поддерживают
четыре  стандартных  модели  памяти.  Использование  стандартных моделей
памяти-это  простейший   способ  управлять   доступом  к   данным  вашей
программы.

    Когда   вы   используете   стандартные   модели   памяти, компилятор
поддерживает   соответсвующие   библиотеки.   Библиотеки,соответствующие
выбранной вами модели памяти, используются автоматически. Каждая  модель
памяти имеет свою собственную библиотеку.

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

    Недостатком  в  использовании  стандартных  моделей  памяти является
исключетельно то, что с их  помощью можно получить не самый  эффективный
код.  Например,  если  вы   имеете  программу  средней  модели   памяти,
содержащую  большой  массив,  из-за  которого  ваша  программа  занимает
память, превышающую 64К-предел для средней модели памяти, было бы  лучше
объявить один массив с ключевымс словом "far", в то время, как остальная
программа будет храниться в  средней модели памяти, в  противоположность
использованию  компактной  модели  для  всей  программы.  Чтобы получить
максимальную гибкость и  управлять процессом использования  памяти вашей
программой,  вы  можете  объединить  метод  стандартных моделей памяти с
ключевыми словами near и far,  описанными в Разделе В.3. Чтобы  во время
компиляции задать  одну из  четырех стандартных  моделей памяти  (малую,
среднюю, компактную  или большую)  можно использовать  опцию /А  команды
QCL. Данные  опции моделей  памяти рассматриваются  в следующих  четырех
разделах.

---------------------------------------------------------------------

    Примечание:

    В следующих разделах, которые описывают адресные преобразования  для
различных моделей памяти, очень важно помнить о двух общих  особенностях
всех пяти моделей:

    1. Ни  один исходный  модуль не  может сгенерировать  64К или больше
кода.

    2. Ни один элемент данных не может превышать 64К.

---------------------------------------------------------------------

           В.2.1. Создание программ для малой модели памяти.

    -Опция:

    /AS

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

    По  умолчанию,  как  к  коду,  так  и к данным программ малой модели
памяти доступ осуществляется через "ближние" адреса. Вы можете  отменить
такой подход  посредством использования  ключевого слова  "far". Если вы
явно  не  определите  модель  памяти,  команда QCL автоматически создает
программы  для  малой  модели  памяти.  То есть опция /AS обеспечивается
автоматически, вам нет необходимости задавать ее явно.

    На рисунке В.1 показано, как распределяется память в малой модели.

    Рисунок В.1. Карта распределения памяти для малой модели.

Старшие адреса

      Динамическая об-   нераспределенная область для динамического
      ласть (Heap)       распределения

      Стек (STACK)       локальные данные

    _BSS, c_common       Неинициализированные глобальные и статисти-
                         тические данные.

      CONST              данные с доступом только на чтение, сгенери-
                         рованные компилятором.

      _DATA              стандартный сегмент данных (проинициализиро-
                         ванные глобальные и статистические данные)

      NULL               контроль над присвоением нулевого указателя.
       TEXT              сегмент кода для всех модулей

Младшие адреса

          В.2.2. Создание программ для средней модели памяти.

    -Опция:

    /AM

    Опция средней модели памяти  распределяет один сегмент для  данных и
несколько  сегментов  для  программного  кода.  Каждому исходному модулю
отводится свой собственный сегмент кода.

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

    Поскольку  программы,  скомпилированные   в  среде  Quick-C   всегда
используют среднюю модель  памяти, данную опцию  вам следует задавать  в
том случае, если вы применяете команду QCL, чтобы скомпилировать  модуль
для использования в программной среде Quick-C.

    На  рисунке  В.2  показано,  как  распределяется  память для средней
модели.

Старшие Динамическая   неиспользованная память, используемая для ди-
адреса  область (Heap) намического распределения.

        STACK          локальные данные

        _BSS c_common  неинициализированные глобальные и статистичес-
                       кие данные.

        CONST          сгенерированные компилчтором данные с досту-

                      пом только на чтение.

        _DATA          стандартный сегмент данных: проинициализирова-
                       нные глобальные и статистические данные

        NULL           контроль на присваивание нулевого указателя

        module TEXT    один сегмент кода на каждый модуль

младшие адреса

        В.2.3. Создание программ для компактной модели памяти.

    -Опция:

    /AC

    При задании  компактной модели  памяти компилятор  создает несколько
сегментов для данных, но всего один сегмент для программного кода.

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

    Стандартно, доступ к элементам  кода в программах компактной  модели
осуществляется   посредством   "ближних"   адресов,   а   к    элементам
данных-посредством "дальних" адресов. Данный стандарт вы можете отменить
с помощью ключевого слова "near" для данных и ключевого слова "far"  для
программного кода.

    На рисунке  В.3 показано,  как распределяется  память для компактной
модели памяти.

Старшие "дальняя"дина- неиспользованная "дальняя" память, применяемая
адреса  мическая об-   для динамического распределения.
        ласть(far heap)

        "ближняя"дина- неиспользованная "ближняя" память, применяемая
        мическая об-   для динамического распределения.
        ласть(near heap)

        STACK          локальные данные

      _BSS и c_common  неинициализированные глобальные и статистичес-
                       кие данные

        CONST          данные с доступом "только-чтение", сгенери-
                       рованные компилятором

        _DATA          стандартный сегмент данных проинициализирован-
                       ные глобальные и статистические данные

        NULL           контроль на присвоение нулевого указателя
        сегмент данных инициализированные и неинициализированные гло-
                       бальные и статистические "дальние" данные

         TEXT          сегмент кода для всех модулей

младшие
адреса

---------------------------------------------------------------------

    Примечание:

    Обратите внимение,  что в  средней и  компактной модели  в некоторых
ситуациях  NULL  следует  использовать  очень  осторожно.  Реально, NULL
означает  нулевой  указатель  на  данные.  В  моделях  памяти, в которых
указатели на код и на модели имеют  один и тот же размер, он модет  быть
использован в любом  месте. Однако, в  моделях памяти, где  указатели на
код данные имеют различный  размер, ситуация иная. рассмотрим  следующий
пример:

void func1(char *dp)
{
.
.
.
}
void func2(char (*fp)(void))
{

.
.
.
}
main()
{
func1(NULL);
func2(NULL);
}

    В  данном   примере  обеим   функциям  func1   и  func2   передается
16-разрядный  указатель  при  компиляции  в  средней  модели  памяти,  и
32-разрядный указатель при компиляции в компактной модели, если не будут
в начале программы добавление прототипы, обозначающие типы данных,  либо
не будет использовано явное  приведение типов в аргументе  функции func1
(компактная модель), либо func2(средняя модель).

---------------------------------------------------------------------

                  В.2.4 Создание программ для большой
                            модели памяти.

    -Опция:

    /AL

    При  заданной  опции   большой  модели  памяти   компилятор  создает
несколько сегментов (столько, сколько требуется) как для кода, так и для
данных.

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

    Стандартно, в  программах большой  модели памяти  доступ к  коду или
данным  осуществляется  посредством  "дальних"  адресов. Отменить данный
стандарт вы можете с помощью использования ключевого слова "near".

    На рисунке В.4 показано распределение памяти большой модели.

Старшие "дальняя"дина- неиспользованная "дальняя" память, применяемая
адреса  мическая об-   для динамического распределения.
        ласть(far heap)

        "ближняя"дина- неиспользованная "ближняя" память, применяемая
        мическая об-   для динамического распределения.
        ласть(near heap)

        STACK          локальные данные

      _BSS и c_common  неинициализированные глобальные и статистичес-
                       кие данные

        CONST          данные с доступом "только-чтение", сгенери-
                       рованные компилятором

        _DATA          стандартный сегмент данных проинициализирован-
                       ные глобальные и статистические данные

        NULL           контроль на присвоение нулевого указателя

        сегмент данных инициализированные и неинициализированные гло-
                       бальные и статистические "дальние" данные

        module  TEXT   сегмент кода для всех модулей

младшие
адреса

            В.3. Применение ключевых слов "near " и "far".

    Существует  одно  ограничение  на  структуру заранее заданной модели
патяти: когда вы изменяете модель памяти, все размеры адресов для кода и
данных  должны  также  изменяться.  Однако, компилятор Microsoft Quick-C
позволяет вам отменить стандартные адресные соглашения для данной модели
памяти  и  установить   доступ  посредством  "коротких"   или  "длинных"
указателей. Это действие  выполняется с помощью  ключевых слов "near"  и
"far". Данные специальные модификаторы  типа могут быть использованы  со
стандартной  моделью   памяти  для   того,  чтобы   преодолеть  адресные
ограничения  на  определенные  элементы  кода  или  данных,  либо  чтобы
оптимизировать доступ к данным элементам, причем без изменения  адресных
соглашений  для  программы  в   целом.  В  таблице  В.1   показано,  как
использование ключевых слов  влияет на адресацию  кода или данных,  либо
указателей на код или данные.

                                                 Таблица В.1.
      Адресация кода или данных, описанных с ключевыми словами
      "near" или "far".

Ключевое Данные                   Функции                 Арифметика

 слово                                                    указателей

near     Распологаются в стандар- Предполагается, что на- Использует
         тном сегменте данных;    ходятся в текущем сег-  16 разря-
         доступ посредством 16-   менте кода; адресуются   дов
         -разрядного адреса (ука- посредством 16-разрядно-
         затели на данные имеют   го адреса (указатели на
         16 разрядов)             функции имеют 16 разрядов)

Ключевое Данные                   Функции                 Арифметика

 слово                                                    указателей

far      Могут распологаться в лю Не обязательно располо- Использует

         бом месте памяти-не обя- жены в текущем сегменте 16 разрядов
         зательно в текущем сег-  кода; адресуются посред-
         менте данных; адресуются ством 32-разрядного адре
         посредством 32-разрядно- са (указатели на функции
         го адреса (указатели на  имеют в длину 32 разряда)
         данные имеют в длину 32
         разряда).

---------------------------------------------------------------------

    Примечание:

    Ключевые слова near и  far-не являются стандартной частью  языка СИ;
Они  имеют  смысл  только   в  системах,  архитектура  которых   подобна
микропроцессору 8086. Имейте это в виду, если вы собираетесь  переносить
ваш программный код на другие системы.

---------------------------------------------------------------------

    В компиляторе Microsoft Quick-C  ключевые слова near и  far являются
стандартными. Для  того, чтобы  данные ключевые  слова трактовались, как
обчные идентификаторы, вам следует выполнить одно из следующих действий.

    -Если  вы  компилируете   программы  в  среде   Quick-C,  выполняйте
компиляцию с выключенной опцией Language Extensions.

    -Если вы  компилируете программы  с помощью  команды QCL,  задайте в
процессе компиляции опцию /Za.

    Данные опции могут оказаться полезны, если вы компилируете программы
с  помощью  компиляторов,  в  которых  near  и far не являются ключевыми
словами-например, если вы переносите программу, в которой одно из данных
слов  используется  в  качестве  метки.  о  том,  как использовать опции
Language  Extension  и  /Za,  смотрите  Раздел  8.1.4.6   "Использование
расширений к языку СИ фирмы Microsoft: Опция Language Extensions."

             В.3.1. Поддержка библиотек для ключевых слов
                              near и far.

    Если  вы  применяете  ключевые  слова  near  и  far  для модификации
адресных соглашений  отдельных элементов  вам можно  с вашей  программой
использовать одну из  стандартных библиотек (малую,  компактную, среднюю
или большую). Однако, вы  должны быть осторожны при  вызове библиотечных
процедур. Обычно, вам нельзя передавать "длинные" указатели, либо адреса
на  "дальние"  элементы  данных  библиотечным  процедурам  малой  модели
памяти.   (Исключениями  к   данному  положению  являются   библиотечные
процедуры halloc и hfree, а также семейство функций printf). Но конечно,
вы  всегда  сможете  передать  значение "дальнего" элемента библиотечной
процедуре малой модели. Например:

long far_time val;
time (&time_val);   /* некорректно */
printf("%ld\n", time_val); /* корректно */

    Если  вы  используете  ключевые  слова  near  и far, мы настоятельно
рекомендуем   вам   применять   прототипы   функций   со  списками типов
аргументов-для  гарантии   того,  что   все  аргументы-указатели   будут
корректно передаваться функциям. Подробности вы найдете в Разделе  В.3.4
"Преобразования указателя".

                    В.3.2. Описание данных с типом
                              near и far.

    Ключевые слова near и far модифицируют либо объекты, либо  указатели
на объекты.  При использовании  их для  описания данных  или кода  (кода
указателей на данные или код), помните о следующих правилах:

     -Ключевое слово всегда оказывает влияние на объект или указа-
      тель, находящийся непосредственно справа. В сложных описа-
      ниях, ключевое слово far и элемент, находящийся непосредстве-
      нно справа, считается одной единицей. Например, в описании

      char far* *p;

      p-это указатель (размер которого зависит от заданной модели па-
      мяти) на длинный указатель на данные типа char. Полные правила
      использования специальных ключевых слов в сложных описани-
      ях смотрите в документе "Microsoft C Language Reference"
      (Справочное руководство по языку СИ фирмы Microsoft).
     -Если элемент, находящийся непосредственно справа от ключевого
      слова, является идентификатором, ключевое слово определяет либо
      элемент, размещаемый в стандартном сегменте данных (near), либо
      в отдельном сегменте данных (far). Например:

      char near a;

      а размещается в качестве элемента типа char с "ближним" адресом

     -Если элемент, находящийся непосредственно справа от ключевого
      слова,является указателем, ключевое слово определяет, будет ли
      указатель содержать "ближний" адрес (16 разрядов), либо "даль-
      ний" адрес (32 разрада). Например:

      char far *p;

      p размещается, как "длинный" указатель (32 разряда) на элемент
      типа char.

     -Ключевое слово far нальзя использовать для описания данных в
      программах, функционирующих в среде Quick-C. Однако, его можно
      использовать для описания указателей на данные. Например, за-
      пись

      int far item;

      для программ, работающих в программной среде, является некорре-
      ктной, а запись:

      int far *item;

      является корректной.

Примеры:

В примерах данного раздела показаны описания данных, использующие
ключевые слова near и far.

char a[3000]; /* программа для малой модели памяти */
char far b[3000];

    Первое описание в  данном примере размещает  массив a в  стандартном
сегменте данных. В противоположность этому, массив b во втором

    описании  может  быть  размещен  в  любом "дальнем" сегменте данных.
Поскольку данные описания находятся в программе для малой модели памяти,
массив a, вероятно представляет собой часто используемые данные, которые
для  более  быстрого  доступа  помещаются  в стандартный сегмент данных.
Массив b,  скорее всего  представляет собой  редко используемые  данные,
которые, могут привести к тому, что размеры стандартного сегмента данных
превысят 64К и могут  вынудить программиста использовать большую  модель
памяти, если  массив не  описан с  ключевым словом  far. Второе описание
использует большой массив, поскольку наиболее вероятно, что программисту
понадобится оопределить размещение в памяти для элементов  значительного
размера.

char a[3000]; /* программа для большой  */
char near b[3000]; /* модели памяти */

    В приведенном выше примере, вероятно, скорость доступа для массива a
не будет верной. Даже, хотя массив может быть размещен, или не  размещен
в стандартном  сегменте данных,  доступ к  нему будет  осуществляться по
32-разрядному  адресу.  Массив  b  явно  описан,  как near. Это увеличит
скорость доступа в данной модели памяти (большой).

char *pa; /* программа для малой */
char far *pb; /* модели памяти */

    В приведенном выше  примере указатель pa  описан, как "короткий"  на
элемент  данных  типа  char.  Указатель  является коротким по умолчанию,
поскольку   данный   пример   работает   в   малой   модели   памяти.  В
противоположность этому,  pb описан,  как длинный  указатель на  элемент
типа char; в этом случае pb может быть использован в качестве  указателя
на  массив  символов,  хранящийся  в  сегменте, отличном от стандартного
сегмента данных. Например, pa можно использовать в качестве указателя на
массив a из первого примера, а pb-может быть указателем на массив b.

char far * *pa; /* программа для малой модели памяти */
char far * *pa; /* программа для большой модели памяти */

    В данном примере  описание указателя иллюстрирует  взаимосвязь между
выбранной моделью памяти и ключевыми  словами far и near. Хотя  описания
для pa идентичны,  в малой модели  памяти pa будет  описан, как короткий
указатель на  массив длинных  указателей типа  char, в  то время,  как в
большой модели памяти, pa будет описан, как длинный указатель на  массив
длинных указателей типа char.

    char far *near *pb; /* любая модель */

    В приведенном  выше примере  в первом  описании pb  описываются, как
короткий указатель  на массив  длинных указателей  типа char;  во втором
описании, pb описан, как длинный указатель на массив длинных  указателей
типа char. Обратите внимание, что в данном примере ключевые слова far  и
near отменяют адресные соглашения для данной модели памяти, показанные в
предыдущем примере; описания  для pb будут  иметь то же  самое действие,
независимо от модели памяти.

        В.3.3. Описания функций с ключевыми словами near и far.

    Правила  использования  ключевых  слов   near  и  far  для   функций
аналогичны использованию этих ключевых  слов для данных, что  вы увидите
из следующих правил:

      -Ключевое слово всегда оказывает действие на  функцию или ука-
      затель, находящиеся непосредственно справа. Смотрите Раздел
      4.3.3. "Описание с помощью специальных ключевых слов" в доку-
      менте "Microsoft CLanguage Reference" (Справочное руководство
      по языку СИ фирмы Microsoft), в котором вы найдете подробные
      правила использования комплексных объявлений.

     -Если описываемый элемент справа от ключевого слова является
      функцией, то ключевое слово определяет, каким образом будет
      распределяться память для данной функции ("ближняя" или "даль-
      няя"). Например, строка:

      char far fun ();

      определяет fun как функцию, вызываемую по 32-разрядному адресу и
      возвращающую тип char.

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

      char (far *pfun)();

      определяет pfun, как длинный указатель (32 разряда) на функцию,
      возвращающую тип char.

     -Описания функций должны соответствовать определениям функций.

Примеры:

void char far fun(void); /* малая модель */

void char far fun (void)
        {
        .
        .
        .
        }

    В приведенном выше примере,  fun описана, как функция,  возвращающая
тип char. Ключевое слово far в описании означает, что функция fun  может
быть вызвана по 32-разрядному вызову.

static char far * near fun( ); /* большая модель */
static char far * near fun( )
        {
        .
        .
        .
        }

    В  приведенном  выше  примере  программы  для  большой модели памяти
функция  fun  описана,  как  "ближняя"  функция,  возвращающяя "длинный"
указатель на тип char. Такая  функция в программе большой модели  памяти
может  быть  использована  в  качестве  часто вызываемой вспомогательной
процедуры, но только процедурами в ее собственном модуле. Поскольку  все
процедуры данного модуля  находятся в одном  и том же  кодовом сегменте,
доступ  к  функции  всегда  может  быть организован с помощью "ближнего"
вызова. Однако, указатель на fun нельзя передавать в качестве  аргумента
другой функции вне модуля, в котором функция fun описана.

void far *fun(void); /* малая модель */
void (far *pfun) ( = = fun;

    В приведенном выше примере для малой модели памяти pfun определяется
как длинный  указатель на  функцию, имеющую  тип возвращаемого  значения
void,  и  затем  адрес  fun  присваивается  pfun. Фактически, pfun можно
использовать в  качестве указателя  на любую  функцию, доступ  к которой
получается посредством  "ближнего" вызова.  Обратите внимание,  что если
функция, адресуемая  с помощью  pfun не  была описана  с ключевым словом
far, либо она не является far  по умолчанию, то вызов функции с  помощью
pfun приведет к ошибке.

double far * (far fun=) =; /*компактная модель */
double far * (far *pfun)( ) = fun;

    Последний пример описывает pfun  в качестве "длинного" указателя  на
функцию, которая  возвращает "длинный"  указатель типа  double, а  затем
присваивает  адрес  fun  pfun.  Данные  строки могут быть использованы в
программах компактной  модели памяти  для функций,  вызываемых не  очень
часто,  и  таким  образом,  которые  могут  не  находиться в стандартном
сегменте  кода.  Как  функция,  так  и  указатель на функцию должны быть
описаны с ключевым словом far.

                   В.3.4. Преобразование указателей.

    Передача указателей в качестве  аргументов функций может привести  к
автоматическому преобразованию  указателя-аргумента, поскольку  передача
указателя функции приводит размер указателя к большему из следующих двух
размеров:

     -Стандартный размер указателя для данного типа, определяемый
      моделью памяти, используемой в процессе компиляции.
      Например, в программах средней модели памяти, аргументы-ука-
      затели на данные являются стандартно "короткими", а аргументы-

      -указатели на код являются по умолчанию "длинными".

    -Тип аргумента.

    Если  прототип  функции   задан  с  типами   аргументов,  компилятор
выполняет контроль  на типы  и производит  преобразование действительных
аргументов  к  описанному  типу  соответствующего формального аргумента.
Однако, если  описание отсутствует,  либо список  типов аргументов пуст,
компилятор   автоматически   преобразует   указатели-аргументы   либо  к
стандартному типу,  либо к  типу аргумента,  в зависимости  от того, что
больше.  Чтобы  избежать  несоответствия  аргументов, вам следует всегда
использовать прототип, имеющий типы аргуметов.

Примеры:
/* данная программа в компактной или большой модели памяти приводит
** к неожиданным результатам */
*/
main( )
       {
        int near *x
        char far *y;
        int z = 1;
        test_fun (x, y, z); /* преобразуется к длинному указателю */
        }
int test_fun(ptr1, ptr2, a)
        int near *ptr1;

        char far *ptr2;
        int a;
        {
        printf("Value of a = %d\n", a);
        }

    Если предшествующий  пример компилируется  в малой  модели памяти (с
опцией /AS в командной строке QCL) или в средней модели памяти (либо без
опций модели памяти, либо с  опцией /AM в командной строке  QCL), размер
аргумента-указателя  х-16  разрядов,  размер  аргумента-указателя   y-32
разряда, и  распечатываемое значение  a -1.  Однако, если предшествующий
пример компилируется  с опциями  /AC или  /AL, оба  указателя x  и y при
передаче  функции  test  fun  автоматически  конвертируются  в "длинные"
указатели.  Поскольку  ptr1,первый  параметр  test  fun  определен   как
короткий указатель, он занимает  только 16 из передаваемых  32 разрядов.
Следующий параметр ptr2 займет оставшиеся 16 разрядов перезаданных  ptr1
плюс  16  разрядов  из  32  разрядов,  передаваемых ему. Наконец, третий
параметр, а займет оставшиеся 16  разрядов от ptr2, вместо значения  z в
функции main. Данный процесс сдвигов не сгенерирует сообщение об ошибке,
поскольку как вызов функции, так  и определение функции корректны, но  в
данном  слечае  программа  не  будет  работать так, как вы предполагали,
поскольку значение, присвоенное а будет не тем, какое должно быть

    Чтобы передать ptr1, как  "короткий" указатель вам следует  добавить
вначале описания, определяющее аргумент  функции test fun, как  короткий
указатель, как показано в следующем примере:

/* во-первых, опишим функцию test_fun таким образом, чтобы
** компилятор заранее знал, что аргумент является коротким указа-
** телем */

*/
int test_fun)int near*, char far *, int);
main( )
        {
        int near *x;
        char far *y;
        int z = 1;
        test_fun(x, y, z); /* теперь, x не будет преобразован к длин-
                           ** ному указателю; он будет передан, как
                           ** короткий указатель, независимо от того,
                           ** какая модель памяти используется
                           */
        }
int test_fun(ptr1, ptr2, a)
        int near *ptr1;
        char far *ptr2;
        int a;
        {
        printf ("Value of a = %d\n", a);
        }

    Заметим, что перестановка порядка определений для функции test fun и
main  в  первом  примере  не  поможет избежать преобразований указателя;
аргументы-указатели  должны  быть  описаны  первый  раз,  как  во втором
примере.

                     В.4. Установка порога данных.

-Опция:

/GT[number]

    По умолчанию, в малой и средней моделях памяти компилятор  размещает
все глобальные и статистические данные в стандартном сегменте данных.  В
компактной  и  большой  модели  памяти  в  стандартном  сегменте  данных
размещаются  только   проинициализированные  статические   и  глобальные
данные.  При  заданной  опции  /GT  все  элементы данных, размер которых
превышает number байтов, будут размещаться в новом сегменте данных. Если
число number задано, оно должно непосредственно следовать за опцией /GT,
без разделяющих пробелов. Если число number опущено, пороговым числом по
умолчанию будет 256. Если же опущена опция /GT, пороговое значение равно
32767.

    Опцию  /GT  можно  использовать  только  с  программами компактной и
большой модели, поскольку программы малой и средней модели имеют  только
один сегмент данных. Данная опция бывает полезна, если программы,  имеют
более  64К  проинициализированных   статических  и  глобальных   данных,
распределенных на малые элементы.

                 В.5.Наименование текстового сегмента.

    -Опция:

    /NTtextsegment

    Сегментом является  последовательный блок  двоичной информации  (код
или  данные),  полученный  после  работы  компилятора Microsoft Quick-C.
Каждый модуль  (то есть  каждый объектный  файл, созданный компилятором)
имеет,  по  крайней  мере,  2  сегмента:  текстовый  сегмент, содержащий
программные инструкции, и сегмент данных, содержащий программные данные.

    Каждый сегмент  в каждом  модуле имеет  имя. Компановщик  использует
данное  имя  для  определения  порядка,  в  котором программные сегменты
располагаются в памяти при загрузке программы для выполнения.  (Обратите
внимание, что сегменты группы, называемой DGROUP, являются исключением).

    Имена  текстового  сегмента  и  сегмента  данных  обычно   создаются
компилятором Quick-C. В программах  средней модели памяти текст  каждого
модуля размещается в отдельном  сегменте со своим именем,  получаемым из
имени  базового  модуля  с  суффиксом  TEXT. Сегмент данных получает имя
DATA.

    Стандартное имя  текстового сегмента  вы можете  отменить с  помощью
опции  /NT  компилятора  Quick-C  ("name  text"),  таким образом изменяя
стандартный  порядок  загрузки.  Данная  опция  дает текстовому сегменту
каждого компилируемого модуля новое имя.

    Аргумент  textsegment,  используемый  опцией  /NT,  может быть любой
комбинацией букв и цифр. Пробел между /NT и textsegment необязателен.


                             ПРИЛОЖЕНИЕ С.

                Интерфейс языка СИ с языком Ассемблер.

С.1.  Написание ассемблерной процедуры.
      С.1.1. Создание процедуры.
      С.1.2. Ввод процедуры.
      С.1.3. Размещение локальных данных (необязательно).
      С.1.4. Резервирование значений регистров.
      С.1.5. Параметры доступа.
      С.1.6. Возвращаемое значение (необязательно).
      С.1.7. Выход из процедуры.
С.2.  Вызов процедур на языке Ассемблер из СИ-программы.
С.3.  Вызов СИ из языка Ассемблер.
С.4.  Сегментная модель фирмы Microsoft.

    Программирование со смешением языков-это процесс создания  программ,
использующих два или более исходных языка. Данное средство позволит  вам
использовать уникальные возможности языков  BASIC, C, FORTRAN, Pascal  и
Macro  Assembler  (MASM)  фирмы  Microsoft.  Любой  из этих языков (в их
последних версиях) может вызывать любой другой.

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

    Смешанное программирование, кроме того, облегчает переход от  одного
языка к другому.  Например, вы можете  иметь большую программу  на языке
FORTRAN, а затем конвертировать ее в СИ.

    Вы можете заменить ваши процедуры на языке FORTRAN один к одному  на
соответствующие СИ-функции. СИ-код будет сгенерирован, как только каждая
функция будет написана.

    Наконец,  смешанное  программирование  будет  вам  полезно,  если вы
поставляете на  рынок ваши  собственные библиотеки.  С помощью описанных
здесь средств вы  можете готовить библиотеки  для любых упомянутых  выше
языков, причем часто с незначительными изменениями.

    Подробно  смешанное  программирование  для  всех  остальных   языков
описано в документе "Microsoft Mixed-Language Programming Guide". Данное
руководство  содержит  описание  смешанного  программирования для языков
Microsoft FORTRAN(версия 4.0  и выше),Microsoft Macro  Assembler (Версия
5.0 и выше),  Microsoft Pascal (Версия  3.3 и выше),  Microsoft C(версия
5.0 и выше).

    Данное же  приложение в  основном касается  методов программирования
необходимых  для  написания   процедур  на  Ассемблере,   пригодных  для
использования в СИ-программах. Подробности об интерфейсах между  другими
языками высокого уровня  смотрите в документе  "Microsoft Mixed-Language
Programming Guide" ("Руководство по программированию со смешением языков
фирмы Microsoft").

    Определения.

    Терминологические  соглашения,  используемые  в  данном   приложении
совпадают  с  соглашиниями,  описанными  в  руководстве пользователя для
каждого языка фирмы Microsoft. Однако, следующие термины используются  в
особом смысле:

Термин      Определения

Процедура   Любая функция, подпрограмма, процедура, которая может
            быть вызвана из другого языка. Данное понятие аналогично
            процедуре в языке Ассемблер; однако сам термин
            "процедура" используется в разных случаях, его не
            следует смешивать с ключевым словом языка Pascal
            "procedure".
Параметр    Часть данных, передаваемая непосредственно между двумя
            процедурами. (Внешними данными пользуются все процедуры,
            но про них нельзя сказать, что они "передаются"). Хотя
            повсюду термин "аргумент" используется попеременно с тер-
            мином "параметр", в данном приложении термин "аргумент"
            используется для обозначения определенных значений или
            выражений, предлагаемых для параметров.
Интерфейс   Метод, обеспечивающий эффективную связь между различными
            форматами. В высокоуровневых языках интерфейс часто ус-
            танавливается некоторыми видами формального объявления.
Формальный  Формальный параметр-это параметр, описанный в интерфей-
параметр    сном операторе или объявлении. Язык СИ использует описа-
              ния типа параметра, а не формальные параметры.

                С.1. Написание ассемблерной процедуры.

    Высокоуровневые  языки  фирмы  Microsoft  используют для процедурных
вызовов приблизительно один и тот же интерфейс. Данный раздел  описывает
интерфейс, позволяющий вам вызывать ассемблерную процедуру с помощью тех
же  самых  методов,  которые  вы  применяли  для  кода, сгенерированного
компиляторами фирмы  Microsoft. Процедуры,  написанные с  помощью данных
методов,   могут   вызываться   рекурсивно   и   могут   быть эффективно
использоваться  со  средством  Stack  Trace многооконного отладчика Code
View фирмы  Microsoft. Стандартный  метод получения  интерфейса с языком
Ассемблер состоит из следующих шагов:

    1.Создание процедуры.

    2.Ввод процедуры.

    3.Размещение локальных данных (необязательно).

    4.Резервирование значений регистров.

    5.Параметры доступа.

    6.Возвращение значения (необязательно).

    7.Выход из процедуры.

    Каждый из следующих шагов описывается в Разделах С.1.1-С.1.7.

                      С.1.1. Написание процедуры.

    Компановщик не сможет объединить ассемблерную процедуру с вызывающей
процедурой,  если   используются  несовместимые   сегменты,  либо   сама
процедура  описана  неправильно.  Могут  оказаться  полезными  следующие
положения:

    -Если вы имеете Macro Assembler версии 5.0, в начале исходного файла
используйте директиву .MODEL. Данная директива автоматически  генерирует
соответствующий  тип  возвращаемого  значения  ("near"  для  малой   или
компактной модели, "far"-в  противном случае). Если  у вас более  ранняя
версия ассемблера,  опишите процедуру  с атрибутом  "far" (либо  "near",
если  вызывающая  программа  работает  в  малой  или  компактной  модели
Quick-C).

    -Если  у  вас  Microsoft  Macro  Assembler  версии 5.0 или выше, для
объявления кодового  сегмента используйте  упрощенную директиву  .CODE и
директиву  .DATA  для  объявления  сегмента  данных.   (Если  у  вас нет
объявлений  данных,  достаточно  только  кодового  сегмента).  Если   вы
используете  более  раннюю  версию  ассемблера,  рассмотрите   директивы
SEGMENT,  GROUP  и  ASSUME  в  Разделе  С.4  "Сегментная  модель   фирмы
Microsoft".

    -Метка  процедуры  должна  быть  объявлена,  как  "public" с помощью
директивы  PUBLIC.  Данное  объявление  делает  процедуру  доступной для
вызовов из других модулей. Кроме  того, любые данные, которые вы  хотите
сделать  доступными  для  других  модулей,  должны  быть  объявлены, как
PUBLIC.

    -Глобальные данные или процедуры, к которым осуществляется доступ из
вашей процедуры, должны быть  объявлены, как EXTRN. Наиболее  безопасный
путь  использования  EXTRN-это  помещение  директивы  вне   сегментоного
определения (тем не менее, "ближние" д

                       С.1.2. Вход в процедуру.

    Процедура начинается с двух инструкций:

push    bp
mov     bp,sp

    Данная  последовательность  команд  устанавливает  регистр  BP,  как
указатель на запись активации. Данный указатель используется для доступа
к параметрам и  локальным данным, расположенным  в стеке. Регистр  SP не
может  быть  использован  для  данной  цели,  поскольку  он  не является
индексным или базовым регистром. Кроме того, значение регистра SP  может
изменяться  при  добавлении  данных  в  стек.  Значение  же  регистра BP
остается постоянным на протяжении всей процедуры, соответственно, каждый
параметр может быть адресован, как фиксированное смещение,  относительно
значения BP.

    Последовательность инструкций,  приведенная выше,  сначала сохраняет
значение BP, поскольку оно потребуется вызывающей процедуре, как  только
закончится текущая процедура. Затем в регистр BP заносится значение  SP,
чтобы иметь значение указателя стека перед входом в процедуру.

          С.1.3. Размещение локальных данных (необязательно).

    Ассемблерная процедура использует для размещения локальных данных те
же самые средства, что и высокоуровневые языки. Чтобы установить размеры
памяти  для  размещения  локальных  данных,  просто уменьшите содержимое
регистра SP в третьей  инструкции процедуры.  (Для гарантии  корректного
выполнения вам следует всегда увеличивать или уменьшать содержимое SP на
четное   число).   Уменьшение   содержимого   регистра   SP  резервирует
пространство стека  для локальных  данных. Данная  память должна  быть в
конце процедуры восстановлена.

    В следующих инструкциях,  "space"-это общий размер  байтов локальных
данных.  Доступ  к   локальным  переменным  осуществляется   посредством
фиксированных отрицательных смещений BP.

push    bp
mov     bp,sp
        sub     sp,space

-Пример:
push     bp
mov      bp,sp
sub      sp,4
.
.
.
mov     WORD PTR [bp-2],0
mov     WORD PTR [bp-4],0

    Приведенный выше пример использует две локальные переменные,  каждая
из которых имеет  размер 2 байта.   SP уменьшается на  четыре, поскольку
для локальных  данных требуется  четыре байта.  Позже, каждая  из данных
переменных инициализируется 0. Данные переменные никогда не  объявляются
формально   какой-либо   директивой   ассемблера;   программист   должен
отслеживать их самостоятельно

    Локальные переменные называются  также динамическими, стековыми  или
автоматическими переменные.

               С.1.4. Резервирование значений регистров.

    Ассемблерные процедуры,  вызываемые из  любого высокоуровнего  языка
фирмы Microsoft должны зарезервировать  значение регистров SI, DI,  SS и
DS ( в  дополнение к регистру  BP, который уже  был сохранен). То  есть,
следует  сохранить  содержимое  тех  регистров,  которые программа может
изменить. Если  программа не  изменяет содержимое  какого-либо регистра,
этот регистр нет нужды запоминать.

    Те регистры, которые вы запомнили перед входом в процедуру,  следует
затем восстановить перед выходом из процедуры (как объясняется в Разделе
С.1.7 "Выход из процедуры").

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

push     bp    ;Запоминание старого указателя записи активации
mov      bp,sp ;Установка текущего указателя записи активации
sub      sp,4  ;Размещение памяти для локальных данных
push     si    ;Сохранение SI и DI
puih     di
.
.
.

                      С.1.5. Доступ к параметрам.

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

Старшие    |параметр       |
адреса     |параметр       |
           |   .           |
           |   .           |
           |   .           |
           |               |
           |параметр       |
           |адрес возврата |
           | запомненное   |   здесь хранится указатель на запись
           | BP            |   активации (BP)
           |память для ло- |
           |кальных данных |
           |запомненный SI |
           |запомненный    |   SP указывает на последний элемент,
           | DI            |   помещенный в стек.
Младшие
адреса

                    Рисунок С.1. Запись активации.

    Запись     активации     процедуры     устанавливается     следующей
последовательностью действий:

    1.Вызывающая программа помещает каждый  параметр в стек, после  чего
регистр SP указывает на последний размещенный параметр.

    2.Вызывающая   программа   инициирует   инструкцию   CALL,   которая
устанавливает адрес возврата (место  в вызывающей программе, на  которое
возвращается управление после окончания работы процедуры) и помещает его
в стек. Данный  адрес может быть  либо дыа байта  длинной (для "ближних"
вызовов),  либо  четыре  байта  длинной  (для "дальних" вызовов). Теперь
регистр SP указывает на данный адрес.

    3.Первая инструкция вызванной процедуры сохраняет старое значение BP
(push bp). Регистр SP теперь указывает на сохраненную копию BP.

    4.Используйте регистр BP для захвата текущего значения регистра SP с
помощью инструкции mov  bp, sp. Теперь  BP указывает на  старое значение
BP.

    5.Поскольку BP остается постоянным на протяжении всей процедуры,  SP
может  быть  уменьшено  для  того,  чтобы  освободить  место в стеке для
локальных данных или зарезервированных регистров.

    В основном, смещение (относительно BP) для параметра X равно:

2 + размер адреса возврата
+ общий размер параметров между X и BP.

    Например,  предположим,  что  процедура  FAR получает один параметр,
двухбайтовый адрес. Смещение для этого параметра будет равно:

смещение аргумента = 2 + размер адреса возврата
                   = 2 + 4
                   = 6

    Аргумент может в таком случае  быть загружен в регистр BP  с помощью
следующей инструкции:

    mov bx,[bp+6]

    Если вы однажды определили смещение для каждого параметра, вам могут
понадобиться  строковые  уравнения  или  структуры,  чтобы к параметру в
вашем исходном ассемблерном коде можно было обратиться по  единственному
идентифицирующему имени. Например,  к параметру, находящемуся  по адресу
BP+6  будет  удобно  обращаться,  если  в начале исходного ассемблерного
файла вы поместите следующий оператор:

    Arg1 EQU [bp+6]

    После этого в любой инструкции на данный параметр можно ссылаться по
идентификатору  Arg1.  Используйте  это  средство  в  качестве полезного
дополнения.

---------------------------------------------------------------------

    Примечание:

    Высокоуровневые  языки  фирмы  Microsoft  всегда  размещают   адреса
сегментов  перед  адресами  смещений.  Поэтому,  если  в стек опускаются
аргументы  больше  2-х  байтов,  старшие  слова  всегда опускаются перед
младшим словом.

---------------------------------------------------------------------

               С.1.6. Возврат значений (необязательно).

    Высокоуровневые языки Microsoft для получения возвращаемых  значений
пользуются аналогичными соглашениями. Данные соглашения совпадают,  если
возвращаемый  тип  данных  не  является  сложным  (например массивом или
структурой) и имеет длину не  более четырех байтов. Это включает  в себя
все "ближнии" и "дальние" адреса (то есть все указатели и все параметры,
передаваемые по ссылке).

Размер данных          Возвращаемое значение

1 байт                 AL
2 байта                AX
4 байта                старшая часть (или адрес сегмента) в DX
                       младшая часть (или адрес смещения) в AX

    Если  возвращаемое   значение  больше   четырех  байтов,   процедура
вызываемая  из  языка  СИ,  должна  отвести  память  для   возвращаемого
значения,  а  затем  поместить  этот  адрес  в  DX:AX.  Удобным способом
распределения  памяти  для   возвращаемого  значения  является   простое
объявление его в сегменте данных.

                      С.1.8. Выход из процедуры.

    При завершении процедуры должны быть выполнены следующие шаги:

    1.Если какие-либо из регистров SS, DS, SI и DI были сохранены, перед
выходом  из  процедуры  они  должны  быть  извлечены из стека в порядке,
обратном их размещению.

    2.Если локальные  данные размещены  в начале  процедуры, регистр  SP
должен быть восстановлен с помощью инструкции mov sp, bp.

    3.Восстановите  регистр  BP  с  помощью  pop  bp.  Данный шаг всегда
необходим.

    4.Наконец,  вернитесь   в  вызывающую   программу  с   помощью  ret.
Вызывающий  модуль  на  языке  СИ  автоматически  отрегулирует  стек  по
отношению к параметрам, которые были опущены при вызове.

-Примеры:
pop     bp
ret

    Приведенный  выше  пример  показывает  простейшую последовательность
выхода.  Никакие  регистры  не  были  зарезервированы, не были размещены
локальные данные, и использованы соглашения о связях языка СИ.

pop     di     ;Восстановление зарезервированных регистров
pop     si
mov     sp, bp ;Освобождение пространства, занятого локальными дан-
                ными
pop     bp     ;Восстановление старого указателя на запись активации
ret     6      ;Выход и восстановление 6 байтов, занятых аргументами

    В данном примере  показана последовательность выхода  для процедуры,
которая  предварительно  зарезервировала  значения  регистров  SI  и DI,
разместила  локальные  данные  и  использовала  соглашения  о  связях не
относящиеся  к   языку  СИ.   Поэтому,  процедура   должна  использовать
инструкцию ret  6, чтобы  восстановить 6  байтов, занятых  параметрами в
стеке.

          С.2. Вызов процедур на языке Ассемблер из языка СИ.

    Программа на языке  СИ может вызвать  процедуру на языке  Ассемблер,
находящуюся в другом модуле, как и при вызове СИ-функции. В дополнение к
шагам, описанным в Разделе С.1 "Написание процедуры на языке Ассемблер",
могут оказаться полезными следующие правила:

    1.Описывайте процедуры, вызываемые из СИ-программ с ключевым  словом
far,  если  СИ-модуль  был  скомпилирован  в  большой,  сверхбольшой или
средней модели  памяти, и  с ключевым  словом near,  если СИ-модуль  был
скомпилирован в малой или компактной модели. Ключевые слова far или near
отменяют  любые  стандартные  назначения.  Если вы используете директиву
.MODEL, имеющуюся в  Micro soft Macro  Assembler версии 5.0,  объявление
модели памяти для процедуры делается явно.

    2.Обзор  соглашений  о  связях  языка  СИ.  По  соглашениям языка СИ
параметры  опускаются  в  стек  в  том  порядке, в каком они находятся в
исходном коде. Например, вызов функции  СИ calc(a,b); опускает b в  стек
раньше  a.  В  противоположность  остальным  высокоуровневым  языкам,  в
соглашениях  о  связях  языка  СИ  положено,  чтобы вызывающая процедура
всегда восстанавливала стэк непосредственно после возвращения управления
из вызываемой программы. Соглашения  о связях языка СИ  делают возможным
вызов переменным числом  параметров.  (Поскольку первый  параметр всегда
опускается в стек последним,  он имеет относительно указателя  на запись
активации  один  и  тот  же  адрес.  Независимо от количества переданных
числом параметров применяются следующие этапы:

    а)Возврат  производится  посредством  простой  инструкцией  ret.  Не
восстанавливайте  стек  посредством   инструкции  ret  size,   поскольку
вызывающая  СИ-процедура  сама  восстановит  стек,  как  только ей будет
передано управление.

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

    с)Стандартно,  параметры  языка  СИ  передаются  значением, исключая
массивы, передаваемые по адресной ссылке.

    3.Обзор соглашений о наименованиях языка СИ.

    Наличие  подчеркивания  перед  любым  именем  в  языке СИ делает его
глобальным.  В  языке  СИ  распознаются  только  первые восемь символов,
поэтому  не  делайте  имена,  используемые  СИ,  длинной  более   восьми
символов.  Кроме  того,  если  вы  будете  выполнять компановку с опцией
/NOIGNORECASE, помните, что язык СИ чувствителен к буквенным  регистрам,
и не преобразуйте имена к верхнему регистру.

    В  следующем  примере  программа  на  языке СИ вызывает ассемблерную
процедуру,  которая  вычисляет  А*2**B,  где  А  и  В-первый  и   второй
параметры,  соответственно.  Вычисления  выполняются  путем сдвига влево
разрядов в А В раз.

    Программа  на  языке  СИ   использует  для  создания  интерфейса   с
ассемблерной процедурой описание  extern. Не требуется  никаких ключевых
слов, поскольку ассемблерная  процедура будет использовать  соглашения о
связях языка СИ.

extern int power2(int, int);
main()
{
     printf("3 times 2 to the power of 5 is %d\n", power2(3,5));
}

    Чтобы  понять,  как  пишется  ассемблерная  процедура,   рассмотрите
рисунок С.2, на котором показана схема размещения параметров в стеке.

Старшие адреса         | B | Arg<-2              |    BP+6
(С каждым опусканием   | A | Arg<-1              |    BP+4
аргумента или каждым   |     Адрес возврата      |    BP+2
вызовом стек растет    |     Зарезервированный   |    BP
вниз)                  |      BP                 |
Младшие адреса

                   Рисунок С.2. Запись активации СИ.

    Адрес возврата имеет в  длину байта, предполагая, что  СИ-модуль был
скомпилирован  в  малой  или   компактной  модели.  Если  же   СИ-модуль
компилируется  в  большой,  сверхбольшой  или  средней модели, то адреса
Arg<-1 и Arg<-2-каждый увеличиваются на 2 байта, то есть, соответственно
становятся BP+6 и BP+8, поскольку адрес возврата здесь 4 байта длиной.

    Первый  параметр  Arg<-1  расположен  по  адресам более младшим, чем
Arg<-2,поскольку язык СИ опускает  аргументы в стек в  обратном порядке.
Каждый аргумент передается значением. Ассемблерная процедура может  быть
написана следующим образом:

.MODEL SMALL
.CODE
        PUBLIC _power2
_power2 PROC
        push     bp     ;Входная последовательность-сохранение старо-
                         го BP

        mov      bp,sp  ;Установка указателя на запись активации

        mov      ax,[bp+4]   ;Загрузка Arg 1 в AX
        mov      cx,[bp+6]   ;Загрузка Arg 2 в CX
        shl      ax,cl       ;AX = AX*(2 в степени CX)
                             ;Возвращаемое значение остается в AX
        pop      bp          ;Выходная последовательность-востанов-
                              ление старого BP
        ret                  ;Выход
_power2 ENDP
        END

    Приведенный выше пример предполагает, что СИ-модуль компилируется  в
малой модели памяти. Смещение параметра и директива .MODEL изменятся для
других моделей памяти.

    Обратите внимание,  что инструкция  ret используется  без переменной
size, поскольку вызывающая программа после возвращения из процедуры сама
выравнивает стек.

                С.3. Вызов языка СИ из языка Ассемблер.

    Процедуры  высокоуровневых  языков  предполагают, что предварительно
был выполнен некоторый инициализирующий код; вы должны быть уверены, что
при   старте   модуля   высокоуровневых   языков   выполнена  корректная
инициализация,  а  затем  вызвать  ассемблерную  процедуру. Ассемблерная
процедура может затем сама вызывать высокоуровневые языковые  процедуры,
как показано на рисунке С.3.

       СИ-код                 Код на Ассемблере
(начало программы на СИ)     |
main(){                      |
       asub();               |
}                            | PROC asub
                             |   .
(C termination)              |   .
                             |   .
                             |       call ctest
ctest(){                     |   .
   .                         |   .
   .                         |
                             |       ret
   .                         | ENDP asub
}                            |

                 Рисунок С.3. Вызов СИ из Ассемблера.

    Для вызова  высокоуровневых языков  из языка  Ассемблер вам  следует
соблюдать следующие правила:

    -Каждый  параметр  опускайте  в  стек,  соблюдая соглашения о связях
высокоуровневых языков.  Константы, такие,  как адреса  смещений, должны
быть загружены в регистр до любых опусканий в стек.

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

    -Выполняйте  вызов.  Вызов   должен  быть  "дальним",   если  только
высокоуровневая процедура не относится к малой модели памяти.

    -Если  процедура  использовала  соглашения  о  связях  языка  СИ, то
непосредственно сразу после вызова очистите стек от параметров с помощью
инструкции:  add  sp,  size,  где  size-это  общий  размер в байтах всех
параметров, опущенных в стек.

                С.4. Сегментная модель фирмы Microsoft.

    Если  вы   применяете  простейшие   сегментные  директивы,   вам  не
потребуется знать  имена, назначенные  каждому сегменту.  Однако, версии
Macro  Assembler  предшествующие  версии  5.0  не  поддерживают   данные
директивы.  В  старших  версиях  ассемблера  вам  следует   использовать
директивы  SEGMENT,  GROUP,   ASSUME,  ENDS,  эквивалентные   упрощенным
сегментным директивам.

    В  Таблице  С.1  показаны  стандартные  имена сегментов, создаваемые
каждой   директивой.   Использование   данных   сегментов    гарантирует
совместимость с языками фирмы Microsoft и поможет вам получить доступ  к
внешним именам.

    За  таблицей  следует  описание  трех  шагов иллюстрирующих реальные
объявления, и пример программы.

                                                 Таблица С.1.
      Стандартные сегменты и типы для стандартных моделей памяти.

Модель    Директива Имя       Выравни-  Способ объ Класс   Группа
                              вание     единения

Малая     .CODE     _TEXT     WORD      PUBLIC     'CODE'
          .DATA     _DATA     WORD      PUBLIC     'DATA'  DGROUP
          .CONST    CONST     WORD      PUBLIC     'CONST' DGROUP
          .DATA?    _BSS      WORD      PUBLIC     'BSS'   DGROUP
          .STACK    STACK     PARA      STACK      'STACK' DGROUP

Средняя   .CODE     name_TEXT WORD      PUBLIC     'CODE'
          .DATA     _DATA     WORD      PUBLIC     'DATA'  DGROUP
          .CONST    CONST     WORD      PUBLIC     'CONST' DGROUP
          .DATA?    _BSS      WORD      PUBLIC     'BSS'   DGROUP
          .STACK    STACK     PARA      STACK      'STACK' DGROUP

Компакт-  .CODE     _TEXT     WORD      PUBLIC     'CODE'
ная       .FARDATA  FAR_DATA  PARA      Private    'FAR_DATA'
          .FARDATA? FAR_BSS   PARA      Private    'FAR_BSS'
          .DATA     _DATA     WORD      PUBLIC     'DATA'  DGROUP
          .CONST    CONST     WORD      PUBLIC     'CONST' DGROUP
          .DATA?    _BSS      WORD      PUBLIC     'BSS'   DGROUP
          .STACK    STACK     PARA      STACK      'STACK' DGROUP

Большая   .CODE     name_TEXT WORD      PUBLIC     'CODE'
          .FARDATA  FAR_DATA  PARA      Private    'FAR_DATA'
          .FARDATA? FAR_BSS   PARA      Private    'FAR_BSS'
          .DATA     _DATA     WORD      PUBLIC     'DATA'  DGROUP
          .CONST    CONST     WORD      PUBLIC     'CONST' DGROUP
          .DATA?    _BSS      WORD      PUBLIC     'BSS'   DGROUP
          .STACK    STACK     PARA      STACK      'STACK' DGROUP

    Директивы Таблицы С.1 относятся к следующим типам сегментов:

Директива              Описание сегмента

.CODE                  Сегмент, содержащий весь код модуля.
.DATA                  Проинициализированные данные.
.DATA?                 Неинициализированные данные. Компиляторы фир-
                       мы Microsoft хранят неинициализированные дан-
                       ные отдельно, поскольку такие данные можно раз
                       местить более эффективно, чем проинициализиро-
                       ванные данные.
.FARDATA и .FARDATA?   Данные, которые не будут объединяться с соот-
                       ветствующими сегментами других модулей. Сег-
                       мент размещенных здесь данных, тем не менее,
                       всегда может быть определен с помощью операто-
                       ра ассемблера SEG.
.CONST                 Постоянные данные. Компиляторы фирмы Microsoft
                       используют данный сегмент для элементов, та-
                       ких, как строковые константы и константы с
                       плавающей точкой.
.STACK                 Стек. Обычно, данный сегмент объявляется в
                       главном модуле и не должен быть переопределен.

    Для создания  реальных директив  с помощью  Таблицы С.1  используйте
следующие шаги:

    1.В определении сегмента следует  задать имя, тип выравнивания,  тип
объединения, класс. Таким образом, сегмент кода для малой модели  памяти
должен быть объявлен следующим образом:

    _TEXT SEGMENT WORD PUBLIC 'CODE'

    Если тип объединения "private", просто не используйте никакого  типа
объединения.

    2.Если у вас есть сегменты в DGROUP, поместите их в DGROUP с помощью
директивы GROUP, как в примере:

    GROUP DGROUP _DATA _BSS

    3.Директивы ASSUME и ENDS используйте, как обычно. Помните, что  при
вводе, регистры DS и SS, оба указывают на DGROUP.

    Следующий пример показывает программу "СИ-Ассемблер" из Раздела С.3,
но  без  упрощенных  сегментных  директив  из версии 5.0 Макроассемблера
фирмы Microsoft.

_TEXT   SEGMENT WORD PUBLIC 'CODE'
        ASSUME  cs: TEXT
        PUBLIC   Power2
_Power2 PROC
        push    bp     ;Входная последовательность-сохранения регис-
                        тра BP.
        mov     bp,sp  ;Установка записи активации.

        mov     ax,[bp+4]  ;Загрузка Arg1 в AX.
        mov     cx,[bp+6]  ;Загрузка Arg2 в CX.
        shl     ax,cl      ;AX = AX+(2 в степени CX).
                           ;Значение возврата остается в AX.
        pop     bp   ;Выходная последовательность-восстановление ре-
                      гистра BP.
        ret          ;Выход.
_Power2 ENDP
_TEXT   ENDS
       END


                             ПРИЛОЖЕНИЕ D.

                   Справочник сообщений об ошибках.

D.1.  Сообщения компилятора об ошибках.
      D.1.1.Сообщения о фатальных (неисправимых) ошибках.
      D.1.2.Ошибочные сообщения периода компиляции.
      D.1.3.Предупреждающие сообщения.
      D.1.4.Ограничения компилятора.
D.2.  Сообщения об ошибках при работе с помощью командной
      строки.
      D.2.1.Фатальные ошибки командной строки.
      D.2.2.Сообщения об ошибках командной строки.
      D.2.3.Предупреждающие сообщения командной строки.
D.3.  Сообщения об ошибках периода выполнения.
      D.3.1.Исключения при операциях с плавающей точкой.
      D.3.2.Сообщения об ошибках библиотеки периода вы-
            полнения.
      D.3.3.Ограничения периода выполнения.
D.4.  Сообщения об ошибках компановщика LINK.
D.5.  Сообщения об ошибках утилиты LIB.
D.6.  Сообщения об ошибках утилиты MAKE.

    В  данном  Приложении  приводится  список  сообщений  об ошибках, на
которые вы можете натолкнуться в процессе разработки программ, и,  кроме
того, дает  краткое описание  действий, которые  вам следует предпринять
для  исправления  ошибок.  Следующий  список  покащывает вам, где искать
ошибочные сообщения различных компонентов компилятора Microsoft Quick-C:

Компонент                         Раздел

Компилятор Microsoft Quick-C      Раздел D.1, "Сообщения об ошибках
                                  компилятора.
Командная строка, используемая    Раздел D.2, "Сообщение об ошибках
для вызова компилятора Quick-C    командной строки".
Библиотеки исполняющей системы    Раздел D.3, "Сообщения об ошибках
Microsoft C и другие ситуации     периода выполнения".
периода выполнения.
Оверлейный компановщик Microsoft, Раздел D.4, "Сообщения об ошибках
утилита LINK.                     компановщика".
Диспетчер библиотек фирмы         Раздел D.5, "Сообщения об ошибках
Microsoft-утилита LIB             утилиты LIB".
Утилита поддержки разработки      Раздел D.6, "Сообщения об ошибках
программ MAKE                     утилиты MAKE".

    Обратите  внимание,   что  все   ошибочные  сообщения   компилятора,
командной строки,  периода выполнения  приведены в  данном приложении  в
алфавитном порядке.

    В Разделе D.1.4 вы найдете информацию об ограничениях компилятора, а
в Разделе D.3.3-ограничения периода выполнения.

                 D.1.Сообщения об ошибках компилятора.

    Сообщения об ошибках,  Полученные при сбоях  СИ-компилятора, делятся
на три категории:

    1.Сообщения о фатальных ошибках.

    2.Сообщения об ошибках компиляции.

    3.Предупреждающие сообщения.

    Сообщения каждой  категории даны  ниже в  пронумерованном порядке, с
кратким  объяснением  каждой  ошибки.  Чтобы  найти требуемое сообщение,
сначала определите  категорию сообщения,  затем найдите  соответствующий
номер  ошибки.  Каждое  сообщение,  сгенерированное  в  среде   Quick-C,
появляется в  окне ошибок;  курсор устанавливается  на строке, вызвавшей
ошибку  (подробности  в  Разделе  7.3.4).  Каждое  сообщение  об ошибке,
сгенерированное во время компиляции с помощью команды QCL, содержит  имя
файла и номер строки, вызвавшей ошибку.

    Сообщения о фатальных ошибках.

    Сообщение о фатальной ошибке обозначает некоторую проблему,  которая
запрещает компилятору дальнейшее выполнение. Данный тип сообщения  имеет
следующий формат:

    имя файла(строка): fatal error C1xxx: текст сообщения

    После того, как компилятор высветит сообщение о фатальной ошибке, он
завершит выполнения без создания объектного файла и какой-либо  проверки
на последующие ошибки.

    Сообщения об ошибках компилятора.

    Сообщения  об  ошибках  компилятора  индицируют реальные программные
ошибки. Данные сообщения выводятся в следующем формате:

    имя файла(строка):error C2xxx:текст сообщения

    Компилятор в данном случае  не создает объектный файл  для исходного
файла, в котором компилятор обнаружил ошибки. Если компилятор  встречает
такие ошибки,  он делает  попытку их  исправить. Если  это возможно,  он
продолжает обработку исходного файла и выдает ошибочные сообщения.  Если
ошибок слишком  много или  они слишком  серьезны, компилятор  прекращает
работу.

    Предупреждающие сообщения.

    Предупреждающие сообщения носят  только информативный характер;  они
не  прерывают  процесс  компиляции  или  компановки.  Данные   сообщения
появляются в следующем формате:

    имя файла(строка): warning C4xxx: текст сообщения

    Вы можете  использовать опцию  /W для  управления уровнем сообщений,
генерируемых компилятором. Данная опция описана в Разделе 9.3.1.

                 D.1.1. Сообщения о фатальных ошибках.

    Следующие сообщения идентифицируют  фатальные ошибки. Компилятор  не
может исправить фатальную ошибку; он прекращает работу после  распечатки
сообщения об ошибке.

Номер   Сообщение о фатальной ошибке

C1000 "Неизвестная фатальная ошибка, Свяжитесь с Техническим сервисом
      фирмы Microsoft".
      Компилятор обнаружил неизвестную ошибку. Пожалуйста, сообщите
      фирме Microsoft Corporation условия возникновения данной ошиб-
      ки посредством специальной формы "Product Assistan Request",
      на обложке данного руководства.
C1001 "Внутренняя ошибка компилятора, свяжитесь с Техническим серви-
      сом фирмы Microsoft".
      Компилятор обнаружил внутреннее несоответствие. Пожалуйста, со-
      общите условия возникновения данной ошибке с помощью бланка
      "Product Assistance Request" на обложке данного руководства.
      Пожалуйста, включите в ваше сообщение имя файла и номер стро-
      ки, вызвавшей ошибку; обратите внимание, что "имя файла" отно-
      носится к внутреннему файлу компилятора, а не к вашему исход-
      ному файлу.
C1002 "Выход за пределы динамической области".
      Компилятор вышел за пределы динамическогй области памяти. Дан-
      ная ситуация обычно означает, что ваша программа имеет слишком
      много символических имен и/или комплексных выражений. Чтобы из-
      бавиться от данной проблемы, разделите файл на несколько мень-
      ших исходных файлов, либо разбейте выражения на меньшие подвы-
      ражения.
C1003 "Счетчик ошибок превысил n; компиляция остановлена".
      Ошибок в программе слишком много, либо они слишком серьезны,
      чтобы возможно было восстановление, компилятор должен прервать
      выполнение.
C1004 "Неожиданный конец файла (EOF).
      Данное сообщение появляется, если у вас не достаточно памяти на
      стандартном дисковом устройстве, чтобы компилятор создал требу-
      емые временные файлы. Требуемое пространство примерно в 2 раза
      больше размера исходного файла. Данное сообщение может быть
      также сгенерировано, если комментарий не имеет закрывающего
      ограничителя (*/), либо если директиве #if не хватает закры-
      вающей директивы #endif.
C1005 "Строка слишком велика для буфера".
      Строка в промежуточном файле компилятора переполняет буфер.
C1006 "Ошибка записи в промежуточный файл компилятора".
      Компилятор не может создать промежуточные файлы, используемые
      в процессе компиляции. К данной ошибке обычно приводят следую-
      щие ситуации:
      1.Слишком мало файлов в строке
      files = number
      файла CONFIG.SYS (компилятор требует чтобы число number было
      не меньше 15).
      2.Не хватает памяти на устройстве, содержащем промежуточные
      файлы компилятора.
C1007 "Нераспознанный флаг 'string' в 'option'"
      string-в опции командной строки option не является корректной
      опцией.
C1009 "Ограничения компилятора, возможно рекурсивно определенное мак-
      роопределение".
      Расширение макрокоманды превышает размеры доступной памяти.
      Проверьте, не было ли рекурсивно-определенных макрокоманд, либо
      не слишком велик расширяемый текст.
C1010 "Ограничения компилятора: макро-расширение слишком большое".
      Расширение макрокоманды превышает доступную память.
C1012 "Неверное вложение скобок-пропущенный 'character' (символ)".
      Несоответствие скобок в директиве препроцессора; 'character'-
      -это либо левая, либо правая скобка.
C1013 "Невозможно открыть исходный файл 'filename'".
      Данный файл 'filename' либо не существует, либо не может быть
      открыт, либо не найден. Удостоверьтесь, что параметры установ-
      ки среды корректны, и что для файла задано корректное имя марш-
      рута.
C1014 "Слишком много включаемых файлов".
      Вложение директив #include превышает 10-уровневый предел.
C1015 "Невозможно открыть включаемый файл 'filename'".
      Данный файл либо не существует, либо не может быть открыт, либо
      не найден. Удостоверьтесь, что параметры неазначений среды за-
      даны корректно, и что вы определили корректное имя маршрута для
      данного файла.
C1016 "Директиве #if [n]def требуется идертификатор".
      С директивами #ifdef и #ifndef вы обязательно должны употреб-
      лять идентификатор.
C1017 "Неверное выражение целой константы".
      Выражение в директиве #if должно вычисляться в константу.
C1018 "Неожиданная директива '#elif'".
      Появление директивы #elif разрешено только внутри директив #if,
      #ifdef, или #ifdef.
C1019 "Неожиданная директива '#else'".
      Появление директивы #else возможно только внутри директив #if,
      #ifdef, или #ifndef.
C1020 "Неожиданная директива '#endif'"
      Директива #endif появилась без соответствующей директивы #if,
      #ifdif, или #ifndef.
C1021 "Неверная команда препроцессора 'string'"
      Символы, следующие за знаком (#) формируют неверную директиву
      препроцессора.
C1022 "Ожидается директива '#endif'".
      Директива #if, #ifdef или #ifndef не заканчивается директивой
      #endif.
C1026 "Переполнение стэка, пожалуйста, упростите вашу программу."
      Ваша программа не может быть далее обработана, поскольку па-
      мять, требуемая для "разбора" программы переполняет стэк ком-
      пилятора.
      Чтобы разрешить данную проблему, упростите вашу программу.
C1027 "Ограничения компилятора: вложение структур/смесей".
      Определения структур и смесей вложены более 10 раз.
C1028 "Сегмент segment занимает более 64К"
      В данном сегменте размещены более 64 "дальних" данных. Один мо-
      дуль может иметь не более 64К "дальних" данных.
      Чтобы разрешить данную проблему, либо разбейте объяснения на
      отдельные модули, сократите общий объем используемых данных,
      либо откомпилируйте вашу программу с помощью Оптимизирующего
      компилятора Microsoft-C.
C1032 "Невозможно открыть файл, содержащий объектный листинг
      'filename'".
      Имеет силу одно из следующих утверждений, касающихся имени фай-
      ла или имени маршрута:
      1.Данное имя не верно.
      2.Файл с данным именем не может быть открыт из-за нехватки
        памяти.
      3.Уже существует файл с данным именем и атрибутом "только-чте-
        ние".
C1033 "Невозможно открыть выходной файл на языке ассемблер
      'filename'".
      Одно из условий, рассмотренных в описании ошибки с кодом C1032,
      привело к невозможности открыть данный файл.
C1034 "Невозможно открыть исходный файл 'filename'".
      Одно из условий, рассмотренных в описании ошибки с кодом C1032,
      привело к невозможности открыть данный файл.
C1035 "Выражение является слишком сложным, пожалуйста упростите".
      Компилятор не смог сгенерировать код для сложного выражения.
      Чтобы разрешить данную проблему, разбейте выражение на более
      простые подвыражения и повторите компиляцию.
C1036 "Невозможно открыть файл, содержащий исходный листинг
      'filename'".
      Одно из условий, рассмотренных в описании ошибки с кодом C1032,
      привело к невозможности открыть данный файл.
C1037 "Невозможно открыть объектный файл 'filename'".
      Одно из условий, рассмотренных в описании ошибки с кодом C1032,
      привело к невозможности открыть данный файл.
C1039 "Невосстанавливаемое переполнение динамической области в треть-
      ем проходе компилятора":
      В третьем оптимизирующем проходе компилятор переполнил динами-
      ческую область и прекратил работу.
      Попытайтесь повторить компиляцию с включенной опцией Optimiza-
      tions (в среде программирования Quick-C), либо с опцией /Od (в
      командной строке QCL), либо попытайтесь отделить функцию, со-
      держащую строку, вызвавшую ошибку.
C1040 "Неожиданный EOF в исходном файле 'filename'".
      В процессе создания листинга исходного файла, либо исходного/
      объектного файла компилятор обнаружил неожиданный конец файла.
      Данная ошибка произошла, вероятно, если исходный файл был отре-
      дактирован в процессе компиляции.
C1041 "Невозможно открыть промежуточный файл компилятора-больше нет".
      Компилятор не может создать промежуточный файл, используемый в
      процессе компиляции, поскольку больше нет логических номеров
      файлов.
      Данная ошибка может быть исправлена путем изменения строки
      files=number в файле CONFIG.SYS, чтобы задать большее число од-
      новременно открытых файлов (рекомендуется назначить число 20).
C1042 "Невозможно открыть промежуточный файл компилятора-нет такого
      файла или каталога".
      Компилятор не может создать промежуточные файлы, используемые в
      процессе компиляции, поскольку в переменной операционный среды
      TMP задан неправильный каталог, или маршрут.
C1043 "Невозможно открыть промежуточный файл компилятора".
      Компилятор не может создать промежуточные файлы, используемые в
      процессе компиляции. Точная причина неизвестна.
C1044 "Нехватка дисковой памяти для промежуточного файла компилятора"
      Из-за недостатка памяти компилятор не может создать промежуточ-
      ный файл, используемый в процессе компиляции. Для исправления
      данной ситуации освободите место на диске и повторите компиля-
      цию.
C1045 "Переполнение при операции с плавающей точкой".
      Компилятор получил ошибку при присваивании арифметических конс-
      тант элементам с плавающей точкой, как в следующем примере:
           float fp val = 1.0e100;
      В данном примере константа двойной точности 1.0е100 превышает
      максимально-допустимое значение для данных с плавющей точкой.
C1047 "Слишком много появлений опции 'string'".
      Данная опция упоминается слишком много раз. Строка 'string' со-
      держит опцию, вызвавшую ошибку.
C1048 "Неизвестная опция 'character' в 'optionstring'".
      Символ является некорректной буквой для опции 'optionstring'.
C1049 "Неверный числовой аргумент 'string'".
      Вместо string ожидался числовой аргумент.
C1050 "Сегмент кода 'segmentname' слишком большой".
      В процессе компиляции сегмент кода вырос за пределы 36 байтов
      от 64К.
      В данном случае используется 36-байтовый заполнитель, поскольку
      сбой на некоторых платах микропроцессоров 80286 могут вызвать
      непредсказуемое поведение программ, если среди прочих условий
      размер кодового сегмента находится в пределах 36 байтов от 64К.
C1052 "Слишком много директив #if/#ifdef's".
      В программе превышено максимальное число уровней вложения ди-
      #if/#ifdef.
C1053 "Размещение данных DGROUP превышает 64К".
      В стандартном сегменте данных были размещены более 64К перемен-
      ных.
      Для программ компактной, средней и большой модели памяти выпол-
      няйте компиляцию с помощью команды QCL, используя опцию
      /GT для размещения элементов данных в отдельных сегментах.
C1054 "Ограничения компилятора: слишком глубокая вложенность инициа-
      заторов".
      Были превышены ограничения компилятора на вложенность инициали-
      заторов. Предел - от 10 до 15 уровней, в зависимости от комби-
      нации инициализируемых типов.
      Чтобы решить данную проблему, для сокращения уровней вложен-
      ности упростите тип инициализируемых данных, либо после опи-
      санияия присваивайте первоначальное значение в отдельных опе-
      раторах.
C1056 "Ограничения компилятора: переполнение в процессе макро-расши-
      рения".
      Компилятор переполнил внутренний буфер при расширения
      макрокоманды.
C1057 "Неожиданный EOF в макро-расширении; (пропущено ')'?)".
      Компилятор обнаружил конец исходного файла в процессе сборки
      аргументов макро-вызова. Обычно, это является результатом опу-
      щенной  закрывающей правой скобки) в макро-вызове, как и в сле-
      дующем примере:
      #define print(a) printf(string is(,#a))
      main()
      {
           print(the quick brown fox;
      }
C1059 "Превышены пределы "ближней" динамической области".
      При размещении элементов данных в "ближней" динамической обла-
      сти (стандартный сегмент данных), компилятор вышел за допусти-
      мые пределы.
C1060 "Превышены пределы "дальней" динамической области".
      При размещении элементов данных в "дальней" динамической облас-
      ти компилятор вышел за допустимые пределы памяти. Обычно дан-
      ная ошибка происходит во встроенных в память программах, по
      причине того, что таблица имен содержит слишком много имен.
      Чтобы исправить данную ситуацию, попробуйте выполнить компиля-
      цию с выключенной опцией Debug, либо попытайтесь подключить
      меньше включаемых файлов. Если такой способ не спасает ситу-
      ацию, выполните компиляцию программы посредством команды QCL.
C1061 "Ограничения компилятора: слишком глубокое вложение блоков".
      Вложенность блоков в данной прогамме превышает возможности ком-
      пилятора. Для исправления данной ситуации перепишите программу
      так, чтобы вложенность блоков была меньшей.
C1063 "Ограничения компилятора-переполнение стека компилятора".
      Ваша программа слишком сложна, поскольку привела к переполнению
      стека. Упростите вашу программу и повторите компиляцию.

               D.1.2. Сообщения об ошибках компилятора.

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

Номер         Сообщения об ошибках компилятора

C2000 "Нераспознанная ошибка. Обратитесь в Технический сервис фирмы
      Microsoft".
      Компилятор не может определить тип обнаруженной ошибки. Пожа-
      луйста, сообщите условие возникновения данной ошибки в фирму
      Microsoft, воспользовавшись специальным бланком "Product Assis-
      tance Reguest", находящимся на обложке данного руководства.
C2001 "В константе обнаружен символ перехода на новую строку
      (newline)".
      Символ перехода на новую строку в символьной или строковой
      константе употребляется не в корректной форме управляющей
      последовательности (/n).
C2002 "Фактические параметры макрокоманды превышают допустимые пре-
      делы памяти".
      Аргументы макро-препроцессора превышабт 256 байтов.
C2003 "Требуется идентификатор".
      Идентификатор для проверки условия в #if не найден.
C2004 "Требуется идентификатор".
      Директива #if вызвала синтаксическую ошибку.
C2005 "В директиве #line требуется номер строки".
      В директиве #line не хватает заданного номера строки.
C2006 "Директиве #include требуется имя файла".
      В директиве #include не хватает спецификации имени файла.
C2007 "Синтаксическая ошибка директивы #define".
      В директиве #define была обнаружена синтаксическая ошибка.
C2008 "'character': невозможен в макроопределении".
      Данный символ был использован в макроопределении некорректно.
C2009 "Повторное использование формального параметра 'identifier'
      макроопределения".
      Данный идентификатор был дважды использован в списке формальных
      параметров макроопределения.
C2010 "'character': невозможен в формальном списке".
      Данный символ был некорректно использован в списке формальных
      параметров макроопределения.
C2011 "'identifier': определения слишком велико".
      Данное макроопределение превышает 256 байтов.
C2012 "Пропущено имя, следующее за '<'".
      В директиве #include не хватает требуемой спецификации имени
      файла.
C2013 "Не хватает знака '>'".
      В директиве #include пропущена закрывающая угловая скобка (>)
C2014 "Команда препроцессора должна начинаться с первого значащего
      (не пробельного) символа".
      В директиве препроцессора на той же самой строке появились не
      пробельные символы перед знаком #.
C2015 "Слишком много символов в константе".
      Символьная константа содержит более одного символа, либо была
      использована управляющая последовательность.
C2016 "Отсутствует закрывающая одинарная кавычка".
      Символьная константа не была заключена в одинарные кавычки.
C2017 "Некорректная  управляющая последовательность".
      Символ или символы, следующие за знаком (\) не имеют корректной
      формы для управляющей последовательности.
C2018 "Неизвестный символ 'Oxcharacter'".
      Данное шестнадцатеричное число не соответствует символу.
C2019 "Требуется команда препроцессора, обнаружен символ 'character'"
      Данный символ следует за знаком (#), но не является первой бук-
      вой директивы препроцессора.
C2020 "Неверное восьмеричное число 'character'".
      Данный символ не является корректной восьмеричной цифрой.
C2021 "Число 'number'слишком велико для символа".
      Число 'number' слишком велико, чтобы представлять символ.
C2023 "Деление на нуль".
      Второй операнд операции деления (/) при вычислении дает нуль.
      что может привести к непредсказуемым результатам.
C2024 "По модулю 0".
      Второй операнд в остатке операции (%) при вычислении дает нуль,
      что может привести к непредсказуемым результатам.
C2025 "'identifier': переопределение типа enum/struct/union".
      Данный идентификатор уже был использован в перечислении, струк-
      туре или тэге смеси.
C2026 "'identifier': переопределение числа перечисления ".
      Данный идентификатор уже был использован в константе перечисле-
      ния, либо в том же самом типе перечисления, либо в другом типе
      перечисления в том же самом виде.
C2028 "Член структуры/смеси должен находиться внутри структуры/смеси"
      Члены структуры или смеси должны быть описаны внутри структу-
      ры или смеси. Данная ошибка может быть вызвана описанием пе-
      речисления, содержащим описание члена структуры, как в следу-
      ющем примере:
      enum a {
             january,
             february,
             int march; /* описание структуры :
                        ** некорректно
                        */
             };
C2029 "'identifier': битовые поля разрешены только в структурах".
      Только структуры могут содержать битовые поля.
C2030 "'identifier': переопределение члена структуры/смеси".
      Данный идентификатор был более одного раза использован в качес-
      тве члена одной и той же структуры/смеси.
C2031 "'identifier': функция не может быть членом структуры или сме-
      си".
      Данная функция была описана в качестве члена структуры или
      смеси. Для исправления данной ошибки воспользуйтесь указателем
      на функцию.
C2032 "'identifier': базовый тип с ключевыми словами near/far/huge не
      разрешен".
      Данный член структуры или смеси был описан с ключевыми слова-
      ми far и near.
C2033 "'identifier': к битовым полям нельзя применять оператор кос-
      венного обращения (*)".
      Данное битовое поле было описано как указатель (*), что не
      разрешено.
C2034 "'identifier': битовое поле слишком мало для данного количества
      разрядов".
      Количество разрядов, заданное в описаний битового поля превы-
      ша%т количест-о разрядов в данеод базовом т(пе.
C2040 "'.'требует имя структуры или смеси".
      Выражение перед оператором выбора структуры или смеси (.) явля-
      ется указателем на структуру или смесь, а не структурой или
      смесью, как требуется.
C2041 "Ключевое слово 'enum' некорректно".
      В описании структуры или смеси появилось ключевое слово
      'enum', либо определение типа 'enum' было сформировано некор-
      ректно.
C2042 "ключевые слова signed/unsigned является взаимо-исключающими".
      Оба ключевых слова signed и unsigned были одновременно исполь-
      зованы в одном описании, как в следующем примере:
           unsigned signed int i;
C2043 "Некорректный оператор break".
      Оператор break разрешен только внутри операторов do, for, while
      или switch.
C2044 "Некорректный оператор continue".
      Оператор continue разрешен только внутри операторо do, for, или
      while.
C2045 "'identifier': повторное определение метки".
      Данная метка появилась перед более, чем одним оператором в од-
      ной и той же функции.
C2046 "Некорректное ключевое слово case".
      Ключевое слово case может находиться только внутри оператора
      switch.
C2047 "Некорректное ключевое слово default".
      Ключевое слово default может находиться только внутри оператора
      switch.
C2048 "Более одного default".
      Оператор switch содержит более одной метки default.
C2050 "Не целое выражение switch".
      Выражение switch не является целым.
C2051 "Выражение case не константное".
      Выражения case должны быть целыми константами.
C2052 "Выражение case не является целым".
      Выражения case должны быть целыми константами.
C2054 "Значение case 'number' уже было использовано".
      Данное значение case уже было использовано в операторе switch.
C2054 "Требуется знак '(' после идентификатора 'identifier'".
      По контексту требуются скобки после функции 'identifier'.
C2055 "Требуется список формальных параметров, а не тип list".
      В определении функции вместо списка формальных параметров поя-
      вился тип аргумента list.
C2056 "Некорректное выражение".
      Из-за предыдущей ошибки выражение является некорректным (Пре-
      дыдущая ошибка могла не вызвать ошибочного сообщения).
C2057 "Требуется константное выражение".
      По контексту требуется константное выражение.
C2058 "Константное выражение не является целым".
      По контексту требуется целое константное выражение.
C2059 "Синтаксическая ошибка: 'token'".
      Данная лексема вызвала синтаксическую ошибку.
C2060 "Синтаксическая ошибка: EOF".
      Был обнаружен неожиданный конец файла, что вызвало синтак-
      сическую ошибку. Данная ошибка может быть вызвана опущенной зак
      рывающей скобкой '}' в конце вашей программы.
C2061 "Синтаксическая ошибка: идентификатор 'identifier'".
      Данный идентификатор вызвал синтаксическую ошибку.
C2062 "Тип 'type' не требуется".
      Данный тип был некорректно употреблен.
C2063 "'identifier': не является функцией".
      Данный идентификатор не объявлен как функция, но сделана попы-
      тка использовать его в качестве функции.
C2064 "Данный терм не вычисляется в функцию".
      Сделана попытка вызова функции с помощью выражения, которое при
      вычислении не дает указатель функции.
C2065 "'identifier': не определен".
      Данный идентификатор не определен.
C2066 "Преобразование к функции некорректно".
      Объект был преобразован к типу функции.
C2067 "Преобразование к типу массива некорректно".
      Объект был преобразован к типу массива.
C2068 "Некорректное приведение типов".
      Тип, используемый в приведении типов, не является корректным.
C2069 "Приведение типа void к типу, не являющемуся void".
      Тип void был приведен к другому типу.
C2070 "Некорректный операнд sizeof".
      Операнд выражения sizeof не является идентификатором, либо наи-
      менованием типа.
C2071 "'class': неверный класс памяти".
      Данный класс памяти не может быть использован в таком контекс-
      те.
C2072 "'identifier': инициализация функции".
      Была сделана попытка инициализации функции.
C2073 "'identifier': невозможно инициализировать массив в функции".
      Была сделана попытка проинициализировать данный массив внутри
      функции. Массив можно поринициализировать только на внешнем
      уровне.
C2074 "В функции запрещено инициализировать структуру или смесь".
      Была сделана попытка проинициализировать данную структуру или
      смесь внутри функции. Структуры и функции могут быть проинициа-
      лизированы только на внешнем уровне.
C2075 "'identifier': инициализация массива требует только фигурных
      скобок".
      При инициализации массива были пропущены фигурные скобки {}.
C2076 "'identifier': инициализация структуры или смеси требует только
      фигурных скобок".
      При инициализации структуры или смеси были пропущены фигурные
      скобки {}.
C2077 "Нецелый инициализатор поля 'identifier'".
      Была сделана попытка инициализации члена структуры-битового по-
      ля нецелым значением.
C2078 "Слишком много инициализаторов".
      Количество инициализаторов превышает количество инициализируе-
      мых объектов.
C2079 "'identifier'-неопределенная структура или смесь".
      Данный идентификатор был описан, как структура или смесь, тип
      которой не определен.
C2082 "Повторное определение формального параметра 'identifier'".
      Формальный параметр функции был повторно описан в теле функции.
C2083 "Массив 'identifier' уже имеет размер".
      Размерность для данного массива уже была описана.
C2084 "Функция 'identifier' уже имеет тело".
      Данная функция уже была определена.
C2085 "'identifier': не в списке формальных параметров".
      Данный параметр был объявлен в определении функции для несущес-
      твующего формального параметра.
C2086 "'identifier': переопределение".
      Данный идентификатор был определен более одного раза.
C2087 "'identifier': пропущенный описатель".
      В определении массива с несколькими описателями было опущено
      значение описателя для размерности, отличной от первой, как в
      следующем примере:
      int func(a)
          char a[10][]; /* некорректно */
          {
          .
          .
          .
          }
      int func(a)
          char a[][5]; /* корректно */
          {
          .
          .
          .
          }
C2088 "Использование неопределенного идентификатора 'identifier' пе-
      речисления/структуры/смеси".
      Данный идентификатор обращается к структуре или смеси, тип ко-
      торой не определен.
C2089 "typedef определяет функцию near/far".
      Использование ключевых слов near или far в объявлении typedef
      не согласуется с использованием ключевых слов  near или far для
      объявленного элемента, как в следующем примере.
      typedef int far FARFUNC();
      FARFUNC near *fp;
C2090 "Функция возвращает массив".
      Функция не может возвращать массив (она может возвращать только
      указатель на массив).
C2091 "Функция возвращает функцию".
      Функция не может возвращать функцию (она может возвращать толь-
      ко указатель на функцию).
C2092 "Элемент массива не может быть функцией".
      Массивы функций не разрешаются; однако, можно использовать мас-
      сивы указателй на функции.
C2093 "Невозможно инициализировать статические данные или структуры
      адресами автоматических переменных".
C2098 "Не-адресное выражение".
      Была сделана попытка инициализации элемента данных, не являю-
      щегося адресным выражением.
C2099 "Неконстантное смещение".
      Инициализатор использовал неконстантное смещение.
C2100 "Некорректное использование оператора (*)".
      Оператор (*) был применен к неуказателю.
C2101 "'&' в константе".
      Оператор (&) не имеет адресного значения в качестве операнда.
C2102 "'&' требуется адресное значение".
      Оператор адресации (&) должен применяться к адресному значению.
C2103 "'&' в регистровой переменной".
      Была сделана попытка взять адрес регистровой переменной.
C2104 "'&' в битовом поле".
      Была сделана попытка взять адрес битового поля.
C2105 "'operator' требует адресного значения".
      Данный оператор не имеет адресного операнда.
C2106 "'operator': левый операнд должен быть адресным".
      Левый операнд данного оператора не является адресным.
C2107 "Некорректный индекс, косвенное наименование (*) не разрешено".
      Описатель был применен к выражению, которое не вычисляется в
      указатель.
C2108 "Не-целый индекс".
      В качестве описателя массива было использовано не-целое выраже-
      ние.
C2109 "Описатель в не-массиве".
      Описатель был использован в переменной, которая не является
      массивом.
C2110 "'+': 2 указателя".
      Была сделана попытка сложить один указатель с другим.
C2111 "Указатель + не-целое значение".
      Была сделана попытка сложить не-целое значение с указателем.
C2112 "Некорректное вычитание указателей".
      Была сделана попытка вычесть указатели, не указывающие на один
      и тот же тип.
C2113"'-': правый операнд-указатель".
      Правый операнд в операции вычитания (-) является указателем, а
      левый операнд-нет.
C2114 "'operator': указатель слева; требуется целое справа".
      Левый операнд в данном операторе является указателем; правый
      операнд должен быть целым значением.
C2115 "'identifier': несовместимые типы".
      Выражение содержит несовместимые типы.
C2116 "'operator': неправильный левый (или правый) операнд".
      Заданный операнд данного оператора не соответствует данному
      оператору.
C2117 "'operator': Некорректно для структуры или смеси".
      Значение структуры и смеси не разрешено с данным оператором.
C2118 "Отрицательный описатель".
      Значение, определяющее размер массива, -отрицательно.
C2119 "'typedefs' оба определяют косвенное наименование (*)".
      Были использованы одновременно два типа typedef для объявления
      элемента данных и оба типа typedef имеют косвенное наимено-
      вание. Например, объявление p в следующем примере-некорректно:
      typedef int *P INT;
      typedef short *P SHORT;
      /* данное объявление некорректно */
      P SHORT P INT P;
C2120 "'void'-некорректно со всеми типами".
      Тип void был использован в объявлении с другим типом.
C2121 "typedef определяет другое перечисление".
      Была попытка использовать тип, объявленный в операторе typedef
      для задания, как типа перечисления, так и другого типа.
C2122 "typedef определяет другую структуру".
      Была сделана попытка использовать тип, объявленный в операторе
      typedef, для задания как типа структуры, так и другого типа.
C2123 "typedef определяет другую смесь".
      Была сделана попытка использовать тип, объявленный в операторе
      typedef, для задания как типа смеси, так и другого типа.
C2125 "'idetifier': память, занятая данными, превышает 64К":
      Данный элемент данных превышает предельный размер 64К.
C2126 "'identifier': данные типа automatic превышают размер 32К".
      Память, занятая локальными переменными функции, превышает зада-
      нный предел.
C2127 "Память, занятая параметрами, превышает 32К".
      Память, требуемая для парметров функции превышает предел 32К.
C2129 "Статическая функция 'identifier' не найдена".
      Была сделана ссылка на статическую функцию, которая никогда не
      была определена.
C2130 "#line требуется строка, содержащая имя файла".
      В директиве #line было опущено имя файла.
C2131 "Атрибуты near/far/huge заданы более одного раза".
      Ключевые слова near и far были применены к элементу данных бо-
      лее одного раза, как в следующем примере:
      typedef int near NINT;
      NINT far a; /* некорректно */
C2132 "Синтаксическая ошибка: неожиданный идентификатор".
      Идентификатор появлился в синтаксически некорректном формате.
C2133 "Массив 'identifier': неизвестный размер"
      Была сделана попытка описать массив с неназначенным размером,
      как в следующем примере:
      int mat add(array1)
          int array1[]; /* корректно */
          {
          int array2[]; /* некорректно */
          .
          .
          .
          }

C2134 "'identifier': структура или смесь слишком велики".
      Размер структуры или смеси превышает предел, установленный ком-
      пилятором (232 байтов).
C2135 "Пропущен знак ')' в макро-расширении".
      В обращении к макрокоманде с аргументами была опущена закрыва-
      ющая скобка.
C2137 "Пустая символьная константа".
      Была использована некорректная пустая символьная константа
      (' ').
C2138 "Несоответствие закрывающей границы комментария '/*'".
      Компилятор обнаружил открывающий ограничитель комментария (/*)
      без соответствующего закрывающего ограничителя (*/).
      Данная ошибка может возникнуть из-за попытки использования не-
      корректных вложенных коментариев.
C2139 "Тип, за которым следует 'type', некорректен".
      Некорректная комбинация типов, как в следующем примере:
      long char a;
C2140 "Тип аргумента не может быть функцией, возвращающей ...".
      Функция была объявлена, как формальный параметр другой функ-
      ции, как в следующем примере:
      int funcl (a)
          int a(); /* некорректно */
C2141 "Для константы перечисления значение превышает допустимые пре-
      делы".
      Константа перечисления имеет значение, превышающее допустимые
      пределы для типа int.
C2142 "Для многоточия требуется три точки".
      Компилятор обнаружил лексему, содержащую две точки (..) и пред-
C2143 "Синтаксическая ошибка: недостает лексемы 'token1' перед лексе-
      мой 'token2'".
      Компилятор ожидает появления перед token2-token1. Данное сооб-
      щение может появиться, если пропущена требуемая закрывающая фи-
      гурная скобка (}), правая скобка ()) либо точка с запятой (;).
C2144 "Синтаксическая ошибка: недостает лексемы 'token' перед типом
      'type'".
      Компилятор требует наличия данной лексемы перед данным типом.
      Данное сообщение может появиться пре пропущенной закрывающей
      фигурной скобке (}), правой скобке ()), или точке с запятой
      (;).
C2145 "Синтаксическая ошибка: перед идентификатором не хватает лексе-
      мы 'token'".
      Компилятор требует наличия перед идентификатором данной лексе-
      мы. Данное сообщение может появиться при пропущенной точке с
      запятой (;) в последнем объявлении блока.
C2146 "Синтаксическая ошибка: перед идентификатором 'identifier' не
      хватает лексемы 'token'".
      Компилятор требует наличия данной лексемы перед данным иденти-
      фикатором.
C2147 "Массив: неизвестный размер".
      Сделана попытка увеличить индекс, либо указатель на массив, ба-
      зовый тип которого еще не объявлен.
C2148 "Слишком большой массив".
      Массив превышает максимально-допустимый размер (232 байта).
C2149 "'identifier': данное битовое поле не может иметь нулевую шири-
      ну".
      Битовое поле с данным именем имеет нулевую ширину. Нулевой раз-
      мер разрешается иметь только неименованным битовым полям.
C2150"'identifier': битовое поле должно иметь тип int, signed int или
      unsigned int.
      Стандарт ANSI C требует, чтобы битовые поля имели типы int,
      signed int или unsigned int. Данное сообщение может появиться
      только при компиляции с опцией /Za.
C2151 "Задано более одного атрибута cdecl/fortran/pascal".
      Было задано более одного ключевого слова, определяющего согла-
      щения о вызове функций.
C2152 "'identifier': указатели на функции с различными атрибутами".
      Была сделана попытка присвоить указатель на функцию, объявлен-
      ную с одними соглашениями о связях (cdecl, fortran или pascal)-
      -указателю на функцию, объявленную с другими соглашениями о
      связях.
C2153 "Шестнадцатеричные константы должны иметь по крайней мере одну
      шестнадцатеричную цифру".
      Ox или OX-являются некорректными шестнадцатеричными константа-
      ми. За "x" или "X" должна следовать хотя бы одна шестнадца-
      теричная цифра.
C2154 "'name': не относится к сегменту".
      Имя функции name было первым идентификатором, заданным в аргу-
      ментном списке прагмы alloc_text, и уже определено как какое-
      -либо имя, отличное от имени сегмента.
C2155 "Имя 'name': уже имеется в сегменте".
      Имя функции name появляется более, чем в одной прагме alloc_
      text.
C2156 "Прагма должна быть на внешнем уровне".
      Некоторые прагмы должны быть определены на глобальном уровне,
      вне тела функции, а одна из таких прагм оказалась внутри фун-
      кции.
C2157 "'name': перед использованием в списке прагмы данное имя долж-
      но быть описано".
      Данное имя функции из списка функций прагмы alloc_text не было
      описано перед включением в список.
C2158 "'name': является функцией".
      Имя name было задано в списке переменных прагмы same_seg, но
      ранее было объявлено, как функция.
C2159 "Определено  более одного класса памяти".
      В описании было задано более одного класса памяти, как в сле-
      дующем примере:
      extern static int i;
C2160 "## не может встретиться в начале макро-определения".
      Макро-определение начинается с оператора подстановки лексем,
      как в следующем примере:
      #define mac(a,b) ##a...
C2161 "## не может находиться в конце макро-определения".
      Макро-определение заканчивается оператором подстановки лексем
      (##).
C2162 "Требуется формальный параметр макрокоманды".
      Лексема, следующая за оператором (#), не является именем фор-
      мального параметра, как в следующем примере:
      #Define print(a) printf(#b)
C2163"'string': отсутствует, как intrinsic".
      Функция, определенная в списке функций для прагмы intrinsic или
      function, не является одной из имеющихся в форме intrinsic фун-
      кций.
C2165 "'keyword': невозможно изменить указатели на данные".
      Были некорректно использованы ключевые слова fortran, pascal
      или cdecl для модификации указателя на данные, как в следующем
      примере:
      char pascal *p;
C2166 "Значение определяет объект, относящийся к классу памяти
      'const'".
      Была сделана попытка присвоить значение элементу данных, объяв-
      ленному с классом памяти const.
C2167 "'name': слишком много фактических параметров для intrinsic.
      Ссылка на имя intrinsic function содержит слишком много факти-
      ческих параметров.
C2168 "'name': слишком мало фактических параметров для intrinsic".
      Ссылка на имя содержит слишком мало фактических параметров.
C2169 "'name': является intrinsic оно не может быть определено ".
      Была сделана попытка задать определение для функции, уже описа-
      нной, как intrinsic.
C2171 "'operator': неверный операнд".
      Данный унарный оператор был использован с операндом некоррект-
      ного типа, как в следующем примере:
      int (*fp)();
      double d, d1;
        .
        .
        .
      fp++;
      d=~d1
C2172 "'function': фактически не указатель, параметр номер'number'.
      Была сделана попытка передать аргумент, не являющийся указате-
      лем, функции, требующей указатель. Данный номер указывает, ка-
      кой аргумент ошибочен.
C2173 "'function': фактически не указатель, параметр 'number': спи-
      сок параметров 'number'".
      Была сделана попытка передать аргумент, не являющийся указате-
      лем, функции, требующей указатель. Данная ошибка может произой-
      ти в вызовах, возвращающих указатель на функцию. Первый номер
      указывает, какой аргумент вызвал ошибку; второй номер показы-
      вает, какой список аргументов содержит неверный аргумент.
C2174 "'function': фактически имеет тип void: параметр 'number', спи-
      сок параметров 'number'".
      Была сделана попытка передать аргумент типа void функции. Фор-
      мальные параметры и аргументы функции не могут иметь тип void;
      однако, они могут иметь тип void* (указатель на void). Данная
      ошибка происходит в вызовах, возвращающих указатель на функцию.
      Первый номер показывает, какой аргумент вызвал ошибку; второй
      номер показывает, какой список аргументов содержит неправильный
      аргумент.
C2175 "'function': неразрешенная внешняя ссылка".
      Данная функция неопределена в исходном файле, либо встроена в
      среду программирования QUICK-C, либо находится в библиотеке
      QUICK, если она загружена.
      Данная ошибка возникает только в одно-модульных, встроенных в
      среду Quick-C программах. Чтобы разрешить данную проблему, либо
      определите функцию в исходном файле, либо загрузите библиотеку
      QUICK,содержащую данную функцию, либо (если функция содержится
      в стандартной библиотеке СИ-функций), создайте для программы
      программный список.
C2177 "Константа слишком велика".
      Информация была потеряна, поскольку константа слишком велика,
      чтобы заменить тип, которому она присваевается. (1)

                   D.1.3. Предупреждающие сообщения.

    Сообщения,  перечисленные  в  данном  разделе,  вскрывают  некоторые
возможные  проблемы,  но  не  мешают  компиляции  и  компановке. Номер в
скобках  в  конце  сообщения  об  ошибке  означает  минимальный  уровень
предупреждения, установленный для данного сообщения.

Номер  Предупреждающее сообщение

C4000 "Нераспознанное предупреждение, свяжитесь с техническим сер-
      висом фирмы Microsoft".
      Компилятор обнаружил неизвестную ошибку. Пожалуйста, сообщите
      условия возникновения данной ошибке фирме Microsoft Corpora-
      tion, воспользовавшись бланком "Product Assistant Request",
      находящимся в конце данного руководства.
C4001 "Макрокоманда 'identifier'требует параметров".
      Данный идентификатор был определен, как макрокоманда, имеющая
      один или более аргументов, но используется в программе без ар-
      гументов. (1).
C4002 "Слишком много фактических параметров для макрокоманды 'identi-
      fier'".
      Число фактических аргументов, употребляемых с данным идентифи-
      катором, больше, чем число формальных параметров, заданных в
      макроопределении данного идентификатора. (1).
C4003 "Не достаточно фактических параметров для макрокоманды
      'identifier'".
      Число фактических аргументов, употребляемых с данным идентифи-
      катором, меньше, чем число формальных параметров, заданных в
      макроопределении данного идентификатора. (1).
C4004 "Не хватает закрывающей скобки после 'defined'".
      После фразы #if defined пропущена закрывающая скобка. (1).
C4005 "'identifier': повторное определение".
      Данный идентификатор был повторно определен. (1).
C4006 "Директиве #indef требуется идентификатор".
      В директиве #indef задан идентификатор, определение которого
      отсутствет. (1).
C4009 "Строка слишком велика, хвостовые символы отсекаются".
      Размер строки превышает предел, установленный компилятором.
      Для исправления данной ситуации разбейте строку на две или бо-
      лее подстроки. (1).
C4011 "Идентификатор усечен до 'identifier'".
      Принимаются только первые 31 символ идентификатора. (1).
C4014 "'identifier': битовое поле должно иметь тип unsigned.
      Данное битовое поле не было описано с типом unsigned. Битовые
      поля должны быть описаны, как целые без знака. Компилятор со-
      ответственно конвертирует данное битовое поле. (1).
C4014 "'identifier': битовое поле должно иметь целый тип".
      Данное битовое поле было описано, не как целое. Битовые поля
      должны быть описаны, как целые без знака. Было применено пре-
      образование. (1).
C4016 "'identifier': нет типа, возвращаемого функцией".
      Данная функция еще не была описана либо определена, поэтому
      тип возвращаемого значения неизвестен.
      Подразумевается стандартный тип (int). (2).
C4017 "Приведение целого выражения к 'дальнему' указателю".
      Дальние указатели содержат полные адреса сегментов. На процес-
      соре 8086/8088 приведение целого (int) значения к "дальнему"
      указателю может создать адрес с бессмысленным значением сегмен-
      та. (1).
C4020 "Слишком много фактических параметров".
      Число аргументов, определенных в вызове функции, больше числа
      формальных аргументов, заданных в списке аргументов определения
      функции. (1).
C4021 "Слишком мало фактических параметров".
      Число аргументов, заданных в вызове функции, меньше числа фор-
      мальных параметров, определенных в списке аргументов определе-
      ния функции. (1).
C4022 "Несоответствие указателей: параметр n".
      Тип указателя данного параметра отличен от типа указателя, за-
      данного в списке аргументов определения функции. (1).
C4024 "Различные типы: параметр n".
      Тип данного параметра функции не согласуется с типом, заданным
      в списке аргументов определения функции. (1).
C4025 "Описание функции задает переменный список аргументов".
      Список типов аргументов определения функции заканчивается запя-
      той, за которой следует многоточие, что  означает, что функция
      может принимать переменное число аргументов, но для функции не
      были описаны формальные параметры. (1).
C4026 "Функция была описана со списком формальных параметров".
      Функция была описана, как принимающая аргументы, но в определе-
      нии функции не задано формальных параметров. (1).
C4027 "Функция была описана без списка формальных параметров".
      Функция была описана, как не принимающая аргументов (список
      типов аргументов состоит из слова void), но в определении функ-
      ции заданы формальные параметры, либо в вызове функции заданы
      фактические параметры. (1).
C4028 "Отличается описание параметра n".
      Тип данного параметра не согласуется с соответствующим типом в
      списке типов аргументов, либо с соответствующим формальным па-
      раметром. (1).
C4029 "Описание списка параметров отлично от определения":
      Список типов аргументов, заданный в описании функции, не со-
      гласуется с типами формальных параметров, заданных в опреде-
      лении функции. (1).
C4030 "Первый список параметров длиннее второго".
      Функция была описана более одного раза, причем с различными
      списками типов аргументов. (1).
C4031 "Второй список параметров длиннее, чем первый".
      Функция была описана более одного раза, причем с различными
      списками типов аргументов. (1).
C4032 "Неименованная структура/смесь в качестве параметра".
      Тип структуры или смеси был передан как неименованный аргумент,
      то есть описание формального параметра не может использовать
      имя и должно описать тип. (1).
C4033 "Функция должна возвращать значение".
      Если функция не описана, как void, она должна возвращать зна-
      чение. (2).
C4034 "Оператор sizeof возвратил 0".
      Оператор sizeof был применен к операнду, причем в результате
      был получен 0. (1).
C4035 "'identifier': нет возвращаемого значения".
      Функция описана, как возвращающая значение, но не делает
      этого. (2).
C4036 "Не ожидаемый список формальных параметров".
      Список формальных параметров был задан в описании функции.
      Список формальных параметров игнорируется. (1).
C4037 "'identifier': формальные параметры игнорируются".
      В описании функции не найдено перед описанием формальных
      параметров ни класса памяти, ни наименование типа, как в сле-
      дующем примере:
         int * f(a,b,c);
      Формальные параметры игнорируются. (1).
C4038 "'identifier':формальный параметр имеет некорректный класс па-
      мяти".
      Данный формальный параметр был описан с классом памяти, от-
      личным от auto или register. (1).
C4039 "'identifier': функция используется в качестве аргумента"
      Формальный параметр функции был описан, как функция, что не-
      корректно.Формальный параметр будет преобразован в указатель
      функции (1).
C4040 "Ключевое слово near/far/ в идентификаторе 'identifier' игнори-
      руется".
      Ключевые слова near или far не оказывают никакого действия на
      данный идентификатор и потому игнорируются.(1).
C4041 "Формальный параметр 'identifier' переопределен".
      Данный формальный параметр был в теле функции определен повтор-
      но, сделав соответствующий фактический параметр для функции не-
      доступным. (1).
C4042 "'identifier' имеет не корректный класс памяти".
      Заданный класс памяти не может быть использован в данном конте-
      ксте (например, параметрам функции не может быть присвоен класс
      extern). Для данного контекста использован вместо некорректного
      стандартный класс памяти. (1).
C4043 "'identifier': тип void изменен на int".
      Элемент данных, отличный от функции, был описан с типом void.
      (1).
C4045 "'identifier': массив переполнен".
      Для данного массива было задано слишком много инициализаторов.
      Лишние инициализаторы будут игнорированы. (1).
C4046 "Знак '&' в функции/массиве игнорируется".
      Была сделана попытка применить оператор адресации (&) к иден-
      тификатору, обозначающему функцию или массив. (1).
C4047 "'operator': различные уровни косвенного наименования".
      Данную ситуацию иллюстрирует следующий пример:
      char **p;
      char *q;
      .
      .
      .
      p=q;
C4048 "Массив описан с помощью различных описателей".
      Массив был описан дважды с различными размерами. Используется
      большой размер. (1).
C4049"'operator': косвенное наименование применяется к различным ти-
      пам".
      Оператор косвенного наименования (*) был использован в выраже-
      нии для доступа к значениям различных типов. (1).
C4051 "Преобразование данных".
      В выражении два элемента данных имеют различные типы, что при-
      ведет к преобразованию данных к одному типу. (2).
C4052 "Различные типы enum".
      В выражении были использованы два различных типа enum. (1).
C4053 "По крайней мере один операнд void"
      Выражение с типом void было использовано в качестве операнда.
      (1).
C4056 "Переполнение в константной арифметике".
      Результат операции превышает 0x7FFFFFFF. (1).
C4057 "Переполнение при перемножении констант".
      Результат операции превышает 0x7FFFFFFF. (1).
C4058 "Взят адрес переменной фрейма, DS!=SS".
      Программа была скомпилирована со стандартным сегментом данных
      (DS), не равным стэковому сегменту (SS), программа пытается об-
      ратиться к переменной фрейма посредством ближнего указателя.(1)
C4059 "В результате преобразования адрес сегмента потерян".
      Преобразование "дальнего" указателя (полного адреса сегмента) к
      "ближнему" указателю (смещение) привело к потере адреса сегмен-
      та. (1).
C4060 "Преобразование 'длинного' адреса в 'короткий' адрес".
      Преобразование длинного адреса (32-разрядного указателя) в ко-
      роткий адрес (16-разрядного указателя) привело к потере адреса
      сегмента. (1).
C4061 "long/short несоответствие в аргументе: применено преобразо-
      вание".
      Базовые типы действительных и формальных параметров функции
      различны. Фактический параметр преобразовывается к типу фор-
      мального параметра. (1)
C4063 "'identifier': функция слишком велика для шага оптимизации".
      Данная функция не была оптимизирована, поскольку для этого
      недостаточно памяти. Чтобы исправить данную ситуацию, сократи-
      те размер функции путем разделения ее на две или более меньших
      функций. (0).
C4066 "Таблица локальных имен переполнена-некоторые локальные имена
      могут быть пропущены в списке".
      Генератор листинга вышел за пределы динамической области, отве-
      денной под локальные переменные, поэтому исходный листинг может
      не включать в себя полную таблицу имен для всех локальных пере-
      менных
C4067 "За директивой 'directive' следуют непонятные символы-требует-
      ся символ перехода на следующю строку".
      За директивой препроцессора следуют лишние символы, как в
      следующем примере:
      #endif NO_EXT_KEYS
      Это принимается в некоторых версиях компилятора Microsoft C,
      исключая версию 1.0 Microsoft Quick C. (1).
C4068 "Неизвестная прагма".
      Компилятор не смог распознать прагму и игнорировал ее. (1).
C4069 "Преобразование ближнего указателя к длинному целому".
      Ближний указатель был преобразован к длинному целому, что за-
      полнило старшие разряды текущим значением сегмента данных, не
      равным нулю. (1).
C4071 "'identifier': прототип функции не задан".
      Данная функция была вызвана компилятором перед тем, как компи-
      лятор обработал соответствующий прототип функции. (3).
C4072 "Недостаточно памяти для обработки отладочной информации".
      Вы скомпилировали программу с опцией /Zi, но для создания со-
      ответствующей отладочной информации недостаточно памяти. (1).
C4073 "Вложенность слишком глубока, дальнейшая вложенность во время
      отладки игнорируется".
      Описания появились на уровне вложенности, большем 13. В ре-
      зультате, все описания будут восприниматься как бы на одном
      уровне. (1).
C4074 "Было использовано нестандартное расширение-'extension'".
      Было использовано данное нестандартное расширение в то время,
      как опция Language Extension в диалоговой рамке Compile была
      выключена, либо опция /Ze не действовала. Данные расширения да-
      ны в Разделе 8.1.4.6. "Использование расширений языка СИ фирмы
      Microsoft: Опция Language Extension". (если включена опция /Za,
      данная ситуация дает ошибку). (3).
C4075 "Размер выражения в операторе switch или константа в операторе
      case имеют слишком большой размер-преобразуются к типу int".
      Значение, появляющееся в операторах switch или case, больше ти-
      па int. Компилятор преобразует данное некорректное значение в
      тип int. (1).
C4076 "'type': может быть использовано только с целыми типами".
      Модификатор типа signed или unsigned был применен к не целому
      типу, как в следующем примере:
      unsigned double b;
C4077 "Неизвестная опция прагмы check_stack".
      Со старой формой прагмы check_stack была задана неизвестная
      опция, как в следующем примере:
      #pragma check_stack yes
      В старой форме прагмы check_stack аргумент прагмы должен быть
      пустым + или -.
C4079 "Неожиданный символ 'character'".
      В аргументном списке прагмы был найден неожиданный разделитель
      'character'".
C4080 "Пропущено имя сегмента".
      В первом аргументе аргументного списка прагмы alloc_text про-
      пущено имя сегмента. Это случается, если первая лексема в ар-
      гументном списке не является идентификатором.
C4082 "Требуется идентификатор".
      В списке аргументов прагмы пропущен идентификатор.
C4083 "Пропущено'('".
      В аргументном списке прагмы пропущена открывающая левая скобка,
      как в следующем примере:
      #pragma check_pointer on)
C4084 "Требуется ключевое слово pragma".
      Лексема, следующая за ключевым словом pragma, не является иден-
      тификатором, как в следующем примере:
      #pragma (on)
C4085 "Требуется [on/off]
      Для новой формы прагмы check_stack был задан некорректный аргу-
      мент, как в следующем примере:
      #pragma check_stack (yes)
C4087 "'name': описана с пустым списком параметров".
      Данная функция была описана, как не принимающая параметров, в
      то время как вызов функции определяет фактические параметры,
      как в следующем примере:
      int fl(void);
         .
         .
         .
      fl(10);
C4090 "Различные атрибуты 'const'".
      Указатель на элемент данных, описанный, как const, был пере-
      дан функции, соответствующий формальный параметр которой явля-
      ется указателем на элемент данных, не являющийся const. Это
      значит, что данный элемент данных может быть незаметно изме-
      нен, как в следующем примере:
      const char *p = "ascde";
      int str(char *s);
         .
         .
         .
      str(p);
C4091 "Не описано никаких имен".
      Компилятор обнаружил пустое описание, как в следующем примере
      (2):
      int;
C4092 "Описание перечисления/структуры/смеси не имеет имени".
      Компилятор обнаружил пустое описание, использующее не имеющую
      соответствующего тэга структуру, смесь или перечисление, как в
      следующем примере:
      struct {
         .
         .
         .
              };
C4093 "Некорректный символ перехода на новую строку в символьной кон-
      танте в не действующем коде".
      Константное выражение в директиве препроцессора #if, #ifdef или
      #ifndef вычисляется в 0, что делает соответствующий код неактив
      ным, причем символ перехода на новую строку появляется в данном
      не активном коде между соответствующими одиночными или двойными
      кавычками.
C4095 "Слишком много аргументов для прагмы".
      В прагме, имеющей только один аргумент, появляется более одного
      аргумента.
C4096 "Элемент типа huge трактуется, как far".
      Поскольку компилятор Microsoft Quick-C не поддерживает ключевое
      слово huge, элемент данных трактуется, как описанный с ключе-
      вым словом far. Если элемент данных или функция должны все же
      иметь тип huge, перекомпилируйте программу с помощью Оптимизиру
      ющего компилятора Microsoft C.
C4097 "В строке встретился символ 'hex-character', не относящийся к
      коду ASCII".
      Данный не ASCII-символ был использован в данной символьной
      строке.

                    D.1.4. Ограничения компилятора.

    Для  работы  с  компилятором  Microsoft  Quick-C  вам  нужно   иметь
достаточное   количество   памяти   для   обработки   временных  файлов,
используемых для обработки. Требуется  память приблизительно в два  раза
большая, чем размер исходного файла.

    В  таблице  D.1  приводятся  ограничения,накладываемые   СИ-компиля-
тором.  Если  ваша  программа  превышает  один из заданных пределов, вас
информирует об этом сообщение об ошибке.

                                                 Таблица D.1.
                      Ограничения СИ-компилятора.

Элемент программы      Описание                  Ограничения

Строковые литералы     Максимальная длина строки, 512 байтов
                       включающая нулевое оконча-
                       ние (\0).
Константы              Максимальный размер констан-
                       ты зависит от ее типа; смот-
                       рите "Справочное руководство
                       по языку СИ".
Идентификаторы         Максимальная длина идентифи- 31 байт (дополни-
                       катора                       тельные символы
                                                    не воспринимают-
                                                    ся).
Описания               Максимальный уровень вло-    10 уровней
                       женности для определений
                       структуры или смеси.
Директивы препроцес-   Максимальный размер макро-   512 байтов.
сора                   определения.
                       Максимальное количество      8 аргументов
                       фактических параметров в
                       макроопределении.
                       Максимальная длина реально-   256 байтов
                       го аргумента препроцессора.
                       Максимальный уровень вложен-  32 уровня
                       ности директив #if, #ifdef,
                       #ifndef.
                       Максимальный уровень вложен-  10 уровней
                       ности для подключаемых фай-
                       лов.

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

             D.2.Сообщения об ошибках в командной строке.

    Сообщения, указывающие  на ошибки  в командной  строке, используемой
для вызова компилятора, имеют один из следующих форматов:

command line fatal error D1xxx: messagetext          Fatal error
(Фатальная ошибка командной строки D1xxx: текст сообщения Фатальная
ошибка)

command line error D2xxx: messagetext                 Error
(Ошибка командной строки D2xxx: текст сообщения       Ошибка)

command line warning D4xxx: messagetext               Warning
(Предупреждение командной строки D4xxx: текст сообщения
Предупреждение).

    Если   возможно,   компилятор   продолжает   работу,    распечатывая
предупреждающее сообщение. В  некоторых случаях ошибки  командной строки
являются  неисправимыми  и  компилятор  прекращает  работу.   Сообщения,
приведенные в разделах D.2.1-D.2.3 описывают ошибки командной строки.

             D.2.1. Неисправимые ошибки командной строки.

    Следующие сообщения описывают фатальные ошибки. Драйвер  компилятора
не  может  восстановить  работу  после  фатальной  ошибки; он прекращает
работу после распечатки сообщения.

Номер   Сообщение о фатальной ошибке в командной строке

D1000 Неизвестная фтатальная ошибка командной строки. Свяжитесь с тех
      нической службой фирмы Microsoft. Компилятор обнаружил нераспоз
      нанную неисправимую ошибку.
      Пожалуйста, сообщите условия возникновения данной ошибки в фир-
      му Microsoft Corporation с помощью формы Product Assistance
      Request, находящейся в конце данного руководства.
D1001 "Невозможно выполнить 'filename'".
      Компилятор не может найти данный файл в текущем рабочем катало-
      ге, либо в других каталогах, определяемых посредством перемен-
      ной PATH.
D1002 "Слишком много открытых файлов, невозможно переадресовать
      'filename'".
      Больше нет файлов, чтобы переадресовать вывод опции /P в файл.
      Попробуйте изменить ваш файл CONFIG.SYS и увеличьте значение
      num в строке files=num (если num меньше 20).

             D.2.2. Сообщения об ошибках командной строки.

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

Номер   Сообщение об ошибках командной строки

D2000 "Нераспознанная ошибка командной строки, обратитесь в техничес-
      кий сервис фирмы Microsoft".
      Компилятор обнаружил неизвестную ошибку. Пожалуйста, сообщите
      условия возникновения данной ошибки фирме Microsoft Corporati-
      on, используя бланк "Product assistance Request", находяцийся в
      конце данного руководства.
D2001 "Слишком много имен определены с -D".
      Слишком много символических констант были определены с помощью
      опции /D командной строки.
      Обычный предел определений на командной строке 16; если вы ис-
      пользуете опции /U или /u-предел увеличивается до 20.
D2002 "Предварительно определенная модель была отменена".
      Были определены две различные модели памяти; используется мо-
      дель, заданная на командной строке позже.
D2003 "Пропущено имя исходного файла".
      Вы не задали имя компилируемого исходного файла.
D2007 "Неверно задана опция, следует заменить 'string1' на
      'string2'".
      Данная опция была задана более одного раза с конфликтующими ар-
      гументами string1 и string2.
D2008 "Слишком много флажков опции 'string'".
      С заданной опцией было определено слишком много букв (например,
      с опцией /O).
D2009 "Неизвестный символ опции 'option string'".
      Одна из букв данной опции нераспознана.
D2010 "Неизвестная опция плавающей точки".
      Данная опция плавающей точки ( опция /FP) не является коррект-
      ной.
D2011 "Разрешена только одна опция плавающей точки".
      На командной строке вы задали более одной опции плавающей точ-
      ки (/FP).
D2012 "На командной строке слишком много опций компановщика".
      Вы сделали попытку задать на командной строке более 128 отдель-
      ных опций и объектных файлов для компановщика.
D2015 "Ассемблерные файлы не обрабатываются".
      Вы задали на командной строке имя файла с расширением .ASM.
      Поскольку компилятор не может автоматически вызывать Макроас-
      семблер (MASM), он не может ассемлировать данные файлы.
D2018 "Невозможно открыть файл компановщика cmd".
      Файл соответствий, передающий компановщику имена объектных фай-
      лов и опции, не может быть открыт.
      Данная ошибка может произойти, если какой-либо файл с атрибутом
      "только-чтение" имеет то же самое имя, что файл соответствий
      компановщика.
D2019 "Невозможно перезаписать исходный файл 'name'".
      Вы задали исходный файл в качестве выводного. Компилятор не
      позволяет исходному файлу быть перезаписанным одним из выход-
      ных файлов компилятора.
D2020 "Опция -Gc требует возможности разрешения расширенных ключевых
      слов (-Ze)".
      Опция /Gc и опция /Za были заданы на одной командной строке.
      Опция /Gc требует возможности задания расширенного ключевого
      слова cdecl, если осуществляется доступ к библиотечным функ-
      циям.
D2021 "Неверный числовой аргумент 'string'".
      Нечисловая строка была задана за опцией, требующей  числового
      аргумента.
D2022 "Невозможно открыть файл помощи cl.hlp".
      Была задана опция /HELP, но файл содержащий вспомогательные
      сообщения не был найден в текущем каталоге, либо в каталогах,
      заданных с помощью переменной PATH.

          D.2.3. Предупреждающие сообщения командной строки.

    Сообщения,  перечисленные  в  данном  разделе,  описывают  возможные
проблемы, но не прерывают компиляцию и компановку.

Номер   Предупреждающие сообщения

D4000 "Неизвестное предупреждение командной строки, свяжитесь с тех-
      нической службой фирмы Microsoft".
      Компилятором была обнаружена неизвестная ситуация.
      Пожалуйста, сообщите условия возникновения данной ситуации фир-
      ме Microsoft Corporation, используя бланк "Product Assistance
      Request", находящийся в конце данного руководства.
D4002 "Неизвестная опция 'string' игнорируется".
      Одна из опций, заданных на командной строке, была  нераспоз-
      нана и потому проигнорирована.
D4003 "Для генерации кода выбран 80186/286, а не 8086".
      Были заданы обе опции: /G0 и /G2; преимущество дано опции /G2.
D4004 "Оптимизация по времени, а не по размеру".
      Данное сообщение подтвердило использование для оптимизации оп-
      ции /Ot.
D4005 "Невозможно выполнить 'filename'; пожалуйста, вставьте дискету
      и нажмите любой ключ".
      Команда QCL не может найти заданный выполняемый файл по задан-
      ному маршруту.
D4006 "Разрешена только одна из опций -P/-E/-EP, выбрана -P".
      Было задано более одной выводной опции препроцессора.
D4007 "Опция -C игнорируется (нужно задать также -P или -E, либо
      -EP)".
      Опция /C должна использоваться вместе с одной из выводных
      опций препроцессора (/E, /EP, /P).
D4009 "Порог только для данных far/huge, игнорируется".
      Опция /Gt была использована в модели памяти, имеющей ближние
      указатели на данные. Она может применяться только для ком-
      пактной и большой моделей.
D4010 "Опция -Gp не применяется, игнорируется".
      Версия операционной системы DOS Microsoft C не поддерживает
      профайлинг.
D4013 "Комбинированный листинг имеет преимущество над объектным
      листингом"
      Если опция /Fc задана вместе с одной из опций /Fl или /Fa, соз-
      дается комбинированный листинг (/Fc).
D4014 "Неверное значение number для строки 'string'. Используете ста-
      ндартное значение number".
      В контексте, требующем определенное числовое значение, было за-
      дано некорректное значение.
D4017 "Конфликтующие опции проверки стэка-проверка стека отменяется".
      Вы задали на командной строке CL обе опции /Ge и /Gs. Опция Gs
      имеет преимущество, поэтому в данной программе стэковый конт-
      роль отменяется.

             D.3. Сообщения об ошибках периода выполнения.

    Ошибки периода выполнения подразделяются на четыре категории:

    1.Исключительные ситуации при выполнении операций с плавающей точкой
математическим сопроцессором 8087/80287 или эмулятором. Данные  ситуации
описаны в Разделе D.3.1.

    2.  Сообщения  об   ошибках,  сгенерированные  библиотекой   периода
выполнения,  информирующие  вас  о  серьезных  ошибках. Данные сообщения
перечислены и описаны в Разделе D.3.2.

    3.  Сообщения  об  ошибках,  сгенерированные  во  время  обращения к
процедурам  обработки  ошибок  библиотеки  периода  выполнения  - abort,
assert, perror-как только программа вызовет процедуру. Данная  процедура
направляет сообщения  в стандартный  вывод. Описание  данных процедур  и
соответствующих сообщений об  ошибках смотрите в  документе: "Справочное
руководство по библиотеке процедур Microsoft-C".

    4.  Сообщения  об  ошибках,  сгенерированные вызовами математических
процедур  из   библиотеки  СИ   периода  выполнения.   В  случае  ошибки
математические  процедуры  возвращают  ошибочное  значение,  а некоторые
выводят сообщение на стандартной вывод. Описание математических процедур
и соответствующие сообщения об ошибках смотрите в документе  "Справочное
руководство по библиотеке проц Microsoft-C".

                D.3.1. Исключительные ситуации операций
                          с плавающей точкой.

    Сообщения    об    ошибках,    перечисленные    ниже,   генерируются
математическим  сопроцессором  8087/80287.  Описание  сбоев оборудования
смотрите в  документации по  процессорам семейства  Intel. Данные ошибки
могут  быть  также  выявлены  эмулятором  операций  с  плавающей точкой,
встроенным в стандартную библиотеку Quick-C.

    С  помощью  назначений  управляющего  слова сопроцессора 8087/80287,
следующие исключительные ситуации маскируются и потому не происходят

Исключительная         Стандартное маскирующее действие
ситуация

Слишком малое число    Ситуация маскируется
Потеря значимости      Результат приводится к нулю
Потеря точности        Ситуация маскируется

    Информацию  о  том,  как  изменить  управляющее  слово  операций   с
плавающей   точкой,   смотрите   в   справочных   страницах, посвященных
_control87, в документе  "Справочное руководство по  библиотеке процедур
Microsoft C".

    Кроме того, следующие ошибки не возникают в коде, сгенерированном  с
помощью  компилятора  Microsoft   Quick-C  или  полученном   посредством
стандартной СИ-библиотеки:

      Квадратный корень
      Выход за нижнюю границу стэка
      Неэмулируется

    Исключительные  ситуации  при  операциях  с  плавающей  точкой имеют
следующий формат:

      run-time error M61nn: MATH
      - floating-point error: messagetext

Номер   Исключительные ситуации при операциях с плавающей точкой

М6101 "Неверно".
      Произошла некорректная операция. Обычно это происходит при дей-
      ствиях с с неопределенностями.
      Данная ошибка приводит к останову программы с кодом завершения
      129.

Номер   Исключительные ситуации при операциях с плавающей точкой

М6102 "Слишком малое число".
      Было сгенерировано слишком малое число с плавающей точкой, даль
      нейшее его использование приведет к потере значимости. Такие
      ситуации обычно маскируются, они отлавливаются и обрабатывают-
      ся. Программа заканчивается с кодом завершения 130.
М6103 "Деление на нуль".
      Была сделана попытка деления на нуль. Программа заканчивается
      с кодом 131.
М6104 "Переполнение".
      При выполнении операции с плавающей точкой произошло переполне-
      ние. Программа заканчивается с кодом 132.
М6105 "Потеря значимости".
      Во времы операции с плавающей точкой произошла потеря значимос-
      ти. Такие ситуации обычно маскируются; слишком малое значение
      заменяется нулем. Программа заканчивается с кодом завершения
      133.
М6106 "Потеря точности".
      Во время операции с плавающей точкой произошла потеря точности.
      Данная ситуация обычно проходит незамеченной, поскольку почти
      все операции с плавающей точкой могут привести к потере точнос-
      ти. Программа заканчивается с кодом 134.
М6107 "Невозможна эмуляция"
      Была сделана попытка выполнить инструкцию сопроцессора 8087/
      /80287, являющуюся некорректной и не поддерживаемую эмулятором.
      Программа завершается с кодом 135.
М6108 "Квадратный корень".
      Операнд операции извлечения квадратного корня отрицателен. Про-
      грамма завершается с кодом 136. (обратите внимание, функция
      sqrt из библиотеки процедур языка СИ проверяет аргумент перед
      выполнением и возвращает ошибку, если аргумент отрицателен;
      описание функции sqrt смотрите в документе: "Справочное руко-
      водствопо библиотеке процедур Microsoft-C":
М6110 "Переполнение стэка".
      Выражение с плавающей точкой привело к переполнению стэка на
      сопроцессоре 8087/80287 или эмуляторе. (ситуации переполнения
      стэка отлавливаются до предела 7 уровней в дополнение к восьми
      уровням, обычно поддерживаемым сопроцессором 8087/80287). Прог-
      рамма завершается с кодом 138.
М6111 "Выход за нижнюю границу стэка".
      Выполнение операции с плавающей точкой на сопроцессоре
      8087/80287 или эмуляторе вызвало выход за нижнюю границу
      стэка. Программа завершается с кодом 139.
М6112 "Явно сгенерирована ошибка".
      Сигнал, означающий ошибку при выполнении операции с плавающей
      точкой, был послан с помощью вызова raise (SIGFPE). Программа
      завершается с кодом 140.

            D.3.1. Сообщения об ошибках периода выполнения.

    Следующие  сообщения  описывают  ошибки, сгенерированные в
процессе   выполнения   программы.   Номера   ошибок   периода
выполнения лежит в пределах от R6000 до R6999.

    Сообщения об  ошибках периода  выполнения имеют  следующую
основную форму:

    run-time error R6nnn

    - messagetext

    (ошибка периода выполнения R6nnn)

    (- текст сообщения)

Номер Сообщение об ошибке периода выполнения

R6000 "Переполнение стэка".
      Ваша программа переполнила пространство, отведенное под стэк.
      Это может произойти, если ваша программа использует большое
      количество локальных данных или является рекурсивной. Программа
      завершается с кодом 255.
      Чтобы исправить данную ситуацию, перекомпилируйте программу с
      помощью команды QCL с опцией /F и перекомпануйте программу, ис-
      пользуя опцию компановщика /STACK для размещения большого стэка
R6001 "Присваивание нулевого указателя".
      В процессе выполнения программы было изменено содержимое сег-
      мента NULL. Сегмент NULL-это специальное место, расположенное
      по младшим адресам памяти, которое обычно не используется. Ес-
      ли содержимое сегмента NULL изменилось в процессе выполнения
      программы, это означает, что программа была записана на эту об-
      ласть, обычно, из-за примененного по небрежности нулевого ука-
      зателя. Заметим, что ваша программа может содержать нулевые
      указатели, но данное сообщение не будет генерироваться; данное
      сообщение появляется только в случае обращения к области памяти
      с помощью нулевого указателя
      Данная ошибка не будет вызывать останов программы; за сообщени-
      ем об ошибке следует нормальное завершение программы. Ошибка
      возвращает ненулевой код завершения. Данное сообщение отражает
      возможность серьезных ошибок в программе. Хотя программа, в ко-
      торой возникла такая ошибка, может работать правильно, она ве-
      роятно дает ошибки в будущем, и может дать сбой при работе в
      другой операционной среде.
R6002 "Библиотека процедур операций с плавающей точкой не загружена".
      Ваша программа требует библиотеку с плавающей точкой, но данная
      библиотека не загружена. Программа завершается по ошибке с ко-
      дом 255. Такая ошибка может произойти в следующих двух ситуа-
      циях:
      1.Программа была скомпилирована или скомпанована с такой опци-
      ей, как /FPi87, требующей сопроцессор 8087 или 80287, но прог-
      рамма выполняется на машине, не имеющей такого. Для исправления
      ошибки либо перекомпилируйте программу с опцией /FPi, либо ус-
      тановите сопроцессор. (В разделе 9.3.5 данного руководства вы
      найдете более подробную информацию о данных опциях и билиоте-
      ках.
      2.Строка формата для одной из процедур семейства printf или
      scanf содержит спецификацию для формата с плавающей точкой, в
      то время, как значений или переменных с плавающей точкой в про-
      грамме нет. Компилятор Quick-C делает попытку минимизировать
      размер программы посредством загрузки библиотеки поддержки пла-
      вающей точки только в случае крайней необходимости. Поскольку в
      форматных строках не обнаружено спецификаций плавающей точки,
      необходимые процедуры для работы с плавающей точкой не были за-
      гружены. Для исправления данной ошибки используйте какой-либо
      аргумент с плавающей точкой для соответствия заданной специфи-
      кации формата. Это приведет к тому, что библиотека поддержки
      плавающей точки будет загружена.
R6003 "Целое, деленное на нуль".
      Была сделана попытка разделить целое число на нуль, что дало
      неопределенный результат. Программа завершается с кодом 255.
R6004 "Требуется версия DOS 2.0 или выше".
      Компилятор Quick-C не может работать на версиях операционной
      системы DOS младше 2.0.
R6005 "Не хватает памяти для exec".
      Ошибки с R6005 по R6007 происходят при сбое в процедурах, вызы-
      ваемых одной из библиотечных, когда операционная система DOS не
      может вернуть управление в родительский процесс. Данная ошибка
      показывает, что для загрузки вызываемой программы не хватает
      памяти.
R6006 "Неверный формат для exec".
      Файл, выполняемый одной из функций exec, не имеет формата, тре-
      буемого для выполняемого файла.
R6007 "Некорректная среда для exec".
      Во время вызова одной из функций exec, операционная система DOS
      обнаружила некорректность среды для детского процесса.
R6008 "Не хватает памяти для аргументов".
R6009 "Не хватает памяти для программной среды".
      Ошибки R6008 и R6009 могут произойти при старте программы, если
      для загрузки программы хватает памяти, но недостаточно места
      для вектора argv, либо вектора envp, либо для обоих. Чтобы
      избежать данной проблемы перепишите процедуры _setargv или
      _setenvp
R6012 "Некорректное обращение к ближнему указателю".
      В программе был использован нулевой ближний указатель.
      Данная ошибка может произойти только при включенном контроле на
      указатели (то есть, если программа была скомпилирована с опцией
      Pointer Check в диалоговой рамке Compile, опцией /Zr на команд-
      ной строке, либо при действующей прагме pointer_check).
R6015 "Неожидаемое прерывание".
      Программа не может выполняться, поскольку она содержит неожида-
      емые прерывания.
      Когда прерывания создаются в программе из программного списка,
      работающей в программной среде, Quick-C автоматически создает
      объектные файлы и передает компановщику. Объектные файлы, пере-
      данные компановщику, содержат прерывания , требуемые для про-
      граммной среды Quick-C. Однако, вы не сможете запускать програ-
      мму, полученную из данных объектных файлов, вне программной
      среды Quick-C.

                D.3.3. Ограничения периода выполнения.

    В  таблице  D.2  приведены  ограничения,  накладываемые на
программы в  период выполнения.  Если ваша  программа нарушает
одно  из  данных  ограничений,  система выдает соответствующее
сообщение об ошибке.

                                                 Таблица D.2.

              Программные ограничения периода выполнения.

Элемент данных   Описание                            Ограничения

Файлы            Максимальный размер файла           232-1 байт
                                                     (4 гигабайта)
                 Максимальное число одновременно от-  20
                 крытых файлов (потоков).
Командная строка Максимальное количество символов     128
                 (включая имя программы).
Таблица операци- Максимальный размер.                  32К
онной среды.

---------------------------------------------------------------------

    Примечание:

    Пять стандартных потоков открываются автоматически (stdin,
stdout, stderr, stdaux, stdprn),  оставляя еще 15 потоков  для
нужд программы.

---------------------------------------------------------------------

                D.4. Сообщения об ошибках компановщика.

    Данный раздел описывает сообщения об ошибках, генерируемые
компановщиком LINK  (Оверлейный компановщик  фирмы Microsoft).
При  возникновении  фатальной  ошибки  компановщик   прерывает
выполнение.  Сообщения  о  фатальных  ошибках  имеют следующий
формат:

    место возникновения: fatal error L1xxx: текст сообщения

    Нефатальные ошибки выявляют проблемы в выполняемом  файле.
Компановщик LINK строит  выполняемый файл. Нефатальные  ошибки
имеют следующий формат:

    место возникновения: error L2xxx: текст сообщения

    Предупреждения  также  обозначают  возможные  проблемы   в
выполняемом файле. Компановщик  LINK строит выполняемый  файл.
Предупреждения имеют следующий формат:

    место возникновения: warning L4xxx: текст сообщения

    В данных сообщениях-место возникновения-это входной  файл,
в  котором  обнаружена  ошибка,  либо  программа  LINK,   если
входного файла нет. Если входной файл-это файл .OBJ или .LIB и
известно  имя  модуля,  имя  модуля  заключается в скобки, как
показано в следующем примере:

SLIBC.LIB( file)
MAIN.OBJ(main.c)
TEXT.OBJ

Ошибки компановщика могут возникнуть, как при неявном его вызове с
помощью команды QCL, так и при явном вызове с помощью команды LINK.
Они могут также произойти и при компиляции программы, имеющей
программный список, либо когда вы создаете на диске выполняемый файл
в среде Quick-C. Если ошибка компановщика возникает в программной
среде Quick-C, Quick-C высвечивает сообщение:

Error during link phase
No .EXE file produced
(Ошибка в процессе компановки
 Выполняемого файла не создается).

    Для  просмотра  ошибок  компановщика  нажмите  ENTER, либо
отметьте  "мышью"  командную  кнопку  OK.  Ошибки   последнего
прохода компановщика хранятся в файле с именем LINK.ERR.

    В следующем списке приведены ошибки, возникающие во  время
компановки  объектных  файлов  с  помощью  Microsoft   Overlay
Linker, LINK.

Номер    Сообщение об ошибке компановщика

L1001 "'option': имя опции неясно".
      После индикатора опции (/) не появилось уникального имени оп-
      ции. Например, команда
        Link /N main;
      сгенерирует ошибку, поскольку программа LINK не может опреде-

Номер    Сообщение об ошибке компановщика

      лить, какая из опций, начинающихся на букву "N" имеется в виду.
L1002 "'option': нераспознанное имя опции".
      За индикатором опции (/) появился нераспознанный символ, как в
      следующем примере:
         LINK /ABCDEF main;
L1004 "'option': неверное числовое значение".
      Для одной из опций было задано некорректное числовое значение.
      Например, для опции, требующей числовое значение, задана сим-
      вольная строка.
L1006 "'option': размер стэка превышает 65535 байтов".
      Размер, определенный для стэка, превышает 65535 байтов.
l1007 "'option': номер прерывания превышает 255".
      В качестве значения опции /OVERLAYINTERRUPT задано число, более
      255.
l1008 "'option': слишком большое предельное число сегментов".
      Было установлено предельное число сегментов, большее 3072 ( с
      помощью опции /SEGMENTS).
L1009 "'option': CPARMAXALLOC: некорректное значение".
      Число, определенное в опции /CPARMAXALLOC не лежит в пределах
      1-65535.
L1020 "Не заданы объектные модули".
      Для компановщика не заданы имена объектных файлов.
L1021 "Файлы соответствий вкладывать невозможно".
      Один файл соответствий оказался внутри другого файла соответст-
      вий.
L1022 "Файл соответствий слишком длинный".
      Строка в файле соответствий длиннее 127 символов.
L1023 "Выполнение прекращено пользователем".
      Вы нажали CONTROL+C.
L1024 "Вложение правых скобок".
      В командной строке содержимое оверлея было написано некоррекн-
      но.
L1025 "Вложение левых скобок".
      В командной строке содержимое оверлея было написано некоррекн-
      но.
L1026 "Несоответствие правых скобок".
      В командной строке в спецификации содержимого оверлея пропуще-
      на правая скобка.
L1027 "Несоответствие левых скобок".
      В командной строке в спецификации содержимого оверлея пропуще-
      на левая скобка.
L1043 "Таблица распределения памяти переполнена".
      В программе задано более 32768 длинных вызовов, длинных перехо-
      дов, либо других длинных указателей.
      Попытайтесь заменить длинные ссылки короткими, если возможно, и
      перестроить объектный модуль
L1045 "Слишком много записей TYPDEF.
      Объектный модуль содержит более 255 записей TYPDEF. Данные за-
      писи описывают общие переменные. Такая ошибка может возникнуть
      только в программах, созданных компилятором Microsoft Quick-C
      или другими компиляторами, поддерживающими общие переменные.
      (TYPDEF-это термин операционной системы DOS. Он разъясняется в
      документе "Справочное руководство программиста по операционной
      системе MS-DOS фирмы Microsoft" или других справочных книг по
      DOS.)
L1046 "Слишком много внешних имен в одном модуле".
      В объектном модуле определено более 1023 внешних имен. Разбейте
      модуль на меньшие части.
L1047 "Слишком много имен групп, сегментов, классов в одном модуле".
      Программа содержит слишком много имен групп, сегментов, клас-
      сов. Сократите число групп, сегментов или классов и перестройте
      объектный файл.
L1048 "Слишком много сегментов в одном модуле".
      Объектный модуль имеет более 255 сегментов. Расщепите модуль
      или объедините сегменты.
L1049 "Слишком много сегментов".
      Программа имеет более, чем максимально разрешенное число сег-
      ментов. (опция /SEGMENTS определяет максимально разрешенное
      число; стандартно 128).
      Повторите компановку с опцией /SEGMENTS с соответствующим чис-
      лом сегментов.
L1050 "Слишком много групп в одном модуле".
      Программа LINK обнаружила более 21 определения групп (GRPDEF) в
      одном модуле.
      Сократите число определений групп или расщепите модуль. (Опре-
      деления групп разъясняются в документе "Справочное руководство
      программиста по MS-DOS" и в других справочных книгах по DOS.
L1051 "Слишком много групп".
      В программе определено более 20 групп, не считая DGROUP.
      Сократите количество групп.
L1052 "Слишком много библиотек".
      Была сделана попытка скомпановать более 32 библиотек.
      Объедините библиотеки, либо используйте модули, требующие мень-
      шего количества библиотек.
L1053 "Переполнение таблицы имен".
      Компановщик не имеет достаточно места для размещения таблицы
      имен программы (таких, как глобальные, внешние, имена сегмен-
      тов, групп, классов, файлов).
      Объедините модули или сегменты и перестройте объектные файлы.
      Исключите столько глобальных имен, сколько возможно.
L1054 "Требуемое количество сегментов слишком велико".
      Компановщик не имеет достаточно памяти для размещения таблицы,
      описывающей количество требуемых сегментов (стандартное число
      128 или значение, определенное в опции /SEGMENTS). Повторите
      компановку снова, используя опцию /SEGMENTS для задания меньше-
      го количества сегментов (например, 64, если ранее было исполь-
      зовано стандартное значение), либо освободите некоторое коли-
      чество памяти путем удаления резидентных программ или паралле-
      льных задач.
L1056 "Слишком много оверлеев".
      В программе определно более 63 оверлеев.
L1057 "Запись данных слишком велика".
      Запись LIDATA (в объектном модуле) содержит более 1024 байтов
      данных. Это ошибка транслятора. (LIDATA-это термин операционной
      системы DOS, его объяснение можно найти в документе "Справочное
      руководство программиста по MS-DOS фирмы Microsoft" или в дру-
      гих справочных книгах по DOS.
      Обратите внимание, какой транслятор (компилятор или ассемблер)
      построил некорректный объектный модуль и при каких обстоятель-
      ствах. Пожалуйста, сообщите о данной ошибке, используя форму
      Product Assistance Request, находящуюся в конце данного руко-
      водства.
L1070 "'name': размер сегмента превышает 64К".
      Заданный сегмент содержит более 64К кода или данных.
      Повторите компиляцию и компановку в большой модели памяти.
L1071 "Сегмент _TEXT больше 65520 байтов".
      Данная ошибка вероятнее всего может случиться только в СИ-прог-
      раммах малой модели памяти, однако она может произойти и, если
      любая программа с сегментом, названным _TEXT, компануется пос-
      редством команды LINK с опцией /DOSSEG. Программы на языке СИ
      малой модели памяти должны резервировать адреса кода 0 и 1; для
      целей выравнивания этот предел увеличивается до 16.
L1072 "Общая область больше 65536 байтов".
      Программа имеет более 64 общих переменных. Данная ошибка не мо-
      жет возникнуть в объектных файлах, сгенерированных с помощью
      Макроассемблера MASM (Microsoft Macro Assembler). Она возникает
      только в программах, полученных с помощью компилятороа, поддер-
      живающих общие переменные.
L1080 "Невозможно открыть файл-листинг".
      Диск или корневой каталог переполнены. Удалите или переместите
      файлы, чтобы освободить место.
L1081 "Переполнение при записи выполняемого файла".
      Диск, на который записывается выполняемый файл .EXE, переполнен
      Освободите место на диске и повторите компановку.
L1083 "Невозможно открыть выполняемый файл".
      Диск или корневой каталог переполнены. Удалите или переместите
      файлы, чтобы освободить место.
L1084 "Невозможно создать временный файл".
      Диск или корневой каталог переполнены. Освободите место на
      диске и повторите компановку.
L1085 "Невозможно открыть временный файл".
      Диск или корневой каталог переполнены. Удалите или переместите
      файлы, чтобы освободить место.
L1086 "Не хватает временного файла".
      Заметьте обстоятельства возникновения данной ситуации и свяжи-
      тесь с фирмой Microsoft Corporation, воспользовавшись формой
      "Product Assitance Request", находящейся в конце данного руко-
      водства.
L1087 "Неожиданный конец временного файла".
      Диск с временным выходным файлом компановщика удален.
L1088 "Переполнение при записи файла-листинга".
      При записи на диск файла-листинга диск переполнился. Освободите
      место на диске и повторите компановку.
L1089 "'filename': невозможно открыть файл соответствий".
      Программа LINK не может найти заданный файл соответствий. Обыч-
      но, это опечатка при задании имени файла.
L1090 "Повторно открыть файл-листинг невозможно"
      По запросу оригинальный диск не был заменен. Повторите компа-
      новку.
L1091 "Неожиданный конец файла в библиотеке".
      Диск, содержащий библиотеку, был вероятно, удален. Установите
      диск, содержащий библиотеку и повторите компановку.
L1093 "'filename':объектный файл не найден".
      Компановщик не может найти заданного объектного файла. Задайте
      правильное имя объектного файла и повторите компановку.
L1101 "Некорректный объектный модуль".
      Один из объектных модулей является некорректным. Если данная
      ошибка произошла после перекомпиляции, пожалуйста, свяжитесь с
      фирмой Microsoft Corporation, воспользовавшись формой "Product
      Assitance Request", приложенной в конце данного руководства.
L1102 "Неожиданный конец файла".
      Для библиотеки был обнаружен некорректный формат.
L1103 "Попытка обращения к данным, лежащим за границами сегмента".
      Заданная запись в объектном модуле продолжена за границы сег-
      мента. Это ошибка транслятора. Заметьте, какой транслятор (ком-
      пилятор или ассемблер) создал некорректный объектный модуль, и
      обстоятельства, в которых он был создан. Пожалуйста, сообщите
      о данной ситуации в фирму Microsoft Corporation, воспользовав-
      шись формой "Product Assistance Request", находящейся в конце
      данного руководства.
L1104 "'filename': некорректная библиотека".
      Заданный файл не является корректным библиотечным файлом. Дан-
      ная ошибка прекращает работу программы LINK.
L1113 "Неразрешенная COMDEF; системная ошибка".
      Заметьте обстоятельства возникновения данного сбоя и свяжитесь
      с фирмой Microsoft Corporation, воспользовавшись формой Product
      Assistance Request, находящейся в конце данного руководства.
L1114 "Файл не подходит для /EXEPACK; повторите компановку без опции
      /EXEPACK".
      В компануемой программе размер упакованного загружаемого обра-
      за плюс заголовок больше, чем неупакованный загружаемый образ.
      Повторите компановку с помощью опции /EXEPACK.
L2001 "Запись fixup без данных".
      Запись FIXUPP не имеет непосредственно предшествующей записи
      данных. Вероятно, это ошибка компилятора. (Подробности о
      FIXUPP смотрите в документе "Справочное руководство программис-
      та по MS-DOS фирмы Microsoft").
L2002 "Переполнение записи fixup при "ближнем" вызове 'number'
      frame seg 'segname'
      target seg 'segname'
      target offset 'number'"
      Данную ошибку могут вызвать следующие условия:
      -Программа компилируется в малой модели памяти с опцией /NT.
      -Группа больше 64К.
      -Программа содержит междусегментные короткие переходы или меж-
       дусегментные короткие вызовы.
      -Имя элемента данных в программе не соответствует процедуре из
       библиотеки процедур, подключенной к компановке.
      -Объявление EXTRN в исходном файле на яхыке ассемблер появилось
       в теле сегмента, как в следующем примере:
      code    SEGMENT public 'CODE'
              EXTRN   main:far
      start   PROC    far
              call    main
              ret
      start   ENDP
      code    ENDS
      Предпочтительна следующая конструкция:
              EXTRN   main:far
      code    SEGMENT public 'CODE'
      start   PROC    far
              call    main
      start   ENDP
      code    ENDS
      Перепишите исходный файл и перестройте объектный файл. (Подроб-
      ную информация о frame segment и target segment вы найдете в
      документе "Справочное руководство программиста по MS-DOS фирмы
      Microsoft".)
L2003 "Дальний вызов на данные собственного сегмента".
      Дальние вызовы на данные собственного сегмента не разрешаются.
L2005 "Тип fixup не поддерживается".
      Оказалось, что тип fixup не поддерживается компановщиком фирмы
      Microsoft. Вероятно, это ошибка компилятора. Обратите внимание

      на обстоятельства данной ошибки и сообщите их в фирму Microsoft
      Corporation, воспользовавшись формой "Product Assistance
      Request", находящейся в конце данного руководства.
L2012 "'name': несоответствие размера элемента массива".
      "Дальний" общий массив был описан с двумя или более различны-
      ми размерами элементов массива (например, первый раз массив был
      описан, как массив символов, а второй раз, как массив дейст-
      вительных чисел).
L2013 "Запись LIDATA слишком велика".
      Запись LIDATA в объектном модуле имеет размер более 512 байтов,
      максимально разрешенного размера. Это ошибка компилятора. По-
      жалуйста, сообщите об условиях возникновения данной ошибки в
      фирму Microsoft, воспользовавшись формой "Product Assistance
      Request" в конце данного руководства.
L2024 "'name': имя уже определено".
      Одно из специальных оверлейных имен, требуемое для поддержки
      оверлеев, было определено в объектном файле.
L2025 "'name': имя определено более одного раза".
      Удалите из объектного файла лишние определения имен.
L2029 "Неразрешенные внешние ссылки".
      В одном или более модулей одно или более имен описаны, как
      внешние, но они не были определены, как публичные ни в одном из
      модулей или библиотек. После сообщения появляется список нераз-
      решенных внешних ссылок, как показано в следующем примере:
      EXIT in file(s):
       MAIN.OBJ (main.for)
      OPEN in file(s):
       MAIN.OBJ (main.for)
      Имя, которое идет перед 'in file(s)'-это неразрешенное внешнее
      имя. На следующей строке-список объектных модулей, имеющих ссы-
      лки на данное имя. Это сообщение и список записываются также в
      файл карты распределения памяти, если он существует.
L2041 "Стэк плюс данные превышает 64К".
      Общий размер стэкового сегмента программы плюс DGROUP превышает
      64К; в результате, программа загружается неверно.
L2043 "Стартовый адрес__ aulstart не найден".
      Если вы строите библиотеку Quick с использованием опции /Q,
      компановщик требует имя __aulstart, определенное, как стар-
      товый адрес.
L4003 "Неразрешенный вызов: смещение offset".
      Данная ошибка может быть вызвана компиляцией программы в малой
      модели памяти с опцией /NT.
L4012 "Опция /HIGH отменяет /EXEPACK".
      Опции /HIGH и /EXEPACK не могут быть использованы одновременно.
L4015 "Опция /CODEVIEW отменяет /DSALLOCATE".
      Опции /CODEVIEW и /DSALLOCATE не могут быть использованы одно-
      временно.
L4016 "Опция /CODEVIEW отменяет /EXEPACK".
      Опции /CODEVIEW и /EXEPACK не могут быть использованы одно-
      временно.
L4020 "'name': размер сегмента кода превышает 65500".
      Сегмент кода размером 65501-65536 байтов в длину может на про-
      цессоре Intel 80286 быть обработан некорректно.
L4021 "Нет стэкового сегмента".
      Программа не имеет стэкового сегмента, определенного с типом
      STACK. Данное сообщение не возникнет при обработке модулей,
      скомпилированных с помощью компилятора Microsoft Quick-C, но не
      с помощью Макроассемблера.
      Обычно, каждая программа должна иметь стэковый сегмент с типом
      объединения STACK. Если у вас есть особые причины не определять
      стэк или определить его без типа объединения STACK, вы можете
      проигнорировать данное сообщение. Данное сообщение может быть
      получено и при компановке с помощью LINK версий 2.40 и младше,
      поскольку данные компановщики просматривают библиотеки только
      один раз.
L4031 "'name': сегмент описан более, чем в одной группе".
      Сегмент был описан, как член двух различных групп. Исправьте
      исходный файл и перестройте объектные файлы.
L4034 "Более 239 оверлейных сегментов; лишние помещены в корень".
      В оверлеях не может быть объявлено более 239 кодовых сегментов.
      Все сегменты свыше данного предела помещаются в корень.
L4045 "Имя выходного файла 'name'".
      Компановщик высветил в запросе "Run file" стандартное выходное
      имя файла, но поскольку была использована опция /Q, имя выход-
      ного файла было изменено.
L4050 "Слишком много глобальных имен".
      Для получения отсортированного списка глобальных имен в файле
      распределения памяти была использована опция /MAP, но задано
      для сортировки слишком много имен (более 2048 имен по умолча-
      нию). Повторите компановку с опцией /MAP:number. Компановщик
      выдает неотсортированный список глобальных имен.
L4051 "'filename': невозможно найти библиотеку".
      Компановщик не может найти заданный файл. Введите новое имя,
      новую спецификацию маршрута, или и то, и другое.
L4053 "VM.TMP: некорректное имя файла; игнорируется".
      Имя VM.TMP появилось, как объектное имя файла. Переименуйте
      файл и повторите компановку.
L4054 "'filename': невозможно найти файл".
      Компановщик не может найти заданный файл. Введите новое имя
      файла, новую спецификацию маршрута, либо и то, и другое.

                 D.5.Сообщения об ошибках утилиты LIB.

    Сообщения  об  ошибках,  сгенерированные   администратором
библиотек, программой LIB, имеет один из следующих форматов:

    {filename|LIB}: fatal error U1xxx: текст сообщения

    {filename|LIB}: error U2xxx: текст сообщения

    {filename|LIB}: warning U4xxx: текст сообщения

    Сообщение  начинается  именем  входного  файла (filename),
если  он  существует,  либо  именем  утилиты.  Если  возможно,
программа  LIB   распечатывает  предупреждение   и  продолжает
работу. В некоторых случаях  ошибки неисправимы и утилита  LIB
прекращает  работу.  Утилита  LIB  может  высветить  следующие
сообщения:

Номер    Сообщения об ошибках утилиты LIB

U1150 "Размер страницы слишком мал".
      Размер страницы входной библиотеки слишком мал, что означает
      некорректный входной файл .LIB.
U1151 "Синтаксическая ошибка: неверная спецификация файла".
      Командный оператор, такой как знак минус(-) был задан без соот-
      ветствующего имени модуля.
U1152 "Синтаксическая ошибка: наименование опции опущено".
      Знак опции слэш (/) был задан без следующей за ним опции.
U1153 "Синтаксическая ошибка: значение опции пропущено".
      Опция /PAGESIZE была задана без соответствующего значения.
U1154 "Неизвестная опция".
      Была задана неизвествная опция. В данный момент программа LIB
      распознает только опции /PAGESIZE.
U1155 "Синтаксическая ошибка: некорректный ввод".
      Данная команда не следует правильному синтаксису утилиты LIB,
      описанному в Главе 10, "Создание библиотек Quick и автономных
      библиотек".
U1156 "Синтаксическая ошибка".
      Данная команда не следует правильному синтаксису утилиты LIB,
      описанному в Главе 10, "Создание библиотек Quick и автономных
      библиотек".
U1157 "Пропущена запятая или символ перехода на новую строку".
      В командной строке ожидалась запятая или возврат каретки, кото-
      рые не появились. Это может означать нечаянно поставленную
      запятую, как в следующей строке:
      LIB math.lib, -mod1+mod2;
      Эта строка должна иметь следующий вид:
      LIB math.lib -mod1+mod2;
U1158 "Пропущен возврат каретки".
      Либо ответ на запрос "Output library", либо последняя строка в
      файле соответствий, используемого для запуска программы LIB, не
      заканчивается возвратом каретки.
U1161 "Невозможно переименовать старую библиотеку".
      Программа LIB не может переименовать старую библиотеку с рас-
      ширением .BAK, поскольку версия .BAK уже существует с защитой
      "только-чтение". Измените защиту старой версии .BAK.
U1162 "Невозможно повторно открыть библиотеку".
      Старая библиотека не может быть повторно открыта после того,
      как она была переименована с расширением .BAK.
U1163 "Ошибка при записи файла перекрестных ссылок".
      Диск или корневая директория переполнены. Удалите или переком-
      пилируйте файлы, чтобы освободить место.
U1170 "Слишком много имен".
      В библиотечном файле появилось более 4609 имен.
U1171 "Не хватает памяти".
      Программе LIB не хватает памяти для работы. Удалите параллель-
      ные и резидентные программы и повторите попытку, либо увеличьте
      память.
U1172 "Не хватает виртуальной памяти".
      Заметьте обстоятельства данного сбоя и уведомите фирму
      Microsoft Corporation, воспользовавшись формой "Product
      Assistance Request", находящейся в конце данного руководства.
U1173 "Системный сбой".
      Обратите внимание на обстоятельства данного сбоя и уведомите
      фирму Microsoft Corporation, воспользовавшись формой "Product
      Assistance Request", находящейся в конце данного руководства.
U1174 "mark: не размещено".
      Заметьте обстоятельства данного сбоя и уведомите фирму
      Microsoft Corporation, воспользовавшись формой "Product
      Assistance Request", находящейся в конце данного руководства.
U1175 "free: не размещено".
      Заметьте обстоятельства данного сбоя и известите фирму
      Microsoft Corporation, воспользовавшись формой "Product
      Assistance Request", находящейся в конце данного руководства.
U1180 "Запись извлекаемого файла потерпела неудачу".
      Диск или корневой каталог переполнены. Удалите или перемес-
      тите файлы, чтобы освободить место.
U1181 "Запись в библиотечный файл потерпела неудачу".
      Диск или корневой каталог переполнены. Удалите или перемес-
      тите файлы, чтобы освободить место.
U1182 "'filename': невозможно создать извлекаемый файл".
      Диск или корневой каталог переполнены, либо заданный извлекае-
      мый файл уже существует с защитой "только-чтение".
      Освободите место на диске, либо измените вид защиты файла.
U1183 "Невозможно открыть файл соответствий".
      Данный файл соответствий не найден.
U1184 "Неожиданный конец файла при вводе команды".
      В ответе на запрос был обнаружен символ конца файла.
U1185 "Невозможно создать новую библиотеку".
      Диск или корневой каталог переполнены, либо библиотечный файл
      уже существует с защитой "только-чтение". Освободите место на
      диске или измените атрибуты защиты библиотечного файла.
U1186 "Ошибка при записи новой библиотеки".
      Диск или корневой каталог переполнены. Удалите или переместите
      файлы для освобождения места.
U1187 "Невозможно открыть VM.TMP".
      Диск или корневой каталог переполнены.
U1188 "Невозможно записать в VM".
      Отметьте обстоятельства возникновения данного сбоя и сообщите
      в фирму Microsoft Corporation, воспользовавшись бланком
      "Product Assistance Request", находящейся в конце данного руко-
      водства.
U1189 "Невозможно прочесть из VM".
      Обратите внимание на обстоятельства возникновения данной ошибки
      и сообщите в фирму Microsoft Corporation, воспользовавшись
      бланком "Product Assistance Request", находящейся в конце
      данного руководства.
U1190 "Прервано пользователем".
      Вы прервали работу программы LIB до завершения работы.
U1200 "'name': некорректный заголовок библиотеки".
      Входной библиотечный файл имеет неправильный формат. Он либо не
      является библиотечным файлом, либо разрушен.
U1203 "'name': некорректный объектный модуль по ближнему адресу".
      Модуль, заданный по имени 'name', является некорректным объект-
      ным модулем.
U2152 "'filename': невозможно создать листинг".
      Диск или каталог переполнены, либо файл перекрестных ссылок
      уже существует с защитой "только-чтение".
      Освободите место на диске, либо измените атрибуты файла.
U2155 "'modulename': модуль не найден в библиотеке; игнорируется".
      Заданный модуль не найден во входной библиотеке
U2157 "'filename': невозможно получить доступ к файлу".
      Программа LIB не могла открыть заданный файл.
U2158 "'libraryname': неверный заголовок библиотеки; файл игнориру-
      ется".
      Входная библиотека имеет некорректный формат.
U2159 "'filename': неверный формат 'hexnumber'; файл игнорируется".
      Опознавательный байт слова 'hexnumber' данного файла не имеет
      одного из следующих распознаваемых типов:
      библиотека Microsoft, библиотека Intel, объектный файл Micro-
      soft, архив XENIX.
U4150 "'modulname': переопределение модуля игнорируется".
      Модуль был определен для добавления в библиотеку, но модуль с
      тем де именем уже есть в библиотеке. Либо, модуль с одним и тем
      же именем помещен в библиотеку дважды.
U4151 "'symbol (modulename): переопределение имени игнорируется".
      Заданное имя определено более, чем в одном модуле.
U4153 "'number': размер страницы слишком мал; игнорируется".
      Значение, определенное в опции /PAGESIZE меньше 16.
U4156 "'libraryname': спецификация выходной библиотеки игнорируется".
      В дополнение к новому библиотечному имена была задана выходная
      библиотека.
      Например, задав:

    LIB new.lib+one.obj, new.lst,new.lib

    где new.lib еще не существует-вы получите ошибку.

                D.6. Сообщения об ошибках утилиты MAKE.

    Ошибки, высвечиваемые в процессе работы утилиты  поддержки
программ Microsoft (MAKE) имеют один из следующих форматов:

    {filename|MAKE}: fatal error U1xxx: текст сообщения

    {filename|MAKE}: warning U4xxx: текст сообщения

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

Номер  Сообщения об ошибках утилиты MAKE

U1001 "Макроопределение больше, чем number".
      Было определено макро, имеющее значение строки, длинее установ-
      ленного числа, разрешающего максимальную длину. Попытайтесь пе-
      реписать файл описанний утилиты MAKE и расщепить макро на два
      меньших.
U1002 "Бесконечно рекурсивное макро".
      Был определен циклический вызов макрокоманд, как в следующем
      примере:
      A=$(B)
      B=$(C)
      C=$(A)
U1003 "Выход за пределы памяти".
      Во время обработки файла описаний утилита MAKE вышла за пределы
      памяти. Попытайтесь сократить размер файла описаний утилиты
      MAKE путем его реорганизации или расщепления на меньшие.
U1004 "Синтаксическая ошибка: пропущено имя макрокоманды".
      Файл описаний утилиты MAKE содержит макроопределение без левой
      части (то есть строки, начинающейся с =).
U1005 "Синтаксическая ошибка: пропущено двоеточие".
      В строке, которая должна содержать выходной файл/входной файл,
      не хватает двоеточия, разделяющего выходной файл и входной
      файл. Утилита MAKE требует любую строку, за которой следует
      пустая строка, чтобы считать ее строкой выходного/входного фай-
      ла.
U1006 "'targetname': макрорасширение больше числа 'number'".
      Макрорасширение плюс длина любой строки, с которой оно может
      быть объединено, длинее установленного числа. Попытайтесь пере-
      записать файл описаний утилиты MAKE, расшепив макро на два ме-
      ньших.
U1007 "Много источников".
      Правило вывода были определено более одного раза.
U1008 "'name': невозможно найти файл или каталог".
      Заданные файл или каталог не могут быть найдены.
U1009 "'command': список аргументов слишком длинный".
      Командная строка в файле описаний утилиты MAKE длиннее 128 бай-
      тов, что максимально разрешено в DOS. Перепишите команды, чтобы
      сделать список аргументов короче.
U1010 "'filename': отказ доступа".
      Файл, определенный, как 'filename'-имеет атрибут "только-чте-
      ние.
U1011 "'filename': не хватает памяти".
      Для выполнения программы утилите MAKE не хватает памяти.
U1012 "'filename': неизвестная ошибка".
      Заметьте обстоятельства возникновения данной ошибки и сообщите
      о них фирме Microsoft Corporation, воспользовавшись бланком
      "Product Assistance Request", данным в конце данного руко-
      водства.
U1013"'command': ошибка errcode".
      Одна из программ или команд, вызванная в файле описаний утилиты
      MAKE, завершилась с ненулевым кодом завершения.
U1015 "'file': целевой файл не существует".
      Обычно, это не означает ошибку. Данное сообщение предупреждает
      пользователя о том, что целевой файл не существует. Утилита
      MAKE выполняет любые команды, заданные в блоке описаний, поско-
      льку в большинстве случаев выходной файл создается последней
      командой файла описаний утилиты MAKE.
U4000 "'filename': не существует".
      Обычно, это сообщение не свидетельствует об ошибке. Оно пре-
      дупреждает пользователя о том, что указанный файл не существует
      MAKE выполняет все команды, заданные в блоке, так как в боль-
      шистве случаев отсутствующий файл будет создан последующими
      командами файла MAKE.
U4001 "Зависимый файл 'filename' не существует; целевой файл 'filena
      me' не строится".
      Утилита MAKE не может продолжать, поскольку требуемый входной
      файл не существует. Удостоверьтесь, что все имена файлов при-
      сутствуют и что все они корректно описываются в файле описаний
      утилиты MAKE.
U4013 "'command': ошибка errcode (игнорируется)".
      Одна из программ или команд, вызванных в файле описаний утилиты
      MAKE, возвратила ненулевой код ошибки, в то время, как утилита
      MAKE работала с опцией /I. Ошибки игнорируются и утилита про-
      должает работу.
U4014 "Синтаксис: make options [name-value...] file options=[/n]
      [/d][/i][/s][/x file]
      Утилита MAKE была неправильно вызвана. Стартуйте утилиту зано-
      во, воспользовавшись синтаксисом, представленным в сообщении:
      make опции[имя-значение...] file опции=[/n][/d][/i][/s]
      [/x file].


www.dstu0752.narod.ru

dstu0752@yandex.ru

ICQ UIN 8107923