Книга
Книга
66624690003 66778811490234613456679902255666780113469124---11112334 444444 5 555'® 66667777777778888888888999 9 99900066624690003 66778811490234613456679902255666780113469124---11112334 444444 5 555'® 66667777777778888888888999 9 999000
66624690003 66778811490234613456679902255666780113469124
---11112334 444444 5 555'® 66667777777778888888888999 9 999000
66624690003 66778811490234613456679902255666780113469124
---11112334 444444 5 555'® 66667777777778888888888999 9 999000
Содержание
Предисловие. Перевод М. Ю, Рачкова
ЧАСТЬ I. ОПЕРАЦИОННАЯ СРЕДА. Перевод М. Ю. Рачкова
Введение
Основные понятия
Использование меню
Составление программ
Компиляция модулей и программ
.1.5. Исправление ошибок
Отладка программ
Системы
Интегрированная система
Система загрузки
ЧАСТЬ II. ЯЗЫК. Перевод М Ю. Рачкова
Лексические понятия
Комментарии
Идентификаторы
Ключевые слова
Литералы
Описания
Описание простых переменных
4-2. Описание блоков переменных
Определение класса памяти
Присвоение начальных значений (инициализация объекта)
4-5. Описание типов
Области действия и структура программы
Выражения
Первичные выражения и 1-выражения
Арифметические операторы二
Операторы сравнения
Логические операторы
55 Битовые операторы
56 Операторы сдвига
Операторы "доступа по указателю (*)** и "указатель (&)"
Операторы присваивания
59 Условный оператор
Оператор соединения
Оператор преобразования
Оператор размера
Обработка выражений
Операторы
Оператор-в1»1ражение
Пустой оператор
Оператор перехода
Блок
Условный оператор
Операторы цикла
Оператор продолжения
Оператор завершения
Оператор-переключатель
Оператор воз
Функции
7-1. Связь параметров с аргументами
Получение результата
Рекурсия
Параметры функции main ...л
Принципы выполнения операции ввода-вывода
Управление оперативной памятью
Препроцессор
Включающие директивы
Определяющие директивы
Директивы условного включения
Примеры написания программ с использованием функций
Стандартные расширения.
Ключевые слова
Литералы
Операторы
Типы данных
Модификаторы
Структурные выражения
Функции с переменным имслом аргументов
Несгандартные расширения
Модификаторы pascal и deci
Модификатор Interrupt
Модели памяти:
4. Ассемблерные вставки
ЧАСТЬ Ш. ГРАФИКА. Перевод А/. Ю. Рачкова 14. Программирование графики
Текстовый режим
Графический режим
Графика BGI
ЧАСТЬ IV. ТХРВО АССЕМБЛЕР. Перевод А. В. Стрельцова 15. Ассемблер
Процессоры
Программы
Процедуры
Команды
Включение файлов, условная компиляция
Макроопределения и макровызовы
Организационные директивы
Версии Masm и Ideal
ЧАСТЬ V. ТУРБО ОТЛАДЧИК. Перевод 4 В. Стрельцова
16. Отладчикл
Система меню.
Классификация окон
Информационные окна.
Инспекционные окна
Составление выражений 16-6. Опции меню
НАСТЬ VI. БИБЛИОТЕКИ. Перевод А. Д Плитмана 17. Принципы описания
Графическая библиотека
Системная библиотека
Литература
ПРИЛОЖЕНИЕ А. КОДЫ. Перевод Л. Д Плитмана
ПРИЛОЖЕНИЕ Б. РЕДАКТОР. Перевод 4 Д Плитмана
ПРИЛОЖЕНИЕ В. СИНТАКСИС. Перевод А Д Плитмана
ПРИЛОЖЕНИЕ Г. ГРАФИКА. Перевод А. 4 Плитмана
ПРИЛОЖЕНИЕ Д. АССЕМБЛЕР. Перевод 4 Д Плитмана
ПРИЛОЖЕНИЕ Е. СТАРТЕР (ПРОГРАММА ЗАПУСКА). Перевод А " Плитмана ПРИЛОЖЕНИЕ Ж. РЕДАКТОР СВЯЗЕЙ. Перевод. А. Д Плитмана
ПРИЛОЖЕНИЕ 3. ОРГАНИЗАТОР (МЕНЕДЖЕР). Перевод А. 4 Плитмана
4667036669914588904 889Q5 8813384859 66922792 9991 6 785c26791811111111121213131313131414141414141515^^^^^^^^^^34弘343536363839^^^^636363646Ы族66例67674667036669914588904 889Q5 8813384859 66922792 9991 6 785c26791811111111121213131313131414141414141515^^^^^^^^^^34弘343536363839^^^^636363646Ы族66例6767ПРИЛОЖЕНИЕ S. ГЕНЕРАТОР. Перевод А 4 Плитмана
4667036669914588904 889Q5 8813384859 66922792 9991 6 785c26791811111111121213131313131414141414141515^^^^^^^^^^34弘343536363839^^^^636363646Ы族66例6767
4667036669914588904 889Q5 8813384859 66922792 9991 6 785c26791811111111121213131313131414141414141515^^^^^^^^^^34弘343536363839^^^^636363646Ы族66例6767
Я. Белецкий
ЭНЦИКЛОПЕДИЯЯЗЫКА
Си
Перевод с польскогоканд. техн, наук А. Д. Плитмана,кацд. техн, наук М. Ю. Рачкова, А. В. Стрельцова
под редакциейканд. техн, наук Ф. Ф. Пащенко
Москва “Мир" 1992
ББК 22.19 Б43
УДК 681.3.06
Белецкий Я.
Б43 Энциклопедия языка Си: Пер. с польск.- М.: Мир, 1992.- 687 с.」
ISBN 5-03-002113-2
Книга известного польского ученого посвящена подробному описанию языка Си, графических возможностей, использованию Ту(^о ассемблера и Ту^о отладчика. Изла ние сопровождается многочисленныги(« примерами.
Для квалифицированных пользователей персональных компьютеров и программисто
ББК 2ББК 22404010000 - 035
ББК 2
ББК 2
Б111-92
041(01) - 92
Редакция литературы по информатике и робототехнике
ISBN 5-03-002113-2 (русое)ISBN 83-206-0919-4 (naibcQISBN 5-03-002113-2 (русое)ISBN 83-206-0919-4 (naibcQ© Copyright by Wydawnictwa Komunikacjl i Lacznosci, Warszawa 1989*
ISBN 5-03-002113-2 (русое)
ISBN 83-206-0919-4 (naibcQ
ISBN 5-03-002113-2 (русое)
ISBN 83-206-0919-4 (naibcQ
© перевод на русский язык, А.Д. Плитман, М.Ю. Ра^к А.В. Стрельцов, 1992
редисловие
Моим друзьям Ганне и Райнеру Лангмаак
\ Язык программирования Си был разработан в 1972 г. Деннисом Ритчи, оторый является одним из авторов операционной системы UNIX. Язык Си последствии был использован для программирования этой системы, а также югатой библиотеки обслуживающих программ, поскольку, являясь универ- :альным языком общего назначения, язык Си удобен для программирования истемных задач. Появление микрокомпьютеров укрепило позиции языка Си. Зыло создано более 30 его новых компиляторов, а после проведения Американским национальным институтом стандартов ANSI (American National standards Institute) работ по стандартизации в области программирования на- 1али разрабатываться компиляторы, соответствующие опубликованному вес- ^ой 1986 г. проекту стандарта.
Первым компилятором по стандарту ANSI явилась система Турбо Си вер- зии 1.0 фирмы Borland International. Эта система, состоящая из компилятора языка Си, связанного с ним редактора, компоновщика и библиотек, обеспечила пользователям удобную интегрированную операционную среду, а также существенно облегчила профессиональное программирование, в котором определяющими параметрами являются высокая скорость компиляции, высокое качество генерируемого кода и малая потребность в оперативной памяти.
Несмотря на то что Турбо Си версии 1.0 оправдал ожидания большинства профессиональных программистов, он имел ряд недоработок из-за поспешности его внедрения на рынок. К таким недоработкам относились ошибки в некоторых библиотечных функциях и в редакторе, отсутствие графической библиотеки и отладчика. Весной 1988 г. фирма Borland представила пользователям усовершенствованную версию системы Турбо Си под номером 1.5. В ней исключены ошибки версии 1.0 и добавлена обширная графическая библиотека, насчитывающая около 100 новых функций, а также заложена разработка отладчика^ В конце 1988 г. появилась версия Турбо Си 2.0 Professional. В ее состав, кроме интегрированного компилятора и компилятора с использованием команд строки, входят расширенная графическая библиотека, встроенная система запуска программ, а также ассемблер с высоким быстродействием и новый символьный отладчик.
Ян Белецкий
ЧАСТЬ L ОПЕРАЦИОННАЯ СРЕДА
Введение
Операционная среда, состоящая из компилятора языка Турбо Си 2.0, связанного с ним редактора, компоновщика и библиотек, разработанная фирмой Borland International для микрокомпьютеров семейства IBM PC, называется интегрированной" системой Турбо Си. Из многочисленных возможностей профессиональной версии языка, известной как система Турбо Си 2.0, необходимо отметить следующие:
доступность очень удобной и значительно расширенной операционной среды;
значительное увеличение быстродействия компилирования программ;
возможность компилирования программ, код или данные которых занимают объем больше 64 Кбайт;
наличие средств условной компиляции и управления способом генерирования кода с помощью директив процессора;
возможность деления больших программ на независимо компилируемые модули;
доступность новых стандартных средств, облегчающих системное программирование;
доступность обширной, предварительно составленной библиотеки графических операций;
доступность средств для эмуляции переменных операций;
наличие механизмов создания программ из подпрограмм, написанных на разных языках программирования;
улучшение качества генерируемого кода путем его оптимизации и исключения из программы библиотечных подпрограмм.
Основные понятия
Специфика языка Си проявляется уже в структуре программы. Написанная на этом языке программа включает в себя ряд описаний: переменных, типов и функций, которая имеет название main. Выполнение программы начинается именно с этой функции.
Примеры
Простейшая программа
main()
{
return 0;
}
Программа содержит описание функции main.
Непосредственно после названия функции в круглых скобках следует список параметров функции. В рассматриваемом примере этот список пустой.
Тело функции состоит из совокупности операторов (блока), ограниченных фигурными скобками. В рассматриваемом примере имеется только одна функция return.
Выполнение программы не приводит ни к каким результатам.
Программа, состоящая из трех описаний
#include <stdio. h>
1nt var;
out(par)
1nt par;
printf("%d”, par);
}
main()
{
var 工 3;
File Edit Run Corapile Project Options DebigBreak/watch
-~-—— Edit
Live 1 Col 1 Insert Indent Tab Fill Uninde泣C:闿NAME. PAS
Turbo C
Version 2.0Copyright (c) 1987, 1988 byBorlaM Inlenw.tioiial, Inc.
Message
Fl-Help F5-2ooi» FG-Switch Г7-1гасе FS-Step F9-Make ПО-Иепм
Рис. 1. Визитная карточка системы.
out(var + 2);
return 0;
}
Программа состоит из описаний переменной var, а также функций out и main.
int - ключевое слово для описания переменной типа integer (целое) с идентификатором var. Функция out имеет один параметр par, заключенный в круглые скобки. В данном случае тип параметра (integer), а телом функции является функция printf. Функция printf принадлежит к группе стандартных функций языка. Ее выполнение приводит к выводу аргумента par по формату, определяемому аргументом "%d". Запись %d означает, что данные выводятся в десятичном виде. Выполнение приведенной программы начинается с функции main. Далее переменной var присваивается значение 3 и вызывается функция var, которой передается параметр, принимающий значение var + 2.*
После выполнения программы будет выведено число 5. В произвольном месте программы могут присутствовать директивы препроцессора. Они начинаются знаком #(〃〃£&), который должен быть первым знаком новой строки. К основным директивам процессора относятся: #include и #define, а также директивы условной компиляции #if, #else, #elif и #endif.
Определение директивы # include приводит к включению в месте ее появления файла с именем, обозначенным в этой директиве. Директива #define дает возможность определения констант и связывания произвольного идентификатора с рядом лексических единиц.
Примеры
Использование директивы # include
#include <stdio. h>
main()
{
putchar('j');
return 0;
Интерпретация директивы #include приводит к включению в программу в месте ее появления содержимого файла с именем stdio.h
Во многих системных реализациях, в том числе в Турбо Си, файл stdio.h включает определение функции putchar. В рассматриваемой программе вызов функции putchar('j') приводит к выводу символа j на устройство стандартного вывода.
Программа с параметризацией
fdefine ZERO
^include <stdio.h>
main()
{
#if defined (ZERO)
printff'XOSd", 13);
#else
printf(^'%df'• 13);
fendif
return 0,
}
Приведенный текст включает функции и директивы препроцессора, начинающиеся знаком #(AasA).
Директива #define определяет константу ZERO. Поскольку при интерпретации директивы условной компиляции эта константа уже определена, в основной программе будет выполнена функция
printf("%05d-, 13);
Если из основного текста убрать директиву #define, то в момент выполнения директивы #if константа ZERO не будет определена, что приведет к включению в основную программу альтернативной функции printf (“%d“, 13);
Таким образом, если основной текст программы содержит директиву #define, то компиляции принадлежит программа
^include <stdio.h>
main()
{
printf("%05d", 13):
return 0;
}
Ее выполнение приводит к выводу значения 00013, т.е. числа 13, представленного в поле размерностью 5 с нулями впереди.
Если из приведенного основного текста убрать директиву #define, то будет скомпилирована программа
^include <stdio.h>
main()
printf (”紀,13);
return 0;
После выполнения этой части программы будет выведено число 13.
Другим способом параметризации рассматриваемой программы является придание ей, например, следующего вида:\
fdefine ZERO
main()厂
{〈
printf(
#if defined(ZERO)
"OS'
#else
#endif
,13);
return 0;
}
Такая запись допустима, поскольку в языке Си разрешены произвольные промежутки методу лексическими единицами.
Программа с определением рада лексических единиц
find ude<std io.h>
#define MAIN main( ){
MAIN
•define END}
♦define Two 2
printff^Xd**, Two + Two);
return 0;
END
Первая директива #define отождествляет с идентификатором MAIN ряд лексических единиц main( ){. Каждое проявление идентификатора MAIN при компиляции программы будет заменено на main( , ) и {.
Аналогичным образом вторая дирастива #define отождествляет с идентификатором END замыкающую фигурную скобку, а третья - отождествляет с идентификатором Two целое число 2.
Преобразованная процессором данная программа эквивалентна следующей:
finclude <stdio.h> main( ){
printf("%d'\ 2 + 2);
return 0;
}
Выполнение этой программы приводит к выводу числа 4.
Структура программы
Анализируя программу, можно сказать, что на верхнем уровне она состоит из описаний и заключенных между ними директив препроцессора. На более низком уровне можно выделить операторы, на самом нижнем - знаки алфавита, а на несколько более высоком - комментарии и лексические единицы. Лексические единицы и комментарии могут разделяться пробелами, знаками табуляции и перевода на новую строку. Пробелы принимаются во внимание только как разделители лексических единиц, а также в случае, когда они находятся в пределах знаковых и строчных литералов. Во всех остальных случаях пробелы игнорируются, что делает возможным свободную форму записи программ. Однако это требует, чтобы знаки #(Аа^А), с которых начинаются директивы препроцессора, были размещены в первых колонках соответствующей строки или по крайней мере перед ними стояли знаки пробела или табуляции. Использование пробелов в качестве разделителей лексических единиц необходимо только тогда, когда пара соседних единиц может быть принята за другую единицу (например, когда рядом находятся два идентификатора или ключевых слова).
File Edit Run Compile Project Options Debug Break/watch
Line 9Col 1 Insert Indent Tab Fill UnindenlC: MATCH.C
int Pow;
PowertBase^Exp)
if(Exp == 1)
relum Base;
else
^■№ ■】■ ; РИжЛ £№tt, : ЬмЛ 4!лжя *1аияк^^ИЕЯПМЯННМ^МЯ^Н^Н
mainC
forCPow 二 1; Pow < 6; Pow«t> printf(nXd\nM, Power(ZjPow));
return 0; }
Exp: 3 Base: Z
Pow: 3
H-Help F5-Zoom F6-Switcb F7-Trace F*3lep F9-Make FlO-Menu
Рис. 2. Окно редактирования и наблюдения.
Пример
,nt F1ve()
return 5;
}
Приведенная запись определяет непараметрическую функцию F跟.Эта функция, согласно первой строке, имеет значение типа integer.
Отсутствие пробела между ключевым словом int и именем Five привело бы к определению функции с другим именем int Five вместо функции Five. Поскольку в этом новом описании тип результата функции не был бы определен явно, то он по умолчанию был бы принят как integer, •
File Edit
Run Compile Project Options DebugBreak/watch
Line 9 Col 1 Insert Indent Tab Fill Unindent C: WATCH. C ffinclude <sldio.h> ini Pow;
PoweH Base, Exp)
if(Exp == 1)
return Base; else
1 return Base * Power(BaseExp - 1>; }
mainO {
f0F(P0W = 1; PON < 6; POW+"
printf(eZd4n*, PoweZ2,Pow)》;
return B;
К£ПЦ£7иОШЦДЫ[ЯНВ1^Н^2вННННИШММНВВВВВ
Unking СЛТЙ\1ХЕ\ИАтВ|. EXE:
Fi-Help F5-Zoon FG-Swilch F7-Trace F8~Step FLMake Fl(kMenu
Рис. 3. Окно редактирования и сообщения.
1.2. Использование меню
Запуск интегрированной системы Турбо Си производится командой ТС, записанной строчными или прописными буквами. После этого на экране появляется главное меню,- а на его фоне - информация о номере версии системы. Нажатие произвольной клавиши приводит к исчезновению этой информации и появлению экрана, разделенного на следующие части:
строка меню, состоящая из полей
File,Edit, Run, Compile,
Project, Options, Debug, Break/Watch;
окно редактора, озаглавленное
Edit;
окно коммуникационное, первоначально озаглавленное
Message;
строка, содержащая информацию о функциональных клавишах Fn.
При работе системы Турбо Си на экране имеется строка меню или одно из перечисленных окон. Кроме этого, на экране могут быть вызваны вспомогательные окна, связанные с реализацией функций системы. В частности, нажатие в произвольный момент клавиши Shift-Fl0 приводит к появлению на экране вспомогательного окна, содержащего информацию о номере версии системы.Выделение строки меню происходит при нажатии клавиш F10, что может быть произведено в произвольный момент работы системы.При этом изменяется цвет одного из его полей. Выделение редакционного или коммуникационного окна осуществляется нажатием клавиши F6, что приводит к увеличению яркости озаглавливающего окно слова (соответственно Edit, Watch или Message), а также сменой одиночной линии, на которой находится данное слово, на двойную.
Выбор функции, определенной главным меню, может быть осуществлен несколькими способами. Простейшим способом является введение с клавиатуры первого символа названия поля, данного в меню. Другой способ заключается в перемещении с помощью горизонтальных стрелок на дополнительной клавиатуре на выбранное поле меню с последующим нажатием клавиши Enter. В каждом из описанных случаев (за исключением Edit) произойдет вывод подменю, содержащего опции (подразделы) .Выбор функции, определенной опцией подменю, происходит способом, аналогичным выбору функции из меню (в этом случае используются клавиши вертикальных стрелок), и может привести к вызову следующего подменю. Следует отметить, что если после выбора первого подменю использовать клавиши горизонтальных стрелок, то на экране будут выведены соседние подменю главного меню. Эта особенность очень полезна в начальной стадии знакомства с системой, когда размещение ее функций между подменю еще хорошо не известно.В случае ошибки в выборе подменю можно вернуться на высший уровень менк) нажатием клавиш Esc. Нажатие этой клавиши в главном меню прп^^ит^ к выводу на экран последнего активного окна (редакционного или коммуникационного). Выбор функции главного меню может быть значительно ускорен с помощью клавиши Alt。Ее нажатие в произвольный момент вместе с первой буквой поля главного меню приводит к немедленному выполнению функции, связанной с этим полем. В частности, это означает, что при выборе поля Edit главного меню, достаточно ввести с клавиатуры знак Alt-E (вместо того, чтобы сначала нажать клавишу F10, а потом Е).Кроме перечисленных клавиш F10, Alt-Fl0 и Alt-p (где р - первая буква поля главного меню), значительное количество используемых функций выполняют клавиши Fn, Alt-Fn и Ctrl-n.
a Fl - вывод на экран справочной информации, связанной с текущим контекстом использования системы;
F2 - сохранение на диске текста, находящегося в редакционном окне;
F3 - вызов в редакционное окно файла с нужным именем (подразумевается, что этот файл имеет расширение .С);
F4 - выполнение программы до строки, в которой находится курсор; F5 - увеличение или уменьшение активного окна;
F6 - переключение активности между редакционным и коммуникационным окнами, а также возврат к активности окна из произвольного меню;
F7-пошаговое выполнение программы со входомв процедуру;
F8-пошаговое выполнение программы без входав процедуру;
F9-компилирование программы в режиме Маке(разд, i.3) (имеется в
виду программа, находящаяся в редакционном окне);
F10-переключение между главным меню и активным окном;
Alt-Fl ~ вывод на экран последней рассматриваемой справочной информации;
AH-F3 - занесение в редакционное окно последнего использованного файла;
A11-F5 - просмотр экрана, на который выведены результаты выполнения программ;
Alt-F6 - замена содержании окна (например, в коммуникационном окне переключение с просмотрового окна на окно связей и наоборот);
A11-F7 - перемещение к месту последней ошибки;
Alt-F8 - перемещение к месту следующей ошибки;
Alt-F9 - компилирование программы или основного модуля, находящегося в редакционном окне;
Ctrl-Fl - вывод справочной информации относительно идентификатора, выделенного курсором;
Cfrl-F2 - окончание выполнения программы;
Clrl-F3 - высвечивание строки вызванных процедур;
Ctrl-F4 - вычисление или модификация переменной;
Ctrl-F7 - занесение выражения в просмотровое окно;
Ctrl-FS - установка /снятие точки останова;'
Ctrl~F9 - выполнение программы.
Каждая из перечисленных функций может быть выполнена б произвольном контексте, но ие во время выполнения программы.Для окончания рабо= ты с системой Турбо Сн можно воспользоваться клавишами Alt-X. Это приведет к завершению фуикционироваиия этой системы и к вызову DOS.
13 Составление программ
Составной частью системы Турбо Си является экранный редактор. Он вызывается из главного меню (клавиша Е) или из другого произвольного контекста (клавишами Alt-E).
Подробное описание редактора на примере редактора Word Star приведено в Приложении Б. Тем, кто не знаком с редактором Word Star, достаточно знат^» что перемещение курсора вверх, вниз, влево и вправо производится с помощью стрелочных клавишей, стирание знаков - с помощью клавиши Backspace (<-> и Delete (Del>, стирание строки - с помощью клавиш Ctrl-Y, вставка пустых строк - с помощью клавиш Ctrl-N. Кроме этого, часто используемые функции осуществляются следующими клавишами: Ноте-перемещениекурсоравначало строки;
End-перемещениекурсоравконец строки;
Ctrl-Home-перемещениекурсоравначало первой строкиэкрана;
Ctrl-End-перемещениекурсоравконец последнейстрокиэкрана;
PgUp _- вызов на экран предыдущей страницы;
PgDn- вызов на экран следующей страницы;
Ctrl-PgUp - перемещение курсора в начало текста;
Ctrl-PgDn - перемещение курсора в конец текста;
Ctrl-T- удаление последних знаков слова;
Ctrl-QY- удаление последних знаков строки;
Ins- переключение с режима вставки в режим замены знаков и
наоборот.
Если во время составления основного текста (программы или модуля) нажать клавиши Ctrl-Fl, то на зкране появится справочная информация в выделенном курсором элементе языка. В частности, если это будет слово initgraph, которое является названием одной из функций графической библиотеки, то на экране появится краткое описание этой функции, а также обозначения близких ей функций. Окончание редакционных операций не требует специальных действий. Для того чтобы произвести запись подготовительного текста на диск, достаточно нажать клавишу F2 или после вызова славного меню (клавиша F10) выбрать поле File (клавиша F), а затем опцию S(Save) или W(Write). Рекомендуем ым способом создания файлов является ускоренный выбор поля File (клавиши Alt-F) и затем опции
File Edit Run Compile Project Options Debug Break/watch
Une 13 Col 4 Insert Indent Tab Fill Unindenl C:CIRCLE. C
#include <graphics. h>
#include <dos
阿p
版inC
int. Driver,
circle: draws a circle at <x,y> of the given radius
void far circlednt x, int y. ini radius);
driver - DE inilqrapb《&
Prototype in
circletgelm delay(ZOOO)
See alsoare
closegraphC
return 0;
FI-Help index -Pick Epic <—*-Go to topic Ese-Exit Help
Рис. 4. Разъяснительное окно.
Load (клавиша L). После выполнения этих действий на экране появляется диалоговое окно, в котором с клавиатуры необходимо задать имя файла и нажать клавишу Enter. Если файл под таким именем уже существует, то в редакционном окне появится содержимое данного файла для дальнейшего редактирования. Если файл с таким именем не существует, то редакционное окно будет очищено и можно вводить требуемый текст, который при записи на диск (клавиша F2) будет занесен в файл с данным именем. Другим способом создания текста является ускоренный набор поля File (клавиши Alt-F) с последующим выбором опции New (клавиша N). Это приведет к очищению редакционного окна и к присвоению файлу имени NONAME.C. Если после окончания редактирования текст запоминается, то задается вопрос: нс требуется ли изменить название NONAME.C на другое? После получения ответа процесс заканчивается.
Примеры. Составление и модификация программ
а) Составление новой программы и запись ее на диск
findude<stdio.h> main() { printf("Hello, I am JanB"); return 0; }
Порядок действий:
-выбор поля File главного меню (клавиши Alt-F);
выбор опции Load (клавиша L);
определение имени файла;
ввод текста программы;
-запись информации на диск (клавиша F2).
Составление программы без записи ее на диск
Порядок действий:
-выбор поля File главного меню (клавиши Alt-F);
-выбор опции New (клавиша N);,
-ввод текста программы.
Введенная программа может быть модифицирована, скомпилирована и выполнена.
Компиляция модулей и программ
Компиляция модулей и программ может осуществляться в режимах Compile, Make и Build. Компиляция в режиме Compile заканчивается созданием файла с расширением .OBJ, а компиляция в режимах Маке и Build заканчивается созданием выполняемого файла с расширением .EXE.
Режим Compile
Вызов компилятора в режиме Compile (клавиши AH-F9 или Alt-С, С) приводит к компиляции модуля, находящегося в редакционном окне.
Режим Make
Вызов компилятора в режиме Маке (клавиша F9 или Alt-С, М) приводит к компиляции программы следующим образом:
если при выборе опции Project определено имя проекта (Project name), которое является именем файла с расширением .PRJ, то программа, складывается . из модулей, имена которых выделены в этом файле, дополненных библиотечными функциями из библиотек с расширением .LIB, а также функциями из стандартной библиотеки;
если имя проекта не определено (подменю Project пусто), но определено имя первичного файла (Primary С file), которое является именем файла с расширением .С, то программа〈состоит из модуля, определенного этим файлом; \
если не определено ни имя проекта, ни имя первичного файла, то программа складывается из модуля, находящегося в редакционном окне.
В любом случае система ограничивается проведением только необходимых компиляций. В частности, не компилируется повторно основной модуль, если существует соответствующий ему скомпилированный модуль с расширением .OBJ. Благодаря этому количество необходимых компиляций модулей сводится к минимуму.
Режим Build
Вызов компилятора в режиме Build (клавиши Alt-C, В) отличается от вызова в режиме Маке тем, что проводятся все компиляции, даже при существовании соответствующих скомпилированных основных файлов.
Внимание: непосредственно после запуска системы Турбо Си как имя проекта, так и имя первичного файла являются пустыми. Это приводит к тому, что требуется ком пилировать модуль, находящийся в редакционном окне. В случае простых программ такая конфигурация системы вполне приемлема. Однако, если программа содержит директивы # include, включающие не задействованные еще фрагменты программы, то целесообразно определить имя первичного файла. В случае многомодульных программ необходимо также определение имени проекта.
Примеры
Выполнение одномодульной программы, находящейся в файле HELLO.C.
Порядок действий:
выбор опции File (клавиши Alt-F);
выбор опции Load (клавиша L);
определение имени файла (имя HELLO);
выбор опции Run (клавиши Alt-R);
выбор подопции Run (клавиша R);
Выполнение одномодульной программы, находящейся в файлах Tail С и HEAD.H, независимо от того, какой из этих файлов занесен в редакционное окно.丄小广一^
TAIL.Cfi nc1ude<stad io.h>main(){•include ,,HEAD.H,t}TAIL.Cfi nc1ude<stad io.h>main(){•include ,,HEAD.H,t}HEAD.Hprintf「Hello!”)return 0;HEAD.Hprintf「Hello!”)return 0;
TAIL.C
fi nc1ude<stad io.h>
main()
{
•include ,,HEAD.H,t
}
TAIL.C
fi nc1ude<stad io.h>
main()
{
•include ,,HEAD.H,t
}
HEAD.H
printf「Hello!”)
return 0;
HEAD.H
printf「Hello!”)
return 0;
Порядок действий:
выбор опции Compile (клавиши Alt-C);
выбор опции Primary file (клавиша P) с целью определения имени первичного файла;
определение имени первичного файла (имя TAIL);
выбор опции Run (клавиши Alt-R);
выбор подопции Run (клавиша R).
в) Выполнение двухмодульной программы, находящейся в файлах FIRST.C 〃 SECOND.С.
FIRST.СSECOND.С
#include<stdio.h>disp1ay()
main(){display();return 0;main(){display();return 0;{
main()
{
display();
return 0;
main()
{
display();
return 0;
printf("That's all")
}
Порядок действий:
-образование файла name PRJ (например, PROGRAM PRJ), содержащего описание проекта или, в простейшем случае указание имен составляющих его файлов.
PROGRAM PRJ
FIRST•
SECOND
-объявление системе Турбо Си имени проекта:
) выбор поля Project (клавиши Alt-P);
) выбор опции Project name (клавиша Р);
определение имени проекта (PROGRAM);
компиляция и выполнение программы (клавиши Alt-R, R).
之)Выполнение программы вне системы Турбо Си
Порядок действий:
составление выполняемой программы (клавиша F9);
временный выход системы Турбо Си и вызов системы DOS (клавиши Alt-F, а затем клавиша О);
выполнение программы в системе DOS;
возврат к системе Турбо Си (директива EXIT).
При разработке программы возникает необходимость исправления имеющихся в ней синтаксических ошибок. Для этого после составления программы следует произвести ее компиляцию (клавиша Alt-F9 для основного модуля в редакционном окне) ^Компиляция правильной программы заканчивается сообщением
Success:Р吗s any key,
а компиляция программы, содержащей ошибки, заканчивается сообщением Errors:Рч^^апу key.
Для нахождения ) места ошибки удобно пользоваться клавишами вертикальных стрелок. После локализации ошибки следует нажать клавишу Enter. При этом активным окном становится редакционное окно, а курсор расположится вблизи локализованной ошибки. После внесения поправок можно вернуть активность коммуникационного окна нажатием клавиши F6. Можно также, находясь в редакционном окне, воспользоваться функциональными клавишами для локализации предыдущей (Alt-F7) и последующей (Alt-F8) ошибок. После исправления, всех ошибок можно повторить компиляцию или провести компиляцию и выполнение программы (клавиши Alt-R,R). Перед этим можно также (с помощью клавиши F6) с произвольной периодичностью переключаться между редакционным и коммуникационным окнами. Процесс идентификации ошибок значительно облегчается благодаря тому, что перемещению со строки на строку в коммуникационном окне автоматически сопутствует перемещение выделенной строки в редакционном окне. Некоторые проблемы возникают тогда, когда в коммуникационном окие появляется ошибка, которая находится в файле, не находящемся в данный момент в редакционном окне. В этом случае перемещение выделенной строки в редакционном окне прекращается, а загрузка в него файла, содержащего ошибку, произойдет только после выбора сообщения, касающегося этой ошибки (клавиша Enter). Для автоматического размещения в редакционное окно требуемой информации необходимо из главного меню перед компилированием программы выбрать следующую опцию:
Options /Environment/ Message Tracking, а затем нажать клавишу Enter столько раз, чтобы рядом с именем опции появилась надпись All files (все файлы). После этою можно вернуться к активному окну (клавиша F10).
Пример
Компиляция программы, в которой перед словом Hello ошибочно пропущены кавычки
#include<stdio.h>
ma1n()
{
printf(Hello, I am Jan B");
return 0;
приведет к появлению в коммуникационном окне следующих сообщений об ошибках:
Undefined symbol 'Hello' in function main
Undefined symbol T in function main
Function call missing) in function main
Unterminated string or character constant ...
Если выбрать первое описание ошибки (клавиша Enter), то в редакционном окне локализуется первая ошибка. Локализация остальных ошибок может быть произведена с помощью клавиш F6, F7 и F8.
1.6. Отладка программ
Символьная программа отладки (отладчик), входящая в состав интегрированной системы, существенно облегчает процесс создания правильной программы.
К важным особенностям отладчика следует отнести:
возможность слежения за ходом выполнения программы;
возможность анализа результатов выполнения программы по ходу их получения;
возможность наблюдения за изменениями величин переменных и выражении;
возможность динамической модификации величины переменных в процессе выполнения программы.
Поскольку отладчик является такой же частью интегрированной системы, как, например, редактор или компилятор, типичный цикл отладки, состоящий из редактирования, компиляции и непосредственно отладки, может быть выполнен внутри системы. В тех случаях, когда желательно использовать дополнительные средства отладки программы, можно воспользоваться автономной программой отладки, описанной ниже.
Запуск отладчика
Для того, чтобы во время выполнения программы имелась возможность символьного обращения к объектам основной программы, требуется уже при хсомпиляции программы обеспечить выработку соответствующей отладочной информации. Проще всего это сделать, задав в интегрированной операционной среде опции
Debug/Source Debugging On、
и
Options/Compiler/Code Generation/OBJ Debug Info. On
После этого инициирование отладки возможно с помощью меню Run (опция Go to Cursor, Trace Into, Step over) или ускоренным способом (соответственно клавишами F4, F7, F8).
Экран монитора
Среднюю часть экрана монитора заполняют два окна: редакционное окно и коммуникационное окно. В редакционном окне находится фрагмент текста отлаживаемой программы, а в коммуникационном окне имеются или
просматриваемые переменные и выражения или сообщения, связанные с компиляцией или компоновкой программы (результаты выполнения программы находятся в окне, высвечиваемом при нажатии клавиш Alt-F5). Если коммуникационное окно обозначено надписью Watch, то оно называется просмотровым, а если надписью Output, то выходным. Если переключение между редакционным и коммуникационным окнами производится с помощью клавиши F6, то переключение между просмотровым окном и окном связей - клавишами A11-F6. Как просмотровое, так и выходное окно может быть увеличено до полного размера экрана (клавиша F5). Повторное нажатие этой клавиши восста на вливает прежние размеры окна.
Слежение за ходом выполнения программы
Простейшим способом локализации ошибок программы являются ее пошаговое выполнение и анализ очередности и результатов исполнения отдельных операторов (трассировка).
Для этого необходимо выбрать поле Run из главного меню, а затем опции Trace Into (клавиша F7) или Step Over (клавиша F8). Если программа не скомпилирована, то это производится в режиме Маке. По окончании компиляции в редакционном окне появится фрагмент главного модуля, в котором будет выделена строка, содержащая имя функции main.
File Edit Run CompileProjectOptions Debug Break/walch
—- Edit —
Line Z Col 1 Insert Indent Tab Fill UiiindentC: DATE. C
Mi “elude <dos.h> ftinclude 《stdio.h〉
struct date "day;
maivK)
getdatet&Today);
printf(“Zd. zOZd. Z02dB, Today. da_year. Today, dajnon^ Today. da_day);
returti 0;
Natch
Fl-Help F5-Zoom F6-Switch F7-Trace F8-Step F9-Make FIO-Menu
Рис. 5. Программа с установкой точек останова.
Выполнение очередных инструкций программы может осуществляться нажатием клавиш F7, F8 и F4. Они имеют следующие значения:
F7 - выполнить инструкцию в выделенной строке программы; если в этой строке содержится вызов функции, то остановиться перед ее первой инструкцией;
F8 - выполнить инструкцию в выделенной строке программы; если в ней имеется вызов функции, то выполнить эту функцию целиком;
F4 - поставить временную точку останова в строке, содержащей 'курсор. Выполнение программы будет приостановлено в точке останова.
Внимание: для повторного выполнения программы с самого начала можно воспользоваться опцией Run/Program Reset (клабиши Ctrl-F2). После этого можно возобновить отладку с помощью клавиши F7 или F8.
Установка точек останова
Поскольку пошаговое выполнение программы может занимать много времени, перед выбранными инструкциями программы устанавливаются точки останова, а затем начинают выполнять программу до попадания на точку останова. Для установки или снятия точки останова требуется переместить курсор на нужную строку программы, а затем выбрать опцию
Break/Watch/Toggle Breakpoint
(клавиши Ctrl-F8). Для снятия всех имеющихся точек останова необходимо выбрать опцию
Break/Watch/C1ear All Breakpoints.
Можно также провести просмотр всех расставленных точек останова с помощью опции
Break/Watch/V1ew Next Breakpoint»
Если выполнение программы не приводит к ее останову, поскольку программа обходит точки останова, можно использовать клавишу Ctrl-Break. При этом выполнение программы приостанавливается.,
Определение значений переменных и выражений
• Во время останова программы можно ознакомиться с текущими значениями переменных и выражений, выбрав опцию
Debug/Evaluate
(клавиши Ctrl-F4).
При этом высвечивается диалоговое окно, представленное тремя рамками. ■
В первую рамку (Evaluate) можно заносить выражения, значения которых необходимо узнать, во второй (Result) будут представлены значения этих выражений, а в третьей (New Value) можно определять новые величины переменных, представленных в выражениях. Окно закрывается клавишей ESC.
Кзалифика^ия идентификаторов
Когда два идентификатора (с различными областями действия) являются идентичными и вступают в противоречие, преимущество имеет идентификатор наиболее локальный или наиболее вложенный.
Обращение к локальным идентификаторам, определенным внутри функции или процедуры, требует квалификации. В общем случае квалифицирова нный идентификатор имеет вид
,tnod.fun,idy
где mod - имя модуля, fun - имя функции, a Xd - имя идентификатора внутри функции или процедуры. Если идентификатор однозначно идентифицирует переменную, то предварительные его квалификации могут быть опущены.
Fik Edit Run Compile Project Options Debug Break/watch -- Edit-
—EvaluateArrElLZResult - 30, 40New value 50—EvaluateArrElLZResult - 30, 40New value 50Line 8 Col 1 Insert Indent Tab Fill Unindent C:VALUE. C ?;include <stdio. h>
—Evaluate
ArrElLZ
Result - 30, 40
New value 50
—Evaluate
ArrElLZ
Result - 30, 40
New value 50
Ш Arr£31 二《20,30,40 mainO
■M№tti3闺УЗ・ЕЩ
return 0;
Hatch
Fl-Help F7-Trace F8-Step FL0~№nu TftB-Cycle《」-Modify
Рис. 6. Определение значения вмраженмй.
Пример. Квалификация идентификатора в основной программе.
Если исполнение следующей программы:
#include<stdio.h>
main()
{
tnt Fix;
Fix * 10;
Add(& Fix);
printf("%d. Fix);
return 0;
}
Add(int * Par)
{
*Par + = 3
будет приостановлено перед выполнением предписания в рамках функции Add, то к переменной Fix можно обращаться с помощью квалифицированного имени main.fix.
Рамка Evaluate
Если в рамку Evaluate занести выражение (в частности, имя переменной), то в рамке Result высветится текущее значение этого выражения. Если значение выражения присваивается некоторой переменной, то, пользуясь клавишами вертикальных стрелок, можно переместиться до рамки New Value и в ней указать новое значение переменной.
Обычно в рамке Evaluate указывается имя переменной. Если после этого имени дополнительно использовать шаблон (отделенный от него запятой), то вывод значения произойдет согласно заданному шаблону.
В простейшем случае шаблон может быть числом, которое определяет общее количество вводимых значений. При этом выводятся значение данной переменной, а также значения переменных того же типа, находящихся в соседних с данной переменной ячейках оперативной памяти. В частности, если Агт - массив с приведенными ниже величинами элементов
static
int Arr[5] = {10, 20. 30. 40, 50};
то указание в окне Evaluate
Arr[l]t 3
приведет к появлению в окне Result чисел
20. 30. 40
В общем случае шаблон может состоять из числа, а также из одного из ниже перечисленных знаков. Если число опущено, то по умолчанию оно принимается равным 1. После знака F может следовать число.
ЗнакИнтерпретация
Свывод в десятичном виде
File Edit Run Compile Project Options Debug Break/watch
L Edit —
Line 1 Col 1 Insert Indent Tab Fill Unindemt C: CHECK. C
int ArrOl 二 < 20.30,40 >;
strucU
char VecE3);
ini Fix;.
Rec = « « TJs'/ai' }J3 };
int Fix 二-13;
enunrf Fiat,Audi»vuel > Car = Audi;
MinOO
Hatch
Arrtll.Z: 30, 40
Car: 1 /* Audi »/
Rec. Fix: 13
Rec:《"Isa\rH, 13 }
Arr: « Z0, 30,幼}
Rec.Veclll: '$'
Fl-Help F5-Zootn FG-*Switch "-Trace F8-Step F9-Make FiO-Menu
Рис. 7. Просмотр переменных и выражений.
Нвывод в шестнадцатеричном виде
F〃вывод в виде числа с плавающей точкой с и знаками
Мвывод каждого байта переменной в виде пары шестнадца
теричных цифр
Мсвыводы каждого байта переменной согласно значению с
(для с: Н, X - в шестнадцатеричном виде; С, S - в символьном виде)
Рвывод адреса указателями в виде сегмент : смещение
segment: off /set
Rвывод величины полей структуры, отмеченных идентифика
торами полей
Sвывод величины элементов строки в шестнадцатеричном
виде со знаком #(hash)
Xвывод в шестнадцатеричном виде
Примеры. Вывод значений выражений
В пределах описания
typedef
struct{
char Name[20];
int Age;
enum{Black. Blond} Hair;
}Child;
Child Isa = {"Isa", 6. Black};
int Arr[3] = {0r 20. 30};
Child * Ref = &Isa;
справедлива следующая запись:
Evaluate
Arr
Arr[l], 2Н
Ref
Ref,P
Isa
Isa, R
RefAge, D (*Ref). Age, 2M
Result
{10, 20, 30%-
6x14. 0x1 E
&Isa
6dE7(DS):0094 &Isa
{“Isa“,6, 0/*Black*/}
{Nanje:MIsau, Age: 6, Hair: 0 / * Black* /}
6
06 00
Просмотр значеиий переменных и выражений
Очень удобной особенностью отладчика является возможность непрерывного просмотра значений выбранных переменных и выражений без необходимости многократного использования диалогового окна.
Просматриваемое непрерывно выражение помещается в просмотровое окно. Каждое программное действие, которое приводит к смене значения выбранного выражения (в частности, к смене значения переменной), сразу же отображается в этом окне.
Занесение выражений в просмотровое окно, а также их модификация и удаление могут производиться двумя способами: через меню или непосредственно с помощью операций в просмотровом окне.
Занесение выражения g окно
выбор опции
Break/Watch/Add Watch
(клавиши Ctrl-F7), а затем запись выражения в рамке Evaluate или
активизация просмотрового окна с последующим нажатием клавиши Ins и запись выражения.
Удаление выражения из окна
выбор опции
Break/Watch/Delete Watch;
(удалению подлежит выражение, выделенное подсветкой или знаком жирной точки); или
активизация просмотрового окна и (после выделения нужной его позиции) нажатие клавиши Del.
Моди力икания выражения в окне
выбор опции
Break/Watch/Edit Watch,
а затем внесение изменений в нажатие клавиши Enter; или
активизация просмотрового окна и (после выделения необходимой позиций) нажатие клавиши Enter. Внесение изменений и повторное нажатие этой клавиши.
File Edit Run Compile Project Options Debug Break/watch
I ,・ I ・ I Edit I i I I■…—“■ line 4 Col 1 Insert Indent fz曲 Fill Unindent C: STACK. C
^include Cstdio. h>
dintf(“Hel!
SecondO
« Third»; >
FirstO
« SecondO; }
mainO
{
FirstO;
Natch
Fl-Help If -Scroll<—»~View call
Рис. 8. Слежение за вызовами.
Удаление всех выражений из окна
-выбор опции
Break/Watch/Remove All Watches;
-активизация просмотрового окна и удаление всех просматриваемых выражений с помощью клавиши Del.
Внимание: просматриваемые выражения могут быть введены вместе с шаблонами, аналогичными описанным выше.
Слежение за вызовами
Каждый вызов процедур или функции приводит к занесению информации об их месте вызова в стеке вызовов. Для просмотра этого стека необходимо выбрать опцию
Debug/Call Stack
(клавиши Ctrl-F3). После этого можно ознакомиться с местом вызова каждой 、активной процедуры или функции, выбирая их с помощью клавиш с вертикальными стрелками и нажимая затем клавишу Enter.
Пример. Стек вызовов
Если в стеке вызовов находятся имена
Local,
Global,
main,
то это означает, что остановка выполнения программы наступила после того, как из функции main была вызвана функция Global, из нее - функция Local. Если в этой ситуации выделить позицию Global и нажать клавишу Enter, то высветится тот фрагмент функции Global, который заключает вызов функции Local. После этого обычным образом можно обращаться к переменным функции Global.
Окончание выполнения программы
Окончание выполнения программы (сброс программы) наступает после выбора опции
Run/Program Reset
или после нажатия клавиш Ctrl-F2. Это приводит к очистке памяти, закрытию всех открытых файлов и подготовке к новому запуску.
Поскольку при этом точки останова не удаляются, легко можно анализировать многократное выполнение одной .программы (например, после Ctri-F2, нажимая клавиши F7 или F4).
КлавишиF4F5F6F7F8Ctrl-F2CtrbF3Ctrl-F4Ctrl-F7Ctrl-F8Ctrl-F9AH-F5Alt-F6КлавишиF4F5F6F7F8Ctrl-F2CtrbF3Ctrl-F4Ctrl-F7Ctrl-F8Ctrl-F9AH-F5Alt-F6
Клавиши
F4
F5
F6
F7
F8
Ctrl-F2
CtrbF3
Ctrl-F4
Ctrl-F7
Ctrl-F8
Ctrl-F9
AH-F5
Alt-F6
Клавиши
F4
F5
F6
F7
F8
Ctrl-F2
CtrbF3
Ctrl-F4
Ctrl-F7
Ctrl-F8
Ctrl-F9
AH-F5
Alt-F6
Функции
Выполнить до курсора
Увеличить окно/уменьшить окно Переключить активность окон Отследить по одной инструкции Отследить инструкции, минуя вызов процедур Закончить выполнение программы Вывести стек вызовов
Вычислить значение выражения
Внести выражение в просмотровое окно
Расставить точки останова /удалить остановы
Выполнить программу
Вывести выходной экран
Выполнить замену содержания окна
В состав пакета Турбо Си 2.0 входят две системы программирования:
-интегрированная система, включающая встроенные редактор, компилятор, компоновщик и отладчик;
-система загрузки с каким-либо текстовым редактором и обслуживающими программами, а также автономные обслуживающие программы, ассемблер и программа запуска.
Вызов интегрированной системы производится командой
ТС options пате,
а системы загрузки - командой
ТСС options пате,
где options - опции вызова, а пате - имя программы. Когда определение опции, а также выбор программы для компиляции производятся посредством системы меню, вызов интегрированной системы упрощается до вида
ТС.
Использование системы загрузки менее удобно, чем интегрированной системы. Эту систему целесообразно запускать при недостаточном размере оперативной памяти, а также при желании использовать другой текстовой редактор, а не встроенный в операционную среду.
Интегрированная система
Для запуска интегрированной системы достаточно задать команду ТС, после чего можно пользоваться системой меню, дающей возможность составления, загрузки, редакции, запуска и выполнения программ, а также установку параметров среды и сохранение их в файле конфигурации.
В этом файле, кроме всего прочего, запоминается информация о программе, находящейся в редакционном окне. Благодаря этому можно вызвать интегрированную систему, обеспечить занесение в редакционное окно последней обработанной перед этим программы. Если в файле конфигурации нет названия проекта^ т.е. имени файла, с которого должна начаться компиляция, то можно его указать непосредственно в команде ТС.
Другими опциями, которые можно указать в этой команде, являются следующие:
/твыполнить компиляцию в режиме Make}
/Ьвыполнить компиляцию в режиме Build}
/dиспользовать два монитора (результаты выполнения
программы выдаются на неактивный монитор);
/спате использовать файл конфигурации name (по умолчанию принимается, что им является TCCONFIG.TC).
Пример. Составление программы с помощью системы ТС
Если во время выполнения файла GREET.C в файле MYCONFIG.TC заполнена конфигурация интегрированной системы, то для составления выполняемой программы и помещения ее в файл GREET.EXE можно воспользоваться, например, директивой
tc/cmyconfig.tc/b
Типовой вызов системы
Типовым вызовом интегрированной системы является такой ее вызов, после которого появляется главное меню, состоящее из полей
File
Edit
Run
Compile
Project
Options
Debug
Break/Watch
Выбор любого из них (за исключением Edit) приводит к появлению подменю, состоящего из опций. Значения отдельных полей и опций описаны во вспомогательных окнах, выводимых на экран нажатием клавиши F1. Принимая это во внимание, указанные ранее описания будут ограничены до минимума.
Поле File
Выбор поля File (клавиша Alt-F) приводит к высвечиванию следующих опций:
LoadF3
PickAlt-F3
New
SaveF2
Write to
Directory
Change Dir
OS shell
Quit Alt-X
Load
Выбор опции Load (клавиши L или F3) дает возможность загрузки файла для его редакции. Система предлагает имя файла, но оно может быть заменено. Если имя будет дано неоднозначно (с наличием звездочек или
вопросительных знаков), то на экран выведется список имен файлов, из которого можно сделать выбор (с помощью клавиш со стрелками я клавиши Enter).
Pick
Выбор опции Pick (клавиши Р или Alt~F3) также дает возможность загрузки файла, но при этом система предлагает провести выбор не более чем среди восьми файлов, которые были загружены последними. Среди предлагаемых имен имеется 'Uoadfile-". Выбор этого имени приводит к такому же результату, что и выбор опции Load.
New
Выбор опции New (клавиша N) приводит к возможности создания нового файла. Предлагаемое имя файла NONAME.C) можно изменить во время записи файла на диск.
Save
Выбор опции Save (клавиши S или F2) приводит к записи на диск файла, находящегося в окне редактора. Если файл имеет имя NONAME.C, то система удостоверится, что именно это имя должно иметь дисковый файл.
Write to
Выбор опции Write to (клавиша W) приводит к записи на диск информации из окна редактора. В случае существования файла с идентичным именем старый файл на диске стирается.
Directory
Выбор опции Directory (клавиша D) дает возможность вывода на экран имен файлов выбранного каталога. Поскольку предлагаемым неоднозначным именем является *.*, то нажатие клавиши Enter приводит к выводу всех имен текущего каталога.
Change dir
Выбор опции Change dir (клавиша С) дает информацию об имени текущего каталога и возможность выбора произвольного каталога (на жестком диске или дискете).
OS shell
Выбор опции OS shell (клавиша О) приводит к временному переходу в состояние, в котором возможно использование команд системы DOS. Выполнение в этом состоянии команды приводит к возврату в систему Турбо Си.
Quit
Выбор опции Quit (клавиши Q или Alt-X) приводит к окончанию работы
с системой Турбо Си и возврату в операционную систему DOS.
Поле Edit
Выбор поля Edit (клавиша Alt-E) редакционного окна на экране.Выбор поля Edit (клавиша Alt-E) редакционного окна на экране.приводит к вызову редактора в видеприводит к вызову редактора в виде
Выбор поля Edit (клавиша Alt-E) редакционного окна на экране.
Выбор поля Edit (клавиша Alt-E) редакционного окна на экране.
приводит к вызову редактора в виде
приводит к вызову редактора в виде
Поле Run
Выбор поля Run опций:
(клавиша Alt~R)
приводит к
высвечиванию
следующих
Run
Ctrl-F9
Program reset
Ctrl-F2
Goto cursor
F4
Trace into
F7
Step over
F8
User screen
Alt-F5
Run
Выбор опции
Run (клавиши R
или Ctrl-F9)
приводит к
компиляции
программы в режиме Маке с
последующим
выполнением
про1раммы.
Аргументы программы могут быть
определены с
помощью поля Options и
опции Arguments.
После окончания
программы на
экране появится надпись
Press any key (нажми произвольную
клавишу).
Program reset
Р или Ctrl-F2) этого очищаетсяР или Ctrl-F2) этого очищаетсяприводит к оперативнаяприводит к оперативнаяВыбор опции Program reiset (клавиши окончанию выполнения программы. После память и закрываются все открытые файлы.
Р или Ctrl-F2) этого очищается
Р или Ctrl-F2) этого очищается
приводит к оперативная
приводит к оперативная
Goto cursor
Выбор опции Goto cursor (клавиши G или F4) приводит к установке временно 访 точки останова в выделенной курсором строке (после его перемещения в редакционном окне), а затем к выполнению программы до точки останова.
Trace into
Выбор опции Trace into (клавиши Т или F7) приводит к выполнению ближайшего оператора основной программы с возможным слежением за операторами тела функции.
Step over
Выбор опции Step over (клавиши S или F8) приводит к выполнению ближайшего оператора основной программы, но без слежения за операторами тела функции.
3—764
User screen
Выбор опции User screen (клавиши U или Alt-F5) приводит к высвечиванию выходного экрана (экрана пользователя).
Поле Compile
Выбор поля Compile (клавиша Alt-C) приводит к высвечиванию следующих опций:
Compile to OBJ
Make EXE file
Link EXE file
Build all
Primary C file
Get info *
Compile
Выбор опции Compile OBJ (клавиша С) приводит к компиляции файла Name,C и созданию файла Name.OBJ. Имя Name идентично имени файла опции Primary С file. Если это имя отсутствует, то присваивается имя файла, находящегося в окне редактора.
Make EXE file
Выбор опции Make EXE file (клавиша М) приводит к выполнению компиляции в режиме Маке и созданию файла Name.EXE, содержащего выполняемую программу. Имя Name идентично имени проекта, определенного в опции Project, в противном случае компилируется последний файл, загруженный в редакционное окно.
Link EXE file
Выбор опции Link EXE file (клавиша L) приводит к объединению текущих файлов с расширениями OBJ и LIB и созданию файла с расширением .EXE (без предварительного выполнения компиляции в режиме Маке).
Build all
Выбор опции Build all (клавиша В) приводит к созданию файла с расширением .EXE в режиме компиляции Build.
Primary С file
Выбор опции Primary С file (клавиша Р) дает возможность определения имени первичного файла.
Get info■
Выбор опции Get info (клавиша G) приводит к высвечиванию
информационного окна, содержащего имя первичного файла, имя основного файла, размер основной программы в байтах, код возврата программы, размер доступной оперативной памяти.
Поле Project
Выбор поля Project (клавиша Alt-P) приводит к высвечиванию следующих опций:
Project name
Break name on Errors {Warnings/.../Fatal/Link)
Auto dependencies On/Off
Clear project
Remove messages
Project name
Выбор опции Project name (клавиша P) дает возможность определения имени проекта. Если именем проекта является Name, то созданные после компиляции проекта файлы будут иметь имена ^a^ne.MAP и Name^XE.
Break make on
Выбор опции Break make on (клавиша В) дает возможность определения момента окончания компиляции проекта. Это может наступить после предупреждающих сообщений (Warnings), ошибок (Errors), фатальных ошибок (Fatal errors) или перед компоновкой (Link).
Auto dependencies
При выборе опции Auto dependencies (клавиша А) в режиме Маке определяется возможность своевременного выполнения компиляции множества источников (Ол) либо невозможность такого выполнения (О//).
Clear project
Выбор опции Clear project (клавиша С) приводит к аннулированию имени проекта и очистке коммуникационного окна.
Remove message
Выбор опции Remove message (клавиша R) приводит к очистке окна связей.
Поле Options
Выбор поля Options (клавиша Alt-O) приводит к появлению следующих опций:
Compiler
Linker
Environment
3*
Directories
Arguments
Save options
Retrieve options
Опция Compiler
Выбор опции Compiler (клавиша С) дает возможность определения способа компилирования программы. С опцией Compiler связано меню, содержащее следующие подопции:-
ModelTiny/Small/,../Large/Huge
Defines
Code generation
Optimization
Source
Errors
Names
Model
Выбор подопции Model (клавиша M) дает возможность определения модели памяти^ По умолчанию принимается модель Small (малая), а всего имеется 6 моделей: Tiny, Small, Medium, Compact, Large и Huge.
Defines
Выбор подопции Defines (клавиша D) дает возможность определения символов, используемых препроцессором, например запись
Alfa; Beta = 3; Gamma = Jan.
определяет символы Alfa, Beta и Gamma, и в частности отождествляет символ Beta с числом 3, а символ Gamma - со строкой знаков Jan.
Code generation
Выбор опции Code generation (клавиша С) дает возможность определения типа генерирования кода. Допустимыми опциями подопции Code generation являются:
Calling convention
- вызов функции в терминах языка Си или Паскаль.
Instruction set Floating point
- выбор набора машинных инструкций.
- использование сопроцессора или эмулятора.
Default char type
- проверка влияния бита знака на операции с переменными типа (char).
Aligment
- определение способа размещения полей структур и объединений.
Generate underbars
- дополнение идентификаторов знаком
подчеркивания.
Merge duplicate stringsStandard stack frameTest stack overflowLine numbersOptimizationMerge duplicate stringsStandard stack frameTest stack overflowLine numbersOptimizationоднократное резервирование места для идентичных знаковых строк.
Merge duplicate strings
Standard stack frame
Test stack overflow
Line numbers
Optimization
Merge duplicate strings
Standard stack frame
Test stack overflow
Line numbers
Optimization
генерация дополнительного кода в прологе и эпилоге функции.
проверка на переполнение стека во время выполнения программы.
генерация номеров строк основнойпрограммы в выходном файле.
Выбор подопции Optimization (клавиша О) дает возможность определения способа оптимизации результирующей программы.
Допустимыми опциями подопции Optimization являются:
Optimize forUse register variablesRegister optimizationJump optimizationSourceOptimize forUse register variablesRegister optimizationJump optimizationSourceоптимизация по быстродействию или времени выполнения.
Optimize for
Use register variables
Register optimization
Jump optimization
Source
Optimize for
Use register variables
Register optimization
Jump optimization
Source
возможность использования регистровых переменных.
использование информации о данных, находящихся в регистрах процессора.
удаление ошибочных команд, связанных с организацией цикла.
Выбор подопции Source (клавиша S) определяет способ трактования основной программы во время ее компиляции. Допустимыми опциями подопции Source являются:
Identifier length Nested comments ANSI keywords onlyIdentifier length Nested comments ANSI keywords only-размер идентификатора.
Identifier length Nested comments ANSI keywords only
Identifier length Nested comments ANSI keywords only
-вложенные комментарии.
восприятие только ключевых слов, определенных ANSI.
Errors
Выбор подопции Errors (клавиша Е) определяет способ реагирования системы Турбо Си на ошибки, содержащиеся в основной программе. Допустимыми опциями подопции Errors являются:
ErrorsWarningsDisplay warningsPortability warningsErrorsWarningsDisplay warningsPortability warningsколичество ошибок, после обнаружения которых наступит прекращение компиляции.
Errors
Warnings
Display warnings
Portability warnings
Errors
Warnings
Display warnings
Portability warnings
количество предупреждений, после которых наступит прекращение компиляции.
определение того, должна ли происходить сигнализация предупреждений.
определение того, должна ли происходить сигнализация предупреждений, связанных с такими ошибками, как
Непереносимое преобразование указателя.
Непереносимое сравнение указателей.
Непереносимое сравнение данных указателей.
Непереносимое сравнение с литералом.
Чрезмерное количество цифр константы.
Возможная утрата значащих цифр во время преобразования.
Неотличимость указателей типов (signed char) и (unsigned char).
ANSI violations- определение того, должна ли
происходить сигнализация таких нарушений требований ANSI, как
Обращение к несуществующему полю структуры.
В: Использование структуры, не содержащей полей.
Наличие в определенной функции, не дающей результата, функции return, содержащей выражение.
Наличие в определении функции как функции return, содержащей выражение, так и функции return, не содержащей выражения.
Ненадежное преобразование указателей.
Отсутствие определения структуры с использованным именем.
Неидентичное переопределение идентификатора.
Common errors- определение того, должна ли
происходить сигнализация предупреждений перед такими ошибками, как
Отсутствие результата функции.
Определение функции, содержащей операторы, которые никогда не будут выполнены.
Определение функции, содержащей оператор, выполнение которого не будет иметь никакого результата.
Использование идентификатора без его предварительного объявления.
Определение данного, которое никогда на будет использовано.
Объявление параметра функции, который никогда не будет использован.
Возможное использование неправильного присвоения.
Less common errors- определение того, должна ли
происходить сигнализация предупреждения перед такими нетипичными ошибками, как
А: Использование оператора указания перед идентификатором массива или функции.
Объявление переменной, которая никогда не будет использована.
Отказ от явного использования скобок в месте источника ошибок.
Использование в качестве аргумента имени структуры, а не указания структуры.
Отсутствие объявления функции с указаным именем.
Вызов функции, имеющей неизвестные типы ее параметров.
Names
Выбор подопции Names (клавиша N) дает возможность замены имен сегментов, в которых будут размещены код, а также данные программы. Допустимыми подопциями подопции Names являются
Code names-определениеименисегментакода.
Data names-определениеименисегментаданных.
BSS names-определениеименисегментаBSS.
Опция Linker
Выбор опции Linker (клавиша L) определяет способ компоновки программы. Допустимыми подопциями опции Linker являются:
Map file - определение типа карты распределения памяти.
Initialize segments - определение необходимости инициализации сегментов.
Default libraries - определение необходимости включения при компоновке библиотек, не принадлежащих системе Турбо Си.
Graphics library - определение необходимости автоматического поиска в графической библиотеке.
Warn duplicate symbols - определение необходимости сигнализации в повторении символов в объективных файлах и библиотеках.
Stack warnings - определение необходимости генерации компоновщиком сообщения, информирующего об отсутствии зарезервированного места для стека.
Case sensitive link - определение необходимости различать компоновщиком строчные и заглавные буквы символов.
Опция Environment
Выбор опции Environment (клавиша Е) определяет каталоги, в которых система Турбо Си может искать необходимые ей файлы. Кроме того, с помощью этой опции можно определить некоторые особенности системы. Допустимыми подопциями опции Environment являются:
Massage tracking - определение способа отслеживания ошибок в редакционном окне во время перемещения курсора в коммуникационном окне (Track ... current file - только в редакционном окне; Track ... all files - во всех файлах).
Keep message - определение способа трактования сообщений, высвеченных в коммуникационном окне (Ол - сохранение сообщений с предыдущих компиляций; Off - очищение окна перед компиляцией).
Config auto save 一 определение условий запоминания действующей конфигурации системы Турбо Си (Ом - перед каждым выполнением программы, а также при вызове системы DOS; Off - только при задании опции О/Save Options).
Edit auto save - определение необходимости автоматической записи на диск файла, находящегося в редакционном окне, перед каждым выбором поля Run или опции OS shell.
Backup files - определение необходимости выбора опции Save после запоминания предыдущей версии основного файла как файла с расширением .ВАК.
Tab size - определение шага табуляции.
Zoomed windows - определение необходимости занятия окном (редакционным или коммуникационным) целого экрана.
Screen lines - определение числа строк текста, высвечиваемых на экране (по умолчанию 25).
Опция Directories
Выбор опции Directories (клавиша D) дает возможность определения каталогов, в которых будет осуществлен поиск файлов данных. Допустимыми подопциями опции Directories являются:
Include directories - определение каталогов, в которых находятся файлы, такие, как, например, stdio.h (имена каталогов отделяются точкой с запятой).
Library directories ~ определение каталогов, в которых находятся библиотечные файлы - с расширением .LIB, а также стартовые файлы -CO7.OBJ (имена каталогов отделяются точкой с запятой).
Output directory - определение каталога, в котором помещены файлы с расширениями .OBJ .EXE и .МАР.
Turbo С directory - определение каталога, в котором находятся файлы:
4 информационный (TCHELP.TCH) и конфигурационный (TCCONFIG.TC).
Pick file name - определение имени файла указания, в котором хранятся имена файлов, выбираемых с помощью опции File/Pick file.
Внимание: Поле,
Current pick file
дает текущее имя файла Pick (определенного подопцией Pick file name).
Опция Arguments
Выбор опции Arguments (клавиша А) дает возможность передачи системе Турбо Си аргументов, с которыми будет вызвана текущая программа. Это позволяет выполнять программу в тех же самых условиях, какие создаются при вызове программы из системы DOS.
Опция Save options
Выбор опции Save options (клавиша S) приводит к запоминанию в конфигурационном файле TCCONFIG.TC опций системы Турбо Си.
Опция Retrieve options
Выбор опции Retrieve options (клавиша R) приводит к загрузке конфигурационного файла TECONFIG.TC последу ющи ми действиями, согласно опциям, записанным в этом файле.
Поле Debug
приводитприводитвысвечиваниювысвечиваниюВыбор поля Debug (клавиша Alt-D) сл(Ьдующих опций:
приводит
приводит
высвечиванию
высвечиванию
Ctrl-F4Ctrl-F3Ctrl-F4Ctrl-F3Evaluate
Ctrl-F4
Ctrl-F3
Ctrl-F4
Ctrl-F3
Cali stack
Find function
Refresh display
Display swapping Smart/ Always /None
Source debuggingOn/Off
Evaluate /
Выбор опции Evaluate (клавиша E или Ctrl-F4) приводит к высвечиванию диалогового окна, состоящего из трех рамок: Evaluate^ Result и New Value. Перемещение между рамками производится с помощью клавиш вертикальных стрелок. Помещение в рамку Evaluate некоторого выражения приводит к высвечиванию его значения в рамке Result. Если выражение является именем переменной, то в рамке New Value можно задать новое значение этой переменной. В соответствии с приведенным ранее описанием, если после выражения будет дан шаблон (Cs S, D, Н, X, F九,М, Р), то осуществится вывод значения выражения по этому шаблону (например, Агг [4 ], 2Х приводит к выводу Агг [4], Агг [5] и Агг [6] в шестнадцатеричной форме).
Call stack
Выбор опции Call stack (клавиши С или Ctrl-F3) приводит к высвечиванию стека вызовов функций.
Find function
Выбор опции Find function (клавиша F) приводит к высвечиванию текста функции с указанным именем.
Refresh display
Выбор опции Refresh display (клавиша R) приводит к очищению экрана монитора.
Display swapping
Выбор опции Display swapping (клавиша D) определяет способ переключения между экраном программы запуска и выходным экраном (Smart - только перед ожидаемым выводом на экран, Always - всегда, None - никогда)»
Source debugging
Выбор опции Source debugging (клавиша S) определяет способ компиляции программы относительно ее запуска (О 九-с помощью интегрированного запуска, Standalone - с помощью автономной программы запуска, None 一 без использования программы запуска).
Поле Break/Watch
Выбор поля Break/Watch (клавиша Alt-B) приводит к высвечиванию следующих опций:
Add watchCtri-F7
Delete watch
Edit watch
Remove all watches
Toggle breakpointCtri-F8
Clear aH breakpoints
View next breakpoint
Add watch
Выбор опцйи Add watch (клавиша А или Ctrl~F7) приводит к размещению в просмотровом окне данного выражения (в том числе имени переменной). Это также можно сделать с помощью клавиши Ins или Ctrl-N, нажатой при активности просмотрового окна.
Delete watch
Выбор опции Delete watch (клавиша D) приводит к удалению выделенной строки в просмотровом окне. Это может быть сделано также клавишей Del при активности просмотрового окна.
Edit watch
Выбор опции Edit watch (клавиша Е) дает возможность редактирования выделенного выражения, находящегося б просмотровом окне. Это также можно выполнить с помощью клавиши Enter, нажимая ее при активности просмотрового окна.
Remove all watches
Выбор опции Remove all watches (клавиша R) приводит к очистке просмотрового окна.
Toggle breakpoint
Выбор опции Toggle breakpoint (клавиши Т или Ctrl-F8) приводит к установке или снятию точки останова в строке, выделенной курсором.
Clear all breakpoints
Выбор опции Clear all breakpoint (клавиша С) удаляет все расставленные точки останова.
View next breakpoint
Выбор опции View next breakpoint (клавиша V) перемещает курсор до строки, в которой находится следующая точка останова.
Вызов системы загрузки имеет вид
ТСС options names,
Где options - опции, a names - имена основных файлов, которые должны быть обработаны. Каждая опция должна начинаться со знака минус и отделяться от другой опции или имени файл否 по крайней мере одним пробелом. Если имя файла имеет расширение .ASM, то содержащийся в этом файле текст компилируется посредством Turbo Assembler (TASM). Созданный таким способом файл с расширением .OBJ, как и другие файлы с таким расширением (перечисленные в команде или возникшие в результате компиляции) после объединения с библиотеками (расширение .LIB), образует исполнительную программу с именем name .EXE, в котором паше совпадает с именем первого файла из последовательности names.
Пример. Создание загрузочного модуля
Вызов
tcc greet -ms hello word.obj libra.lib
организует компиляцию модуля HELLO.C, а затем объединение модулей HELLO.OBJ и WORLD.OBJ с библиотекой LIBRA.LIB и создание в модели SMALL (опция -ms) исполнительной программы HELLO.EXE.
Опции, которые могут быть перечислены в команде ТСС, находятся в тесной связи с опциями, используемыми в интегрированной системе. С этой точки зрения достаточно ограничиться следующим списком, в котором имеется аналогия с интегрированной системой (словесные описания, записанные курсивом, не имеют эквивалентов в интегрированной системе).
Внимание:
Исключение опции реализуется записью после нее знака
минус. Опции,
Опция
-А
-а
обозначенные звездочкой, являются принимаемыми.
Опция менюЗначение
О/С/Source/ANSI keywordsOn
O/C Code generation / AlignmentWord
* -еО/С Code generation/AlignmentByte
-ВВозможность преобразования ассемблерных
вставок
-СО/С/Source/Nested commentsOn
-DnameО/С/Defines
-Dname^str О/C/Defines
~dO/C/Code generation/Merge duplicatestringsOn
*-d-
-Ename
-ename
* -f
-f-
O/C/Code generation/Merge duplicate stringsOff
Определение имени ассемблера no умолчанию (TASM)
Определение имени файла, в котором должна размещаться выполняемая программа О/С/Code generation/Floating point Emulation O/C/Code generation/Floating point None
-f87 -G -g# Apath
-i# -j#
-К
O/C/Code generation/Floating point 8087 0 / C / Optimization / Optimize for 0 / C / Errors / Warnings: stop after 0/С/Include directories 0/C/S/Identifier length 0/ C / Errors / Errors: stop after O/C/Code generation/Default char type
Speed
#
# #
Unsigned
*-К-
O/C/Code generation/Default char type
Signed
* -k
О/С/Code generation/Standard stack Frame
On
-Lpath
О/D Library directory
Передача опции компоновщику
O/L/Map file
0/C/Model Compact
O/C/Model Huge
О/C/Model Large
О/C/Model Medium
*一ms
O/C/Model Small
0/C/Model Tiny
O/C/Code generation/Test stack overflow
On
-npath
О/D/Output directory
О/C/Optimization/Jamp optimization
On
-0
Определение имени файла, в котором должен
быть размещен скомпилированный файл
-P
O/C/Code generation/Calling convention
Pascal
*-p—
O/C/Code generation/Calling convention
C
* -r
0 / C / Optimization / Use register variables
On
~S
Генерация кода ассемблера
Лопате
Стирание предыдущего определения символа пате
*-u
0/С/Code generation/Generate underbars
On
-V
Debug/Source debugging
On
-w
О/C/Errors/Display warnings
On
-w-
О/C/Errors/Display warnings
Off
-wxxx
0 /C/ Errors/ Portability warnings, ANSI violations.
Common errors. Less Common errors
On
-w-xxx
0/C / Errors /Portability warnings, ANSI violations.
Common errors. Less Common errors
Off
-y
O/C/Code generation/Line numbers
On
-z
О/C/Optimization /Register optimization
On
-тАпате
0/С/Names/ Code/ Class
-z^name
O/C/Names/BSS/Class
-zCname
O/C/N ames / Code / Segment
-тХУпате
0/С/Names / Code / BSS / Segment
-^Gnarne
O/C/Names/BSS/Group
-тРпате
0/С/Names/Code/ Group
^■TRname
О/C/Names/Data Segment
-тЗпате
О/C/Names/ Data / Group
^Лпате
О/C/Names/ Data / Class
-1
O/C/Code generation 80186/80286
*-1-
O/C/Code generation 8088/8086
Произвольный набор перечисленных опций может быть расположен в текстовом файле TURBOC.CFG. Удобнее всего это сделать, размещая по
одной опции в строке. При вызове системы загрузки командой ТСС эти опции трактуются, как если бы они находились непосредственно после имени команды. Если имеются взаимоисключающие опции, то правильной считается последняя. Файл TCC.CFG отыскивается последовательно: а) в текущем каталоге, б) в каталоге, в котором находится ТСС.
Пример. Вызов системы загрузки
Выполнение команды
tcc -mm -Libra-egreeting greet greet.asm mylib. lib
приводит к выполнению исполнительной программы GREETING. EXE (egreeting), скомпилированной в модели MEDIUM Gmm) и составленной из программы на языке Си (greet) и в ассемблере (greet, asm) послу объединения их с библиотеками MYUB.LIB и LIBRA «Libra)
ЧАСТЬ II. ЯЗЫК
Лексические понятия
В программах, написанных на языке Си, можно выделить следующие лексические единицы: идентификаторы, ключевые слова, литералы, операторы и разделители. Лексический анализ проводится в порядке расположения знаков в программе. За очередную лексическую единицу принимается наибольший ряд знаков, который может образовывать лексическую единицу. С этой точки зрения, поскольку в языке Си операторами являются как двойной минус, так и просто м〃〃ус, такие выражения, как, например, трактуются как
аb,
а не как отличное от него выражение
аЬ.
Пример
#include <stdio.h>
main()
{ char chr = 'b' putchar(— chr); return 0;
}
В приведенной программе имеются, в частности, следующие лексические единицы: идентификаторы (chr, putchar), ключевые слова (char, return), литералы ('b'), операторы (=) и разделители (;)
Функция
putchar(— chr);
не интерпретируется как
putchar (-(- char));
поскольку за лексической единицей, следующей после открывающей скобки, распознается наибольший ряд знаков, который может быть принят за
лексическую единицу (.двойной минус). По аналогичным причинам не является ключевым словом запись char, содержащаяся в putchar.
Комментарии
Комментарий не является лексической единицей. Каждый комментарий начинается парой последовательных знаков /* (косая черта, звездочке^ и кончается также парой знаков */ (звездочка, косая черта}. В комментариях не могут быть заключены другие комментарии. Комментарий трактуется как пробел. Это означает, например, что описание
int/**/Six;
эквивалентно описанию
int Six;
Пример
/* EWA /* IZA*/ JAN*/
Приведенная запись не является комментарием, поскольку состоит из комментария /*EWA /* IZA ♦/ и последовательности символов JAN */
Для сравнения запись
/* EWA /* IZA*/ /*JAN*/
представляет собой два последовательных комментария.
Идентификаторы
Идентификатором является ряд букв и цифр, начинающихся с букв. В языке Си считается также знак подчеркивания. Строчные и прописные буквы восприми маются отдельно. Хотя число знаков идентификатора не ограничено, идентификаторы, имеющие одинаковые 32 первых знака, считаются идентичными.
Примеры
Идентификаторы: Alpha
-beta-
Very Long R2D2.
Не являются идентификаторами:
4sale - начинается с цифры;
#23 - не начинается с буквы;
Str$ - содержит неразрешенный знак.
48Часть //. Язык
Ключевые слога
Ключевыми словами являются лексические единицы, имеющие вид постоянных идентификаторов. Эти слова зарезервированы и не могут быть использованы в качестве идентификаторов объектов. Ниже приведен список ключевых слов:
auto
break
case
char
const
continue
default
do
doubie
else
enum
extern
float
for
goto
if
int
long
register
return
short
signed
sizeof
static
struct
switch
typed ef
union
unsigned
void
volatile
while
Пример
fun(RETURN)
int RETURN
{
return RETURN;
}
RETURN является идентификатором7 a return “ ключевым словом. Эти слова имеют разные значения и не противоречат друг дру^у.
34 Литералы
Как и в других языках программирования, литералами являются такие символы, которые в рамках принятой интерпретации определяют все свои особенности, в том числе и собственное значение. Литералы подразделяются на числовые, знаковые, с плавающей точкой и строки (строчные литералы).
Числовые литералы
Числовые литералы могут быть в виде десятичных, восьмеричных и шестнадцатеричных чисел. Десятичные числа состоят из десятичных цифр (например, 255). Восьмеричные числа состоят из восьмеричных цифр, перед которыми стоит цифра 0 (например, 0377). Шестнадцатеричные числа представляются шестнадцатеричными цифрами, перед которыми записывается пара знаков Ох или ОХ (например, OxFF). Шестнадцатеричные цифры больше 9 (от 10 до 15) представляются строчными или прописными буквами от А до F соответственно.
Если в данной реализации возможно несколько вариантов представления целых чисел, то по количеству значащих цифр целые литералы могут быть числами данного типа (long int).B записи таких чисел в конце прибавляется строчная или прописная буква L (например, OxFFL).
Пример
var н 5L - ОхА;
В приведенном выражении представлены целые литералы 5L и ОхА. Литерал 5L представляет число типа (long int) величиной 5, а литерал ОхА - шестнадцатеричное имело типа (int) величиной 10.
Знаковые литералы
Знаковые литералы обозначаются в виде 'с', ще с - произвольный знак, за исключением знаков (апостроф) и \ (косая черта). Для некоторых символов принято обозначение с помощью обратной дробной черты \L, где L может быть:
буквой;
числомизодной,двухилитрехвосьмеричных цифр (DDD),
определяющих код знака процессора;
числомизодной,двухилитрехшестнадцатеричных цифр с
предшествующей буквой х или X (xDDD), определяющей код знака процессора.
Следующий список содержит знаковые литералы, которые имеют установленную интерпретацию:
Литерал
Интерпретация
Лп
Новая строка
(new Une}
7
Горизонтальная табуляция
(tabulation)
'\Ь'
Возврат на один шаг
(backspace)
Возврат каретки
{carriage return)
'\f‘
Перевод формата
{form feed)
Обратная дробная черта
'\а‘
Звонок
Апостроф
'\0'
Знак кода 0
(ноль)
Пример
putchar ('\'')
Выполнение этой функции приводит к выводу одного апострофа.
Поскольку в ASCII знак ” (апостроф) имеет код 47§ или 27j6, то указанную функцию можно представить в виде
putchar ('\47') или
putchar ('\х27')
Литералы с плавающей точкой
Литералы с плавающей точкой представляют данные с двойной точностью. Они состоят из целой части, точки, дробной части, а также из показателя, имеющего вид целого числа со знаком, перед которым находится прописная 4—764
или строчная буква Е. В записанном таким образом литерале можно опустить целую или дробную часть, а также знак показателя, если он положительный. Кроме этого, можно не указывать точку или показатель вместе с буквой Е.--
Пример
23 23 Зе2 2.ЕЗ-24.00.50.0 ОеО
Все приведенные лексические единицы представляют собой литералы с плавающей точкой.
Строки (строчные литералы)
Строки -葡 это последовательность символов, заключенная в кавычки. Строка соответствует типу данных ^массив символов^. Строка может содержать любые определенные в конкретной реализации символы. Если в литерале использовано описание знака, не имеющего интерпретации, то начинающий его знак \ (косая черта) будет пропущен.
В конец строки компилятор добавляет нулевой символ “0", что является признаком конца строки. Если текстовый литерал должен включать знак “ (кавычки), то этот знак необходимо записать в виде \и {косая черта, кавычки).
Пример
printfK”)
Аргументом функции printf является литерал “\'“, представляющий пару знаков:апостроф и знак нуль.
Литерал "\"" имеет отличный тип от литерала '\": первый из них - строка, а второй - знаковый литерал.
Внимание: Каждая пара соседних строк трактуется как строка, состоящая из всех знаков первого литерала и следующих после них всех знаков второго.
Таким образом, например, запись
“Hello" “ “ “world"
трактуется как запись
"Hello World"
Объекты, подлежащие преобразованию, представляются посредством имен. Простейшими именами объектов являются литералы и идентификаторы. Первые представляют в программах постоянные, а вторые - переменные величины. Кроме этого, объекты могут быть представлены соответствующим образом составленными выражениями.
Поскольку об особенностях объектов обычно судят на основе их имен, важное значение приобретает описание объектов. Описание является излишним при использовании литералов, поскольку все атрибуты объекта, представленного через литерал, могут быть поняты на основе записи литерала, однако описание необходимо для идентификаторов переменных.
Хотя основным атрибутом идентифи катора является тип, который определяет допустимый список операций и значений, в описании помешается обычно некоторые дополнительные атрибуты, связанные с областью действия, классом описываемого объекта н т. д.
Описание простых переменных
Простой переменной называется переменная, которой могут быть приписаны только неделимые данные. Такими данными являются, в частности, данные следующих основных типов: char, int, short, long, float, double и long double.
Типы char (символьный), int (целый), short (короткий целый), long (длинный целый) могут быть модифицированы ключевыми словами signed и unsigned. Данные, имя типа которых включает модификатор signed, являются данными со знаком, а данные, имя типа которых содержит модификатор unsigned, - данными без знака. При отсутствии модификатора по умолчанию принимается модификатор signed. Имя типа, состоящее из одного модификатора, эквивалентно имени, содержащему ключевое слово int. В системе Турбо Си приняты следующие диапазоны величин данных отдельных типов:
Типы
Диапазоны
char, signed char unsigned char short, signed short
-128 .. 127/. *
0 .. 255-~、.
-32768 .. 32767
unsigned short
int, signed int
unsigned, unsigned int
0 .. 65535\ D $ 7 飞'
-32768 .. 32767
0 .. 65535
long, signed long unsigned long
-2147483648 .. 2147483647 } = \7
0 .. 4294967295f 〔 °
-3.4e38 .. 3.4e38丿 卜,二、「/'
float
doubie
-1.7e308 .. 1.7еЗО8'<
long double
-3.4е4932 .. 3・4е4932‘口?”「
Данные типа (char) - 1-байтовые, данные типа (short) и (int) - 2- ;6айтсвне, данные типа (long) и (float) - 4-байтовые, данные типа (double)- 8-байтовые, а типа (long double) - 10-байтовые. Отдельным типом данных является перечислимый тип данных - упорящоченное множество элементов, доступ к которым осуществляется по имени. Над элементами перечислимого типа разрешены операции присваивания и сравнения. Перечислимый тип описывается с помощью служебного слова enum, за которым в фигурных скобках следует список элементов перечисления. Каждый элемент перечисления является константой данного перечислимого типа. Элементы перечисления обозначаются идентификаторами и прсдставляются значениями целого типа (int), начиная с нуля, с последующим увеличением значения на 1. Если в стеке используется форма с присваиванием, то значение константного выражения устанавливает значение данного элемента списка и последующие элементы увеличиваются, начиная от этого нового значения. '
Пример
main() {main() {епит Colour {Red, Green = 3, Blue} Hue: include <stdio.h>
main() {
main() {
Hue = Green;
printf(*•%(]•', Hue - Blue);
return 0;
В программе описана переменная Hue перечислимого типа (enum Colour), а также три идентификатора: Red, Green и Blue.
Приведенная программа эквивалентна следующей:
enum Colour {red. Green = 3. Blue} Hue;
弄include <std1o.h>
main()
Hue = 3;
printfC^M', Hue - 4); return 0;
Выполнение программы приведет к выводу числа -1. Кроме перечисленных типов данных в языке Си существуют также указатели. Описание указателей идентифицируется знаком * {звездочка, которая стоит .. перед пересменкой).
Указатель - это переменная, значением которой является ссылка на другой объект. Указатели делятся на указатели переменных и адресные указатели. Первые из них указывают, на переменные, а вторые - локализуют объемы памяти.
Адресные указатели типа (void*) отличаются от других указателей тем, что существует возможность выполнения преобразования указывающего данного, используя оператор указания, записываемый с помощью знака &
{амперсанд). Предполагается, что если ехр - выражение для имени переменной, то &ехр - указатель этой переменной. Из этого правила существует только одно исключение: если ехр - переменная, которая является именем массива, то принимается, что уже сама эта запись указывает на первый элемент массива.
Обратной операции указания (&) является операция нахождения (*). Если ехр - указатель и, следовательно представляет данное, которое указывает на переменную, то *(ехр) - имя указателя. В частности, если Id -идентификатор указателя, то *id - имя переменной, указываемой посредством данного, которое приписано переменной 1Z.
Примеры
прямое указание
include <stdio.h>
int Dec = 10;
int *Ptr = &Dec;
main ()
*Ptr = *Ptr + 3;
printfC % d". *Ptr); return 0;
}
В программе описаны^ переменная Dec типа (int) и указатель Ptr типа (int*).
Переменной Dec присвоено начальное значение 10, а переменной Ptr- указание переменно访 Dec. Запись &Dec представляет указатель переменной Dec, a *Ptr является именем указателя через присвоенное ей значение и, следовательно, в приведенной программе выполняет роль имени переменной Dec.
С учетом этого выполнение оператора
*Prt = *Prt + 3;
дает такой же результат, как и выполнение оператора
Dec = Dec + 3;
а выполнение программы приводит к выводу числа 13.
Косвенное указание
include <stdio.h>
int Dec == 13;
*Ref = &Dec,
**Prt = &Ref;
main()
printf("%dM, **Prt);
return 0;
}
В программе описаны переменные Dec, Ref и Prt соответственно типов (int), (int*) и (int**). Переменной Prt присвоено начальное значение указателя Ref, а переменной Ref - начальное значение указателя Dec. Поскольку после этих присвоений *Prt - имя переменной Ref, a **Ptr - имя переменной Dec, то выполнение программы приведет к выводу числа 13.
Адресное указание
int Dec = 13;
void *Ptr = &Dec;
Указатель Ptr имеет тип (void*).
Этой переменной приписано адресное указание, локализующее ту часть оперативной памяти, откуда начинается резервирование места для переменной Dec.
Описание, блоков переменных
Блоками переменных являются массивы, структуры и объединения. Массивы состоят из компонентов одинакового типа, а структуры и объединения включают в общем случае различные типы компонент. Компоненты массива называются ее элементами^ а компоненты структуры и объединения - полями.
Поскольку компонентами блоков могут быть не только простые переменные, но также массивные структуры и объединения, возможно описание блоков данных большой сложности.
Массивы
Описание массива отличается от описания простой переменной заданием числа его элементов, взятым в квадратные скобки. Это обычно целое число, хотя в общем случае может быть и произвольным константным выражением, величина которого определена перед началом выполнения программы.
Пример
int vec[3];
int агг[3] [2];
Описан массив vec, который является вектором с элементами vec(0], vec[l ] и vec[2] типа (int). Кроме того, описан массив агг, элементами которого являются векторы, состоящие из двух элементов типа (int).
Массив агг можно трактовать как двумерную таблицу (матрицу) с тремя строками и двумя колонками. Обращения к элементам этой таблицы могут, например, иметь вид агг[2][1 ], а не типичный для многих других языков программирования вид агг [2,1 ].
На языке Си запись arr[i,j] эквивалентна записи arr[j] и представляет двухэлементный вектор, образующий j-й элемент вектора агг.
Поскольку образование массивов часто производится с помощью указателей, надо помнить, что если vec ・ произвольный вектор, то имя его i-ro элемента
vec[i]
трактуется точно так, как выражейие
*(vec + i),
которое также может быть принято за имя элемента. Имея это в виду, легко понять, что если агг, например, массив
short int агг[2] [3];
то выражение
*(*(arr+i)+j)
является элементом
arr[i]口].
а выражение
**агг
-элементом
агг[0] [0].
Другой важной особенностью является принятие имени массива за указатель на первый элемент этого массива (исключением является только описанный ниже оператор sizeof). Поэтому, например» если агг - массив с элементами типа (int), то запись агг является указателем, эквивалентным выражению &агг[0] типа (int*), т. е. типа "указание переменной типа intw.
Принимая во внимание вытеизложеяное, можно заключить, что если некоторое данное указывает элемент массива с индексом i, то добавление к нему целого данного величиной j приведет к образованию данного, указывающего на элемент таблицы с индексом i + j. Это подтверждает тесную связь операций с указателями и массивами на языке Си.
Пример
include <stdio.h>
int агг[2] [2] int (*ref)[2j;
main()
агг[1][1] = 13;
ref = агг + 1;
printf('WB (*ref) [1]); return 0;
}
Поскольку запись агг в выражении
ref = агг + 1;
эквивалентна записи &агг[0], а выражение &агг [0 ]十 1 эквивалентно выражению &arrU ], то переменной ref будет приписано значение, величина которого является указанием на вектор, образующий вторую строку таблицы агг.用
После выполнения присвоения выражение *ref представляет собой вектор, указанный через ref, а выражение (*ref) [1 ] представляет собой второй элемент этого вектора, т. е. элемент агг [1 ] [1 ] массива агг.
В описанном случае вызов функции prinlf эквивалентен вызову
prlntffW, агг[1] [1]);
а в результате выполнения программы выводится число 13.
Можно убедиться, что тот же результат дало бы выполнение программы, в которой вызов функции printf имел бы вид
printf(**%d", *(*ref + 1));
или
printf(”%d", ref[0] [1]);
Во всех приведенных выше примерах элементами массивов были переменные типа (int), а также векторы элементов типа (int)« Конечно, элементами массивов могут быть переменные и других типов, в том числе указатели. Это иллюстрирует, например, описание
float *(ptr[4]);
массива ptr, каждый из 4 элементов которого является указателем типа (float).
Поскольку приоритет квадратных скобок выше приоритета оператора 赤 (звездочка), то использованные в приведенном описании круглые скобки могли бы быть опущены. Однако их нельзя опустить, например, в описании простой переменной ref
float(*ref)[4];
так как это приведет к описанию массива, что превратило бы ptr в массив с рассмотренными особенностями.
Структуры и объединения
Особый тип блоков образуют структуры н объединения. В отличие от массивов эти объекты состоят в общем случае из компонент различных типов. Ими могут быть простые переменные, массивы, структуры и объединения, а также рассматриваемые ниже поля битов. Поля структуры размещаются в оперативной памяти одно за другим в той последовательности, в которой перечислены в описании. Поля объединений размещаются, начиная с одного места памяти, и, следовательно, накладываются друг на друга.
Поскольку разница между структурами и объединениями ограничивается способом размещения их полей, в дальнейшем будут рассматриваться только структуры. Типичное описание структуры имеет вид
struct{
fields
}list;
где fields - набор полей структуры, a list - список определяемых одновременно структур, например
struct{
char агг[3][2], *ref, var;
float (*ptr)[4j;
}Str. Vec[5]. *Ref;
В приведенном описании поле arr - двумерный массив, поле ref - указатель типа (char), поле (ptr) - указатель на вектор из 4 переменных типа (float). Из этих полей состоит структура Str, а также каждый элемент массива Vec. Идентификатор Ref определяется как указатель на структуру с данными полями. Это означает, что правильно было бы, например, присвоение
Ref = &Str
в котором & (амперсанд - оператор указания, используемый для определения указания переменной Str.
Поскольку не имеется ограничений на вид полей структур и объединений, правильным, в частности, является следующее описание двух структур Strl и Str2:
struct{
char chr;
struct{
float CompF;
char CoinpC;
}max, min;
short, en;
}Strlf Str2
полями которых соответственно являются: переменная типа (char), две структуры с полями типа (float) и (char), а также переменная типа (short int). Для обращения к переменным типа (float), находящимся в структуре Strl, требуется два раза воспользоваться оператором выбора, например
Strl.max.CompF=Stri.m * n.CompF-3e2;
В некоторых случаях может быть удобным связывание с определенной структурой некоторого идентификатора без описания при этом структуры. Для этого требуется воспользоваться записью-
struct пате{ fields
};
где пате - имя структуры, идентифицирующее ее поля fields.
В рамках такого описания запись
struct name list;
эквивалентна записи
struct{ fields
}list;
Этот способ часто используется для описания тех полей структур, которые определяют указатели идентично описанной структуры, например:
struct tree{
char name [30];
int count;
struct tree *east;
struct tree *west;
str. *ptr;
}
В приведенном описании tree - имя структуры с полями name、 count, east и west, str - структура типа (struct tree), a ptr - указатель на структуру типа (struct tree).
Если будет выполнен оператор
ptr = &str;
то указателю ptr будет приписан адрес структуры str. В этом случае обращение к полю может иметь уже известный вид
(*ptr).count
или эквивалентный ему вид
ptr-> count
В последнем случае используется двухаргументный оператор выбора -> {минус, больше) с целью идентификации полей структуры посредством ука
зателя.
Поля битов
Как отмечалось выше, полями структур могут быть, в частности, поля битов. Хотя правила языка не имеют ограничений на характер этих полей, кроме требования, чтобы они помещались в объеме машинного слова, в типичных применениях поля битов служат для хранения целых данных - чаще типа (unsigned). Описание поля битов состоит из описания поля, его ■ имени и указанного после двоеточия размера поля, например
unsigned status:6;
Если имя поля опущено, то создается скрытое поле. Если размер поля битов представлен числом 0, то следующее поле битов начнется с границы слова. Примером описания структуры, у которой одно из полей является полем битов, может служить следующее описание:
struct{
char chr;
unsigned flag: 1; int value;
}str;
Определение класса памяти
Одним из важных атрибутов объекта языка Си является класс памяти. Он характеризует время существования объема памяти и место хранения объекта в программе.
В языке существуют четыре класса памяти объектов: auto, static, extern и register. Если класс не определен явно, то по умолчанию принимаются класс extern для объектов, описанных вне функций, и класс auto в пределах описания функций. Объекты, описанные внутри блока с классом памяти auto либо без указания класса памяти, относятся к автоматическим объектам. Последние являются локальными по отношению к блоку объектами и хранятся внутри того блока, где они описаны. Автоматические объекты существуют только во время выполнения данного блока и при выходе из блока теряют свои значения и освобождают занимаемую или физическую память.
Классы static и extern касаются объектов, существующих в течение всего времени выполнения программы и хранятся вне любой функции, входящей в состав программы. Разница между ними заключается в том, что объекты класса extern (внешние, глобальные) доступны из всех модулей программы, в то время как объекты класса static (внешние, статические) доступны только в пределах того модуля или блока, в котором были описаны. Константы являются объектами статического класса памяти. Объекты, описанные с классом памяти extern либо описанные вне функции без указания класса памяти, относятся к внешним объектам. Объекты, описанные с классом памяти static, относятся к статическим объектам. Объекты, описанные внутри блока с классом памяти register, называются регистровыми переменными.
Класс register касается тех автоматических переменных, которые должны быть сохранены в регистрах компьютера, а не в оперативной памяти, что ведет к ускорению операций под этими переменными. Поскольку количество
регистров, как правило, ограничено, это требование касается обычно только нескольких переменных. Остальные трактуются как переменные класса auto.
В связи с понятием класса переменной, требуется знать, что описания имеют в общем случае характер обращения или определения. Это имеет- особое значение в отношении переменных класса extern, так как они доступны из всех модулей, в которых были описаны. В этом случае принимается во внимание, что все описания идентификатора связаны с одной переменной. Среди этих описаний в программе должны присутствовать одно главное описание (без слова extern) после определения функций и произвольное число описаний обращения.
Пример
struct list{
char *first_name;
char *last凍ame;
struct list *next;
};
static struct list *var;
Переменная var - простая переменная класса static, указатель на структуру типа (struct list).
Эта переменная создается перед выполнением программы и доступна только в блоке или в модуле, в котором описана.
Если переменная var должна быть доступна в нескольких несвязанных модулях, то в одном из них должно присутствовать ее главное описание, например
struct list *var;
а в других 一 описание обращения
extern struct list *var;
Присвоение начальных значений (инициализация объекта)
Одной из особенностей языка является возможность задания в описаниях инициирующих присваивающих выражений, присваивающих начальные значения переменным во время их описания.
Начальные значения, присваиваемые арифметическим и знаковым переменным, могут быть определены только с помощью - арифметических выражений. Начальные значения, присваиваемые указателям, могут быть определены только с помощью числа 0 или указывающих выражений, которые включают в себя указатели на предварительно описанные внутренние или внешние переменные или указатели, отличающиеся от них на константу.
Если начальное значение не будет определено явно, то внутренним и внешним переменным присваиваются нулевые начальные значения. Остальным переменным будут присвоены неопределенные начальные значения. Следует отметить, что внутренним и внешним переменным начальные значения присваиваются однократно, непосредственно перед выполнением программы, а автоматическим и регистровым переменным начальные значения присваиваются во время каждого описания переменных.
Пример
static char chr[5];
int var = 5;
fun(par)
int per;
{
register int loc = par * par;
, return loc;
}
#1nclude <stdio.h>
main,
auto int val=fun(var~2)+2;
char *ptr=chr+3;
static char *ref= “EWA”,
return 0;
{
Непосредственно перед выполнением программы каждому элементу внутреннего массива chr будет присвоено значение '\0'“ Непосредственно перед выполнением программы внешней переменной var будет присвоено значение 5.
Непосредственно после вызова функции fun регистровой переменной 1ос будет присвоено начальное значение, равное квадрату аргумента. Непосредственно после вызова функции main автоматической переменной ptr будет присвоено значение, указывающее на переменную chr(3 ].
Непосредственно перед выполнением программы внутренней переменной ref будет присвоено значение адреса, указывающего на строку "EWA".
Начальные значения могут присваиваться не только простым переменным, но также массивам и структурам. В этом случае начальные значения компонент определяются с помощью взятого в фигурные скобки списка выражений, разделенных запятыми. Если компонент блока, которому присваивается начальное значение, также представляет собой блок, то его элементы в свою очередь заключаются в фигурные скобки подсписка. Если такой подсписок определяет значения, дающие начальные величины всех составляющих компонент, то их фигурные скобки могут быть опущены. Эти скобки также могут быть опущены, если подсписок не является полным, но за ним нет ни одного выражения, определяющего начальное значение. Однако требуется, чтобы число начальных значений нс превышало числа компонент. Если же оно меньше, то остальным компонентам присваиваются нулевые значения.
Пример
int vec[ ] = {2.3,4};
float arr[3] [2] = {{1, 2}
{3, 4}};
float brr[3] [2] = {1,2.3,4};
short crr[3] [2] = {{l}f {2}. {3}};
Массив vec описывается по умолчанию (по числу инициирующих значений) как vec[3 ]. Массив агг состоит из трех элементов, которые являются векторами. Начальные значения 1 и 2 будут присвоены элементам первого из векторов, а начальные значения 3 и 4 - элементам второго вектора. Элементам третьего вектора будут присвоены нулевые значения. Отсутствие в описании массива агг внутренних фигурных скобок не изменило бы смысла описания. Этот факт использован в описании массива brr.
Во время инициализации массива err начальные значения 1, 2 и 3 будут присвоены первым элементам, составляющим вектор err. Остальным элементам будут присвоены нулевые начальные значения.
Требуется обратить внимание» что проведенное описание массива err аналогично описанию
short сгг[3] [2] = {{1, 0}. {2, 0}, {3, 0}};
а отсутствие 厚 в первоначальном описании внутренних фигурных скобок недопустимо, поскольку привело бы к описанию
short сгг[3] [2] = {{1,2}, {3,0}f {0,0}};
эквивалентному short err [3] [2] = {{1,2}, 3};
Описаниеvтипов
Для описания идентификатора как имени типа необходимо пользоваться обычным описанием с заменой в ней описателя класса ключевым словом typedef. В этом смысле, например, в описании
typedef short 1nt fixed. * pointer;
идентификаторы fixed и pointer могут трактоваться соответственно как ключевые слова, означающие тип (short int) н указывающей тип (short int*). Благодаря этому такое описание, как, например,
short int агг [3], *ref;
может быть представлено в виде
fixed агг[3];
pointer ref;
Описание типов не ограничивается простыми переменными. Легко видеть, что если идентификатор complex означает тип структуры
typedef struct {float re, Im;} complex;
то описание
complex arr[3];.
эквивалентно описанию
struct{float re, 1m;} arr[3]
Области действия и структура программы -
В языке Си с каждым объектом (константы, переменные, массивы, структуры, функции, имена типов н метки) связывается область действия - часть программы, в которой этот объект доступен. С любым объектом языка, кроме константы, связывается идентификатор, обозначающий этот объект. В языке действуют правила, согласно которым любому идентификатору, используемому в некоторой точке программы» однозначно соответствует один объект. Эти правила называются правилами. областей действия объектов. Существует связь между областями действий объектов и структурой программы. Область действия зависит от класса памяти и местоположения описания объекта в программе. Так, область действия объекта класса extern выходит за рамки того модуля, где он был описан, и распространяется на всю программу.
Пример
Программа' размещена в двух модулях, каждый из которых начинается с комментария
/ * modul main * /
char chr;
main()
{
int chr; •
return 0;
}
/ * modul fun * /
fun()
{
extern char chr;
}
Переменная с идентификатором chr типа (char) описана в модуле main, a ее областью действия является тело функции fun.
Переменная с идентификатором chr типа (int) описана в теле функции ,(main) модуля main.
Областью действия первой из этих переменных является внешняя область модуля main, а именно тело функции fun.
Областью действия второй из этих переменных является тело функции main.*
Язык Си в значительной степени является языком выражений. Это следует из того факта, что некоторые операции, например присваивания, не реализуются с помощью операторов, а трактуются как операции с двумя аргументами. Важной особенностью языка является возможность превращения произвольнйго выражения в оператор. Для этого достаточно закончить выражение точкой с запятой. Такой способ чаще всего используется в отнотении операции присваивания, которая в записи, заканчивающейся точкой с запятой, образует оператор, известный из других языков программирования как оператор присваивания. Принципы вычисления значений выражений вытекают из семантики и приоритетов, содержащихся в них операторов, а также из видов использованных аргументов. Если данный аргумент находится в границах более чем одного оператора с одинаковыми приоритетами, то оператбры являются связанными. Большинство операторов связывает аргументы слева направо. Исключения составляют только операторы с одним аргументом и операторы присваивания, а также трехаргументные операторы выбора. Связывание и упорядочивание операторов б очередности уменьшения приоритетов представлены в следующей таблице:
Приоритет151413121110Приоритет151413121110СвязываниеЛевое Правое ЛевоеСвязываниеЛевое Правое Левое987654321987654321ОператорОператор* & sizeof* & sizeof& &I I?:=+=-=*=/=%=»=v <=&=%=:=,& &I I?:=+=-=*=/=%=»=v <=&=%=:=,ПравоеЛевоеПравоеЛевое
Приоритет
15
14
13
12
11
10
Приоритет
15
14
13
12
11
10
Связывание
Левое Правое Левое
Связывание
Левое Правое Левое
987654321
987654321
Оператор
Оператор
* & sizeof
* & sizeof
& &
I I
?:
=+=-=*=/=%=»=v <=&=%=:=,
& &
I I
?:
=+=-=*=/=%=»=v <=&=%=:=,
Правое
Левое
Правое
Левое
Если приоритеты и связывания однозначно не определяют очередности выполнения операции, то она может быть произвольной, а выражения, записанные с помощью действий (*, +, \ I), могут быть преобразованы в эквивалентные математические выражения даже с опусканием скобок. Решение вопросов, связанных с неопределенностями, как, например, деление на нуль, осуществляется в процессе реализации программы. При составлении правильного выражения необходимо определить способ его интерпретации. Это зависит от принятых в языке приоритетов и связей операторов.
Операции, связанные с операторами внешнего приоритета, выполняются в первую очередь. Если некоторый аргумент операции касается двух операторов одинакового приоритета, то очередность выполнения операции определяется по связыванию.
Использование приоритетов и связываний операторов дает возможность во многих случаях убрать из выражений лишние круглые скобки, в частности правильным является выражение
a- = b = -cz + d-e.
В этом выражении с аргументом "с" связаны два оператора одинакового приоритета: оператор смены знака (-) и оператор постинкремента (+ +). Поскольку связывание этих операторов правостороннее, рассматриваемое выражение будет трактоваться как
а -= Ь = ('(с++)) + d - е.
Поскольку приоритеты операторов сложения (+) и вычитания (-) выше, чем у оператора присваивания (=«), можно сделать запись с дополнительной парой скобок
а -= b = ((~(a+))+d - е).
вычитания (-) связывают выражение интерпретируется :
а -= Ь = (((-(с++)) + $- е).
Операторы присваивания
следовательно, окончательный
а -= b = -C++ + d - е
интерпретируется как
(а -= (ь = (((-(с++)) + d) - е:
Примеры
а) Поскольку связывание
(минус) левостороннее, то вы]
а - Ь * с
трактуется как выражение
(а - Ь) + сг
а не как выражение
аргументы левосторонне, то рассматриваемое как выражение
связывают свои аргументы правосторонне, вид первоначального выражения
двухаргументных операторов + (плюс) и - ражение
Операции сложения (+) и вычитания (-), входящие во внутренние скобки, имеют равный приоритет. Поскольку операторы сложения (+) и
66Часть II. Язык
а - (Ь + с)
Поскольку связывание трехаргументного оператора ?: {вопросительный знак, двоеточие} правостороннее, то выражение
a?b:c?d:e:f
трактуется как выражение
а ? Ь : (с ? d : е) а не как выражение
(а ? Ь : с) ? d : е
Первичные ^выражения и /-выражения
Выражения состоят из аргументов и операторов. Операторы делятся на одно~, двух- и трехаргументные, а грамматический разбор выражения приводит к выделению в нем первичных выражений, к которым относятся
Идентификатор
Литерал • (Выражение) Первичное выражение [выражение] Первичное выражение (список аргументов) Первичное 1-выражение, Идентификатор Первичное выражение -> идентификатор
Использованное в приведенном списке определение 1-выражения касается выражений, представляющих объекты, которым могут быть присвоены значения. Согласно определению языка Z-выражениями являются
Идентификатор
Первичное выражение [выражение]
Первичное 1-выражение. Идентификатор
Первичное выражение -> идентификатор * выражение (1~ выражение)
Выражениями в широком значении являются
Первичное выражение
* выражение I-выражение -выражение + выражение / выражение ~ выражение•
++ I-выражение
—1-выражение 1-выражение ++
sizeof (имя типа)
sizeof выражение
(имя типа) выражение
Выражение оператор - двухаргументное выражение
Выражение ? выражение ; выражение
В данном определении двухаргументный оператор относится к операторам, выражающим операции
Арифметические Сравнения Логические Битовые Переносов Присваивания СвязиАрифметические Сравнения Логические Битовые Переносов Присваивания Связи♦ / % + - <> V =>■ ЯСН
Арифметические Сравнения Логические Битовые Переносов Присваивания Связи
Арифметические Сравнения Логические Битовые Переносов Присваивания Связи
! && I I
« »
н +н — *■ /= %Н >>=»«= &н " ■ N
На основе приведенного списка, а также принимая во внимание факт, что лексической единицей признается наибольший ряд знаков, можно сделать вывод о - правильности и значении отдельных выражений, если только известна интерпретация первичных выражений.
Идентификатор
Идентификатор является первичным выражением, тип которого следует из описания. Если идентификатор представляет собой имя массива, то он является не Л-выражением, а выражением указывающего типа, представляющего указатель на первый элемент массива. Аналогично трактуется идентификатор функции, который является не /-выражением, а выражением, указывающим на функции.
Пример
extern fun()
1fun()
1nt arr[3];
*ref=arr;
finclude <stdio.h>
main()
{
1nt var dun (ifun);
return 0;
}
Начальное значение переменной ref есть указатель на первый элемент массива агг.
Если имя массива не было отлично от других идентификаторов, то правая сторона присваивания должна была иметь вид &агг[О ].
В описании
int var = fun(lfun)
первичное выражение ifun трактуется аналогично агг, т. е. запрещено использование перед ним оператора & {амперсанд}.
Арифметический литерал
Арифметический литерал является первичным выражением, тип которого следует из записи литерала. Знаковые литералы - это выражения типа (int), а литералы с плавающей точкой без приращений - выражения типа (double).
Пример
float var = 5 + '\20' + 2е0;
Литерал 5 *имеет тип (int).
Литерал '\20' имеет тип (int).
Литерал 2е0 имеет тип (double).
Выражение с правой стороны символа присваивания имеет тип (double) и величину 23.
Строчный литерал
Строчный литерал является первичным выражением, которое имеет тип (char[ 1), но аналогично идентификатору, который представляет имя массива, трактуется как указатель на элемент типа (char).
Пример
char ewa[ ] = "izunla",
*jan = "izunia”;
Литерал “izunia" при инициализации переменной ewa образует удобное сокращение от
{ 丁,’z', Н, if, Т, 0, '\0'}
Литерал "izunia" при инициализации указателя jan дает указание на первый знак строки, состоящей из знаков izunia и знака нуль»
{Выражение) - первичное выражение того же типа, что и выражение в скобках. Если выражение, находящееся внутри скобок, - /-выражение, то и рассматриваемое первичное выражение является /-выражением
Пример
int var- х, var— у
*ptr =&var—х;
*ref =&var—y;
*(ref = ptr?ref:ptr>=5;
Выражение в скобках не является первичным. После заключения в скобки оно становится первичным, но не /-выражением.
3. Выражения69
После использования операции * (звездочка) левая сторона оператора присваивания становится /-выражением. Выполнение приведенного оператора дает в данном случае такой же результат, как выполнение оператора
var_x=5;
Первичное выражение [выражение ]
эквивалентно по определению выражению
* ((первичное выражение + (выражение))
и, следовательно, несмотря на асимметрию, индексация является переменной операцией. Необходимо, чтобы выражение во внутренних круглых скобках было указателем.
Пример
char агг[4] [4];
агг[2] [3] =,Е]
Выражение оператора присваивания интерпретируется как
(агг[2]) [3]=・Е'.
а затем как выражение
(*(агг+2))[3] ='Е'.
а также как выражение
*(*arr+2)+3) = 'Е'.
В каждом из рассмотренных примеров выражение с левой стороны оператора присваивания является /-выражением.
Первичное выражение (список аргументов)
первичное выражение, представляющее название функции. Первичное выражение в названии должно быть указателем функции, а взятый в круглые скобки список выражений в общем случае может состоять из стольких выражений, сколько параметров насчитывает вызываемая функция*
Пример
extern fun();
struct{
Int (*sub)();
char chr;
}str = {fun, 'A'}
str.chr = (*str.sub) (2+str.chr);
В операторе присваивания имеется вызов функции fun с аргументом 2 + str.chr.
В этом операторе str.sub представляет поле структуры str, которому могут быть присвоены показатели функции, дающие результаты типа (int), а следовательно, указатель функции fun.
Первичное 1-выражение • идентификатор
первичное выражение, представляющее поле структуры или объединения.
Выражение перед знаком . (точка) должно представлять структуру или объединение, а идентификатор должен быть идентификатором их пола.
Пример
struct {
char chr;
Int tally;
}str = {*j*};
*ptr = &str;
putchar((*pt?). chr);
В рассматриваемом случае (*ptr) - /-выражение, представляющее структуру str, a chr - идентификатор ее поля. Выполнение оператора приводит к выводу знака 了.
Первичное выражение -> идентификатор
первичное выражение, представляющее поле структуры или объединения. Выражение перед символом -> должно представлять указатель структуры или объединения, а идентификатор должен быть идентификатором их поля. По определению принимается, что выражение
Указатель -> Поле
эквивалентно выражению
(* Указатель) . Поле
Пример
union{
char nam, fam;
}var. *ptr = 8tvar;
ptr -> nam = *j*;
ptr -> fam = 'b*;
Выражение ptr->nam представляет поле nam объединения var. После выполнения второго присвоения данное, находящееся б поле, имеет величину
Арифметические операторы
Арифметические операторы служат для описания арифметических действий: замена знака (-), инкремент (++), декремент (—), сложение (+), вычитание (-), умножение (*), деление </), а также обозначение остатка от деления (%). Операторы замены знака, инкремента и декремента - одноаргументные (унарные), а их использование приводит соответственно к смене знака аргумента, добавлению к аргументу числа 1 и вычитанию из аргумента числа 1. Если аргумент операции замены знака имеет тип (unsigned), то замена знака реализуется путем вычитания аргумента из числа 2n, itk п - число битов, используемых для представления данных типа (int). Инкремент и декремент означают соответственно увеличение и уменьшение на 1 и относятся только к аргументу, имеющему вид /-выражения. В случае преинкремента + + arg результатом операции является arg + 1. В случае постинкремента arg + + результатом операции жляется arg.
Аналогичные правила относятся к декременту.
Примеры
Замена знака
int var_i=~536;
,unsigned int var_u = -536;
Переменной var_i будет присвоено начальное значение -536.
Переменной var_u будет присвоено начальное значение 65000.
Инкремент и декремент арифметических переменных
#include <stdio.h>
int arb: main() { a=3; b=6;亠
printfCW, ++a+b—); prlntf('Wt a); printfCXd'*, b);
return 0;
Результатом операции ++a будет величина 4, а операции b— - величина 6.
После выполнения программы будут выведены числа 10, 4 и 5. Если первому вызову функции printf придать вид
printf("%d'\ а++ + —Ь);
то в результате выполнения программы будут выведены числа 8, 4 и 5.
Остальные арифметические операторы являются двухаргументными и служат для выполнения основных арифметических действий, а также для обозначения остатка от деления первого аргумента на второй. Деление целых аргументов приводит к отбрасыванию дробной части результата. В случае обозначения остатка от деления знак результата совпадает со знаком делимого и, кроме этого, справедливо равенство
72Часть 〃. Язык
(a/b) * Ь+ а%Ь=а
Важной особенностью языка является возможность выполнения арифметических действий (сложения и вычитания, в особенности инкремента и декремента) с указателями. В общем случае эти действия имеют смысл тогца, когда указатели относятся к одному и тому же массиву. Если величиной ref является указатель на /-й элемент некоторого массива, а п - целое арифметическое выражение, то значением суммы
ref + п
является указатель на а + п)-й элемент этого массива. Если ref и ptr - соответственно указатели на элементы Z и / некоторого массива, то величина разности
ref - р>
равна разности
Следует отметить, что вычитание указателей является правильным действием, а сложение не имеет смысла, коща отсутствуют данные типа сумма указателей. С этой точки зрения, если необходимо, например, найти указатель на элемент массива, равноудаленный от элементов, представленных указателями ref и ptr, то вместо неправильного выражения
(р> +,е/)/2
надо воспользоваться выражением
(р> - ref)/2 + ref
(естественно, такой элемент будет равноудаленным только в том случае, кода разница в скобках четная).
Примеры
Инкремент и декремент указателей
int агг[2] = {2, 3}.
*ref = агг;
--*ref ++;
Приведенный оператор эквивалентен оператору
—(*ref++ ));
Его можно также представить в виде пары операторов
--(*ref); ref++;
Двухаргументные операции над указателями
float агг[8];
*ptr = агг+3;
fun(*ptr+2));
Если переменная ptr сохранила присвоенное ей начальное значение, то рассматриваемый оператор выполняется как оператор
fun(arr[5]);
При тех же условиях выражение
агг - ptr
(в котором агг представляет указатель на элемент агг[0], a ptr - указатель на элемент arr[3 J) имеет значение -3.
Операции с двумерными массивами—
float агг[2] [2] = { {1, 2}, {3,4}}. (*ref)[2] = агг, var;
var н (*++ref)[0];e
Переменная ref описывается как указатель на первый элемент массива (♦ref)2 типа (float). Начальным значением, присвоенным переменной ref,, является указатель на первый из двух векторов массива агг [2 ]. Оператор присваивания может быть представлен посредством двух операторов
++ref;
var н (*ref)[0];
В данном случае второй из этих операторов может быть заменен оператором
var н агг[1] [0];
и, следовательно, оператором var = 3;
Операторы сравнения
Операторы сравнения служат для описания следующих действий: равно (==), не равно (!=), меньше (<), больше (>), меньше или равно (v:> и больше или равно (>=). Результатом сравнения является данное типа (int), принимающее значение 0 при невыполнении условия сравнения (условие ложно) и значение 1 при выполнении условия (условие истинно). Если какой-либо из аргументов сравнения имеет тип (char), то он подвергается преобразованию в тип (int). Если какой-либо из аргументов является
указателем, то он может сравниваться только с аргументом того же типа, указывающим на некоторый элемент того же массива или с литералом О, представляющим пустой указатель.
Примеры
Сравнение арифметических величин
float var_ s » 1.0/3.0;
double var_ d =1.0/3.0;
short int flag =var_d> var_ s;
В случаях когда величины типа (float) и (double) имеют разные представления (как это, в частности, имеет место в Турбо Си), переменной flag будет присвоено начальное значение 1. В остальных случаях этой переменной будет присвоено начальное значение 0.
Сравнение указателей
float агг[4];
*ptr =агг+2;
short int flag = ptr !=arr;
Переменной flag будет присвоено начальное значение 1.
Логические операторы
Логические операторы служат для описания следующих действий: инверсии (!), конъюнкции (&&) и дизъюнкции (::). Первый из перечисленных операторов является одноаргументным, а два других - двухаргументными. Во всех случаях результатом операции будет данное типа (int) со значением 0 (нуль) или 1 (истина). Результатом инверсии будет значение 1, если аргумент имел значение 0, и наоборот. Результатом конъюнкции будет 1, если аргументы имеют значения, отличные от нуля, или 0 в противном случае. Результатом дизъюнкции является значение 1, если по крайней мере один из аргументов отличен от нуля, или 0 в противном случае. Следующий список дает определение логических операторов:
ОперацияОпределение
а && b а II bа && b а II bа == 0
а && b а II b
а && b а II b
(!!а) + (!!b) > 1
(!!а) + (!!b) > 0
В отличие от рассмотренных двухаргументных операций, операции конъюнкции и дизъюнкции всегаа выполняются в очередности слева направо, значение аргумента b обозначается толькр тогда, когда на основе значения аргумента а нельзя сделать вывод о результате операции. В отношении оператора конъюнкции можно показать, что оператор
if(expl)if(exp2)Ins
5. Выражения по существу выполняется как команда.
Пример
int var, * ptr;
var 工! ptr == var :; var== 0;
Приведенный оператор интерпретируется как оператор var « ((( ! ptr == var) !! (var ==0));
5・5. Битовые операторы
Битовые операторы служат для описания следующих действий: отрицания битов (~), конъюнкции битов (&), u Исключающие ИЛИ" С) и дизъюнкции (I). Первый из перечисленных операторов - одноаргументный, а остальные - двухаргументные. Аргументы битовых операций могут быть только целого типа. Результат операции также имеет целый тип. Результатом отрицания битов является единичное дополнение аргумента. Результаты конъюнкции м Исключающее ИЛИ" и дизъюнкции получаются путем поразрядных (побитовых) действий. Результатом конъюнкции является логическое произведение битов, результатом мИсключающего НЛИ" - сумма битов по модулю два, а результатом дизъюнкции ~ логическая сумма битов.
Примеры
Отрицание битов
int а = -2;/* Ш1..Л110*/
int res = ~а;/* 0000...0001*/
Переменной res присваивается начальное значение 1.
Конъюнкция битов
int а = 10/*0000...1010*/
b = 12;/*0000...1100*/
int res = a&b;/*0000...1000*/
Переменной res присваиваетсяначальноезначение 8.
Исключающее ИЛИ
int а = 10/*0000...1010*/
b = 12;/*0000...1100*/
int res = a^b/*0000...ОНО*/
Переменной res присваивается начальное значение 6.
Дизъюнкция битов
int а = 10int а = 10〃 0000... 1010 */〃 0000... 1010 */
int а = 10
int а = 10
〃 0000... 1010 */
〃 0000... 1010 */
b = 12;/* 0000... 1100 */
int res = a|b;/* 0000... 1110 */
Переменной res присваивается начальное значение 14.
5-6- Операторы сдвига
Операторы сдвига служат для сдвига битов аргумента влево (<<) или вправо (») на заданное число позиций. Операции сдвига являются двухаргументными. Левый аргумент подлежит сдвигу, а правый - определяет число битов, на которое необходимо произвести сдвиг. Оба аргумента должны быть целыми, а результат - того же типа, что и левый аргумент.
Результат операции неопределен, если правый аргумент имеет отрицательную величину или превышает число битов, представляющих левый аргумент. Во время сдвига влево происходит дополнение нулями справа. Во время сдвига 補 вправо дополнение нулями происходит только в том случае, кстща левый аргумент имеет тип (unsigned). В остальных случаях определение того, какого вида сдвиг: логический (дополнение нулями) или арифметический (дополнение битом знака), производит система.
Внимание: В Турбо Си используется арифметический сдвиг!
Примеры (данные типа (int) занимают по 2 байта).
Сдвиг вправо
unsigned а = -2;/* 1111 ... 1110 */
int res = а » 14;/* 000 ... ООП */
Переменной res будет присвоено начальное значение 3.
Сдвиг влево
int а = -2;/* 1111 ... 1110 */
int res = а « -а;/* 1111 ... 1000 */
Переменной res будет присвоено начальное значение -8.
Операторы "доступа по указателю (*]" и "указатель (&)"
Операторы (•) и (&》являются одноаргументными. Первый из них относится только к указателям, а второй - только к 1-выражениям. Результатом операции (*) является значение переменной, на которую ссылается данный указатель, результатом операции является получение указателя на некоторый объект (адрес объекта).
Примеры
Использование оператора ⑴
#include <stdio,h>
main()
static char arr[ ] = ”123456789".
*ptr = '•123456789";
printfCW, *(arr +2));
printf”,*ptr);
return 0;
}
Запись агг+2 представляет собой указатель на элемент агг [2] массива агг. Запись * (агг+2) представляет собой само значение этого элемента. Запись ptr указывает на первый элемент массива, состоящего из знаков Т, 2, 3 и т.д. Запись *ptr предствляет данное 'Г. Выполнение программы приводит к выводу кодов знаков '3' и Кодами ASCH этих знаков являются числа 51 и 49.
Использование оператора (&)
int агг[2] [2];
В приведенном описании выражение **агг эквивалентно выражению агг[0] [0] и представляет элемент агг [0] [0] массива агг. В отличие от правильного выражения **агг выражение &*агг неправильное. Это следует из того, что запись *агг представляет собой массив, а следовательно, не жляется 1-выражением и не может быть аргументом оператора (&).
Операторы присваивания^
Оператор присваивания может быть простым и составным. Простая операция присваивания - двухаргументная операция вида
刃ееа兄 сторона = "раса兄 сторона/
В этой операции левая сторона является /-выражением, а правая - выражением, которое всегда преобразуется к типу левой стороны. Выполнение операции присваивания приводит к присваиванию представленной /-выражением переменной значения выражения, стоящего с правой стороны оператора присваивания. Результатом операции является значение правой стороны оператора. Если при выполнении операции присваивания необходимо преобразование данных, то вступают в силу следующие правила:
преобразование короткого целого данного со знаком в длинное целое данное со знаком (например, signed char в long int) производится с сохранением значения данного;
преобразование короткого целого данного со знаком в длинное целое данное без знака (например, signed char в unsigned long) производится в два этапа - сначала в длинное целое (long int), а затем в длинное целое без знака;
преобразование короткого целого данного без знака в длинное целое (например, unsigned char в long int) производится с сохранением значения данного;
преобразование целого длинного данного в целое короткое производится с потерей не помещающихся старших битов;
преобразование данного с плавающей точкой (например, float) в данное целого типа (например, unsigned char) производится с сохранением значения,
но после отбрасывания дробной части;
преобразование одного данного с плавающей точкой в другое данное этого же типа производится с сохранением значения;
преобразование одного указателя в другое данное этого же типа возможно только тогца, когда одно из данных имеет тип (void*) или когда преобразуемым данным является пустой указатель; в остальных случаях следует применять явные операторы преобразования.
Примеры
При следующих описаниях:
int 1;
short si;
unsigned ui;
float f; »
double d;
список операторов присваивания эквивалентен списку
i = -12,9;1 e -12;
f = 5;f = 5,0;
si =,\377•产si=-1;
si ='\177';si=127;
ui =-32768;ui=32768;
Кроме простого присваивания, в языке Си есть составные присваивания вида
е/ ор= е2;
в которых е/ м е2 - выражения, а ор= - один из следующих двухаргументных операторов:
+=7 *= /= %= >>= «= &=人=| =
Составное присваивание выполняется как присваивание
(el)=((el) ор (е2)).
Оператор
arr[var++] +=2;
реализуется не как оператор
arr[var++] = arr[var++] + 2.
а как пара операторов'
arr[var] += 2;
var++;
(принимается, что var - имя простой переменной, а агг - имя массива).
Пример
float агг[4]*
*ptr=arr +2;
*ref ;
ref н ptr +* 1;
Приведенный оператор присваивания эквивалентен оператору
ref н (ptr « ptr+1);
В результате выполнения этого оператора переменной ref, как и переменной ptr, будет присвоен указатель на последний элемент массива агг.
Условный оператор
Условная операция выражается с помощью трехаргументного оператора ?: и в общем случае имеет вид
el ? е2 : еЗ;
где el, е2 и еЗ ^ выражения.
Выполнение условной операции начинается с анализа значения выражения е/. Если оно отлично от нуля (условие истинно), то вычисляется выражение е2. Если значение условия (выражение е/》равно нулю (ложно), то в качестве значения всего условного выражения вычисляется третье выражение (еЗ). Всегда вычисляется только одно из двух выражений, разделенных двоеточием.
Поскольку результат условной операции не представляет собой Z- выражение, то условная операция не может выступать в качестве левой стороны оператора присваивания.
Пример
int a.b,ct var;
vai* = a>b ? (a>c ? a : c):(b>c? b:c);
Переменной var будет присвоено значение max (a,b,с).
Оператор соединения
Операция соединения выражается с помощью двухаргументного оператора соединения и в общем случае имеет вид
Зе е/ и е2 - выражения.
Сначала вычисляется левое выражение, затем правое. Результатом операции соединения являются значения и тип второго (правого) выражения е2. В контексте, где лексическая единица ",“ {запятая имеет специальное значение, как, например, в списке аргументов обращения к функциям, она не принимается в качестве оператора соединения.
Пример
int a.b*c»d; extern fun();
fun(2+ (a == btb : -а)Дс = 5t d + 2));
В приведенном операторе имеет место выход функции fun с двумя аргументами.
Если во время выполнения оператора, например, выражение а == b истинно, то результат выполнения равен выполнению двух операторов
с = 5;
fun(2 + b, d + 2);
Если в рассматриваемом операторе были опущены внутренние круглые скобки, т. е. если вызов имел вид
fun(2 + а == b ? b : -а『с = 5, d + 2);
то была вызвана функция трех аргументов.
Если во время выполнения такого оператора выполнялось действие а — Ь, то результат равнялся выполнению двух операторов
fun(-a, 5, d + 2);
Оператор преобразования
Операция преобразования выражается с помощью одноаргументного оператора преобразования и в общем случае имеет вид
,type)expf
где type - имя типа, а ехр - выражение. Результатом преобразования является значение выражения ехр, преобразованное к типу (type).
Примеры. Обозначения типов
Имя типаМнтЕрпрета^ия
Тип (int)
int *int *[4]int (ф) [4 ] int ♦()int *int *[4]int (ф) [4 ] int ♦()Массив переменных типа (int)
int *
int *[4]
int (ф) [4 ] int ♦()
int *
int *[4]
int (ф) [4 ] int ♦()
Указатель типа (int)
Массив указателей типа (int)
Указатель на массив переменных типа (int)
Функция, результатом которой является указатель
типа (int)
int (*)( )Указатель на функцию, результатом которой является
переменная типа (int)
int * (*)( )Указатель на функцию, результатом которой являются
данные типа (int)
Способ интерпретации некоторых преобразований, касающихся указателей, зависит от реализации системы. Определение языка гарантирует выполнимость преобразования указателя в целую величину соответствующего размера (например, long int). Целое данное также может быть подвергнуто преобразованию в указатель. Всегда можно преобразовать указатель некоторого объекта, имеющий особые требования к способу размещения в памяти, в указатель объекта с меньшими требованиями к размеру памяти. В этом случае выполнимо также обратное преобразование, которое восстанавливает первоначальный указатель. Имея в виду эти принципы, можно, в частности, определить функцию
set(adr, chr) unsigned adr; char chr;
{
*(char *)adr = chr;
}
которая, получая адрес байта в памяти и символ, помещает его в данном байте. Например, выполнение инструкции
set(200, 'j');
приводит к размещению символа 了 в байте с адресом 200. Однако не в каждой системе такбе действие будет правильным. В Турбо Си указанное действие справедливо.
Примеры
Преобразование аргумента 6 вызове функции
int fun(par) float par;
return par+2;
}
auto var sfun((float)5);
Переменной var будет присвоено значение 7. Отсутствие оператора преобразования перед литералом 5 привело бы к совпадению с параметром типа (float) аргумента типа (int), что недопустимо.
Преобразование указателей
int агг[ ] [2] = {1,2,3,4}; float var;
6—764
var * -*(int *) arr;
Переменной var будет присвоено значение -1,0. Массив агг имеет тип (int [2 ] [2], а идентификатор агг в выражении представляет данное типа (int (*) [2 ]).
Отсутствие оператора преобразовани янедопустимо, поскольку это
превращает оператор присваивания в ошибочный.
var = -&агг[0] [0];
Оператор размера
В общем случае одноаргументный оператор размера sizeof имеет вид
sizeof exp
или
sizeof(fype),
тде exp - выражение, a type - имя типа.
Результатом оператора размера является значение, которое определяет размер аргумента. Байт - это единица размера данных типа (char).
Примеры
Определение размера массива
int агг[4],
var = sizeof агг;
Если переменная типа (int) представлена в 2 байт каждая, то весь массив агг занимает 8 байт, и таким образом переменной var будет присвоено значение 8.
Определение размера данных принятого типа
int var = sizeof(char) + 5;
Переменной var будет присвоено значение 6. Поскольку оператор sizeof(char) имеет более высокий приоритет, чем оператор + (плюс), то приведенное описание не интерпретируется как
int var = sizeof((char)+5);
Обработка выражений
Принципы обработки выражений следуют из приоритетов и связей операторов, а также из семантики отдельных операций. Необходимо принимать во внимание неявные преобразования, которые могут возникнуть при
一 выполнении операций с указателями, например
int arr[4], *ptr = arr;
ptr++;
выполнении присваиваний, например
float f 工 12.4;
int 1;
i = f;
обозначении аргументов в обращениях к функции, а также приведении в соответствие с типом функции в операторе return;
выполнении арифметических операций с данными различных типов, например
putchar(*(“Jan ” +2));
Поскольку преобразования в двух первых случаях уже были рассмотрены, а преобразования, связанные с вызовами функции, будут рассматриваться особо, рассмотрим преобразования при выполнении арифметических операций. Эти преобразовани я, называемые типовыми арифметическими преобразован иями, выполняются в два шага:
сначала аргументы типов (char), (unsigned char), (signed char) и (short) преобразуются в тип (int), а аргументы типа (float) - в тип (double);
затем выполняются преобразования, определяемые списком
Тип аргумента
Преобразование второго аргумента
(long double) (double) (unsigned long) (long) (unsigned int)
(long double) (double) (unsigned long) (long) (unsigned int)
Внимание: Принятые в Турбо Си принципы выполнения приведенных типовых арифметических преобразований несколько отличаются от принципа стандарта ANSI. В частности, преобразование аргумента типа (float) к типу (double) выполняется не всегда, а только то叫а, когда второй аргумент выражения имеет тип (double). Однако в стандартных программах эта разница не имеет существенного значения.
Примеры
Использование связей
struct { int *val; int (*ptr)[2];
} str[4], *ref;
*str[3]. val = *ref -> ptr ++ || *(ref++)-> ptr;
,84Часть 11. Язык
Приведенный оператор трактуется как
*((str[3]). val)« ((*((ref-> ptr)++))||
(*((ref 心> ptr)));
Обработка выражения левого аргумента дизъюнкции приводит к инкременту переменной ref-> ptr после предварительного доступа к величине, указанной этой переменной.
Обработка выражения правого аргумента дизъюнкции приводит к инкременту переменной ref после предварительного доступа к величине, указанной посредством ref -> ptr.
Использование преобразования
char Chr;.
short int SHI;
unsigned Uns;
double Db1;
extern fun ();
fun(12.4, (Chr + SB)* Uns - Dbl /12L);
Требуемые преобразовани я могут быть выражены явно с помощью операторов преобразования
fun((double)12.4,
(double)(unsigned)((1nt)Chr+(int)Shi)* Uns) - Dbl / (double)12L);
Как можно убедиться, аргументы суммы будут преобразованы к данным типа (int), а поскольку правый аргумент умножения имеет тип (unsigned int), то сумма будет преобразована к данному типу (unsigned int). Псюкольку левый аргумент операции деления имеет тип (double), то правый аргумент будет преобразован к данному типа (double). В операции вычитания вычитаемое преобразуется к величине типа (double).
Если принять, что последним выполняемым оператором функции fun является
return par;
где par имеет тип (double), то, поскольку подразумеваемым типом результата функции является (int), этот оператор будет выполнен как
return (int)par;
Псюкольку вызову функции придан вид оператора выражения, это данное во внимание не принимается.
6. Операторы
Операторы делятся на три группы:
операторы-выражения;
пустые операторы и блоки;
операторы, начинающиеся с ключевого слова.
Перед каждым оператором может находиться метка или список меток. Метка от оператора или от другой метки отделяется знаком ":" (двоеточие). Поскольку использование метки связано с применением оператора перехода (goto), которого из-за ухудшения читаемости программы следует избегать, в приведенных ниже примерах метки не будут обозначены.
Примеры
Оператор-выражение
а = b + 2, b = с - 3;
Оператор, начинающийся с ключевого слова
if(a = b)
а = 2;
else
b = 2;
Оператор-выражение
Оператор-выражение имеет вид
Ехр;
Гце Ехр - произвольное выражение.
Выполнение оператора-выражения состоит в вычислении выражения с последующим отбрасыванием вычисленного значенйя. Частным случаем оператора-выражения является оператор присваивания^ например
а ■ b = 13;
Пример
2 + (Count = printf(иHello^^);
Выполнение оператора-выражения приводит к вычислению величины 7 и к ее отбрасыванию.
Побочным результатом выполнения приведенного оператора является вывод надписи “Hello" и присвоение переменной Count величины 5 (равной числу выведенных знаков).
Пустой оператор
Этот оператор имеет вид
а его выполнение ие дает никаких результатов.
Пустой оператор удобно использовать для помещения метки в конец блока при использовании его вместо более сложного оператора, который будет добавлен в программу в будущем и т.д.
Пример
Простая программа
main( ) { return 0;
Оператор перехода
Этот оператор имеет вид
goto Lz5;
тде Lab - метка оператора. Поскольку диапазоном действия метки является функция, в которой описана данная метка, выполнение оператора не приведет к переходу вне границ функции.
Пример•
main()
{goto Lab;} lab:;
return 0;
}
Выполнение оператора goto приводит к переходу на выполнение пустой инструкции, обозначенной меткой lab.
Блок
Блок - составной оператор, имеющий вид
{Deci Ins}
Операторы, содержащиеся в списке, выполняются один раз в порядке их следования по списку. При обработке списка описания блоков происходит описание переменных класса auto и register, а также присваивание им начальных значений с помощью инициирующих выражений. Во время выполнения операторов - блока до момента завершения переменные,
описанные вне данного блока, с идентичными именами будут недоступны в этом блоке.
Пример
•Include <stdio.h>
main()
char Chr = *j*;
char Chr = 'b‘;
putchar(Chr);
}
putchar(Chr);
return 0;
}
Тело функции main состоит из блока, в котором находятся описание переменной Chr, внутренний блок, вызов функции putchar(Chr) и оператор return. Во внутреннем блоке описывается переменная Chr, и далее выполняется функция putchar(Chr);
Во время обработки описания происходит создание автоматической переменной Chr и присвоение ей начального значения 'Ь'. Поскольку имя Chr, использованное во внутреннем блоке, совпадает с именем Chr, описанным в блоке, охватывающем этот блок, то переменная Chr недоступна в пределах внутреннего блока. После выполнения действий во внутреннем блоке происходит удаление локальной переменной и открывается доступ к переменной, описанной во внешнем блоке. В результате выполнения программы выводится надпись bj.
Условный оператор
Этот оператор имеет вид (I форма)
讦(田屮)
〃lSp else
или (II форма)
讦(Exp) /"Sp
что эквивалентно оператору
if(Exp)
/"Sp
else
Выражение в скобках Ехр является условием. Если его значение не равно нулю (истинно), то выполняется оператор Insp9 в противном случае если условие равно нулю (ложно), то выполняется оператор Ins^ (для I формы оператора) или выполняется очередной оператор программы (для II формы). Если условный оператор содержит другие условные операторы, то слово else соотносится с ближайшим ключевым словом if, еще не связанным ни с каким ключевым словом else.
Пример
if(a == b). if(а == 0) b = 2; else a = 2,
Приведенный условный оператор выполняется не как оператор if(a == Ь),
if(a == 0) b = 2;
} else
a = 2;
а как оператор if(a == b),
{
if(a == 0)
b = 2;
else a = 2 }
. Операторы цикла
Существуют три формы оператора цикла. Их семантика выражается с помощью условных операторов и операторов перехода.
Оператор while
Этот оператор имеет вид
while (Ехр)
Ins
где Ехр - выражение, a Ins - оператор и выполняется как
Lab: if(Exp){
Ins goto Lab; }
Иначе говоря, оператор [ns выполняется до тех пор, пока условие, определяемое выражением Ехр, отлично от нуля, т. е. истинно. Вычисление значения выражения производится перед каждым выполнением оператора.
Пример
char *Ptr = "Jan Bielecki";
•include <stdio.h>
ma1n()
while(*Ptr)
printf("%c, *Ptr++); return 0;
Выполнение программы приводит к выводу надписи Jan Bielecki.
Оператор do
Этот оператор имеет вид
do
Ins
while (Exp);
где Ins - оператор, a Exp - выражение. Он выполняется следующим образом:
Labt Ins 仟(£хр) goto Lab;
Оператор Ins выполняется до тех пор, пока выражение Ехр истинно. Выражение и анализ значения выражения производятся после каждого выполнения оператора.
Пример
char *Ptr м "Jan Bielecki"
#include<stdio.h>
main()
do
printf("%c".*Ptr);
wh1le(*++Ptr);
return 0;
}
Выполнение программы приводит к вводу надписи Jan Bielecki.
Оператор for
Этот оператор имеет вид
for(£xpfl; Ехр; Ехр»
Ins
где Ехр - выражение, a Ins - оператор. Он выполняется следующим образом:
Ins
Ехр.
goto Lab}
Иначе говоря, непосредственно после выполнения оператора-выражения Ехра выполняются оператор Ins и оператор-выражение Ехрь до тех пор, пока выражение Ехр истинно. Любое из перечисленных выражений может быть пустым. Если среднее выражение Ехр отсутствует, то по умолчанию оно принимается равным 1, считается всегда истинным, и в этом случае цикл считаете^ бесконечным.
Пример
char *Ptr;
finclude <stdio.h>
main()
{•
for(Ptr н "Jan Bielecki", *Ptr;)
printf("%c”, *Ptr ++);
return 0;
}
Выполнение программы приводит к выводу надписи Jan Bielecki.
Оператор продолжения
Этот оператор имеет вид
continue;
и может находиться в пределах оператора цикла.
Выполнение этого оператора приводит к продолжению выполнения непосредственно после этого оператора следующего шага цикла. Это означает, что в каждом из последующих примеров выполнение оператора continue в месте, обозначенном комментарием, могло бы быть заменено выполнением оператора
goto Next;
Оператор while
while(…){
/* ... */ Next:;
}
Оператор do
Next;
} whtle( ...);
Оператор for
for(…){
Next:; }
Использование оператора продолжения в программах должно быть сведено к минимуму, чтобы не усложнять их.
Оператор завершения
Этот оператор имеет вид
break;
и может находиться в пределах оператора цикла или условного оператора.
Оператор завершения вызывает преждевременное завершение выполнения охватывающего оператора (цикла или условного) и переход на выполнение следующего за ним оператора.
Пример
char *Ptr = "Jan Bteleckt";
•include <stdto.h>
matn()
{
for(;;){
printf(”%c\ *Ptr);
if(!*++Ptr) break;
return 0;
Выполнение программы приводит к выводу надписи Jan Bielecki.
Оператор-переключатель
Этот оператор имеет вид
switch (£хр)
Ins
гце Ехр - выражение типа (int, char, short int, insigned int), a Jns -
произвольный оператор (чаще всего блок).
В рамках оператора^переключателя могут находиться приставки вида
case сЕхр:
а также по крайней мере одна приставка вида
default:
Постоянные выражения сЕхр в приставках должны иметь такой же тип, как и выражение Ехр. Выполнение оператора-переключателя начинается с вычисления значения выражения сЕхр. Это значение в дальнейшем последовательно сравнивается со значениями выражений Ехр. В случае равенства выполняется оператор, стоящий после приставки case, а также все последующие за ним операторы вплоть до выполнения оператора goto или break или 启 выполнения последнего оператора в пределах оператора- переключателя. В противном случае выполняется оператор после приставки default: и возможно - последующий оператор. Если равенство не выполняется и ие используется приставка default:, то выполнение оператора- переключателя считается законным.
Примеры
Оператор-переключатель, содержащий блок
char *ptr = "janb'*, chr;
whtle(chr = *ptr ++) switch (chr){
case 'j':
case 'a*: putchar ('e');
default: putchar ('w');
break;
case 'n': putchar (*ar); }
Выполнение оператора while приводит к выводу надписи ewewaw. В частности, если chr -= 了,то будут выданы символы ew, а при chr == 'b'- символ w.
Пары эквивалентных операторов-переключателей, не содержащих блоки:
switch (chr) case 'j' putchar(chr); tf(chr == 'j') putchar(chr)
switch (chr) default: putchar(chr);
putchar(chr)
switch (chr)
switch (chr) putchar(chr)
Оператор возврата
Этот оператор имеет вид
return
или
return Exp;
где Exp - выражение.
Выполнение оператора возврата приводит к окончанию выполнения содержащей ее функции. Если оператор возврата включает выражение Ехр, то значение этого выражения является результатом функции. Требуется, чтобы этим не были массив, структура, объединение или функция.
Пример
char *Ptr = "Jan Btelecki";
♦include vstdto.h〉
main()
{
while(l){
printf(”c”. *Ptr++);
if(!Ptr[O])
return 0;
}
}
Выполнение программы приводит к выводу надписи Jan Bielecki.
7. Функции
Функции являются внешними объектами. Так же как для переменных, описания функций мо1ут иметь характер описания или обращения. Вложенность функций запрещается.
В общем случае описание функции состоит из заголовка и тела функции. Заголовок со^ржит описание типа результата функции и имя функции, а также взятый в круглые скобки список параметров функции и описание их типов. Типом результата функции по умолчанию является (int), а классом функции - extern. Описание параметров необходимо только тогда, коща параметры имеют тип, отличный от (int). Явно заданным классом параметров может быть только класс регистровых переменных, несмотря на то что параметры по существу трактуются как простые переменные класса auto.
Описания параметров должны находиться либо в списках параметров функции, либо после него. В первом случае они образуют список, последним элементом которого может быть параметр "…"(многоточий. Использование этого параметра делает возможным описание функций, которые могут быть вызваны с переменным числом аргументов.
Внимание: Такие описания используются в расширенном языке Си и Турбо Си. Они рекомендуются к употреблению, поскольку обеспечивают контроль параметров функции посредством компилятора.
Примеры
Классическое описание
float
Sum (a,b.c)
int a;
char b, c;
{
return a + b + c;
}
Описание 6 списке параметров
float
Sum (int a, char b. char c)
{
return a * b * c;
}
Описание обращений к функциям
extern float Sum();
extern float Sum (int a, char b. char c);
Функции класса static
Функции класса static доступны через свои идентификаторы только в рамках модулей, где имеются их описания. Остальные функции доступны из всех модулей, но если только они в них описаны.
Примеры
Функция класса static
static double sqr(par) int par:
{
return par *par;
}
Функция sqr возвращает квадрат аргумента.
Аргумент функции - целое число типа (int), а результат - типа (double).
Функция^ доступная через выражение, не являющееся идентификатором
fun(name, val) tnt (*name)();
{
return (*name) (val + 3);
} int abs(par)
{
return par < 0? - par: par;
}
finclude vstdto.h〉 matn()
{
int var = fun(abs( -5);
printf(,,%d,'< var);
return 0;
}
Программа состоит из трех функций: fun, abs и main. При инициализации переменной var происходит вызов функции fun с аргументами abs и -5.
Поскольку abs трактуется, как указатель на функцию, входящую в оператор return, выражение паше представляет в рассматриваемом контексте выход функции abs.
В результате выполнения программы будет выведено число 2.
int var к ( *(*(*name) [i][j])(a,b))(c);
С правой стороны оператора присваивания находится вызов функции, ще name является указателем на двумерный массив, элементами которого являются указатели на функции с двумя параметрами i и j, результатом которой Является в свою очередь ссылка (указатель) иа функцию с параметром с.
Связь параметров с аргументами
Некоторым неудобством языка Си является то, что связь параметра с аргументом может быть осуществлена только по значению. Это приводит к тому, что для связи через переменную требуется передавать параметры в функции в виде Указателей на переменные. Приведенная ниже программа иллюстрирует различие между связью через переменные и связью через значения.
finclude vstdlo.h〉 main()
char Alfa = *e', Beta,'b';
fun (&A1fa. Beta);
printfC%c%c,#, Alfa, Beta); return 0;
}
fun (Ref, Vai) char *Ref, Vai;
{
*Ref=.尸; Vai = •**;
}
В функции fun имеются две различные переменные Ref и Vai. В прологе функции переменной Ref приписывается значение Alfa, а переменной Vai - значение Beta. Обе переменные представляют собой переменные функции fun. Выполнение операции *Re£ = "j‘ позволяет переменной Alfa приписать значение 丁,а выполнение операции Vai = * - переменной Vai - значение
Следовательно, последняя операция не затрагивает переменной Beta. Впоследствии выполнение программы приводит к выводу надписи jb.
Сущность связи через значения заключается в том, что с каждым параметром функции fun связана локальная переменная, которой в момент вызова приписывается начальное значение. При условии правильности выбора начального значения тип параметра соответствует аргументу функции. Однако такое соответствие - лишь испытание неявного преобразования аргументов и параметров. Неявное преобразование зависит от местонахождения вызова функции. Если вызов функции находится в пределах описания, то каждый ар1умент* поддается преобразованию к типу параметра (следующего из описания). После этого другие преобразования аргументов уже ие проводятся. Это означает, что две следующие программы эквивалентны:
Вызов g пределах описания
■include <stdto.h>
main()
{
void fun(double Arg)^
fun(3)
return 0;
void
fun(double Par)
{■.
prSntf("%e". Рат);
Вызов без использования описания
♦include <stdio.h>
matn()
{
void fun();
fun((double) 3);
return 0;
}
void
fun(double Par)
{
printfC^Xe", Par;
}
Если вызов находится вне пределов описания, то проводятся только неявные преобразования аргументов. Они основаны на том, что аргументы типа (char) и (short int) неявно заменяются аргументами типа (int) а аргументы типа (float) - аргументами типа (double). Это означает, что две следующие программы эквивалентны:
Программа с неявными преобразованиями аргументов
•include «stdio-h1*
main()
char Chr = 'j‘,
fun(Chr, 45.0);
return 0;
}
fun (Letter, Number)
int Letter;
double Number;
{
printf(**Xc = X Of", Letter, Number);
}
7—764
Программа с явными преобразованиями аргументов
#include <stdio.h>
main()
char Chr = 丁
fun (int) Chr, (double) 45.0);
fun (Letter, Number)
int Letter;
double Number;
{
printf("%c 匸 % 0f“,Letter, Number);
Если параметр функции описан как массив, то он трактуется как объект того же тип% что и элементы этого массива. Следовательно, две следующие программы эквивалентны:
Программа с параметрами е виде массивов
include <stdio.h>
char Letters [2][3] = {{'j'.}. {'b,}}:
matn( ){
fun(Letters);
return 0;
}
fun(Arr)
char Arr [2][3]:
{
printffXcXc", Arr[0][0], (Arr + 1) [0][0];
}
Программа с параметрами g виде указателей
^include <stdio.h>
char Letters ⑵[3] = {{'j',}・ {'b'}};
matn()
{
fun(Letters);
return 0;
}
fun(Ptr)
char(*Ptr)[3];
{
pNntf(”c%c"・ Ptr[O][O]. (Ptr + 1) [0][0];
Если параметр описывается как переменная типа (char) или (short int), то он трактуется по типу (int), а если описывается как переменная типа (float), то - по типу (double). Каждому из преобразованных параметров присваивается начальное значение, полученное от преобразований (в случае необходимости) аргумента к первоначальному типу параметра. Это означает, что две следующие программы эквивалентны:
Неявное преобразование параметров
^Include vstdto.hA
main()
{
void fun(char. float);
fun(259, 1.0/3);
return 0;
}
void
fun(Char. Real)
char Char;
float Real;
{
printfC'% 6f", Char * Real);
}
Явное преобразование параметров
•include vstdto.h〉
main()
{
void fun();
fun(259, 1.0/3);
return 0;
void
fun(Char, Real)
int Char;•
double Real;
{
Char = (char)Char;
Real = (float) Real;
printf「% 6Г, Char * Real);
}
Во всех рассмотренных преобразованиях аргументов и параметров требуется, чтобы соответствующие друг другу аргументы и параметры были одного типа. Это, в частности, означает, что аргументу типа (char) может, например, соответствовать параметр типа (short int), но не может соответствовать, например, параметр типа (float).
Полученм® резужтгата
Если последним выполняемым оператором функции является
return Exp;
i)xe Exp - выражение, то в месте вызова функции возможно получение результата, представленного выражением Ехр. Если тип входящего в оператор return выражения не идентичен описанному или принятому по умолчанию типу идентификатора функции, то выражение будет преобразовано к данному типу.
Внимание: Если функция не дает результата, то ее последним выполняемым оператором должен быть оператор
return;
Тип *4результатам такого оператора должен быть представлен как void.
Примеры
Функция, дающая результат
char агг[3][2] = {'J'};
•include <stdio.h>
main()
{帮
char *fun();
putchar(*fun());
return 0;
}
char;
fun()
{*
return arr;
}
Выполнение программы приводит к выводу буквы j. Поскольку агг представляет собой массив типа (char [3] [2]), то оператор return будет неявно преобразован к виду
return (char(*)[2j)arr;
Поскольку после этого образования выражение, входящее в оператор return, имеет тип (char(*> [2]), а результат функции должен быть типа (char*), то выполняется неявное преобразование выражения &агг[0], а рассматриваемый оператор return выполняется, как если бы имел вид
return (char*)(char(*)[2])arr;
эквивалентный в рассматриваемом случае оператору
return &шт[0][0];
Функция, не 0々/0心0兄 результата
♦include <stdio.h>
matn()
{
void Greet();
Greet();
return 0;
void Greet()
{
printfHello");
return;
}
Выполнение программы приводит к выводу надписи Hello. Ключевое слово void перед именем функции означает, что эта функция не дает результата. Использование оператора return по существу излишне, поскольку он выполняется по умолчанию в месте нахождения фигурной скобки, заканчивающей описание функции.
Рекурсия
Функции языка Си могут быть вызваны рекуррентно. Ири каждом вызове образуются последующие автоматические переменные.
Примеры
Обращение строки символов
mirror(par) char*par;
{
char chr =*par ++;
if(*par)
mirror(par);
putchar(chr);
}
Вызов функции mirror в виде
mirrorfave");
приведет к выводу надписи “疝е“, а очередность действий при выборе функции mirror будет следующей.
На первом этапе параметру par будет присвоено значение указателя на знак 'а\ а переменной chr - значение '斫,после чего произойдет инкремент параметра 秒口 2 ,
Поскольку *раг! =0, то произойдет рекуррентный вызов функции mirror.
На втором этапе параметру par будет присвоено значение указателя на знак V, а переменной chr - значение V и вновь произойдет инкремент параметра par.
Поскольку *раг! = 0, то произойдет рекуррентный вызов функции mirror.
На третьем этапе параметру par будет присвоено значение указателя на 1@ а переменной chr - значение 'е\ и после очередного инкремента параметра par он получит значение указателя на знак nul, заканчивающий строку ave.
Поскольку *раг| = 0, произойдет переход к выполнению стандартной функции putchar, что приведет к выводу значения переменной chr, присвоенного на третьем этапе, те символа '% и закончится выполнение третьего этапа вызова функции mirror.
При возврате с третьего этапа вызова функции mirror на второй произойдет вывод значения переменной chr, присвоенного на втором этапе, т. е* символа V。
При возврате со второго этапа вызова функции mirror на первый будет выведено значение переменной chr, присвоенное на первом этапе, т. е. символа "а", и завершится выполнение первого этапа функции mirror.
На этом заканчивается выполнение функции
mirror(,(ave");
Вывод значения величины, представленной через аргумент функции g виде ряда знаков
void
outdec(par)
int par;視
{
int var;
1f(par<0)
putcharf1-*), par ^ - par;
if(var = par /10)
outdec(var);
putchar(par % 10 + P');
}
Функция не дает результата, так как ее выполнение заканчивается неявным оператором
return;
Если заголовку outdec придать вид
static void outdec(par) register int par;
то функция outdec будет доступна только в модуле, содержащем ее определение. Кроме того, во время выполнения функции ее параметр par был бы сохранен не в оперативной памяти, а в одном из регистров процессора.
74 Параметры функции main
Во всех приведенных выше примерах функция main, определение которой должна содержать каждая программа, была представлена как функция без параметров. Однако по существу она является двухпараметрической с параметрами argc и argv. Параметры, передаваемые программе, написанной на языке Си, выступают в роли аргументов функции main. Параметр argc имеет тип (int) и определяет число передаваемых параметров, которые могут быть приняты за имя и аргументы программы, а параметр argv имеет тип (char* [ ]) и указывает на начало массива строк, являющихся передаваемыми параметрами, каждая из которых обычно заканчивается знаком nul. Первая из этих строк образует имя программы в системе.
Пример
Программу выявляющая аргументы, с которыми она была вызвана
finclude <stdio.h>
ma1n(argcv argv)
int argc;
char*argv[];
{
while (argc —)
pr 1 ntf("%s%c'*,*argv ++, argc ? .'/'n');
return 0;
Если программа будет вызвана с использованием имени Jan с добавочным аргументом Bielecki, то argc будет присвоено значение 2 и цикл while выполнится два раза с выдачей надписи Jan Bielecki.
Принципы выполнения операции ввода-вывода
Операции ввода-вывода касаются файлов данных или устройств. В программах как файлы данных, так и устройства представляются посредством некоторых символических указателей, которые не являются физическим объектом, а его логической интерпретацией, такой, как файл данных е памяти или файл данных от знакового устройства, например клавиатуры.При написании программ на языке высокого уровня и при кодировании алгоритма удобно пользоваться абстрактным понятием “канал". Тем не менее необходимо 血мнить, что содержащиеся в алгоритме операции с каналами будут реализованы во время выполнения программы как операции с файлами и устройствами. Поэтому при выполнении операций с каналами предварительно должно быть установлено соответствие канала с определенным файлом данных или устройством. Это соответствие устанавливается сразу после создания абстрактного объекта, каким является канал. Для связи канала с файлом или с устройством служит функция fopen, а для * устранения такой связи служит функция fclose. Результатом функции fopen является указатель на файл типа FILE, определенный в файле stdio.h. Аргументом функции fclose является указатель, полученный посредством функции fopen. Каждый из перечисленных указателей является указателем файла и дает возможность идентификации файла.
Кроме указателя, полученного с помощью функции fopen в файле stdio.h, определены три дополнительных указателя, представленные символами stdin, stdout и stderr. Эти указатели служат соответственно для идентификаи.ии стандартных входного и выходного устройств и стандартного файла для обнаружения ошибок.
Внимание: По умолчанию принимается, что стандартный входной канал связан с клавиатурой, а стандартный выходной канал и стандартный файл для обнаружения ошибок связаны с экраном монитора.
Функция fopen
Заголовок: FILE* fopen(char*Name, char*Mode)
Выполнение функции fopen приводит к образованию канала, связи его с файлом или с устройством с именем Name и к появлению указателя на файл. Если Mode представлено символом "г", то файл будет открыт в режиме ввода, а если символом “w“,то - в режиме вывода. Если файл открывается в режиме вывода, а файл с данным именем уже существует, то он будет удален перед открытием. Если открытие файла окажется невозможным (например, файл открывается в режиме ввода, а файл с указанным именем не существует), то результатом функции будет пустой указатель, представленный символом NULL.
Заголовок: int
fclose(FILE*Strea«)
Выполнение функции fclose приводит к закрытию файла, идентифицируемого аргументом stream. Результатом функции является величина, равная 0, если закрытие файла реализовано, или величина, равная EOF, в противном случае.
Во время выполнения операции ввода-вывода с файлами, идентифицированными посредством указателей, могут быть два вида исключительных ситуаций: подтверждение ошибки операции, а также попытка ввода данных из файла, когда он находится в конечной позиции. В приведенном примере в идентифицированной посредством указателя файла структуре типа FILE будет записана информация, к которой можно обращаться с помощью функции ferror и feof.
Эта функция может быть удалена посредством функции ciearerr.
Функция ferror
Заголовок: int
ferror(FILE*Stream)
Выполнение функции ferror приводит к возможности получения информации о появлении ошибки во время проведения операции с файлом, идентифицируемым аргументом Stream. Результатом функции является величина, отличная от 0 в случае подтверждения ошибки и равная 0 в противном случае.
Функция feof
Заголовок: int
feof(FILE*Stream)
Выполнение функции feof приводит к возможности получения информации о том, предпринята ли попытка ввода данных из файла, идентифицируемого аргументом Stream, когда файл находится в конечной позиции. При подтверждении результатом функции является величина, отличная от 0 и равная 0 в противном случае.
Функция ciearerr
Заголовок: void
ciearerr(FILE*Stream)
Выполнение функции ciearerr приводит к удалению из структуры, указанной аргументом Stream, информации о подтверждении ошибка операции, а также о попытке ввода данных из файла, когда он находился в конечной позиции.
Функция fgefc
Заголовок: int
fgetc(FILE*Stream)
Выполнение функции fgetc приводит к вводу очередного символа из файла, идентифицируемого аргументом Stream. Результатом функции является величина со значением, равным коду вводимого символа. Если перед вызовом функции fgetc файл находился в конечной позиции, то результатом функции будет величина со значением EOF.
Функция fputc
Заголовок: int
fputc(int Chr, FILERStream)
Выполнение функции fputc приводит к занесению в файл, идентифицируемый аргументом Stream, символа с кодом Chr. Результатом функции является величина, значение которой представляет собой код заносимого символа. Если ввод символа не состоялся, то результатом функции будет величина со значением EOF.
Внимание: Вызов fputc(c,stdout) может быть заменен вызовом putchar(c).
Пример .
Следующая программа иллюстрирует использование описанных функций:
finclude <stdio.h>
main()
{
FILE *inp;
int ch;
4np ^ fopenC^ANB.DOC", V);
if(inp){
while((ch = fgetc(inp))! = EOF)
fputc(ch『 stdout);•
close(inp);
} else;
fputc('?'・ stderr);
return 0;
}
Выполнение программы приводит к копированию текста из файла JANB.DOC на стандартном устройстве ввода.
Функция fread
Заголовок: unsigned
fread(void *Buf.
int Size•
Int Count,
FILE *Stream)
Выполнение функции fread приводит к вводу из файла, идентифицируемого аргументом Stream, порции информации, местоположение Buf и размер Count которой в оперативной - памяти указан посредством Size. Результатом функции является величина со значением, равным количеству вводимых объектов информации. Если данное количество меньше, чем Count, то это означает наличие ошибки выполнения функции или ввод данных из файла, находящегося в конечной позиции.
Внимание: Локализация объема памяти производится с помощью величины типа (void*>. Эта величина может быть принята за указатель переменной типа (void) с размером 0, находящейся в начале локализованного объема.
Функция fwrite
Заголовок: unsigned
fwrite(void *Buf,
int Size,
int Count,
FILE ^Stream)
Выполнение функцииfwriteприводитк выводу бфайл,
идентифицируемый аргументом Stream, объектов информации размером Size каждый из оперативнойпамяти,указанныйс помощьюBuf,Count.
Результатом функции является величина со значением, равным числу выводимых объектов. Если указанное - число меньше, чем Count, то это означает наличие ошибки выполнения функции.
Функция fprinff
Заголовок: int
fprintf(FILE ^Stream, char "Format
Обращение к библиотечной функции fprintf требует в качестве первого аргумента использовать указатель на файл. Библиотечная функция fprintf обеспечивает вывод в произвольный файл, открытый как поток данных для вывода. Выполнение функции fprintf приводит к интерпретации и к выводу в файл, идентифицируемый аргументом Stream, последовательности знаков, определенных через Format, а также аргументов, связанных с параметром “•••“ (многоточие). Результатом функции является число выведенных знаков.
Принимается, что строка, указанная через Format, состоит из знаков и из шаблонов преобразования. Требуется, чтобы каждому шаблону преобразования соответствовал один аргумент вызова функции.
Обязательными являются следующие принципы интерпретации:
Интерп ретация следующего после шаблона преобразования знака приводит к выводу такого же знака.
Интерпретация шаблона преобразования приводит к выводу строки ..знаков, выражающей значение аргумента, связанного с этим шаблоном.
Внимание: Если вывод производится на стандартный выход (представленный через stdout), то вызов функции fprintf может быть представлен в виде
fprintf(format, alr a2v ..., an)
Уточнения
Функции fprintf и printf могут быть вызваны с переменным числом аргументов а/, а2, •••, «п, в общем случае равным числу шаблонов, содержащихся в аргументе format
Каждый шаблон, если он имеется, состоит из строки знаков, начинающегося со знака % (процент) и кончающегося буквой (или парой букв), принадлежащей к следующему списку кодов преобразования
d о х Id 1е 1х с s е f g
и сятределяющей тип выводимой величины, а также способ преобразования ее значения в строку выводимых знаков.
Непосредственно перед кодом преобразования могут быть слова field.count или просто fields где field - число, определяющее ширину выходного поля знаков, a count числовой счетчик, который определяет количество выводимых цифр или знаков. Если указанная ширина поля слишком мала, то она неявно расширяется (например, % 2.5 заменяется на % 5.5).
Значения кодов преобразования и других знаков следующие:
%%начинает шаблон преобразования.
%
%
означает, что выводимая строка знаков должна быть выровнена по левой стороне выходного поля.
характеризует строку, состоящую из цифр, специфицирует число знаков в поле формата от другой строки, состоящей из цифр. Если ширина поля является числом, начинающимся с цифры 0, а
выводимая строка знаков не заполняет поля, то на излишних позициях поля помещаются не пробелы, а цифры 0.
приводит к выводу аргумента типа приводит к. выводу аргумента типа (без начального нуля).
приводит к выводу аргумента типа числа (без начальных знаков Ох).
приводит к выводу аргумента типа приводит к выводу аргумента типа (без начальных знаков Ох).
приводит к выводу аргумента типа числа (без начальных знаков Ох), приводит к выводу аргумента типа (char).
(int) в виде десятичного числа.(int) в виде восьмеричного числа(int) в виде шестнадцатеричного(int) в виде десятичного числа.(int) в виде восьмеричного числа(int) в виде шестнадцатеричного(long) в виде десятичного числа.(long) в виде восьмеричного числа(long) в виде шестнадцатеричного(int) после преобразования в тип(long) в виде десятичного числа.(long) в виде восьмеричного числа(long) в виде шестнадцатеричного(int) после преобразования в типприводит к выводу строки знаков, первый из которых указан через аргумент типа (char *>, а их число определено счетчиком.
(int) в виде десятичного числа.
(int) в виде восьмеричного числа
(int) в виде шестнадцатеричного
(int) в виде десятичного числа.
(int) в виде восьмеричного числа
(int) в виде шестнадцатеричного
(long) в виде десятичного числа.
(long) в виде восьмеричного числа
(long) в виде шестнадцатеричного
(int) после преобразования в тип
(long) в виде десятичного числа.
(long) в виде восьмеричного числа
(long) в виде шестнадцатеричного
(int) после преобразования в тип
приводит к выводу аргумента типа (double) в виде десятичного числа с плавающей точкой и показателем; число цифр мантиссы
определяется счетчиком.
приводит к выводу аргумента типа (double) в виде десятичного числа с плавающей точкой без показателя; число цифр мантиссы определяется счетчиком.
приводит к выводу аргумента типа (double) в виде десятичного числа с плавающей точкой и показателем или без показателя в зависимости
от того, какой вид можно выразить с помощью меньшего числа знаков; число цифр мантиссы определяется счетчиком.
Примеры
Функции 〃 выводимые строки знаков
Функция
Выводимая строка
printff'Any text**);
Any text
printfn%・2d)",5);
(5)
printf(**%8И, -JanB");
JanB
pr1ntf(w(«e)nf "JanB");
(JanB)
prtntf「X・4,3s); "JanB'0);
(Jan)
printf「(%4,3s)\ ”JanB“);
(Jan)
printf (^/B*);
В
pr紀tf("%u”, - 1);
65535
printff'Xo", - 1)
177777
pEntfl/x: - 1);
FFFF
printf("%d,紀”,2.5);
2』
pr1ntf(M%4e2rt 6.232);
6.23
Программа с вызовом функции printf
•include <stdio.h>
main()
{
printf("Jan %c is 猊 %s"・■,• 47, "now");
return 0;
}
Выполнение программы приводит к выводу надписи
JanB is 47 now
Программа с вызовом функции fprintf
finclude <stdio.h>
FILE *out;
matn()
if((out = fopenU'JanB.DOC”, ”w”)!=NULL
fprintffout, WI am %d now'*, 47);
return 0;
}
Выполнение программы приводит к созданию файла JANB.DOC и размещения в нем строки знаков I ат 47 now.
Функция fscanf
Заголовок: int
fscanf(FILE *Stream,
char *Format,
Библиотечная функция fscanf обеспечивает ввод из производного файла, открытого как поток данных для ввода. Выполнение функции fscanf приводит к выводу файла, идентифицируемого аргументом Stream, последовательности знаков, определенных через Format, а также аргументов, связанных с параметром "…“ {многоточие^, к трактованию их в виде записей значений величин и к последующему прргсвоению этих значений переменным, указанным через аргументы, связанные с параметрами.
Принимается, что строка, указанная через Format, состоит из пробелов, шаблонов преобразования и других знаков. Требуется, чтобы каждому шаблону преобразования, не содержащему знака * (звездочка), соответствовал один аргумент.
Внимание: Если ввод производится со стандартного входа, то вызов функции fscanf может быть представлен в виде
sea殲(format, al, а2у ...» an)
Уточнения
Интерпретация пробела приводит к его опусканию. Интерпретация шаблона преобразования приводит к игнорированию ближайшего пробела (интерпретация относится к шаблону, заканчивающемуся буквой с) с последующим введением одного поля знаков, образованием на основе этого поля величины и присвоением ей имени переменной, указанной через очередной аргумент.
Внимание: Если непосредственно после знака % (процент), с которого начинается шаблон преобразования, следует знак * (звездочка), то образованная величина игнорируется.
Интерпретация знака, не принадлежащего шаблону преобразования, приводит к опусканию этого знака.
Интерпретация управляющего аргумента заканчивается в момент подтверждения, что шаблон преобразования не соответствует требуемому по этому шаблону входному полю, а также когда знаку управляющего аргумента не соответствует идентичный знак в потоке данных. Каждый шаблон состоит из строки знаков, начинающейся со знака % {процент} и кончающейся буквой или парой букв, принадлежащих к следующему набору кодов преобразования:
d о х Id 1е 1х с s е f g
и определяющих способ преобразования к величине ряда вводимых знаков. Непосредственно перед кодом преобразования может быть слово fields которое является числом, определяющим ширину входного поля знаков. За ширину поля принимается минимум из field и widths где width - число знаков перед ближайшим пробелом. Если в шаблоне нет слова fieldy то за ширину поля принимается width.
Значение отдельных букв или пар букв, заканчивающих шаблон,
приведено ниже:
d в поле ожидается ввод десятичного числа; величина типа (int) со значением, равным этому числу, будет присвоена переменной, указанной через аргумент.
о в поле ожидается ввод восьмеричного числа; величина типа (int) со значением, равным этому числу, будет присвоена переменной, указанной через аргумент.
х в поле ожидается шестнадцатеричное число; величина типа (int) со значением, равным этому числу, будет присвоена переменной, указанной через аргумент.
п в поле ожидается десятичное число; величина типа (short) со значением, равным этому числу, будет присвоена переменной, указанной через аргумент.
Id в поле ожидается десятичное число; величина типа (long) со значением, равным этому числу, будет присвоена переменной, указанной через аргумент.
1о в поле ожидается восьмеричное число; величина типа (long) со значением, равным этому числу, будет присвоена переменной, указанной через аргумент.
1х в поле ожидается шестнадцатеричное число (с наличием или без предшествующих знаков Ох); величина типа (long) со значением, равным этому числу, будет присвоена переменной, указанной через аргумент.
с в поле ожидается символ; величина типа (char) со значением кода этого символа будет присвоена переменной, указанной через аргумент.
s в поле ожидается строка знаков; эти знаки (вместе с последним знаком 0) будут размещены в массиве типа (char[l ]), первый элемент которого указан через аргумент.
f,e,g в поле ожидается число с плавающей точкой; величина типа (float) со значением, равным этому числу, будет присвоена переменной, указанной через аргумент.
Ie, If в поле ожидается число с плавающей точкой; величина типа (double) со значением, равным этому числу, будет присвоена переменной, указанной через ар!умент.
Выполнение функции fscanf заканчивается после интерпретации всего ряда, введения неправильного знака илн знака, не позволяющего осуществить преобразование, а также при окончании файла. Результатом функции является величина со значением, равным числу правильно выполненных присвоений, или величине со значением EOF в случае окончания файла.
Пример. Программа^ содержащая вызов функции scanf
•include <std1o.h>
ma,n()
{ char Initial; int Age;
Char Name [4];
scanf("%s Xc%*s is %d%*s”,Name, «.Initial. JkAge);
printf(”s%c is Xd now". Name. Initial, Age);
return 0;
}
Выполнение приведенной программы для данных
Jan Bielecki is 47 now
даст вывод надписи
Jan is 47 now
Функции с переменным числом аргументов
Отличительной особенностью функций типа printf н scanf является то, что они могут быть вызваны с переменным числом аргументов. В первом варианте языка определение таких функций не было возможно. Только в стандарте ANSI и вслед за ним в языке Турбо Си появились средства, позволяющие определять этн функции. Следующая программа содержит пример описания упрощенной функции printf. В ней, в частности, содержатся описание вспомогательной переменной Ptr типа va—list, а также вызовы макроопределений va—start, va—arg и va—end.
#inclucle<stdk).h>
#include<stdarg.h>
main()
{
int printf(char*, ...);
printf(**Jan %c is %d %s\n"/B\ 45. ”no。];
return 0;
}
int Count = 0;
int printf(char "Format. …)
{
char ch;
void outdec(inf), outstr(char):
int ourchar(char);
va-llst Ptr;
va-start(ptr, Format);
whi】e((ch = "Format ++) ! = 0){ switch(ch){ case '%':
sw i tch(ch=*Forma t ++){
case 'cT:
outclec(va arg(ptr, int));
break;
case *c*:
outchar(va_arg(Ptr,int));
break;
case 's':
outstr(va_arg(Ptr. char *));
}
break;
case '\V.:
"Format ++, ch = '\n';
default:
outchar (ch);
}
vaencl(Prt);
return Count;
}
void outdec(clec)
int dec;
{
int num;
if(clec<0)
outchar(* - *), dec = ~ dec;
if(num = dec \ 10) ! = 0) outclec(num);
outchar(dec % 10 + *0*);
}
void outstr(str) char*str;
{
char ch;
whi】e((ch = *str ++)! = 0 outchar (ch);
'}
int outchar(char chr)
{ •
(void)putchar(chr)
{
(void) putchar(chr):
Count++;
}、
Тип va—list, а также все макроопределения даны в заглавном файле stdarg.h. Упрощенная функция printf определена на основе следующих принципов:
в заголовке функции обозначено, что функция будет вызвана с переменным числом аргументов (лексический символ "...");
описан и связан с упреждающим параметром символ "…"{многоточий вспомогательной переменной типа va—list (макровызов va—start);
выполнено обращение к макроопределению, дающему доступ к аргументам функции указанного типа (макровызов va—arg);
объявлено окончание обслуживания неявных аргументов функции (макровызов va—end)..
9. Управление оперативной памятью
Управление оперативной памятью реализуется посредством библиотечных функций malloc, calloc и fre 已 Функции malloc и calloc осуществляют разделение памяти, а функция free - ее освобождение. Описания этих функций находятся в файле заголовка stdio.h.
Функция malloc
讃
Заголовок: void *
ma11ос(unsigned size)
Функция malloc возвращает в качестве своего значения указатель на область памяти, начинающуюся на границе слова. Размер этой области в байтах определяется с помощью ар!умента. Если разделение объема памяти невозможно, то результатом функции будет пустой адресный указатель.
Пример
#include<stdio.h>
#include<stcllib.h> double cabs(re, im) double re, Im;
{
return sqrt(re*re +im * ini);
}
typedef struct{
double Re, Im;
} COMPLEX;
Comtlex *Ptr;
main()
{
Ptr=(COMPLEX*) malloc(s1zeof(Complex));•
Ptr -> Re = 3.0;
Ptr -> Im = 4.0;
printf("%f'\ cabs(Ptr -> Ref Ptr -> Im);
return 0;
}
Выполнение программы приводит к выводу пары чисел (3.0, 4.0).
Функция calloc*
Заголовок: void * calloc(unsigned count, unsigned size)
Выполнение функции calloc приводит к увеличению объема оперативной памяти на величину count*size. Результатом функции является указание адреса увеличенного объема. Если увеличение объема не происходит, то результатом функции будет указание на пустой адрес.
Пример
finclude vstdio.h»
•include «stdlib.hA
^include <math.h>
struct coriglox *Ptr;
main()
Ptr = (struct complex *)
calloc(lv sizeof(struct complex));
Ptr ~a x »: 3.0;
Ptr -> у = 4.0;
prSntf("%f',cabs^Ptr));
return 0;
}
Выполнение программы приводит к выводу пары чисел (3.0, 4.0).
Используется то, что в файле заголовка math.h определена структура
struct complex{ double 乂. у;
}
Функция free
Заголовок: void
free(void *ptr)
Функция free обеспечивает в результате своего выполнения освобождение выделенной ранее с помощью функции области памяти, определяемой с помощью аргумента ptr.
Пример
#include<stdio.h>
#tnclude<std1tb.h>
main()
int Count;
void*Ref;
for(Count = 1;; Count++){
Ref = calloc(Count, 1024);
If(Ref h= NULL) break;
free(Ref);
}
printf('Available heap: % dK bytes**. Count - 1);
return 0;
}
Выполнение программы приводит к оцениванию размера и к выражению его в килобайтах.
Действия, основанные на включении в основную программу текстов нз файлов данных, формировании макроопределений и на условных переходах, называются входными преобразованиями, а программа, реализующая этн преобразования и обычно являющаяся составной частью компилятора, называется препроцессором.
Директивы препроцессора отличаются от других выражений, образующих основной текст, тем, что начинаются знаком # (hash), перед которым в строке нмеютоа знаки пробела и табуляции.
Те директивы, которые не умещаются на одной строке, могут быть продолжены. Знаком продолжения является косая черта в конце продолжаемой строки. Границы директивы препроцессора определяются основным модулем, в котором эта директива была использована.
Пример
•define max(a.b) а > b? \ а : b
Приведенная директива эквивалентна директиве
#define max(a.b) а > b? а : b
и записана на двух строках, первая из которых продолжена.
Включающие директивы
Этн директивы имеют вид
#include uNameu
или
#include <Name>
где Name - нмя файла
Интерпретация директивы #include приводит к включению в месте ее появления содержимого файла Name. Если имя файла заключено в угловые скобки, то поиск файла ограничивается каталогом файлов, определенным с помощью опции компилятора. Если имя файла заключено в кавычки, то предварительно проводится его поиск в текущем каталоге. Если будет указано сложное имя файла, например С: \JB-TC \JB-HEAD.H, то поиск, естественно, не проводится, а сразу включается содержимое указанного файла. Остается добавить, что допускаются вложенные директивы #include.
IQ Препроцессор〃7
В этом случае требуется, чтобы только был закончен процесс встроенных включений.
Пример
Если файл EWA содержит текст
main()
#1nclude<IZA>
}
файл IZA - текст
{
•include "JAN"
a JAN - текст
printf("Hello, I am JanB**);
то передача препроцессору файла EWA приведет к образованию основного модуля
main()
{
printf("Hello, I am JanB");
}
Определяющие директивы
Эти деректнвы имеют вид
•define Id Seq
или
#defire Id(List)Seq
ще /d - идентификатор, Seq - произвольная строка лексических единиц, а List - список идентификаторов параметров макроопределения.
Интерпретация первой из упомянутых выше директив приводит к связи с идентификатором Id строки лексических единиц и к генерации этой строки при каждом появлении указанного идентификатора. Во второй директиве список параметров List состоит из идентификаторов, разделенных запятыми. Если во время интерпретации очередных строк основного текста (не содержащих директив #define) встретится идентификатор Id, а за ним список apiyментов в круглых скобках, то вся эта запись, называемая далее макровызовом, будет генерировать запись, образованную из строки лексических единиц Seq, в которой каждый из параметров заменен соответствующим (может быть пустым) ар1ументом.
Описанные действия, называемые развитием макровызовов, продолжаются столько, сколько выполняются замены, определенные директивой #define. После их окончания генерируется результирующая запись.
Если среди лексических единиц, содержащихся в макроопределении, находится пара стоящих рядом знаков # (hash), которые мо1ут иметь пробелы с каждой стороны, то после выполнения всех преобразований макроопределения, оба знака #(hash) вместе с пробелами будут удалены. Эта особенность часто используется для составления новых идентификаторов. Кроме того, если некоторый параметр макроопределения имеет впереди знак #(hash), то во время преобразования мароопределения соответствующий этому параметру аргумент будет освобожден от пробелов спереди и сзади, а затем заключен в кавычки. Если преобразованный таким образом ар1умент содержит знаки “ (кавычки), то перед каждым из ннх будет стоять косая черта.
Макроопределения, образованные с помощью директивы #define, могут быть аннулированы директивой
fundef Id
Такое аннулирование необходимо прн образовании нового макроопределения, связанного с аналогичным идентификатором, когда ряды лексических единиц в старом и новом определении не идентичны.
Примеры
Использование директивы без параметров
#define SIZE 200
Int ArrfSIZE] [SIZE];
Интерпретация приведенной записи приведет к генерации выражения
Int Агг[200] [200];
Использование директивы ^define с параметрами
•define max(a, b) a>b? a:b main()
{
int x = 5;
prinfC'W, max(x + 3, x - 2));
return 0;
}
Интерпретация приведенной записи приведет к генерации выражения
main()
int х = 5;
printf("%d". х+3>х-2?х+3: х - 2);
}
Использование директивы Wndef •
•define Kaja 13
out(Kaja)
fdeflne Kaja 13
funclef Kaja
out(Kaja)
•define Kaja 14
out(Kaja)
Интерпретация приведенной записи приведет к генерации выражения
out(13)
out(Kaja)
out(14)、
Использование директивы #undef является обязательным, так как лексическая единица в третьей директиве #define отличается от лексической единицы в первой и второй директивах.
Игнорирование макровызовов 6 директивах #define
#def1ne Jan Ewa
#define Kaja Jan
•undef Jan
Kaja
Интерпретация приведенной записи приведет к генерации надписи
Jan
а не (как можно было бы предположить) надписи
Ewa
Игнорирование макровызовов 6 знаковых и строчных литералах
•define j е
#define b wa
#1nclude<stdio.h>
main()
{
prlntfC^cXs, •j*. Mb°); return 0;
Интерпретация приведенной записи приводит к генерации программы, выполнение которой приводит к выводу надписи jb, а не (как можно было бы предположить) надписи ewa.
Многократное развитие макровызовов
•define alfa 5 + beta
#define beta gamma + 3 alfa - beta
Интерпретация приведенной записи приведет к генерации 5 + gamma + 3 -gamma + 3
120Часть /Z. Язык
Использование оператора # #
#defint Jan Ka
#define Ewa ja
#define Kaja Iza
#define Ka Ve
#def1ne ja ra
#define Name(乂. у) x ## у
Name(Jan, Ewa)
Интерпретация приведенной записи приведет к генерации
Vera
Исполь^рвание оператора #
#def1ne Show (var, fmt) printf(#varw = ” fmt, var)
Show(0net ,W);
Show("Two"t "Xa");
Интерпретация приведенной записи приводит к генерации
printf("OneM* = "M%d'\ One);
prlntfCVTwo …=Г sM. иТиои);
Директивы условного включения
В соответствии со своим названием директивы условного включения дают возможность генерирования текстов, идентичных выбранным фрагментам основного текста. В общем случае директива условного включения имеет вид
#if Exp
Те』
#elif 玲pi
Texty
#elif Exp?
Text2
#elif ExpR
Texin
•else
Те%
fendif.
Эта директива начинается с фразы #if и заканчивается фразой #endif. Между этой парой фразможет произвольное число разнаходиться фраза
#elif и только один раз- фраза #else.Выражения Ехри £%во фразах
#if и#endif являютсявыражениями,определяющимиспосоогенерации
текста. Эти выражения должны быть целыми и постоянными, т. е. каждое из них может быть заменено числом, но не может содержать ни оператора sizeof,ни операторапреобразования.Однако онимогутсодержать
подвыражения вида
defined id
или
defined(Zd)
представляющие число 1 или 0 в зависимости от того, определено или нет макроопределение, идентификатор которого совпадает с 2d в момент появления этих подвыражений. Интерпретация директивы условного включения начинается с анализа выражения Ехр. Если значение этого выражения отлично от 0, то всю директиву заменяет Тех%. В противном случае по очередности определяются значения выражений Ехр^ Если значение выражения, например Ехрр отлично от 0, то вся директива заменяется на Texty Если значения всех выражений равны 0, то директиву заменяет Text,. Допускается, чтобы любой из перечисленных текстов содержал директивы условного включения. Директива условного включения может быть также записана в упрощенном виде, не содержащем фразы #else° Для обеспечения соответствия с основной версией языка допускается также, чтобы фраза
#if defined(Id)
была представлена в виде
#ifdef Id
а также, чтобы фраза
#if !defined(Id)
была представлена в виде
#ifndef Id
Примеры
Простая директива условного включения
#if defined(ArrFlg)
int Arr[30];
#endif
Если во время интерпретации директивы определено макроопределение ArrFIg, то приведенная запись дает генерацию выражения
int Агг[30];
В противном случае не будет генерировано ни одно выражение.
Директива условного включении с альтернативой
#if а + b === 5
pritnf(”%d, 5);
♦else
prirtfCW, 13);
fend if
Если выражение a + b — 5 представляет величину, отличную от 0, то будет сгенерировано
printfC'Xd", 5);
В противном случае
printfCW, 13);
Составная директива условного включения
♦define Alfa 3
•define Beta(x) x - 4
#if Alfa == 6
int One;
#elif Beta(2) + Alfa
printf(" Izabela'*);
♦endif
Интерпретация приведенной записи приведет к генерации
printf("Izabela”)
Встроенные директивы
«define Alfa 5
#if Alfa * 5 > 20
maln()
#if Alfa == 4
int Arr [2];
*elif Alfa == 3
char Arr [2];
♦else
{
#endif
♦if 0
printf("IzaM);
#else
printfCKaja'*)
#endif
•else
printf(EwaM);
fendlf■
Интерпретация приведенной записи приведет к генерации
main(),
printf(Kajaw);
}
Примеры написания программ с использованием функций
В данном разделе приведены варианты решения некоторых простых задач, которые основаны не на оптимальном программировании, а на использовании различных языковых средств.
Задача
Определить функцию для нахождения величины аргумента типа (int).
int
abs(par)
int par;
{
return par<0? -par: par;
}
#include<stdio.h>
int vec[3]={30, 0, -30},
ent = 3;
main()
{
while(ent --){
printf("%3d, abs(vec[cnt]));
}
return 0;
Выполнение программы приводит к выводу чисел 30, 0, 30.
Задача
Определить функцию для нахождения квадратного корня аргумента типа (int).
int
root(par)
{
int sum, i. j;
for(sum = j = 0, i = 1; sum<par; J ++)
sum + = (i + = 2) ~ 2;
return, j;
}
# include<stdio.h>
main()
int num;
char ch;
do{
scanf ("%d%c,&rum,8ich);
printf('AnXdXdXn", num, root(num));
J whllefch =- ',*);
return 0;
Выполнение программы приводит к нахождению квадратных корней введенных с клавиатуры чисел. Принимается, что отдельные числа разделяются запятыми, а после псюледнего числа ставится точка.
Задача
Определит^ функцию для нахождения максимального элемента таблицы с элементами типа (int).
int
max(arr, len) int len, arr[];
{
int max = *32768;
while(len --)
if(arr[len]>inax) max = arr[len];
return max;
#include<stdio.h>
int vec[6] = {2, - 3. 5, - 4, 1. 8};
main()
printf("%d"・ max(vec.6));
return 0;
}
Выполнение программы приводит к выводу числа 8.
Задача
Определить функцию для нахождения целой степени аргумента типа (int).
int
power(base, exp) int base, exp;
{
register int res;
for(res = 1; exp > 0 — exp) res *= base
return res;
}
#include<stdio.h>
main()
int pwr;
for(pwr = 0; pwr v 5; pwr ++)
printf("\n%d%2d". pwr, power(2, pwr)); return 0;
Выполнение программы приведет к выводу последовательных степеней числа 2.
Задача
Определить функцию для подсчета количества ненулевых битов в аргументе типа (int).
int
count(bits) insigned bits;
{A
int tally; 〃 for (tally = “"bits; bits»=l) tally += bits & 1;
return tally; }
#include<stdio.h> mafn() {
int num;
char ch;
do{
scanf("Xd%c*\ &num,&ch);
printf(,,\n%d%d\n,,.num, count(num));
} wtiile(ch == l');
return 0;
Выполнение претраммы приведет к подсчету битов в двоичном исчислении введенного ряда чисел. Числа при вводе разделяются запятыми, а последнее число заканчивается точкой.
Задача
Определить функцию, которая оценивает, представлен ли ее аргумент типа (char) прописной буквой английского алфавита.
1supper(с) char с;
register char сс;
return(сс н с)>=,А' && cc<=*Z*;
#include<stdio.h> char name[]="Jan В", агг[5]г pos; mat") {
for(; pos<4; pos ++) arrfpos] = isupper(name[pos] )?"':'•■;
рг1ntf("%s\n%s", name, arr); return 0;
Выполнение программы приводит к выводу надписи JanB и непосредственно под ним записи ! .. ! . Восклицательные знаки помещаются под прописными буквами, а точка - под строчными буквами.
Задача
Определить функцию для преобразования строчных букв английского алфавита в прописные.
char ' toupper(c) •
char с;
{ register char cc; if((cc = c)> = 'a' && cc v = *z*) return cc - * ';
return cc; }
#inc]ude<stdio.h> char pos,
пате[6]«{*J* r *af,*л*,re* r *k*};
main()
for(pos = 0; pos<5; pos ++) printf("%c". toupper(name[pos]));
printf (飞rT); return 0;
Выполнение программы приводит к выводу надписи JANEK.
Задача
Определить функцию, аргументом которой является адрес байта оперативной памяти, а результатом - величина типа (char), находящаяся в этом байте.
char peek(addr)
unsigned addr;
return*(char *)addr;
}
f1nclude<stdio.h>
char letter я 'J';
main()
{
printf(”c". peek((unsigned)&letter));
return 0;
}
Выполнение программы приводит к выводу бу^вы j.
Задача
Определить функцию, которая в типа (char).Определить функцию, которая в типа (char).указанный адрес помещает величинууказанный адрес помещает величину
Определить функцию, которая в типа (char).
Определить функцию, которая в типа (char).
указанный адрес помещает величину
указанный адрес помещает величину
poke(addrt data)
unsigned addr;
char data;«
一 *(char *)addr
}
#include<stdio.h>
char name[3];
ma1n()
{
poke((unsigned)name, *3*);
poke((unsigned)(name + 1). ,b');
pr1ntf("Xs”・ name);
return 0;
Выполнение программы приводит к выводу надписи jb.
Задача
Определить функцию для обозначения длины строки знаков, указанной через аргумент.
int
strlen(s)
char*s;
{
register char *x;
for(x = s; *x++;);
return x - s- 1;
}
#include<stdio.h>
char buffer[81];
ma1n()
{
scanf("%80s". buffer);
prlntff"Length of Xs is Xd. buffer, strlen buffer));
return 0;
}
Выполнение программы приведет к определению длины строки текста, введенного с клавиатуры.
Задача
Определить функцию для копирования знаковых строк.
char*
strcpy(d.s)
char *d,貞s;
{
while((*d++ = *s++) I = 0;
return -- d;
}
findude<stdio.h*
char First Name[] = "Jan'*,
Last Name[] = "Bielecki**,
Full Name[13];
main()
{
*strcpy(strcpy(Full Name, First Name), Last Name) = r\0';
printf(”%s”. FullName);
return 0;
}
Выполнение программы приводит к выводу надписи Jan Bielecki.
Задача
Определение формулы для сравнения знаковых рядов.
int
strcmp(s.t)
char*st*t;
{
while(*s ^= *t ")
if(!*s ++) return 0;
return*s - t[- 1];■
#include<stdio.h>
char First [80],
Second[80];
main()
{
scanf(”Xs Xs”. First, Second);
printf("\n%s%s%sM.
First,
"NOT EQUAL "+(!strcrnp(First; Second)« 2).
Second);
return 0;
}
Выполнение программ» приводит к вводу двух строк знаков и их сравнению. В зависимости ст результата сравнения строк появляется надпись EQUAL или NOT EQUAL.
Задача
Определить функцию для преобразования строки знаков в виде числа к величине типа (int).
int
atol(s)
char*s;
{
int c( val, sign;
while(isSpace(*s)) ++s;
val = 0, sign = 1;
if(*s =='-,)
++s, sign = -1;
else if(*s == *+*)
++s;
while(isDIgitfc = *s++))
val = 10*val + c - 'O'.
return sign > 0?val: -val;
int
isSpace(c) char c;
return c =='';
}
int
isDigit(C)
char c;
{
return c>='0'&&c<='9‘;
#include<stdio.h>
char number[81];
main()
{
scanf("%80s'*r number);
printf("%d". atoi(number));
return 0;
Выполнение программы приведет к вводу знакового ряда в виде числа и Ук выводу числа с таким значением.
Задача
Определить функцию для реализации преобразования величины типа (int) в строку знаков в виде числа.
1toa(val(str) int val; char*str;
{
extern char *extptr;
if(val < 0)
*str ++='■"• val = -val;
extptr = str;
digit(val);
*extptr = '\0*;
char *extptr;
digit(vai) int val;
{
int head;
if((head = val/10)!= 0) digit(heed);
*extptr++ = val % 10 'O';
}
#include<stdio.h>
main()
char mumber[7];
Itoa(~40.number);
printf(M%s,r, number);
return 0;
}
Выполнение программы приведет к преобразованию величины со значением -40 на строку знаков в виде числа и к выводу этой строки.
Задача
Составить программу, содержащую функции для динамического управления оперативной памятью. Реализовать редактор строк, дающий возможность составления текста, состоящего из строк с целыми числами без знаков. Принимается, что если текст строки пустой, то строка удаляется, а если не будут заданы ни число, ни текст, то -будут введены все строки. Принимается также, что каждая введенная строка заканчивается нажатием клавиши Enter, а определение конца файла данных приводит к окончанию определения программы.
#include<stdio.h>
typedef struct Str{
struct Str *next;
int lab;
} LIST;
LIST head = {NULL};
main()
{
LIST *find();
int num, del;
char line [81];
LIST *pos;
num = del = 0;
while(del != E0F){
1f(!num)
display();
else{
pos = find(num);
1f(pos-> next && pos -> next -> lab == num) delete(pos);
if(deT! = ,\n'){
getL1ne(11net SI);
insert(pos, num, line);
,}
}
getNumber(&num,&de1);
}
return 0;
}
LIST *
find(num)
Int num;
{
LIST *ref;
ref = &head;
whilefref -> next && ref ->next -. labsnum)
ref = ref -> next;
return ref;
}
delete(pos)
LIST *pos;
{
LIST *ptr
ptr = pos ->next;
pos->next = ptr ->next;
free((char *)ptr);
}
getLInefptr, max)
char *ptr;
Int max;
{
Int if c;
for(1 =0;
v max -1 && (c = get char(J) !=*\n*
++) *ptr ++ = c;
if(c !='\n‘)
9*
while(getchar() l='\n');
*ptr = 0;
}
length(H ne)
char*line;
{
Int len;
len = 0;
wh11e(*11ne++)
len++
return len;
}
1nsert(pos num.line)
LIST*pos;
Int num;
char 11ne[];
{
LIST*ptrf *ref;
int size;
size * sizeof(LIST*) + slzeof(lnt) + length(line) + 1;
1f((ptr ■ (LlST*)calloc(lr size)) 1 = NULL){
ref = pos ->next;
pos->ne、t ■ ptr;
ptr->next ■ ref;
ptr~>lab ■ num;
fill((char*)(ptr + 1), Une);
} else
pr1ntf(MIgnored. -Out of memory);
}
dlsplayO
{
LIST*ref;
ref = head.next;
while(ref){
print('X3d%s\n”・ ref->1ab, (char *)(ref + 1));
ref = ref~>next;
}
}
fH1(ref, line)
char *ref, *11ne;
{
whlle((*ref ++ *11ne ++) ! « 0;
}
void
getNumber(num,del)
1nt *num.*del);
{
Int c. val.
val = 0;
wh11e((c ■ getchar ())> s fo' && c<='9‘)
val = 10 *val + c - *0*;
*num ■ val;
*del = с;
}
Если входной файл связан с клавиатурой, с которой будет введен ряд строк
30 Ewa
20 IZa
40 Jan
Kaja.
то после введения строки будет выведена запись
Kaja
20 Iza
30 Ewa
40 Jan
Если затем будет введен ряд строк
20
30
40 Vera.
то после введения пустой строки будет выведена надпись
10 Kaja
40 Vera
Задача
Составить программу, выполнение которой анализирует файл данных и подсчитывает количество знаков в файле, которые не являются пробелами.
finclude<stdio.h>
ma1n()
{
int count;
char name [20];
FlLE*fopen();
Int chr;
FILE*inp;
getName(name);
if((inp = fopen(namer "r"))==NULL){
printf("Can4 open file %s", name);
exit ⑴;
}
for(count = 0; (chr = getc(inp)) I = EOF;)
if(nonwhite(chr)) count ++;
printf("Fi1e %s contains %d nonwhites'*,
name, count);
return 0;
int
nonwhlte(chr)
char chr;•
{
return!(chr «* , *[!
chr > *\f I:
chr == M :; chr == чг*!! chr == '\v';: chr == V);
getName(name)
char*name;
{
int c; 浦
■hile((c =get char())l = *\л* && c! = EOF)
*name++ * c;
*name='\0‘;
Выполнение программы приводит к вводу имени файла, определению числа знаков данного файла, исключая пробелы, и к выводу строки вида
File SOURCE.DOC contains 234 nonwhites
Задача
Составить программу, выполнение которой приводит к соединению группы файлов в один файл. Принимается, что первым артументом вызова программы является имя выходного файла, а остальными аргументами являются имена входных файлов.
ficlude<stdio.h>
main(argc, argv)
Int argc;
char *argv[];
FILE *fopen() *1np, *out;
1f(argc— == 1) exlt(O);
If((out = fopen(*++ argv. *V*)) = = NULL){ printf("Can't open output fHe**);
exlt(l);
}
while(—argc){
1f((inp = fopen(*++ argv, "r”)) == NULL){ printf ("СапЧ open input file %s”. *argv); exit (1);
}
append (out, Inp);
}
fclose(out);
printf(”Done・・);
return 0;
}
append(out, inp)
FILE *out, *inp;
{
Int chr;
wh"e((chr. fgetc( 1 np))! =E0F)
fputc(chr, out);
Если в файле SOURCE.DOC находится надпись
Jan Bielecki,
то выполнение программы с аргументами TARGET.DOC SOURCE.DOC SOURCE.DOC
приводит к размещению в файле TARGET.DOC надписи
Jan Bielecki
Jan Bielecki
Стандартные расширения
Язык Турбо Си имеет расширение основного языка, которое описано в книге В. Kernighan, D. Ritchi “The С Programming Language'"). Большинство его новых элементов следуют из стандарта расширения языка Си, разработанного ANSI, и описаны ниже. Некоторые из них уже упоминались ранее.
Ключевые слова
В качестве*5 ключевых слов основного языка могут быть использованы следующие слова: const, enum, signed, void и volatile.
Литералы
Расширения языка касаются целых, знаковых литералов, литералов с плавающей точкой и строчных литералов.
Целые литералы
Целые литералы могут быть записаны в десятичном, восьмеричном или шестнадцатеричном виде. Если после записи литерала следует буква U, то литерал представляет целое данное без знака. Если после записи литерала следует буква L, то литерал представляет длинное целое данное. Если имеются обе буквы, то литералы представляют длинное целое данное без знака. Буквы U и L могут быть также прописными. О типе литерала судят на основе его значения. В качестве типа литерала берется первый из установленных списков типов, к которому принадлежит величина со значением литерала. Списки типов могут быть следующими:
-для десятичных литералов, не содержащих дополнительных букв
(int)
(long int)
(unsigned long int)
-для восьмеричных и шсстнадцатеричных литералов, не содержащих дополнительных букв.
(int)
(unsigned int)
(long int)
(unsigned long)
D Имеется русский перевод: Керннган Б., Ритчи Д.» Рьюэр А. Язык программирования Си. Задачи по языку Си. - Прим, перев.
-для литералов с дополнительной буквой U
(unsigned int)
(unsigned long int)
-для литералов с дополнительной буквой L
(long int)
(unsigned long Int)
Примеры
Литерал
ЗначениеТип литерала
32767 32768 077777 0100000 13L OxF Oxful
32767(int)
32768(long int)
32767(int)
32768(unsignedint)
13(long int)
15(unsignedint)
15(unsignedlong int)
Знаковые литералы
Знаковые литералы метут состоять из одного или двух знаков. Двухзнаковые литералы трактуются как величины типа (int), в представлении которых первый знак занимает байт с меньшим значением, а второй - с большим. Однознаковые литералы также являются величинами типа (int). В этом случае по умолчанию принимается, что при преобразовании величины типа (char) к величине типа (int) происходит увеличение бита знака. Это приводит к тому, что знаковые литералы, представляющие знаки с кодами, большими, чем 127, трактуются как данные типа (int) с отрицательными значениями.
Список описаний знаков дополнился описанием \а, представляющим знак звонка, а также описанием \?, представляющим знак вопроса. Кроме этого, непосредственно после косой черты можно указать не только восьмеричный, но и шестнадцатеричный код знака. В последнем случае перед шестнадцатеричными цифрами должна стоять буква х.
Пример
#1nclude<stdio.h>
main()
{
putchar(*\a');
putchar('\x4A');
putchar(7\x42*);
printf("\n=%d, 'JB');
return 0;
}
Выполнение программы приводит к выводу знака '\а' (звуковою сигнала), пары знаков JB, а также значения величины типа (int), представ-
ленной в программе посредством двухзнакового литерала JB.
Результат, выполнения программы был бы таким же, если двухзнаковый литерал заменить выражением
《'В,« 8) + 丁
Литерал с плавающей точкой
В основном языке все литералы с плавающей точкой имеют тип (double). В расширенном языке литерал с плавающей точкой, имеющей дополнительную букву F, представляет величину типа (float), а букву L - величину типа (long double). Буквы F и L могут записываться также в виде прописных букв. Величины типа (ling double) являются величинами с плавающей точкой удвоенной точности. Ввод и вывод таких величин может производиться с помощью шаблонов преобразования, содержащих букву (прописную или строчную).
Пример
f1nclude<stdio.h>
main()
{*
long double Number = 1.23456789L;
print*"Number = %lf"・ Number);
return 0;
}
Выполнение программы приводит к присвоению переменной Number величины с плавающей точкой типа (long double), а затем к выводу надписи
Number = 1.234568
Строчные литералы
Расширенный язык дает возможность сегментирования строчных литералов. Это основано на том, что если непосредственно друг за другом следуют два строчных литерала, то они трактуются как один литерал, состоящий из всех знаков первого литерала и всех знаков второго. Указанное расширение облегчает запись строчных литералов, которые занимают более одной строки программы.
Пример
#1nclude<stdio.h>
mafn()
{
printf ('* Jan"
” Andrzej” “Bielecki”); return 0;
}
Выполнение программы приводит к выводу надписи Jan Andrzej Bielecki.-
Операторы
Список операторов дополнился одноаргументным оператором + (плюс). Этот оператор дает возможность использования скобок и исключает трактование, например, выражения
а + (Ь + с)
как выражения
(а + Ь) + с
Результатом операции + (плюс) является величина, представленная через ее аргумент
Пример
#1nclude<std1o.h>
mafn()
{
double Big = 2e20.
Small = le-5;
prlntfCT* - Big + + (Big + Smell));
return 0;
Выполнение программы приводит к выводу приближения числа 0. Если убрать из программы одноаргументный оператор + (плюс), то мог бы произойти вывод приближения числа 0.00001.
Типы данных
Расширенный язык содержит новые первичные типы: дополнительный арифметический тип с плавающей точкой (long double), перечислимый тип (enum) и тип, связанный с пустым файлом данных (void). Дополнительными первичными типами являются типы, имена которых содержат модификаторы signed, unsigned, const и volatile. Два первых типа дают возможность описания переменных, которым соответственно могут быть присвоены величины со знаком (signed) или без знака ( unsigned). Два остальных типа дают соответственно возможность описания переменных, которым в программе могут быть присвоены начальные значения (const), а также таких переменных, присвоение значений которым может производиться неконтролируемым программой способом (volatile).
Тип (void)
В отличие от остальных типов тип (void) связан с пустым файлом данных. Поэтому нет смысла и не существует возможности описания переменных типа (void), поскольку нет величин, которые можно им присвоить. Тем не менее есть ряд важных применений этого типа и связанное с ним Ключевое слово. Простейшим использованием ключевого слова void является
его помещение в описание функции. Принимается, что, если в месте списка параметров находится ключевое слово void, то функция - без параметров.
Пример
#1nclude<stdio.h>
malnf)
{
fun();
return О:
}
fun (void)
{
printf("Empty”);
}■
Ключевое слово void может быть также использовано для обозначения того, что функция не дает результата, и для преобразования, приводящего к явному исключению результата оператора-выражения.
Пример
#1nclude<std1o.h>
ma1n()
{
void fun(); fun();
void fun()
{
char *Name;
(void)(Name * "Izabela");
printf("XsM. Name);
return 0;
}
Выполнение программы приводит к выводу надписи Izabela. Выполнение преобразования (void), стоящего перед присваиванием, приводит к исключению результата присваивания (значение указателя на первый знак выражения Izabela).
Тип (void ")
Важнейшим применением типа (void) является возможность использования величин типа (void ♦). Указатели этого типа, естественно, не могут быть очищены, так как величин типа (void) не существует. Однако они могут использоваться во всех тех контекстах, где производится локализация переменной в оперативной памяти вне зависимости от типа этой переменной. Другими словами, насколько обычные указатели применяются для локализации объектов, настолько указатели типа (void*), называемые адресными указателями, служат для локализации объемов оперативной памяти.
Важной особенностью расширенного языка является возможность преобразования величины типа (void*) в величину любого другого указывающего типа, а выполнение условия ехр - в выражение
(typ) (void*) (exp) = (ехр)
где ехр - произвольный указатель выражения типа (typ)»
Внимание: Кроме перечисленных преобразований величин указывающего типа независимо от реализации существуют преобразования пустых указателей на пустые указатели других типов. Преобразование остальных указателей зависит от реализации, но если не происходит изменение размера указателя, то производится изменение представления величины. Такой способ выполнения преобразования принят, в частности, в Турбо Си.
Пример
#include<stdio.h>
ma1n()
{
void *calloc(unsigned, unsigned);
void *Ref = calloc(3.1);
((char*)Ref[0]='『;
((char*)Ref)[l] = W;
pr1ntf(M%st (char*)Ref); return 0;
Выполнение программы приводит к выводу надписи jb. Результатом функции calloc является адресный указатель.
■ 12.5. Модификаторы
Модификатором является ключевое слово, которое определяет дополнительные возможности переменной указанного или принимаемого по умолчанию типа. Модификаторы signed и unsigned позволяют присвоить описанной переменной значение со знаком или без знака. Модификатор const определяет, что после описания переменной ей не будут присваиваться другие значения, а использование модификатора volatile означает, что присваивание значений описанной переменной может происходить не контролируемым программой способом.
Модификатор signed
Модификатор signed (со знаком) может стоять перед следующими ключевыми словами: char, int, short int, long int. Использование его перед int, short int н long int излишне, поскольку величины этих типов всегда имеют знак.
Внимание: Так как в языке Турбо Си принимается по умолчанию, что тип (char) идентичен типу (signed char), то и в этом случае использование Модификатора излишне.
Пример
#1 nc lude<std1o .2
maln()
{
signed char Vdr = *\377*;
printfC'Xd0, Var);
return 0;
}
Выполнение программы приводит к выводу числа -1. Если исключить из программы модификатор signed, то с точки зрения стандартного языка программа была бы неоднозначной, поскольку ее выполнение могло бы привести к выводу как числа -1, так и числа 255.
Модификатор unsigned
Модификатор unsigned (без знака) может стоять перед следующими ключевыми словами: char, int, short int, long int. Его использование перед словом char приводит к тому, что во время преобразования величины типа (unsigned char) к величине типа (int) не происходит увеличение бита знака.
Пример *
#tnclude<stdio.h>
main()
{
unsigned char Var = "\377‘.
printfC^Var); return 0;
}
Выполнение программы приводит к выводу числа 255. Если убрать из программы модификатор unsigned, то ее выполнение в системе Турбо Си привело бы к выводу числа -1.
Модификатор const
Использование модификатора const приводит к тому, что выражение, имя типа которого начинается с этого модификатора, представляет переменную, которая с точки зрения программы сохраняется как постоянная.
Имя такой переменной не может находится в левой части оператора присваивания, а также быть аргументом операторов инкремента, декремента и указания. Единственно, где переменной, описанной с атрибутом const, можно присвоить значение, является ее описание. Это объясняет использование для такой переменной названия постойной переменной. Такой переменной является, например, переменная Min, описываемая как
int const min н -13;
а также указатель Greet, описываемый как
char * const Greet = "Hello";
Поскольку описанная таким образом переменная Min является постоянной переменной, для нее невозможна, например, операция .
Min ++
По аналогичным причинам невозможно выполнение с переменной Greet, например, операции
Greet = "Good bye"
В то же время ничто не мешает выполнить, например, операцию
Greet [4] ='!*
Пример
#include<std1o.h>
const int Arr[2] = {12, 13},
*Ptr = Arr;
main()
{
const int *const Ref = Ptr;
printff'Xd", *Ref);
return 0;
}.
Выполнение программы приводит к выводу числа 12. В программе описаны двухэлементный массив постоянных переменных типа (int), переменная Ptr, указывающая на постоянную переменную типа (int), а также переменная Ref, указывающая на переменную типа (int).
Величина, присвоенная переменной Ref, подобрана таким образом, что она указывает иа тот же объект, что и Ptr, т.е. на первый элемент массива Агг.
Следует обратить внимание, что в приведенных описаниях можно пользоваться, например, операцией Ptr++, однако нельзя пользоваться операцией Ref++, так как Ref является постоянной переменной.
Модификатор volatile
Использование модификатора volatile дает возможность описания временных переменных, т.е. переменных, которым значения могут присваиваться неконтролируемым со стороны программы способом н даже в том случае, когда эти переменные описаны с модификатором const.
Программа, содержащая обращения к временным переменным, может быть оптимизирована только в ограниченных пределах. Это приводит к тому, что в характеристических точках программы значения, присвоенные временным переменным, будут точно такими же, как и значения, которые были бы присвоены этим переменным в случае, когда программа не подлежала бы оптимизации н выполнялась строго в последовательности 夕 расположения ее операторов.
Принимается, что характеристической точкой программы является:
-место, в котором оканчивается обработка аргументов функции; ,
-место нахождения любого из следующих операторов: конъюнкции (&&〉, альтернативы (II), условия (?) и соединения (,);
-место, в котором завершена обработка сложного выражения, в том числе выражения, инициирующего автоматическую переменную; выражения, образующего оператор-выражение; выражения, идущего после ключевых слов if или switch, а также выражения, определяющего ход выполнения операторов цикла while, do или for.
Пример
#include<std1o.h>
volatile Int *Ptr = (int *)…;
matn()
{
register FJx = *Ptr;
printfCW. *Ptr);
printfCW. *Ptr);
return 0;
Выполнение программы приводит к двухкратному выводу значения, присвоенного .переменной, указанной через Ptr. Поскольку указываемая переменная является временной, то выводимые значения могут быть разными. В связи с этим неправильной была бы оптимизация пары операторов printf к виду
printfcw. Fix);
printf("%d'\ Fix);
(Это было бы допустимо, если бы в программе не находился модификатор volatile.)
Структурные выражения
Структурное выражение представляет структуру или объединение. Обычно оно имеет вид идентификатора, но может иметь также вид присваивания или вызова функции. Структурное выражение может быть только левым аргументом структурного оператора, правым аргументом оператора присваивания и может быть заключено в круглые скобки.
Пример
#1nclude<stdio.h>"
struct COMPLEX{
double Re„ Im;
} Str = {- 3.0. 4.0};
main()
{
struct COMPLEX Cut(struct COMPLEX);
struct COMPLEX Tmp;
Tmp н Cut(Str);
printf(M% If. X, If)*, Tmp.Re Tmp.Im);
return 0;
Struct COMPLEX
Cut(Struct COMPLEX Par) {
Par.Re = fabs(Par.Re)
Par.Im = fabs(Par.Im); return Par;
Функции с переменным числом аргументов
Функция, которая может быть вызвана с переменным числом аргументов, характеризуется тем, что в месте ее последнего параметра находится параметр ... (многоточие). Нельзя вызвать такую функцию с числом аргументов меньше числа параметров перед этим лексическим символом. Обращения к аргументам, представленным через параметр многоточие, должны проводиться посредством макровызова va—arg, первым ар^ментом которого является имя вспомогательной переменной типа va—list, а вторым - имя типа аргумента. Первому (в данной функции) обращению к макроопределению va^arg должно предшествовать макроопределение va—start, а после последнего обращения должен находиться макровызов vaYnd. Первым аргументом va—start и первым аргументом va—end является имя упомянутой вспомогательной переменной, а вторым аргументом va-start является имя параметра функции, стоящего перед параметром многоточие. Все оговоренные макроопределения имеются в файле заголовка stdarg4h.
Пример
#include<stdio.h>
enuni Type {Char. - Int, Float};.
matn()
{
void Outfint, enum Type, …);
0ut(3, Char, 'E'. *w*. ra*);
0ut(2, IntB 1, 3);
Out(l, Float, 4, 8f);
return 0;
}
#include<stdarg.h> void
Out(int Count, enuiri Type Sort. ...) {
va_Mst Area;
va-start(Area, Sort);
pr1ntf("\nw);
while(Count ——) switch(Sort){ case Char: printf('*%c, va arg (Area, Int); break;
10—76410—764case Int;
10—764
10—764
printf("Xd'*, va_arg(Area, int)); break;
case Float;
prtntf("Xf"・ va_arg(Area, double));
} va_end(Area);
}
Выполнение программы приводит к выводу
Ewa 13 4,800000
13. Нестандартные расширения
Описанные здесь расширения выходят за пределы стандарта ANSI, что приводит к непереносимости, где используются эти расширения.
Использование нестандартных расширений связано с использованием в программе следующих ключевых слов:
pascal
cdecl interrupt
near
ar huge
asm
_AX_AH_AL_BX_BH_BL
_CX_CH_Ct_DX_DH_DL
_CSJS_SS_ES
_SP_BP_DI一SI
Ключевые слова pascal, cdecl и interrupt дают возможность смены способа вызова и генерации кода функции, а слова near, far и huge дают возможность оптимального использования указателей. Слово asm дает возможность получения в программе ассемблерных вставок, а слова, начинающиеся со знака подчеркивания, дают возможность обращения в основной программе к регистрам процессора. Поскольку перечисленные слова не принадлежат к стандарту ANSI, каждый модуль, который содержит по крайней мере одно из них, должен быть компилирован с опцией
O/C/S ANSI keywords only Off
Модификаторы pascal и deci
В большинстве реализаций языка Си аргументы функции обрабатываются справа налево и размещаются в стеке, увеличивающемся в направлении низших адресов. Кроме этого, извлечение аргументов нз стека производится вызывающей функцией, а не вызываемой. Эта особенность очень облегчает использование функций с переменным количеством аргументов. То же самое свойство присутствует и в Турбо Си. Тем не менее благодаря использованию модификатора pascal можно сделать так, что накопление аргументов в стеке будет происходить слева направо, а извлечение аргументов из стека будет производиться вызываемой функцией. Побочным результатом использования рассматриваемого модификатора является передача компоновщику имени функции, перед которой нет знака подчеркивания, и преобразование ее происходит путем замены строчных букв на заглавные. Использование модификатора pascal в описании переменной приводит только к замене строчных букв идентификатора на заглавные, а также к снятию перед ним знака подчеркивания.
Если требуется, чтобы вся программа была скомпонована так, чтобы в описании каждого идентификатора переменной н функции выступал модификатор pascal, то используют опцию компилятора
O/C/Code generetion/Calling convention Pascal
Пример
#include<stdio.h>
ma1n()
{
int pascal surn(int a. int b);
printf("surn = %d", sum(2.3)j;
return 0;
}
int pascal s£rn(int x, int y)
{
return x+y; }
Выполнение программы приводит к выводу числа 5.
Идентификатор sum будет передан ком поновщику в виде SUM, а аргументы 2 七 3 разместятся в стеке в порядке их нахождения в вызове функции. Извлечение аргументов из стека производит функция sum. Если программа была скомпилирована с опцией Calling convention Pascal, то ее отдельные функции могут быть скомпилированы, как в языке Си при условии, что перед их идентификаторами стоят модификаторы cdecl. Если программа была скомпилирована с опцией Calling convention С, то использование модификатора cdecl не будет иметь никаких последствий.
Надо подчеркнуть, что если программа скомпилирована с опцией Calling convention Pascal, то все библиотечные функции должны быть описаны с модификатором cdecl. Это касается не только таких функций, как printf, но также функции main, которая всегда вызывается в языке Сн.
Пример
#include<stdio.h>
cdecl main()
{
printff^Izabela"); return 0;
Выполнение программы приводит к выводу надписи Izabela. Программа будет выполнена правильно независимо от того, была ли она скомпилирована как программа на языке Паскаль или Си.
Использование описания
int cdecl printf(...
излишне, так как оно находится в файле заголовка stdio.h
Модификатор interrupt
Функции, предназначен ные для обслуживания прерываний, должны описываться с модификатором interrupt. От остальных функций они отличаются тем, что в стеке размещаются не только регистры BP, SP, SS, CS и IP, но и регистры АХ, ВХ, СХ, DX, SI, DI, ES и DS.
Пример
#include<stdio.h>
#fnclude<dos.h>
#define INT OxlC
static Flag:
static Count;
void interrupt far
timer()
if(Count ++ %18) return;
Flag ++:
}
main()
{
void interrupt (far *Ref)();
auto 1=0;•
Ref = getvect(INT);
setvect(Intr timer);
while(! kbhit()){
pr^ntf("\n%d^^, i++);
if(Flag)
Flag — . putchar('\a*);
}
setvect(INT, Ref);
return 0;
Выполнение программы приводит к выводу последовательных целых чисел. Приблизительно каждую секунду раздается звуковой сигнал. Программа составлена таким способом, что временной перерыв приводит к асинхронной активизации функции timer. Функции setvect и getvect использованы для изменения вектора прерываний.
Модели памяти
В микрокомпьютерах IBM PC адреса оперативной памяти имеют 20 бит и составлены из двух 16-бит частей: номера сегмента и смещения в сегменте. Если принять, что номер сегметгга обозначен символом seg, а смещение символом off9 то адрес определяется по формуле
addr = (seg « 4) + off
Выполняя трансляцию программы на машинный язык, было бы удобно пользоваться адресами, состоящими из двух 16-бит величин: номера сегмента и смещения в сегменте. Однако это не является оптимальным вариантом, и чаще всего сегментная часть хранится в регистре микропроцессора, а адреса данных и операторов определяются адресом, обозначенным сегментной частью. Благодаря этому адреса данных и операторов результирующей программы являются 16-бит. Ограничения на использование смещений вполне удовлетворяются для программ, у которых ни код, ни данные не превышают 64 Кбайт памяти. В случае более длинных программ необходимо пользоваться полными 32-бит адресами, касающимися только данных, только кода или как кода, так и данных. В зависимости от размера кода и данных программы можно выбрать одну из 6 моделей памяти:
модель Tiny - данные и код вместе не могут занимать более 64 Кбайт памяти. Адресация данных и кода производится с помощью 16-бит указаний. Только программы, основанные на модели Tiny, могут быть преобразованы из вида .EXE к виду .СОМ;
модель Small - ни данные, ни код не могут занимать более 64 Кбайт памяти. Адресация данных и кода производится с помощью 16-6ит указаний;
модель Medium - код может занимать более 64 Кбайт памяти. Адресация кода производится с помощью 32-бит указаний, а адресация данных - с помощью 16-бит;
модель ^Compact - данные могут занимать более 64 Кбайт памяти. Код не может занимать более 64 Кбайт памяти. Адресация данных производится с помощью 32-бит указаний, а адресация кода - с помощью 16-бит;
модель Large - как данные, так и код могут занимать более 64 Кбайт памяти. Адресация данных и кода производится с помощью 32-бит указаний;
модель Huge - разновидность модели Large. Отличается тем, что во время обработки сравнений и соотношений выражений указания нормализованы. Это основано на тождественном преобразовании адреса, при котором его смещение имеет значение в пределах от 0 до 15.
Выбор модели памяти и, следовательно, способа адресации данных и кода производится вне программы (в интегрированном компиляторе с помощью опции Options / Compiler / Model, а в загруженном компиляторе с помощью опции -т). По умолчанию принимается модель Small. Задействование конкретной модели приводит к однозначному трактованию всех указаний переменных и функций. Если по некоторым причинам надо трактовать выбранное указание по-другому, то можно воспользоваться модификаторами адресации, выраженными с помощью ключевых слов near, far и huge.
Каждый из модификаторов near, far н huge может выступать только в описании или в псевдоописании (т.е. в описании, с которого снят идентификатор). Если модификатор находится • в описании, то он может стоять только перед идентификатором функции или оператором * (звездочка). В первом случае явно или по умолчанию появление модификатора определяет, будет ли выделено место для функции в сегменте данных (near) по умолчанию или за ним (far и huge). Во втором случае использование модификатора определяет реализацию связанного с ним указания как near, far или huge. В частности, обработка описания
char huge * Агг[3];
приведет к созданию трехэлементного массива указаний типа (char huge *). Если находяхцийся в описании идентификатор функции не имеет перед собой модификатора адресации, то принимается по умолчанию:
near - для модели Tiny, Small, Compact
far - для модели Medium, Large, Huge
Аналогично для операторов * (звездочка} у находягцихся в описаниях и псевдоописаниях, по умолчанию принимается
near - для модели Tiny, Small, Medium
far - для модели Compact, Large, Huge
Модификатор near
Указатель, описанный с модификатором near, представляется в 16-бит памяти. Указания переменной состоят только из смещения адреса в сегменте. Номер сегмента хранится в регистре процессора и является общим для нескольких переменных.
Поскольку для указателей категории near номер сегмента всегда один, то операции сравнения и арифметические операции, относящиеся к этим указаниям, ограничиваются смещением.
Пример
#include<stdio.h>
main()
{
int Fix 二 13.
*Ptr = & Fix,
near *Ref = Ptr;
printfCW, *Ref);
return 0;
}
Если программа будет скомпилирована в модели Small, то по умолчанию принимается, что переменная Ptr имеет тип (int near*), и выполнение программы приведет к выводу числа 13.
Если программа будет скомпилирована в модели Large, то по умолчанию принимается, что переменная Ptr имеет тип (int far*), и программа будет ошибочной, так как Ptr будет представлять далекие указания (far), а переменной Ref могут быть присвоены только близкие указания (near).
Модификатор far
Указатель, описанный модификатором far, представляется в 32-бит памяти. Указания, присваемые этой переменной, состоят как из номера сегмента (более значимая часть), так и из смешения в сегменте (менее значимая часть).
Использование указаний категории far дает возможность обращения к переменным и функциям в программах, где соответственно данные или код
занимают 64 Кбайт памяти. Требуется, однако, иметь в виду, что сравнение таких указаний не всегда дает ожидаемые результаты. Это следует из того, что при сравнении величин с помощью операторов равно (=) и не равно (! «О равенство подтверждается только, когда указания идентичны, а не только эквивалентны. В сравнениях, реализуемых с помощью остальных операторов отношения (например, >=), соотносятся между собой только смещения. Требуется также обратить внимание, что в арифметических операциях с указателями изменению подлежит только смешение, что может привести к преобразованию указания в указание, что не эквивалентно.
Пример
#include<stdio.h>
union{
unsigned Хгг[2];
int far * Var;
} Ref = {0x6e, 0x40},
Ptr = {OxOe, 0x46};
main()
{
printfCW, %d, %d, *Ref.Var,
Ref.Var == Ptr.Var,
*Ptr.Var);
return 0;
}
Выполнение программы приводит к выводу надписи h,O,h, где h - текущее время. Несмотря на то что значения, присвоенные переменным Ref.Var и Ptr.Var, указывают на одну переменную (а следовательно, эквивалентны), отношение в вызове функции printf не справедливо. Это объясняется тем, что сравнение касается только смещений.
Модификатор huge
Указатель, описанный модификатором huge, представляется так же, как указатель, описанный модификатором far.
В отличие от указаний категории far указания категории huge нормализованы, а сравнения и арифметические операции, принадлежащие этим указаниям, не ограничиваются смещениями, а касаются также номеров сегментов. Благодаря этому результаты сравнений всегда соответствуют ожидаемым.,
Пример
•include <std1o. h>
#include<alloc. h>
define COUNT 20000
long int Sum;
long huge * Ptr;
main()
if((Ptr=farсаГ1ос(Count, sizeof(long)))==NULL){ рг i ntf (,f\nFa i lure! **); exit(13);
{
Ptr[Count - 1] = 13;
for(i = 0; i<C0UNT;i++)
Sum += Prt[i];
printf("\n%ld". Sum);
return o;
Выполнение программы приводит к выводу числа 10000.
Если заменить модификатор huge на far, то произошел бы вывод непределенного числа.
Несколько замечаний:
Если выбрана модель памяти Small, то Ptr - указатель, которому могут быть присвоены указания в виде переменных типа (char), a Ref - указатель, которому могут быть присвоены близкие указания таких переменных, которым могут присваиваться далекие указания переменных типа (int).
char huge * Ptr;
int far ** Ref;
Если выбрана модель памяти Large, то Ptr - указатель, которому могут быть присвоены далекие указания таких переменных, которым могут быть присвоены удаленные указания переменных типа (char).
char huge ** Ptr;
Независимо от выбранной модели Ptr - указатель, которому могут быть присвоены близкие указания таких переменных, которым могут присваиваться далекие переменные типа (char), a Ref - переменная, которой могут быть присвоены далекие указания таких переменных, которым могут быть присвоены далекие указания переменных типа (unsigned int).
char far * near * Ptr;
unsigned far * far * Ref;
В результате принятых ограничений на расположение модификаторов near, far и huge в Турбо Си ошибочными будут следующие описания:
float Агг[20000];- поскольку (обширный) массив занимает более
64 Кбайт памяти;
char far Вгг[20];- поскольку не реализованы далекие переменные, а
только далекие указания.
Бнимание: В отличие от переменных функции могут быть описаны как близкие, далекие и удаленные. Описание функции как близкой ускоряет обращение к ней, но ограничивает ее использование модулем, в котором она была описана.
Ассемблерные вставки
Каждая ассемблерная вставка начинается ключевым словом asm, а заканчивается знаком; (точка с запятой}. Если точка с запятой является последним знаком строки, то этот знак может быть опущен. В строке можно записать несколько ассемблерных вставок. Ассемблерная вставка трактуется как оператор основной программы. Модуль, содержащий ассемблерные вставки, должен начинаться с директивы
♦pragma inline
или должен компилироваться с опцией -В.
Внимание: Ассемблерные вставки могут находиться только в программах, использующих загрузочный компилятор (ТСС).
Пример ♦
讦(а > 5){
asm mov ah, 1; asm mov al, 2
} else
asm mov ahr 3
asm mov al, 4
Опускание фигурных скобок невозможно. Последняя вставка выполняется всегда, если не отнсюится к условному оператору.
Ассемблерная вставка может иметь вид оператора или описания величины. Если она имеет вид оператора, то после ключевого слова asm идет код операции и аргументы, а если вид описания, то вместо кода операции выступает директива макроассемблера, такая, как db, dd, dw и extern. Ассемблерные вставки, имеющие вид оператора, размещаются в сегменте кода, а имеющие вид описания - в сегменте данных.
Пример•
asm Fix db 13
asm TRUE equ -1
asm,286
asm Lab call Fun
asm mov ax, word ptr[bx + 2]
Ассемблерные вставки могут содержать обращения к произвольным переменным программы, но если ассемблерной вставкой является команда перехода, то нельзя обращаться к метке, содержащейся в другой ассемблерной вставке.
Если ассемблерная вставка содержит обращение к параметру или переменной локальной функции, то оно заменяется обращением через регистр ВР (гл. 15).
Если ассемблерная вставка содержит обращения к полю структуры, то его идентификатор трактуется как литерал со значением, равным разности адреса поля и адреса структуры. В этом случае, если идентификация поля структуры не однозначна (так как существуют две структуры с одинаковыми полями), то имя поля должно быть подвергнуто преобразованию.
Иногда вместо ассемблерной вставки достаточно воспользоваться символьным обозначением регистра процессора. В таком случае компиляция программы может быть выполнена также в интец)ированной системе. Полный список допустимых символов регистров
16-бит регистры, тип (unsigned int)
-AX, -CS, -SP,
—BX, —CX, -DX,
-DS, -SS, -SS
-BP, -DI, -SI
8-6um
регистры, тип (unsigned char)
—AH,
-CH,
-AL, -BH, ~BL
-CL, -DH, -DL
Примеры
В комментариях дан способ трактования вставок,
Обращения к параметрам и переменным локальных функций
#pragma inline
finclude <stdio.h>
int Global;
main(argc, argv)
int argc;
char *argv[];
{
int Local;
asm mov ax, argc
/* mov ax,[bp + 4] */
asm mov Globalr ax
/* mov DGROUP: Global, ax */
asm nrov ax. Global
/* mov, ax, DGROUP:—Global */
asm mov Local, ax
/* mov [bp - 2], ax */
printf(M%s = %d", argv[0]. Local);•
return 0;
}
Обращения к полям структуры
fpragma inline
struct Girl{
char Name[10];
Int Age;
enum Hair {Bion, Black} Color;
} Isa = {'.Isabel.', 0,Black};
struct Boy{
char Name[10];
int Age;
} Bob «^"Robert"};
#include<stdio.h>
main()
{
Isa.Age = 6;
/* mov wordptr DGROUP:_Isa + 10.6 */
asm n»v bx. OFFSET Isa;
/* mov dx, OFFSET DGR0UP:_Is『/
asm mov ax. [bx]. (struct Girl)Age
/* mov axf [bx] + 10 */
_AX += 4;
/* add axr 4 */
asm mov Bob. (struct Boy)Age, ax
/*mov DGROUP: _Bob + 10. ax */
printf^Bob is Xd". Bob.Age);
return 0;
}
Использование ключевых слов, обозначающих регистры процессора
int
пих(1 nt х, int у) {
_АХ * х
asm стр ах. у
asm jge done
asm mov ax, у
done:
return AX;
}
Внимание: Для запуска программ, содержащих ассемблерные вставки, эффективно использование опции -S, так как это приводит к получению в явном виде кода ассемблерной программы.
14. Программирование графики
Для использования графической библиотеки системы Турбо Си требуется в каждом из основных модулей программы, где находится обращение к графической функции, поместить директиву include, задействующую содержание файла заголовка с прототипом функции:
conio.h для функции текстовой графики,
grafics.h для функции пикселной1) графики, (выбранные описания, содержащиеся б этих файлах, находятся в приложении Г).
Пример. Составление и выполнение графической программы
#include<con.io.h>
ma1n( ){
{
clrscr();
gotoxy(20. 13);
cprintff^Hello, I am Jan B”); return 0;
}
Порядок действий:
Составление файла (например, HELLO .С), содержащего текст. приведенной программы.
Компиляция программы б режиме Маке и ее последующее выполнение (например, клавиша Alt - R,R).
Функции, находящиеся в автоматически подключаемой к программе библиотеке Graphics, обеспечивают распознавание графической среды (например, graph), инициацию пикселной и знаковой графики (например, initgraph, textmode), переключение между графическим и текстовым режимами (например, restorecrtmode), установку графических и текстовых окон (например, setviewport и window), а также вывод текстов (например, cprintf), выделение текстов (например, outtext) и выделение основных графических объектов (например, circle).
Если аргументы функции не нарушают структурных требований, но подобраны несоответственно, то выполнение функции не дает никаких результатов. Если аргументы подобраны правильно, но функция не будет выполнена, то работа программы продолжается. Выяснение причины
D Пиксел - один элемент из большого массива графической информации fricture element (англ.) - элемент изображения. - Прим. ред.
неправильного выполнения графической операции возлагается на программиста. Эту задачу облегчает представленная далее функция graphresult.
Результатом функции graphresuh является величина типа integer. Если выполнение графической функции было правильным, то эта величина имеет значение 0. В противном случае она имеет отрицательную величину, идентифицирующую причину ошибки. Поскольку двукратный вызов функции graphresult (без выполнения между этими вызовами графической операции) приводит к тому, что ее вторым результатом всегда будет величина со значением 0, рекомендуется присваивание первого результата вспомогательной переменной.
Текстовый режим
Выполнение каждой программы начинается в текстовом режиме. Знаки, выводимые на экране, могут быть белыми на черном фоне, черными на белом фоне, мерцающими и цветными. Вывод знаков производится с помощью каналов, связанных с пультом.
Текстовое окно
После начала программы по умолчанию за текстовое окно принимается весь экран. Левый верхний угол экрана с текстом имеет координаты (1,1), а правый нижний (col, lin) где col - число колонок, a lin - число строк экрана. Например, для графической платы CGA в режиме С40 координатами этой точки будут (40, 25)・ С окном связан курсор, положение которого может изменяться с помощью функции goloxy. Смена текстового окна выполняется посредством функции window. Аргументами этой функции являются координаты экрана. Наименьшее окно имеет размеры 1x1 знак. Все текстовые операции относятся к текущему текстовому окну, а координаты текстового курсора всегда отсчитываются от левого верхнего угла окна. Окно имеет все особенности экрана монитора, б частности вертикальное перемещение.
Пример. Вертикальное перемещение
/* Scrolling */
#include<conio.h>
#include<stdio.h> main();
{
clrscr();
windo・(l. 1. 5. 3);
cprintffJan")
cpr1ntf(MIzabela°); return 0;
}
Программа иллюстрирует вертикальное перемещение. На экране появляется строка с надписью Izabe и строка с завершающей надписью 1а. В результате перемещения надпись Jan исчезает из текстового окна.
Цвета
Если монитор обеспечивает цветной вывод, то независимо могут определяться атрибуты цвета знаков и цвета фона (например, красный знак на зеленом фоне). Кроме этого, можно организовать мерцание знака и увеличить его яркость. Атрибуты мерцания, цвета фона, яркости и цвета знаков для каждого выводимого знака определяются на основе битовых полей внутренней переменной системы, называемой TextAttr. Поля мерцания и яркости однобитовые, а поля цвета фона и цвета знаков трехбитовые. Установка переменных полей может производиться с помощью функции textattr (аргумент которой присвоен переменной TextAttr) или посредством функции textbackground и textcolor. Первая из этих функций обеспечивает определение цвета фона, а вторая - цвета знаков, их яркости и мерцания. Аргументы переменных функций обычно выражаются с помощью символов, таких, как, например, RED (красный), BLINK (мерцание) и т.д.
Если пользоваться платой Hercules и монохроматическим монитором, то установка атрибутов должна производиться переменной TextAttr» В рассматриваемом примере ее наиболее значимый бит определяет мерцание, три следущих - фон, еще один бит - яркость, а три наименее значимых - знаки. Кроме мерцания и увеличения яркости, имеет смысл следующий список атрибутов:
Первый тип Фон Результат
70Белые знаки на черном фоне
0Белые подчеркнутые знаки начерномфоне
О7Черные знаки на белом фоне
О0Черные знаки на черном фоне(невидимы)
Пример. Вывод знаков в цвете
"Text Colors */«
findude<conio.h> main() {
clrscr();
textcolor(RED);
textbackground(GREEN):
cprintf(°'Kajusia'*) return 0;
}
На цветном мониторе, управляемом соответствующей графической платой (например, EGA или CGA), появляется красная надпись Kajusia на зеленом фоне.
Графический режим
Переключение системы на графический режим производится с помощью функции initgraph..
Пример. Установка графического режима
/* Initialize */
#i nc1ude<graphics.h>
#1nclude<coni о.h>
main()
{
int Driver, Mode;
Driver = DETECT;
initgraph(&Dri ver, &Mode/'");
putpixel (0.0.1);
while(!kbhit());
closegraph();
return 0;
}
Выполнение программы приводит к автоматическому выходу на графический режим, переключению системы на графический режим и к выделению на экране одного пиксела.
「рабическое окно
После установки графического режима по умолчанию графическим окном является весь экран. Левый верхний угол графического экрана имеет координаты (0,0), а правый нижний угол имеет координаты (getmaxxO, getmaxyO). Смена графического окна может быть выполнена с помощью функции setviewport. Ее аргументами являются координаты окна, а также логическое выражение, определяющее, требуется ли отсекать части текста, выходящие за пределы окна или нет. Все графические операции касаются текущего графического окна, а координаты графического курсора всегда отсчитываются от левого верхнего угла окна. Графический курсор невидим, но его текущие координаты могут быть определены с помощью функции gefx и gety. Эти координаты имеют значения величин типа (int) и могут быть как положительными, так и отрицательными. Если координата X не лежит б области 0„ getxO, а координата Y - в области 0.. getyO, то курсор находится вне пределов графического окна.
Пример. Отсечение на границах окна
/*Clipping*/
findude<graphics;h>
#include<conio.h>
#define clipon I main
{
int Driver, Mode;
Driver = HERCMONO;
Mode = HERCMONOHI
initgraph(&Driver, &Modef "..**);
setviewport(1,1,getmaxx()r getmaxyO» clipon);
putpixel(-*1, -1, 1);
whilef!kbhit());
11—764
closegraph();
return 0;
Поскольку функция SetViewPort вызвана с последним аргументом, имеющим значение 1 (отсечь), выполнение функции putpixel ие дает никаких результатов. Если этот аргумент заменить аргументом со значением О (не отсекать), то рядом с левым верхним углом графического окна (или за ним) был бы изображен один пиксел.
Изображение текстов
Выводимые на графический экран тексты изображаются на нем. Тексты могут быть двух видов: битовые и штриховые. Каждый знак битового текста представляет собой прямоугольник размером 8x8 бит* Качество такого знака при увеличении ухудшается. Значительно лучший визуальный эффект дает увеличенный штриховой знак. Он образуется векторным способом, и его читаемость не зависит от его размера. Имеются четыре вида штрихо)вых знаков: индексный, тройной, простой и готический. Эти знаки могут быть не только увеличены, ио и растянуты по горизонтали и вертикали. Тексты из знаков любого вида могут выводиться по горизонтали (слева направо) или по вертикали (снизу вверх). Алфавиты штриховых видов охватывают знаки основного кода ASCII, а алфавит битового вида содержит алфавит расширенного кода ASCII.
Штриховые знаки хранятся на диске и динамически загружаются в оперативную память. Одновременно в памяти может находится только один автоматически загруженный штриховой вид. Предусмотрены средства, обеспечивающие загрузку знаков по выбору (функция regjsterbgifont), а также их установку на постоянное использование в программе.
Пример. Из обращение текста
/* Texts */
finclude<graph1cs.h>
finclude<std1o.h> malnf) {
int Driver, Mode;
Driver н HERCMOND;
Mode - HERCMONOHI;
1nitgraph(&Driver, &Moder "..“);
settextstyle(SMALL_FONT, HORIZ_DIR. 10); outtext(,,JanH);
settextstyle(GOTHIC_FONT, HORIZ_DIR. 8); outtextfTwa");
settextstyle(TRIPLEX_FONTt HORIZ_DIR. 8);
outtext("Iza);.
sleep(2);
closegraph(); return 0
Выполнение программы приводит к изображению трех текстов: первый выводится шри4угом индексного вида (SMALL-FONT), а следующие соответственно готическим (GOTHIC-FONT) и тройным (TRIPLEX-FONT) видами. Знаки текста Jan увеличиваются 10-кратио, а остальные знаки - 8- кратно. Тексты выводятся по горизонтали (HORIZ-DIR).
Изображение графических объектов
Библиотека графических подпрограмм содержит функции для изображения пикселов (putpixel), обрезков (line), дуг (аг), окружностей (circle), эллипсов (ellipse), а кроме того, ломаных, многоугольников, столбцов и т.д. Линии могут быть тонкими и жирными, непрерывными и прерывистыми.
Пример. Изображение окружности
/* Objects */
#1nclude<graphics.h>
finclude<conio.h>
ma1n()
{
int Driver. Mode;
Driver 二 HERCHMONO;
Mode = HERCMONOHI;
in1tgraph(&Dr1verr &Mode, "..");
c1rcle(getmaxx()/2v getmaxy()/2t 300);
floodfl 11 (getmaxx( ). getmaxy ( )»1,
getmaxcolorf ));
while(!kbh1t());
c1osegrph();
return 0;
}
Выполнение программы приводит к изображению окружности с радиусом 200 пикселов с центром в середине экрана с последующим его заполнением по умолчанию. Изображеиный объект отсечен на границах графического окна.
Цвета
Изображение графических объектов может быть черно-белым или цветным. Черно-белое изображение относится обычно к бесцветным графическим платам, например Hercules. Естественно, в этом случае "белый" цвет зависит от используемого люминофора и по существу может быть зеленым или янтарным.
Если имеется цветное изображение (например, плата EGA или CGA), то во время установки управления графикой определяется режим работы и доступная палитра цветов.
Цвета нумеруются от 0 до getmaxcolor О. Эти цвета могут быть постоянными (плата CGA) или произвольно изменяемыми (плата EGA). Если цвета могут меняться, то присваивание позиции выбранного цвета производится с помощью функции setpalette. Выбор номера цвета для изображения объектов обеспечивает функция setcolor.
После выполнения функции setcolor(n) все объекты изображаются в цвете, связанном (аппаратно или программно) с позицией п палитры цветов. Программное присваивание этой позиции другого цвета приводит к смене цвета рассматриваемых объектов.
Пример. Цветное изображение
/* GraphColors */
finclude<graphics.h> finclude<conio.h> main()-
{
int Driver, Mode;
strict palettetype Palette;
short int 1;
Driver =sEGA;
Mode EGALO;
initgraph(&Driver; &Mode( "..");
if(graphresult()l » grOk)
exit(13);
setpalette(l, RED);
setcolor(l);
line(0# О» getmaxxf), 0);
while(! kbhltO);
(vold)getch();
setpalettefl, GREEN);
outtextxy(Of 0, "Tress a keyM);
whlle(lkbhirO);
(void)getch();
getpalette(&Palette);
restorecrtmode();
■ cprintf (#,Palette");*
for(i н 0; i<Palette.size - 1; 1 ++)
cprintf("No. % 2d «> % d", Palette. colors[i]); return 0;
Программа иллюстрирует принцип использования пакета цветов платы EGA. После установки графического режима и связи с позицией палитры номер 1 красного цвета (RED) изображается горизонтальный отрезок прямой линии. Нажатием произвольной клавиши клавиатуры производится смена цвета, связанного с позицией номер 1, на зеленый GREEN. Это приводит к тому, что как указанный отрезок, так и текст Press a key изображаются в этом цвете. В конце выполнения программы происходит переключение системы на текстовый режим и вывод таблицы, определяющей идентификаторы цветов, соответствующие отдельным позициям палитры. Анализ программы облегчает понимание списков библиотечных функций, размещенных в разд. 17.1.
Г рафика BGI
Наи)1учшей иллюстрацией графики BGI (Borland Graphics Interface) является специально подобранная программа. К такой категории принадлежит программа BGIdemo, содержащаяся на дистрибутивной дискетке системы Турбо Си. В несколько измененном и дополненном виде она приводится здесь с согласия фирмы Borland InternationaL Дана ее полная распечатка и отдельные фрагменты экрана. Списки графических функций, которые использованы в п|юграмме. находятся в разделе, посвященном библиотекам: графической (разд. 17.1) и системной (разд. 17.2).
SetAspectRatio denonstrat ion
Esc aborts or press a key.,.
Рис. 9. Демонстрация SetAcpect Ratio.
/*Turbo C 2.0*/
/*Borland graphics demo*/
/"Copyright Borland International */ /*& jb */
finclude <dos.h> finclude <math.h> finclude <conio.h> fInclude <stdio.h> finclude <stdlib.h> finclude <stdarg.h>
finclude «graphics.h*
#define
ESC
Oxlb
fdefine
TRUE
1
#define
FALSE
D
#define
PI
3.14159
•define ON1
FillEllipse denonstration
Esc aborts or press a keg...
Рис. 10. Демонстрация FillEllipse-
Рис. 1 [.Демонстрация секторов.
記Mine OFFО
char *Driver Names[]=
{•'Detect"rWCGA"r"MCGA", “EGA工•,EGA64",HEGAMono", ”IBM8514“, "HercMono”."ATT400”, "VGA".叩C3270”};
char*Fonts[]=
{"Default FontH,иТг 1 p 1 exFonf /SmallFont", ”SansSerifFont”,'*GothicFont"};
char 4lneStyles[] »
{'•5опа1пи. '^ottedLn". *'CenterLn", •'DashedLnM, "UserBitLn*'};
char *F111Styles[]=
{"EmptyFilF, ,,SolidFill'\ "LineFill". "LtSlashFilF. -SlashFIll",
'WSlashFiir. ,'LtBkSlashFiir,. MHatchFiir\ "XHatchFilF,
•'InterleaveFIll*',
•'WideDotFi 1Г\ ,,CloseDotFi 11"};
char *TextD1rect[]= {"HorizDir", "VertDirM};
char *HorizJust[]= {“LeftText", "Center Text: "Right Text"};
char *VertJust[]= {"BottomText*', •'CerterTexf. MTopText"};
struct PTS{ int x, y;
}; /*strucrure to hold vertex points*/
IntGraphDriver;
intGraphMode;
double AspectRatio;
intMaxX, MaxY;
/* the maximum resolution of the screen */
intMaxColors;
/* the maximum number of colors available */
intErrorCode;
struct palettetypepalette;
/*Function prototypes*/
/**/
void Initialize();
void keportStatus(void);
void TextDutnp(void);
void Bar3DDemo(void);
void RandomBars(void);
void TextDemo(void);
void Color Demo(void);
void ArcDemo(vold);
void ClrcleDewo(void);
void PieOeiFo(void);
void BarDeTFo(void);
void Lin&RelDemo(void)
void PutP1xelDemo(void);
void PutlmageDemo(void);
void LineToDemo(void);
void L1n&StyleDemo(void);
void CRTModeDemo(void);
void UserLineStyleDemoCvoid);
void FillStyleDemo(void);
void FillPatternDemo(vold);
void PaletteDemo(vold);
void PolyDemo(void);
void SayGoodbye(void);
void Pause(void);
void Mai nV/Mow (char *header);
void StatusLinefchar *msg);
void DrawBorder(void);
char *GetMode(vo1d);.
void ChangeTextStyle(int font, int direction, int charsize);
int Display (int *xloc, int *yloc, char *fmt, ♦..);
void Aspect Demo(void);
void FHlEUipseDejno(vold);
void Sector Demo(void);
/**/,
/* Begin main function */
static void (*Demo[])(void) «
Aspect Demo.
FillEllilpseDeino,
Sector Demo.
Report Status,
TextDump,
Bar3DDemo,
RandomBars,
TexDemo.
ColorDemo,
ArcDemo,
ClrcleDerno,
PieDemot
BarDemo.
Lin&RelDemo,
PutPixelDemo,
PutlmageDemo,
LineToDemo,
LineStyleDemo.
CRTModeDemo,
UserL1neStyleDemo,
FillStyleDemo,
FIIIPatternDemo,
PaletteDemo.
SayGoodbye
PolyDemo,
int Number, Margin = 5;
Int mainfint arse, char *argv[]) {
void (*Select)(void);
char *Last;
Number 工 strtol(argv[l], &Last. 10);.
if(Number = 0 &Last = argv[l]| argc == 1){ pr1ntf("\nErrorr try again");
exlt(l);
if(!(Number > 0 &
Number<sizeof Demo /sizeoffvoid (*) ()))){ printf("\nV/rong demo!!*'); exit (2);、
if(argc>2)
Margin = strtal(argv[2]. &Last, 10);
if(Margin == 0 &Last == argv [2]||
Margin <0 | Margin > 15. argc > 3){ * printf("\nMargin error, try again"); e)dt ⑶;
}
Select = Demo[Number];
Initialized;
1f(Select == PaletteDemo){
If(GraphDriver == EGA)|
GraphDriver == EGA64|
GraphDriver == VGA)
PaletteDemof);
else Number ® - 1 } else
Select(); closegraph(); if(Number == ^ 1) printf(*'Sorry, EGA & VGA only*');
closegraph() return(O); }
char Buf[1200]; int Ind;
void
WriteBuf(char Ch) {
Buf[lnd++] = Ch;
void
PrintScreen(char Over)
{
extern void 0neL1ne(intf int);
int yL; ”
extern FILE *Lst;
char Name[] = "SCREEN**";
Name[6] = Number /10 + *0*;
Name[7] = Number % 10 + 'O';
Name[8] = ,\0,;
Lst = fopen(Name. "*b");
setviewport(Ov 0, KaxX MaxY. 1);
Ind = 0;
Write Buf (AxlB*);
WriteBuf('3‘);
Wr1teBuf(24);
fwrite(Buf, 3, 1. Lst);
for(yL » 0; yL < - ((getmaxy() + S)» 3) - 1; yL++) 0neLin&(yL. Over);
Ind н 0;
Write Buf('\x1B');
WriteBufC。');
fwritefBuf, 2, 1. Lst);
fclose(LtSt);
FILE *Lst;
char
OneCharfint x. int yL) {•
static char Bits[] = {128. 64, 32, 16. 8, 4, 2, 1}; char OneByte, i;
yL « = 3;
One Byte = 0;
for(i = 0; i « == 7; 1++)
1f(getpixel(x, yL + i)) OneByte |= Bits[口;
return OneByte;
} void
0neL1ne(1nt yL. Int Over) {
int xxt m, n;
for(m = 1; m< = Over; m ++){
Ind = 0;
for(n =1; n< = Margin; n++)
Write 8uf(' *);
WriteBuf('\xlB*);
WriteBufCL*);.
WriteBuf(getmaxx()+1);
WriteBuf ((getmaxx() + »S);
forfxx н 0; xx<=getmaxx(); xx++)
WriteBuf(OneChar (xx, yL));
If (m < Over) WriteBuf (Ar');
Status report after InitGraph
Graphics device Graphics node Screen resolution Current uiau port Clipping
Current position Colors available Current color Line style Line thickness Current fill style Current fill color Current font Text direction Character size Horizontal justify Vertical justify
EGA⑶
EGfiLo(0)
(0, 0, 639, 199 ) < 0, 0, 63% 199 ) ON < 0, 0 > 16 15
SolidLn
SolidFill 15 DefaultFont HorizDir
LeftText TopText
Esc aborts or press a key …
Рис. 12. Запись состояния после InitiGraph.
DefaultFont Character Set
^♦♦♦■CXMfflBMt—排1”,i,'#$Z4, (>«*,-./0123456789: ;<=>^BCDEFGHIJKLHNO PQ8STUUWXYZ£\J*_' abcdefgh ijk Innopqrstuvwxyz {: }~6§цё2ааА^ ?ёё i Ti ft«iaflSo<>uby Cii^t^h 面63汨記-第办胸田妬中踪u% 一1、肥户^卄、К」册rU Ftt^rfflrpTjGfi^ g三土怨Г心=3 口"
Esc aborts or press a key...
Рис. 13. Набор символов DefaultFont.
fwrite(Buf, Ind, 1. Lst);
Ind = 0;
UriteBuf(13):
WriteBuf(lO);
fwrite(Buf, 2. 1. Lst);
/*INITIALIZE: Initialize the graphics system
/*
void Initialize(void)
{
int xasp, yasp;
GraphDriver = DETECT;
1 ni tgraph(&GraphDr 1 ver r &GraphMode, "'•);
/*actlv^te graphics*/
Error Code = graphresult();
if(Error Code! = gr 0k){
pr 1 ntf(**Graphics System Error; %s\n".
TriplexFont Character Set. 嚼闘()*+,-./0123456789:;Q?跚 CDEFGHLimMW UWXY欣人 _'abcdefghijklmiiopqrstuYwxyzX~
Esc aborts or press a key.・・
Рис. 14. Набор символов TriplexFont.
grapherrormsg(Error Code));
exlt(l);
}
getpalette(&palette);
MaxColors == getmaxcolor() + 1;
MaxX « getmaxx();
MaxY = getmaxy();
/*read size of screen */
getaspectratio(&xaspr &yasp);
/* read the hardware aspect */
Aspect Ratio = (double)xasp / (double)yasp;
/*get correction factor*/
/*REPORSTATUS: Report the current */
/*configuration of the system */
/**/
void Reportstatus(void) {
struct viewporttype viewinfo; struct UnesettIngstype fillinfo; struct fillsettingstype fillinfo; struct textsettingstype textinfo; struct palettetypepalette;
char, *drivert *mode;
int x. y;
getviewsetti ngs(&viewinfo); getlinesettings(&lineinfo); getfillsettings(&fi11 info); gettextsettins(&textinfo);
getpalette(&palette);
x ■ 10:
У н 4;
Ma1nW1ndow(HStatus report after InltGraph”); settextJustify(LEFT_TEXT, TOPJEXT);
driver н DriverNames[GraphDr1ver]; mode = GetMcde;
% - 20S (混尸,% - 20s (我).,(0.0. %d, %d尸.% - 20S (混尸,% - 20s (我).,(0.0. %d, %d尸.Display(&xr &y, "Graphics device driver, GraphDriver);
% - 20S (混尸,
% - 20s (我).,
(0.0. %d, %d尸.
% - 20S (混尸,
% - 20s (我).,
(0.0. %d, %d尸.
Display(&xr &y. "Graphics mode mode, GraphMode);
Display(&x, &yt "Screen resolution
D1splay(&x, &y. getx(), Dlsplay(&xr &y. Display(&x. &y.D1splay(&x, &y. getx(), Dlsplay(&xr &y. Display(&x. &y.(%d. %d, %d. %d)t%s”.(%d, %d)\%d”. MaxColors);Xd", getcolorf));%s”,. %d”.%s”,%de fillinfo.color);%s”.Xs", 紀”, %sM. %s”,(%d. %d, %d. %d)t%s”.(%d, %d)\%d”. MaxColors);Xd", getcolorf));%s”,. %d”.%s”,%de fillinfo.color);%s”.Xs", 紀”, %sM. %s”,*/*/*/*/
D1splay(&x, &y. getx(), Dlsplay(&xr &y. Display(&x. &y.
D1splay(&x, &y. getx(), Dlsplay(&xr &y. Display(&x. &y.
(%d. %d, %d. %d)t
%s”.
(%d, %d)\
%d”. MaxColors);
Xd", getcolorf));
%s”,. %d”.
%s”,
%de fillinfo.color);
%s”.
Xs", 紀”, %sM. %s”,
(%d. %d, %d. %d)t
%s”.
(%d, %d)\
%d”. MaxColors);
Xd", getcolorf));
%s”,. %d”.
%s”,
%de fillinfo.color);
%s”.
Xs", 紀”, %sM. %s”,
*/
*/
*/
*/
getmaxx()f getmaxyU);
D1splay(&xv &y・ *'Current view port : viewinfo.left, viewinfo.top, viewinfo.right, viewinfo, bottom);
Display(&x. &y. ^Clipping:
viewinfo.clip? "ON" : "OFF");
"Current position gety());
"Colors available ^Current color
D1splay(&x( &y, "Line style
L1neStyles[lineinfo.11nestyle]); Display(&xV &y. "Line thickness lineinfo, thickness);
Dlsplay(&x, &y. "Current fill style F11lStyles[f1Tlinfo, pattern]);
D1splay(&xt &y. ("Current fill color
Display(&x* &y, "Current font Fonts[textinfo.font]);
Display(&x, &y, "Text direction TextDirect[textinfo.direction]);
Display(&x, &y, “Character size text1nfo.charsize);
D1splay(&x, &y. "Horizontal justify Ног1zJust[text1nfo.horlz]);
Display(&x, &y. "Vertical justify VertJust[textinfo.vert]);
Paused;
/* TEXTDUMP: Display all the characters
/* in each of the available fonts
/*
void Text Dump()
{
static int CGASizes[] *
(1. 3r 7. 3. 3};
static Int NormSizes]]工
{1. 4. 7. % 4}:
char buffer[80];
inf font, ch. wwidth, Iwidth. size; struct viewporttype vp;
for(font н 0; font <5; ++ font){
/* for each available font */
sprintf(buffer, "Xs Character Set", Fonts[font]);
MainVindow(bufer);
/* display fonthame as banner */ getviewsettings(&vp);
/* read current viewport */
setttextjustify(LEH_TEXT. T0P„TEXT);
moveto(2, 3);
buffer[l] ■ *\0*;
/* terminate string */
wwidth н vp.right - vp.left;
/* determine the window width */
Iwldth н textwidthC'H*1);
〃 get average letter width */
1f(font * DEFAULT_FONT){
ChangeTextStyle(font, H0RIZ_DIR, 1);
ch n 0;
while(ch<256){
/* for each possible character */
buffer[0] = ch;
/* put character Info a string */ outtext(buffer);
/* send string to screen */
if ((get x() + lwidth>wwidth)
moveto(2fgety() + textheight )"H) +3 );
++ch
/* goto the next character */
}
}
else{
size н (MaxY <200)? CGAS1ze[font] : NormSIze[font];
ChangeTextStyle (font, HORIZ IR, size);
ch н T;
/* begin at first printable*/
while(ch<127){
/* for each printable character*/
buffer [0] н ch;
/* put character into a string */ outtext(buffer);
/* send string to screen */
If((get x() + lwidth)*wwidth)
/* are we still in windiw? */
moveto(2, gety( ) + textheight(°H'*) + 3);
++ch;
/* goto the next character */
}
SnalIFont Character Set
I"將鴻'()*+,-. /0123456789: : <=>^ABCDEFGHI JKLtlNOPQRSTUUU XYZt\]A_' abcdef ghi jklriinopqr stuvuxyzd) ~
Esc aborts or press a key...
Рис. 15. Набор символов Smallfont,
SansSerifFont Character Set
!n#%&,0*+.-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQR STUVWXYZf^J^^bcdetghiiWmnopqrsfuvwxyzJlj^
Esc aborts or press a key...
GothidFont Character Set
!"#糕冲+,一川召朋83■:;Q?@AiOE施殛碉》e嬲 繳R卿通2献/血加fgljijMimw叫rshnnu明中
Esc aborts or press a key...
Рис. 17. Набор символов GothicFont.
Pause();
BAR3DDEH0: Display a 3-D bar chart */
void Bar 3DDemo (void)
{
static 1nt barheight[]=
{1, 3, 5. 4, 3, 2, 1, 5, 4. 2, 3};
struct viewporttype vp;
int xstep. ystep;
int 1, j, h, color, bhelght;
char buffer[10];
MainVindowt^Bar 3-D/Rectangle DemonstrationM);
h н 3 *text^leight("H,^);
12—764
getviewsettings(&vp);
settextjust ifу(CENTER„TEXT, TOP_TEXT);
ChangeTextStyle(TRIPLEX_FONTr HORIZ_DIR, 4);
outtextxy(MaxX/2r 6, *These are 3-D Bars");
ChageTextStyle(DEFAULT_FONT, HORIZ_DIR, 1); setviewport(vp.left + 50, vp.top + 40.
vp.right-50, vp.bottom-10, 1);
getviewsetltigs(&vp);
line(h, h. h( vp.bottom-vp.top-h);
line(h, (vp.bottom-vp.top)-h, (vp.right-vp.left)-h, (vp.bottom-vp.top)-h);
xstep н ((vp.right-vp.left) - (2*h)) /10;
ystep н ((vp.bottom-vp.top)) - (2*h))/5;
J = (vp.bottom-vp.top) - h;
settextjustify(CENTERJEXT. CENTER_TEXT);
for(i = o; i<6; ++ 1){
line(h/2, J. h, j);
1toa(1r buffer, 10);
outtextxy(0, j, buffer);
j -= ystep;
j = h;
settextJustify(CENTER_TEXT. TOP_TEXT);
for (i = 0. 1 v 11; ++i){
color = random(MaxColors J;
setfiHstyle(i + 1, color);
line(jf (vp.bottom-vp.top)-h, jf
(vp.bottom-vp.top~3)-(h/2));
itoa(i,buffer, 10);
outtextxy(jr (vp.bottom-vp.top)-(h/2). bu幵er);
if(i != 10){
bheight 二(vp.bottom-vp.top) - h - 1;
bar3d(j. (vp.bottom-vp.top-h)-(barhe^ght[i]*ystep), j+xstep, bheight, 15. 1);
}
j += xstep;
}
Pause();
}
/* RANDOMBARS: Display random bars*/
/**/
void RandomBars(void)
int color;
MainWindow(^Random Bars");
StatusLine('*Esc aborts or press a key.. .**);
/* put msg at bottom of screen*/
while(!kbhit()){
/* until user enters a key ...*/
color = random(MaxColors-l) + 1;
setcolor(color);
setf111style(random(11) + 1. color);
bar3d(random(getmaxx())f random(getmaxy()J. random(getmaxx())f random(grtmaxy(J), 0. OFF);
*/*/*/*/Pause();
*/
*/
*/
*/
/* TEXTDEMO: Show each font
/* in several sizes to the user
void TextOemo(void)
{
Int chars1ze[]=
(1, 3, 7, 3, 4);
int font, size;
int h, xt у. 1;
struct viewporttype vp: char buffer[80];
for(font = 0; font <5; ++ font){
/* for each of the four fonts */
sprintf(buffer, "%s Demonstration", Fonts[font]);
Ma 1riWindow( buffer);
getv i ewsett1ngs(&vp);
ChangeTextStyle(font, VERT_DIR. charsize[font]); settextjustify(CENTER_TEXT? BOTTOM_TEXT);
outtextxy(2 * text*idth("M")»
vp.bottom - 2 * textheight ("M").
“Vertical —> ");
ChangeTextStyle(font. HORIZ_DIR, charsize[font]);
settextjustily(LEFТЛШ, TOP_TEXT);
outtextxy(2 * textwidth("M")» 2. "Horizontal —>”);
settextjustify(CENTER_TEXT, CENTERJEXT); x = (vp.riht - vp.left) /2;
У = textheight ("H");
for (i =« 1; 1 < 5; ++i){
/* for each of the size */
size н (font ” SMALL_FONT) ? 1 + 3: 1; ChangeTextStyle(font, H0RIZ_DIR. size); h n textheight("H**);
у + н h;
sprintf(buffer, "Size Xdw, size);
outtexty(xf yt buffer);
if(font !- DEFAULT_FONT){
/* show user declared font size */
у + « h/2;
/* mpve down the screen */
settextjustify(CENTER_TEXTt TOPJTEXT);
setusercharsize(5( 6. 3. Z);
ChangeTextStyle(fontr H0RIZ_DIR, USER_CHAR_SIZE"
DUttextxy(vp.right-vp.left)/2, yf
"User Defined Size");
}
Pause():#
}
〃*/
/*COLORDEMO: Display the current*/
/*color palette on the screen*/
/**/
void Color Demo(void)
{
struct viewporttype vp;
int color, height, width;
int x. y, 1, j:
char cnum[5];
MainWIndow("Color Demonstrat1on”); /* show demonstration name */
color H 1;
getv iewsettings(&vp);
/* get the current window size */ width н 2 * ((vp.right + 1) / 16);
/* get box dimensions */ height « 2 * ((vp.bottom-10) / 10);
x ■ width /2;
у = height /2;
/* leave 1/2 box border */
Ваг 3-D / Rectangle Denon&tration
These are 3-D Bars
Рис. 18. Демонстрация трехмерной прямоугольной диаграммы
Randon Bars
Esc aborts or press a key...
DefaultFont Demonstration
Horizontal —>
Size 1
Size 2
Size 3
Size 4
2 国
Esc aborts or press a key...
Рис. 20. Демонстрация DefaultFont.
/* row loop */
for 1 = 0; i < 5;卄,){ /* column loop */
setfillstyle(SOLID_FILL. color);
setcolor(color);
bar(x, y, x+width, y+height);
/* draw the rectangle */
rectangle(x. y. x+wldth. y+height);
/* outline the rectangle */
1f(color q BLACK){
setcolor(WHITE);
rectangle(x, y, x+width, y+height); /* outline black In white */
itoa(color, cnum, 10);
outtextxy(x + (width/2), y+height + 4; cnum);
/* show color # */
color = ++ color % MaxColors;
/* advance to the next color */
x + = (width /2) * 3;
/* move the column base */
} /* end of column loop */ у + = (height /2) * 3;
/* move the row base */
x = width /2;
/* reset column base */
} /* end of row loop */
Pause()
/**/
/* ARCDEMO; Display a random pattern of arcs */
/**/
void ArcDemo(vold)
{
int mradius; /* maximum radius allowed *
int aengle;
struct arccoordstype a1;
MainWindow(MArc Demonstration");
StatusLine("ESC Aborts - Press a Key to stop");
mradius = MaxY /10;
/* determine the maximum radius */ wMle(!kbhit()){
/* repeat until a key is hit */ setcolor (random(MaxColors - 1) + 1);
7* randomly select a color */ eangle = random (358) + 1;
/* select an end angle */ arc(random(MaxX). random (MaxY), random(eangle), eangle, mradius); getarccoords(& ai);
/* read Cord data */
Tinefai. x,ai.y.xstart, ai.ystart);
/* line from start to cernter */ 11ne(ai. x. ai.y. ai.xend, ai.yend);
/* line from end to center */
}
Pause();
}
CIRCLEOEMO: Display a random pattern of circles
int mradius; /* maximum radius allowed *
MainWindowC'Tircle Demonstration");
StatusLineC'ESC Aborts - Press a Key to stop");
mradius = MaxY /10;
/* determine the maximum radius */
■hi7e(lkbhit()){
setcolor (random(MaxColors - 1) + 1);
/* randomly select a color */
circle(random(MaxX), random(MaxY), random(mradius));
}
Pause();
}
/**/
/* PIEDEMO: Display a pie chart*/
/**/
#define adjasp(y) ((int)(AspectRatio * (double)(y)))
#define torad(d) (((double)(d) * PI) /180.0)
void PieDemo(void)
{
struct viewporttype vp;
int xcenter. ycenterr radius, Iradius;
int x. y;
double radians;
MainWindow("Pie Chart Demonstration");
getv iewsett ings(Svp) ;•
/* get the current viewport */ xcenter = (vp.right - vp.left)/?;
/* center the Pie */
ycenter = (vp.bottom ~ vp.top)/2+20;
radius = vp.bottom - vp.top)/3;
1radius = radius + (radius /5);
/* labels placed 2D% farther */
if (radius < 75){
radius = (radius*2)/3;
Iradius - = radius/4:
ChangeTextStyle(TRIPLEX_FONT, H0RIZ_DIR, 4); settextjustify(CENTER_TEXT, TQP_TEXT); outtextxy(MaxX/2, 6. "This is a Pie Chart"); 讦(raunds <75)
ChangeTextSty1e(TRIPLEXr H0RIZ_DIR, 2); else
ChangeTextStyle(TRIPLEX, HDRIZ_DIR, 3);
settextjustify(CENTER_TEXT, TOP_TEXT);
setfi1lstyle(SOLID_FILL, RED);
pieslice(xcenter + 10. ycenter-adjasp(10)f
0, 90, radius);
radians = torad(45);
x = xcenter + (1nt)(cos(radians) *(double) Iradius);
у «= ycenter - (int)(sin(radians) * (double)Iradians * Aspect Ratio);
settextjustify(LEFT_TEXT, BOTTOM_TEXT);
outtextxy(x, y, "25 %'*);
setfiHstyle(WIDE_DOT_FILL, GREEN);
pieslice(xcenter, ycenter, 90, 135, radius);
radians = torad(113);
x 匸 xcenter + (int)(cos(radians) *(double) 1radius);
у = ycenter - (int)(sin(radians) * (double)Iradians * Aspect Ratio); settextjustily(RICHT_TEXT, BOTTOM_TEXT);
outtextxy(xf yf **12.5 %");
setfillstyle(INTERLEAVE_FILL, YELLOW);
settextjustily(RIGHT_TEXT. CENTER_TEXT);
pieslice(xcenter-10, ycenter, 135, 225, radius);
radians = torad(lBO);
x = xcenter + (int)(cos(radians) *(double) Iradius);
у = ycenter - (int)(sin(radians) * (double)1radius * Aspect Ratio); settextjustify(RICHT_TEXT, CENTER_TEXT);
outtextxy(x, y, "25 %”);
setfillstyle(HATCH_FILL. BLUE);
pieslice(xcenter, ycenter, 225. 360, radius);
radians = torad(293);
x = xcenter + (int)(cos(radians) * (double)Iradius);
у * ycenter - (int)(sin(radians) * (double)Iradius) * Aspect Ratio);
settextjustify(LEFT_TEXTe TOP TEXT);
outtextxy(x. yf *'37.5%*');
Pause();
/**/
/*BARDEMO: Draw a 2-D bar chart*/
/*using Bar and Rectangle*/
/**/
void BarDemo(void) {
int barheight[] ^
{1, 3, 5. 2. 4 };
int styles[]=
{1, 3, 10. 5, 9, 1 };
int xstep, ystep;
int sheight, swidth;
Int i・ j・ h;
struct viewporttype vp;
char buffer[40];
Ma i nWi ndow (,*Bar/Rectang le demonstration*);
h = 3 * textheight ("H**);
getvj ewsettings(&vp);
settextjustify(CENTER_TEXT. TOP_TEXT);
ChangeTextStyle(TRIPLEX_FONT, H0RIZ__DIR, 4);
outtextxy(MaxX/2. 6, "These are 2-D Bars");
ChangeTextSty1e(DEFAULT_FONT, H0RIZ_DIRt 1);
setviewportj[vp. left + 50, vp. top+30, vp.right-50, vp.bottom-10.1);
getviewsett i ngs(&vp);
sheight - vp.bottom - vp.top;
swidth = vp.right - vp.left;
line(h, h. h. sheight - h);
11ne(h, sheight-h, sheight~hr sheight-h);
у step ® (slielghr - (2*h))/5;
xstep = (swidth - (2*h))/5;
j = sheight - h;
settextjustify(CENTER_TEXT, CENTER_TEXT);
for(i = 0. t<6; ++i){
line(h/2, j, hf j);
itoa(i. buffer, 10);
outtextxy(0, j, buffer);
j -= ystep;
}
j = h;
settextjustify(CENTER_TEXT, TOP_TEXT);
for(i = CF i<6; ++i){
setf i1Istyle(styles[i], random(MaxColors));
line(j, sheight-h, j,sheight-3-(h/2));
itoa(1r buffer, 10);
outtextxy(jf sheight-(h/2), buffer);
if(i! = 5){
bar(jf (sheight-h)-Q)arheight[i] * ystep);
j+xstep, sheight - h - 1);
regtangle(j, (sheight-h)-(barheight[i] * ystep),
j + xstep, sheight - h);
}
j + = xstep;
}-
Pause。;
}
TriplexFont Demonstration
horizontal —>
ISize 1
нSize 2
оSize 3
,Size4
“ fer Defined Size
Esc aborG or m®55 日 к 叫..
Рис. 21. Демонстрация TriplexFont
SnalIFont Denon&tration
Horizontal —〉
ЛSize ^
Size 5
Imu 二 —QDImu 二 —QDSize 6Size 7[側酒馳p
Imu 二 —QD
Imu 二 —QD
Esc aborts or press a key...
SansSerifFont Denonstrat ionSansSerifFont Denonstrat ionРис. 23. Демонстрация SansSeriFont.Рис. 23. Демонстрация SansSeriFont./*LINERELDEMO: Display pattern using
SansSerifFont Denonstrat ion
SansSerifFont Denonstrat ion
Рис. 23. Демонстрация SansSeriFont.
Рис. 23. Демонстрация SansSeriFont.
/*moterel and linerel cmds
/*
*/*/*/*/*/*/*/*/void LlneRel(void) {
*/
*/
*/
*/
*/
*/
*/
*/
struct viewporttype vp;
int hr w. dx, dy, ex, cy;
struct PTS outs[7];
Ma 1 nW i ndowf'MoveRe 1 /L i neRe 1 Demonstration,,J;
StatusLine(MPress any key to continue, ESC to AbortM);
getv1ewsett i ngs(&vp);
ex = (vp.right - vp.left)/2;
/* center of the screen coords*/
cy = (vp.bottom vp.top)/2;
h = (vp.bottom - vp.top)/8;
w 、 (vp.right - vp.left)/9;
dx = 2 * w;
dy = 2 * h;
setcolor(BLACK);
setfiHstyle(SOLID_FILL, BLUE);
bar(O, O,vp.right - vp.left, vp.bottom - vp.top);
f* draw background */
outs[0].x »ex-dx;
outs[0].y =cy-dy;
outs[l].x =ex-(dx-w);
outs[l].y *cy-(dy+h);
outs[2].x «ex+dx;
outs[2].y =cy-(dy+h);
outs[3].x =ex+dx;
outs[3],y =cy+dy;
outs[4].x =ex+(dx~w);
outs[4].y «cy+(dy+h);
outs[5].x =ex-dx;
outs[5].y =cy+(dy+h);
outs[6].x =ex-dx;
outs[6].y =cy-dy;
setfillstyle(SOLlD^FILL, WHITE);
fillpoly(7, (int far *) outs);
outs[0].x = ex - (w/2);
outs[0].y « cy + h;
OUts[l].X H ex + (w/2);
outs[l].y « cy + h;
outs[2].x ® ex + (w/2);
outs[2].y = cy - h;
outs[3].x я ex - (w/2);
outs[3].y = cy - h;
outs[4].x « ex - (w/2);
outs[4].y = cy + h;
setflnstyle(SOLID_FlLL, BLUE);
fillpoly(5, (int far *)outs);
/*Draw a Tesseract object using */
/*linerel and movere1*/
moveto(cx - dx, cy - dy);
linerelfw, - h);
linerel(3*w, 0);
linerel(0, 5*h);
linere1((-wf h);
linerel(-3*w, 0);
linerel(0. -5*h);
moverel(w, - h);、
linerel(D, 5*h);
1inerel(vH-(w/2), D);
11nerel(0, -3*h);
linerel(w/2, - h);
linerel(0# 5*h);
moverel(0, -5*h); linerel(-(w+(w/2))r 0); linerel(0, 3*h);
linere1(-w/2, h);
moverel(w/2, -h); linerel(w, o);
moverel(0, -2*h); linerel (-w. 0);
Pause();
/*税*/
/* PUTPIXELDEMO: Display a pattern of random dots */
/* and pick them back up again*/
void PutPixel Demo(void)
int seed = »195B;
int 1f x, y, h. w, color; struct viewporttype vp;
MatnWtndow(MPutPixel / GetPixel Demonstration");
getviewsettings(&vp);
h = vp.bottom-vp.top;
w , vp.right - vp.left;
srand(seed);
/* restart random number function */
for(i = 0; i < 5000; ++i){
/* put 5000 pixels on screen */ x ^ 1 + random(w - 1);
/* generate a random location */ у = 1 + random(h - 1);
color = random(MaxColors);
putpixel(xr y, color);
srand(seed);
/* restart random number at same number.*/
for(i x 0; , < 5000; ++i){
/* take the 5000 pixels off */
x = 1 random(w -1);
/* generate a random location */ У = 1 random(h -1 );
gthicFunt Dawnstmt ion
协血0血->
g酶I
3痴a
Z飘窈З
S断裔4
耻蝙働
Esc aborts or press a key...
Рис. 24. Демонстрация готического шрифта.
Color DeMonstration
color + getpixel(xf у);
/* read the color pixel */if(color == random(MaxColors))
/* used to keep RANDOM in sync */
putpixel(x, y, 0);
/* write pixel to BLACK */
} Paused;
}
/**/
/*學UTIMAGEDEM。*/
/**/
void PutlmageDemo(void)
{
static int r = 20;
static int StartX = 100;
static int StartY = 50;
struct viewporttype vp;
int PauseTIme, x. yr ulx, uly,
Irx, Iry, size, ir width, height, step; void "Saucer;
Arc Denonstrat ion
Hain Window("Getlmage/Putlmage Demonstration"); getviewsetti ngs(&vp);
/* Draw Saucer */ setcolor(WHITE);
elltpsefStartX. StartY, 0, 360. r, (r/3)+2);
ellipse(StartX, StartY-4. 190, 357, r₽ r/3);
c1rcle(StartX+10. StartY-12, 2);
circle(StartX-10, StartY-12, 2);
setcolor(VHITE);
Mne(Start+7f StartY-6. StartX+10, StartY-12);
】1 ne(Start-7. XtartYY. StartX-10r StartY-12);
setfiHstyle(SOLID_FILLr WHITE);
floodfilHStartX+l, StartY+4. WHITE)
/* Read saucer image */
ulx = StartX-(r+l);
u?x = StartY-14;
Irx = StartX+(r+l);
Iry = StartY+(r/3)+3;
width = Irx - ulx + 1;
height = Iry - uly + 1;
size = Imagesize(ulx, uly, Irx. Iry);
Saucer = malloc(size);
getimage(ulx, uly, Irx. Iry, Saucer);
putimage(ulxt uly. Saucer, X0R_PUT);
/* Plot some "stars'* */
for(i = 0; i < 1000; +4-1)
putpixel(random(MaxX). random(MaxY).
random(MaxColors~l) +1);
x * MaxX /2;
у = MaxY /2;
PauseT ime = 70;
putimage(x, y, Saucer. X0R_PUT);
/* draw the saucer */
while(! kbhit() ){
delay(Pause Time);
putimage(x. y. Saucer. XORPUT);
/* erase the saucer */
/* Move Saucer */
step = random(2*r);
if((step/2)X 2! = 0)
step = -1, * step;
x = x + step;
step = random(r);
if((step/2) %2! = 0)
step - 1 * step;
у = у + step;
if(vp.left + x + width - 1 > vp.right)
x = vp.r ight-vp.left-width + 1;
else
if(x < 0)
x = 0;
1f(vp.top + у + height - 1 > vp.bottom) у = vp.bottom-vp.top-he i ght + 1;
else
if(y v fi)
У = o;
putimagefx, y. Saucer, X0R_PUT);
}
free(Saucer);
Pause();
/**/
/*LINETODEMO: Display a pattern*/
/*using moveto and lineto commands*/
/**/
fdefine MAXPTS 15
void LineToDemo(void)
struct viewopttype vp;
struct PTS point[MAXPTS]
int i, j, h( w( xcenter. ycenter;
int radius, angle, step;
double rads;
MainWindow("MoveTo/L ineTо Demonstrat 1 on**);
getviewsettings(&vp);
h » vp.bottom - vp.top;
w » vp.right - vp.left;
xcenter » w/2;
/* determine the center of circle */
ycenter = h/2;
radiusth-30)/(AspectRatio * 2);
step - 360/MAXPTS;
/* determine number of increments */
angle = 0;
/* begin at zero degrees */
for(i = 0; 1 < MAXPTS; ++1){
/* determine circle intercepts */
rads = (double)angle * PI /180.0;
/* convert angle to radians */
points{i].x «= xcenter + (int)(cos(rads) * radius);
po1nts{l].y = ycenter - (int)sin(rads) * radius * Aspect Ratio);
angle += step;
/* move to next increment */
}
circle(xcenter, ycenter, radius);
/* draw bounding circle */
for(i = 0; i< MAXPTS; H){
/* draw the cords to the circle */
for(j=i; j<MAXPTS; ++j){
/* for each remaining intersect */ moveto(points[i].xr points[i].y);
/* move to beginning of cord*/
lineto(points[j].xv points[j].y);
"draw the cord */
}
}
Paused;
}
*/
LINESTYLEDEMO: Display a pattern*/
using all of the standard linestyles*/
*/
void LineStyleDemo(void)
{
intrstyle,step;
int x, y, w;
struct viewporttype vp;
char buffer[40];
Main Window("Pre-defined line styles");
getviewsettings(&vp);
w = vp.right - vp.left;
x « 35;
У * 10;
step = w/11;
Circle Dettonstratwn
Рис. 27. Демонстрация кругов.
Pie Chart Denonstration
settextjustify(LEFT_TEXT. ТОР_ТЕХГ); outtextxy(xr у. "Normal Width");
settextjustify(CENTER_TEXT. T0P_TEXT);
for(style=0; style<4; ++style){
set]inestyle(style( 0r NORM_WIDTH);
1ine(x, y+20, x, vp.bottom-40);
itoa(style, buffer, 10);
outtextxy(xf vp.bottom-30, buffer); x += step;
}
x += 2 * step;
settextjust1fy(LEFT_TEXT tT0P_TEXT);
outtextxy(x. y, "Thick Width"); settextjustffy(CENTER_TEXT,TOP_TEXT);
for(style=0; sty?e<4; ++sty1e){
setlinestyle(style, 0, THICK_WIDTH);
1ine(x, y+20, x. vp.bottom-40);
itoa(style, buffer, 10); outtextxy(xv vp.bottom-30( buffer); x *= step;
Bar / Rectangle denonstration
These are 2-D Bars
Esc aborts or press a key...
settextj ust i fy(LEF WEXT ,TOP_TEXT);
Pause();
}
/**/
/*CRTMODEDEMO: Demonstrate the effects*/
/*of the change mode commands*/
/*on the current screen*/
/**/
void CRTModeDemofyoid)
{
struct viewporttype vp;
Main Windov^f"SetGraphMode/ RestoreCRTMode demo*1);
getviewsettings(&vp);
settextjustify(CENTER_TEXTfCENTER_TEXT);
outtextxy(vp.right-vp.left)/2,(vp.bottom-vp.top)/2,
"Now you are in graphics mode...w);
StatusLine("Press any key for text mode...");
getch(); *
restorecrtmode();
printf(MNow you are in text mode.\n\nM);
printf("Press any key to go back to graphics...w);
getch();
setgraphmode(getgraphmode());
MainWindow("SetGraphMode/ RestoreCRTMode demo**);
settextj us t i fу(CENTER_TEXT,CENTER_TEXT);
outtextxy((vp.right-vp.left)/2. (vp.bottom-vp.top)/2.
"Back 1n Graphics Mode…");
Pause();
/**/
/* USERLINESTYLEDEMO: Display line styles */ /* showing the user defined line style functions */
/**/
void UserLineStyleDemo(void) {
int x, y. 1. ht flag;
unsigned int style;
struct viewporttype vp;
Ma inWindow ("User defined line styles*');
getviewsettings(&vp);
h = vp.bottom - vp.top;
x = 4;
У = 10;
style * 0;
i =0;
settextjustify(CENTER_TEXT,TDP_TEXT);
flag = TRUE;
/* set the bits in this pass */
while (x< vp.right - 2){
/* draw lines across the screen */
if(flag)
style = style| (1 << f);
/* set the Ith bit ,n word */
else
style = style &! (0x8000) » i);
/* clear the Ith bit in word */
setbnestyle(USERBIT_LlNE, style, NORM_WIDTH);
Ипе(х, y. xf h-y);
/* draw the new line pattern */
x ♦= 5;
/* move the X location of line */
i = ++i % 16;
/* advance to next bit pattern */
If (style == Oxfff){
/* are all bits set ? */
flag = FALSE;
/* begin removing bits */
1 = 0;
/* start with whole pattern */
}
else{
1f (style == 0}
/* are all bits clear? */
flag = TRUE;
/* begin setting bits */
}
}
settextjustify(LEFT_TEXT,TOP_TEXT);
Pause();
*/*/*/*/*/*/*/*/
*/
*/
*/
*/
*/
*/
*/
*/
FILLSTYLEDEMO: Display the standard fill patterns
void FillStyleDemo(void)
Int h. w( style;
int i, ], xr y;
struct viewporttype vp;
char buffer[40];
停
MainWindow('*Pre-defined Fill Styles");
getviewsettings(&vp);
* H 2 * ((vp.right + 1) /13);
n = 2 * ((vp.bottom - 10)/10);
x = w/2;
У= h/2;
style = 0;
MoueRel / L ineRei benonstrat ion
Рис. 30. Демонстрация MoveRel/LineRel.
PutPixel / GetPixel Denonstration
Esc aborts or press a keg...
Рис. 31. Демонстрация PutPixel/GetPtxel.
for(j = 0; j<3; ++j){
/* three rows of boxes */
for(i = 0; i<4; ++i){
/* four column of boxes */ setfillstylefstyle, MaxColors-1);
/* set the fill style and WHITE */ bar(x, yr x+«. y+h);
/* draw the actual box */ rectangle(x. y. x+w. y+h);
/* outline the box */ itoa(style, buffer, 10);
/* convert style 3 to ASCII */ outtextxy(x+(w/2), y+h+4, buffer); ++style;
/* gs on to next style number */
x += (w/2)*3;
/* go to next column */
}
〃 end of column loop */
x = w/2;
/* put Rase back to 1st column */
У +^ (h/2)*3;
/* advance to next row */ } /* end of row loop */
settextjustify(LEFT_TEXT,TOP_TEXT);
Pause();
/*FILLPATTERNDEMO: Demonstrate how to use */
/*the user definable fill patterns*/
〃*/
void Fill PatternDemoc(void)
{
int style
1nt h. w;
int x. y. 1( j;
char buffer[40];
struct viewopttype vp;
static char patterns[][8]=
{ OxAA,
0xS5, OxAA, 0x55, OxAA,
0x55, OxAA, 0x55 }
{ 0x33,
0x33. OxCC, OxCC, 0x33,
0x33, OxCC. OxCC }
{ OxFO,
OxFO, OxFO, OxFO, OxOF,
OxOF, OxOF, OxOF }
{ 0x00,
0x10. 0x28, 0x44. 0x28,
0x10. 0x00, OxGO }
{ 0x00,
0x70. 0x20, 0x27, 0x24,
0x24, 0x07, 0x00 }
{ 0x00,
0x00, 0x00. 0x18, 0x18.
0x00r 0x00,
0x00 }
{ 0x00.
0x00, ОхЗС, ОхЗС, 0x3C,
0x3C. 0x00.
0x00 }
{ 0x00,
0x7E. 0x7E, 0x7E, 0x7E.
0x7E, 0x7E,
0x00 }
{ 0x00,
0x00, 0x22. 0x08. 0x00
0x22. QxlC.
0x00 }
{ OxFF.
0x7E. 0x3C. 0x18. 0x18,
0x3C, 0x7E.
OxFF }
{ 0x00r
0x10, 0xl0r 0x7C. 0x10.
0x10, 0x00v
0x00 }
{ 0x00,
0x42, 0x24, 0x18, 0x18,
0x24, 0x42,
0x00 }
Ma1nV1ndow(MUser Defined Fill Style**);
getviewsettings(&vp);
w « 2 *((vp.right+l) /13);
h * 2 *((vp.bottom -10)/10);
x * w/2;
У * h/2;
style = 0
for(j=0; j<3; ++j){
/* three rows of boxes */
for(i 匸 0; t<4; ++i){
/* four column of boxes */
setfillpettern(&patterns[style][O], NaxColors-1); bar(x, y, x+w, y+h));
/* draw the actual box */ rectangle{x, y. x+w, y+h);
/* outline the box */
1toa(style, buffer, 10);
/* convert style 3 to ASCII */ outtextxy(x+(w/2), y+h+4, buffer); ++style;
/* go on to next style number */
x +» (w/2)*3;
/* go to next column */
}/* end of column loop */
x = w/2;
/* put base back to 1st column */
У += (h/2)*3;
/* advance to next row */
} /* end of row loop */
settextjustify(LEFT_TEXT, TOP_TEXT);
Pause();
/* POLYDEMO: Display a random pattern of polygons */
/**/
void PalletteDemo(vold)
int i. J・ x. y, color;
struct viewporttype vp; int height, width;
MalnWIndow(MPa1ette Demonstrat1on");
StatusLineC'Press and key to continue, ESC to Abort");
getv1ewsett1ngs(&vp);
width * (vp.right 一 vp.left)/15;
/* get width of the box */
height 工(vp.bottom - vp.top /10;
/* get the height of the box */
x * у * 0;
/* start In upper corner */
color * 1;M
/* begin at 1st color */
for(j « 0; j<10; ++j){
/* for 10 rows of boxes */
for(i x 0; i<15; ++1){
/* for 15 cclumns of boxes */
setfl1lstyle(SOLID_FILLf color++);
/* set the color of box */ bar(x, y, x+wtdth, y+helght);
/* draw the box */
x += width + 1;
/* advance to next col */
color * 1 + (color X (MaxColors - 2));
/* set new color */} /* end of column loop */
x »= 0;
/* goto 1st column */
у += height + 1;
/* goto next row */
} /* end of row loop */
wh11e(! kbhit()){
setpalette(l+random(MaxColors - 2), random(65));
}
seta1Ipalette(&palette);
Pause();
"*/
/* POLYDEMO: Display a random pattern of polygons */
/*. */
#defIne MaxPts 6 /* maximum number of points */
void PolyDemo(void)
{
struct PTS poly{MaxPts];
Int color; int i;
MainWindow(,eDrawPoly/F11 iPoly Demonstration"); StatusLine(MESC Aborts - Press a Key to stop");
while(! kbh1t()){
color = 1 + random(MaxColors-l);
/* get a random color number (no black) */
setf1llstyle(random{10)f color);
/* set a random line style */ setcolor(color);
/* set the des 1 red color */
for(i = 0; 1<(MaxPts-l); 1 ++) {
/* determine a random polygon */
poly[i].x = random(MaxX); /* set coords */
poly[i].y = random(MaxY);
}
poly[i].x = poly[0].x; /* last point = first point */ poly[i].y = poly[i].y;
Рис. 33. Демонстрация MoveTo/LineTo.
Pre-defined line styles
Sma]
Nidth
Thick Width
J
1
1
1
1
1
1
1
2
1
1 1 1
1 1 1
1 1 1 I 1 1 1
3
1
1
1
1
1
1
1
2
1 1
1 t
1 1 ■ t
1 1
1 f
1 ■
3
Esc aborts or press
a key...
Рис. 34. Демонстрация типа линий.
SetGraphHode / RestoreCRTHode deno
Ва& in Graphics Hode...
fillpoly(MaxPts, (Int far *) poly);
/* Draw Polygon */
}
Pause();
}
/**/
/* SAYGOODBYE: Give a closing screen*/
/**/
void SayGoodbay(void)
{
struct viewporttype viewinfo; int h, w;
MainWindow( " ~ Finale ==**);
getviewsettings(&v1ewinfo);
/* read viewport settings */
ChangeTextStyle(TRIPLEX_FONT, HORIZ_DIR. 4); settextjustify(CENTER_TEXT, CENTER_TEXT);
lr* view Info, bottom - viewinfo, top;
w * viewinfo.right - viewinfo.left;
outtextxy(w/2r h/2. "Thafs all folks!");
StatusLine("Press any key to EXIT"); getch();
Pause();
}
/**/
/*GETMODE: Convert the current device mode*/
/*into a string for Displaying 1n status*/
/**/
char * GetMode(vold)
{
static char buffer[40];
sw1tch(GraphDrIver){
/* Determine the mode setting */
case CGA:
1f(GraphMode ==CGAHI) return ("CGAHI'1); else
spr1ntf(buffer, "CGACXd**, GraphMode); return(buffer);
}
case MCGA;
sw1tch(GraphMode){
case MCGAMED:
return("MCGAMed);
case MCGAHI:
return(,'MCGAHi',);
default:
sprlntf(buffer, ••MCGACXd'*, GraphMode); return(buffer);
}
case EGA:
sw1tch(GraphMode)
case EGALO:
return ("EpALo**);
case EGAHI:
return(”EGAHi“);
}
break;
case EGA64:
sw1tch(GraphMode){
case EGA64L0:
return("EGA64Lo");
case EGA64HI:
retum("EGA64Hi”);
}
break;
case HERCMONO:
return("HercMonoHi");
case EGAMONO:
returnCEGAMonoHr*);
case PC3270:
return('^PC3270HI',);
case ATT400:
sw1tch(GraphMode){
case ATT400MED:
return(,,ATT400Med•,);
case ATT400HI:
return(”AT400H「);
default:
sprlntf(buffer, ,rATT400C%d", GraphMode); return(buffer);
}
case IBM8514:
sw1tch(GraphMode){
case IBM8514L0:
return(MIBM8514Lo");
case IBH8514HI:
return(-IBM8514HiM);
}
break;
case VGA:
sw1tch(GraphMode){
case VGALO:
return (**VGALow);
case VGAMED:
return ('•VGAMed**);
case VGAHI:
return("VGAHi");
}
break;
}
return(',Unknown,');
/* return as a default value */
/* PAUSE: Pause until the user enters a keystroke */ /**/
void Pause(void)
{
static char msg[] = "Esc aborts or press a key.. .**;
StatusLine(mgs);
/* put msg at bottom of screen */ switch(getch()){
case ESC: {
closegraph():
exit(l); /* return to DOS*/ }
case ' ' ; if(getch()=='') Print Screen(l);
}
cleardevice
}
/**/
/* HAINWINDOU: Establish the main window*/
/**/
void MainWindow(char * header)
{
int height:
—764
cleardevIceO;
/* clear graphics screen */ setcolor(MaxColors - 1);
/* set current color to white */ setvNewport(0. 0, MaxX, MaxY, 1);
/* open port to full screen */
height 工 textheight("HM);
/* get basic text height */
ChangeTextStyle(DEFAULT_FONT, HORIZ_DIR, 1);
settextjustify(CENTER_TEXT,TOP_TEXTj;
outtextxy(MaxX/2, 2. header);
setviewport(0. height + 4, MaxX, MaxY -(height + 4), 1);
DrawBorderO;
setviewporfcfl. helght+5, MaxX-1r MaxY-(height+5), 1);
/**/
/*STATUSLINE: Display a status Une*/
/*at the bottom of the screen*/
void StatuslIne(char *msg) {
1nt height;
setvtewport(0, 0t MaxX. MaxY, 1);
/* open port to full screen */ setcolor(MaxColors-l);
/* set current color to white */
Change TextStyle(DEFAULT_FONT, H0RIZ„DIR, 1); settextjust i fу(CENTER^TEXT, TOP_TEXTj;
setlinestyle(SOLIDJINE, 0. NORM^WIDTH);
setf 11 lstylE(EMPnlFILL. D);
height = textheight(',H^^);
/* determine current height */
bar(0, MaxY-(height+4), NaxX. MaxY);
rectangle(Of MaxY-(height+4). MaxX. MaxY); outtextxy(MaxX/2, MaxY-(height+2), msg); setviewportfl, height+5, MaxX~l, MaxY-jhetght+5). 1);
DRAWBORDER: Draw a solid single line around the current viewport
void DrawBorder(vold) {
struct viewporttype vp;
User defined line sgks
••『川川III
"""IIIIIIII
■,,,||||||||||
”"HHIllll
,4,,«!|||||(
■■"""IIIlli
”"HIIIIIII
'••ilij
■"^hiiiiii
、”"HIIIIIII
"""'НИЦ
"^HIIIIII
■'•'•HIIIIIII
.'""MHill
■■""Hlllll
■"'1Щ
"'"HIIIIII
"'ll 川Hill
■""Hillill
nillllll
"""IIIHill
"""Hlllll
"lllllll
",,,,1III1I)|
""■"IUnni
"""Hlllll
"“fHH||||
Hlllll
”'"HUllin
"""lllllll
"H|||
••will喻
"""IIIIIIII
*1111111
•'•••HIIIIII
,,,,,HI|||||
"Hlllll
"'"UIIlllll
"niij
m嘲
uni
Illi
"•••HIIIIII
•"IIIIIIII
'"""lllllll
"”"Nlllll
."用
■■"••Hlllljl
"Hiiiiii
"""Hlllll
F"川1喻
"'"IIIIIIII
”'"HIlllll
■""'lllllll
'4||||
■,,,,||||||||
…""'llllll
hiiiiiii
•■■•"иniiii
"""Hlllll
"""Hlllll
•“"UiHimi
“'""Hlllll
"'HIIIIII
■•""hiiiiii
■■""4111111
,,ЩШ|||||
nillllll
川川Will
""ПНШШ
""川川川
■"••Hllllllll
•'"H川川1
""nilllllll
Esc aborts or press a key...
рис. 36. Линейные матрицы, определяемые пользователем.
Pre-defined Fill Styles
setco1or(MaxCo1ors - 1);
/* set current color to white */
setlinestyle(SOLID_LINE. 0, NORM_WIDTH);
getviewsettings(&vp);
rectangle(0, 0. vp.right - vp.left. vp.bottom - vp.top);
}
/**/
/*CH豐GETEXTSTYLE: similar to settextstyle,*/
/*but checks for errors that might occur*/
/*while loading the font file*/
void ChangeTextStyle(int font, Int direction, int charsize) {.
int ErrorCode;
graphresult();
/* clear error code */
settfcztsty1e(font, direction, charsize);
User Defined Fill Styles
而而Ё旧而前而 EWAltWcWtMtl rkkkkkMk 賑 kkl ЛкМЛк1ЛМЛ1 -ХС,了 ■,$ т р т a J ▲而而Ё旧而前而 EWAltWcWtMtl rkkkkkMk 賑 kkl ЛкМЛк1ЛМЛ1 -ХС,了 ■,$ т р т a J ▲44■ T ■.• V V V •-' ••' V *■' ■-' -••' /^Vwuwwvvr'-'*■* S' \' W ♦“•.♦•,■■- ■-•♦." / 1.* v V w W W W W 1,J,*^ V W V k* V О U W Vй■ T ■.• V V V •-' ••' V *■' ■-' -••' /^Vwuwwvvr'-'*■* S' \' W ♦“•.♦•,■■- ■-•♦." / 1.* v V w W W W W 1,J,*^ V W V k* V О U W Vй88ймктаетаймктаета1+++++如— !•+++++ + + + +++ +++++++如卜++•卜卜Н + + + + + + + + + .1+++++如— !•+++++ + + + +++ +++++++如卜++•卜卜Н + + + + + + + + + .1010。680。08004 0880*00. 08880?。封nninvnvn kHMHBiami MiBBuiiiiii ИИИИВММИ1 “ЕеобЖИЕДу』7、.'”<,、.■、,、,、,',、,,*”, СХХКХХХХХХХК) :ХХХХХХХХХХХ) JXXXXXXXXXXXI11。680。08004 0880*00. 08880?。封nninvnvn kHMHBiami MiBBuiiiiii ИИИИВММИ1 “ЕеобЖИЕДу』7、.'”<,、.■、,、,、,',、,,*”, СХХКХХХХХХХК) :ХХХХХХХХХХХ) JXXXXXXXXXXXI11
而而Ё旧而前而 EWAltWcWtMtl rkkkkkMk 賑 kkl ЛкМЛк1ЛМЛ1 -ХС,了 ■,$ т р т a J ▲
而而Ё旧而前而 EWAltWcWtMtl rkkkkkMk 賑 kkl ЛкМЛк1ЛМЛ1 -ХС,了 ■,$ т р т a J ▲
4
4
■ T ■.• V V V •-' ••' V *■' ■-' -••' /^Vwuwwvvr'
-'*■* S' \' W ♦“•.♦•,■■- ■-•♦." / 1.* v V w W W W W 1
,J,*^ V W V k* V О U W Vй
■ T ■.• V V V •-' ••' V *■' ■-' -••' /^Vwuwwvvr'
-'*■* S' \' W ♦“•.♦•,■■- ■-•♦." / 1.* v V w W W W W 1
,J,*^ V W V k* V О U W Vй
8
8
ймктаета
ймктаета
1+++++如— !•+++++ + + + +++ +++++++如卜++•卜
卜Н + + + + + + + + + .
1+++++如— !•+++++ + + + +++ +++++++如卜++•卜
卜Н + + + + + + + + + .
10
10
。680。08004 0880*00. 08880?。封
nninvnvn kHMHBiami MiBBuiiiiii ИИИИВММИ1 “ЕеобЖИЕДу』
7
、.'”<,、.■、,、,、,',、,,*”, СХХКХХХХХХХК) :ХХХХХХХХХХХ) JXXXXXXXXXXXI
11
。680。08004 0880*00. 08880?。封
nninvnvn kHMHBiami MiBBuiiiiii ИИИИВММИ1 “ЕеобЖИЕДу』
7
、.'”<,、.■、,、,、,',、,,*”, СХХКХХХХХХХК) :ХХХХХХХХХХХ) JXXXXXXXXXXXI
11
Esc aborts or press a key .
Рис. 38. Матрицы заполнения, определенные пользователем.
Error Code = graphresult();
/* check result */
if(ErrorCode ! = grOk){
/* if error occured */ closegraph();
printf("Graphics System Error: Xs\n". g rapherrormsg(ErrorCode));
exit(l);
}
/* DISPLAY: Used like PRINTF */
/* except the output is sent to the screen */ " In graphics mode at the specified co-ordinate */ 〃 */
int Display(int *xloc, int *yloc. char *fmt,…) {
va_list argptr;
/* argument list pointer */
char str[140];
/* buffer to build sting into */
int ent;
va_start(argptr. format);
/* initialize va_functions */
ent = vsprint(str, fmt, argptr);
/* prints string to buffer */ outtextxy(*x1oc, , *ylocf str);
/* send string In graphics mode */
*yloc += textheight("H'*) +2 ;
/* Advance to text line */
va_end(argptr);
/* close va_functions */
return(ent);
/* return the conversion count */
}
/**/
/*ASPECTDEMO: Demonstrate*/
/*setaspectratio function*/
〃jb */
void AspectDemo(void)
{
struct viewporttype viewinfo;
int centerx, centery, 1t
radius, xasp, yasp, step;
MainWindow(MsetAspectRa11о demonstration"): getviewsettings(&viewinfo);
centerx « (viewinfo.right - viewinfo.left) » 1;
centery = (viewinfo.bottoe - viewinfo.top) » 1;
radius ■ 3 * ((viewinfo.bottom - viewinfo.top)/5);
step н radius/30;
circle(centerx, centery, radius);
getaspectrat1о(&xasp, &yasp);
ford ■ 1. 1 < 31, i++){
setaspectratio(xasp, yasp + 1, * getmaxx());
circle(centerx, centery, radius);
radius -= step;
}
radius += step * 30;
for(1=1; 1<fil; i++)
setaspectratiо(xasp + 1 * getmaxx(). yasp);
1f(radius > step)
radius -= step;
circle(centerx, centery, radius);
}
Pause();
/*FILLELLIPSEDEMO: Demonstrate
jb */jb *//*fillellIpse function
jb */
jb */
/*
void FillEllipseDemo(void) {
Int maxradius, fillcolor. fillstyle, maxx, maxy;
MainWindow("F111Ellipse demonstration**);
StatusLine("Esc aborts or press a key to stop");
maxradius = getmaxy() /10;
maxx = getmaxx() - maxradius;
maxy = getmaxyf) - maxradius;
setlinestyle(SOLlD_LINEr 0, NORM_WIDTH);
while( ! kbh1t()){
f illcolor == random (get maxcolorO + 1);
setco1or(random(f1llcolor + 1));
fillstyle = random(12);
setf1llstyle(fillstyle, fillcolor);
fi1lei1ipse(random(maxx), random(maxy), random(maxrad1us). random(maxradius));
}
Pause();
Palette DeMonstration
Рис. 39. Демонстрация Palette.
DrawPoly / FillPoly Denonstration
Рис. 40. Демонстрация DrawPoly/FUIPoiy.
jbjb*/*/*/*/*/*/*/*/
jb
jb
*/
*/
*/
*/
*/
*/
*/
*/
SECTORDEMO: Demonstrate sector function
void SectorDemo(void)
{
int maxradius, fillcolor, endangle, maxx, maxy, fillstyle;
MainWindow("Sector demonstration");
StatusLinefEsc aborts or press a key to stop");
maxradius = getmaxy()/5;
maxx = getmaxx() - maxradius;
roaxy = getmaxy() - maxradius;
while( ! kbhit ()){
fillcolor == getmaxcolorO;
setcolor*(f1llcolor);
fillstyle == random (12);
<f(fillstyle == ENPTY—FILL) fillstyle = LINE_FILL;
setfillstyle(fi1Istyle, fillcolor);
endangle = random(360);
sector(random(maxx). random(maxy). random(endangle), endangle.
=Finale -=
That's all, folks!
random(endangle). endangle, maxradius/2 + random(maxrad1us/2).
maxradius/2 + random(maxradius/2));
}
Pause();
15. Ассемблер
Несмотря на то что современные языки программирования высокого уровня обеспечивают не только удобное, но и эффективное системное программирование, в тех редких случаях, когда особенно важно получить оптимальный объективный код, необходимо использовать ассемблер.
Представленйый здесь Турбо Ассемблер разработан фирмой <€Борланд Интсрнэйшнл44 для семейства микрокомпьютеров IBM PC, оборудованных микропроцессорами Intel 8088, 8086, 80286 и т. д. Он похож на ассемблер MASM фирмы иМайкрософт Корпорзйшн", но при этом содержит целый ряд дополнений и усовершенствований и, кроме того, значительно более быстрый.
Ассемблер активирован в версии MASM (совместимой с версией MASM 4.*), но с помощью специальных команд может быть переключен к версии MASM S1 (совместимой с версией 5.1) или IDEAL (версия фирмы "Вор- ландм).
Компилятор
Компилятор Турбо Ассемблер является программой в виде загрузочного файла TASM.EXE. Компилятор вызывается командой
TASM патеь
в которой пате является именем компилируемого файла «ame.ASM и создает перемещаемый объектный модуль name.OBJ,
Вызов компилятора TASM в общем случае имеет вид
TASM fileset, fileset; ...; fileset,
в котором каждый fileset представляет собой
options sources, object, list, cross.
Options является набором опций, касающихся каждого fileset, sources - имена файлов, включающих исходные модули, object - имя файла, в который будет помещен созданный ассемблером объектный модульу list - имя файла инстинга, cross - имя файла таблицы перекрестных ссылок. Опции обычно отделяются пробелами, а имена файлов должны быть отделены пробелами либо знаками + (плюс).
Описание правил пользования компилятором TASM дано в приложении Д. Команда
TASM/Zi test 1 + test 2 test; 1 greet
вызовет создание из исходных модулей test l.asm и test 2.asm, связанных опцией/Zi, итогового модуля test.obj. и, кроме того, создание из исходного модуля greet.asm объектного модуля greet.obj я файла листинга greet. 1st (опция/Zi позволит осуществить отладку исполнительной программы).
Компоновщик
С целью создания исполнительной программы необходимо провести компоновку исполнительных модулей с библиотечными модулями. Это можно выполнить с помощью компоновщика Турбо Линк фирмы Borland.
Компоновщик Турбо Линк является программой в виде файла TLINK.EXE. Его вызывают командой
TLINK пате,
в которой пате - имя компонуемого объектного файла name.OBJ, После компоновки создается загрузочный файл name.EXE.
Вызов компоновщика TLINK в общем случае имеет вид
TLINK options object екес, тар, libraries,
где options - набор опций, object - имена файлов, содержащих объектные модули, ехёс - имя файла, содержащего загрузочную программу, тар - имя файла, в котором будет помещена карта компоновки, a libraries - имена файлов объектных библиотек. Опции обычно отделяются пробелами, имена файлов должны быть отделены пробелами или знаками + {плюс).
Пример. Первая программа
В соответствии с принятой традицией исполнение первой программы должно заканчиваться выводом надписи Hello world. Такая программа написана на языке Турбо Ассемблер и предусмотрена для исполнения в операционной системе DOS. Она имеет вид
Data SEGMENT
Greet DB 'Hello world*. 13.10. '$' Data ENDS
Assume CS: Code. DS:Data
Code SEGMENT
Start:
mov ax. Data mov ds, ax; mov dx. OFFSET Greet mov ah. 9 int 21.h mov al. 0 mov ah. 4 ch int 21hCode ENDSmov ax. Data mov ds, ax; mov dx. OFFSET Greet mov ah. 9 int 21.h mov al. 0 mov ah. 4 ch int 21hCode ENDS; загрузка номера сегмента в регистр DS
mov ax. Data mov ds, ax; mov dx. OFFSET Greet mov ah. 9 int 21.h mov al. 0 mov ah. 4 ch int 21h
Code ENDS
mov ax. Data mov ds, ax; mov dx. OFFSET Greet mov ah. 9 int 21.h mov al. 0 mov ah. 4 ch int 21h
Code ENDS
;выведение надписи
; возвращение в систему
Stack - SEGMENT Stack
DB lOOh DUP(?); стек размером 256 байт
Stack-ENDS
END Start; адрес начала программы
Указанная программа состоит из следующих частей: сегмент данных
Data SEGMENT
Data ENDS
сегмент команд
Code SEGMENT 件
Code ENDS
сегмент стека
Stack一SEGMENT STACK
Stack_ENDS
а также из директив ASSUME и END.
Сегменты означают разделение программы на логически разъединенные части, в которых сгруппированы данные и команды, а также зарезерв ировано место для стека.
Директива ASSUME объявляет, что во время выполнения тех команд программы, которые следуют за ASSUME и неявно обращаются к указанным в ней регистрам процессора (здесь CS и DS), эти регистры будут содержать номера сегментов с указанными именами (здесь Code и Data).
Директива END заканчивает запись текста программы и предписывает, чтобы ее исполнение начиналось с команды, снабженной меткой, указанной в директиве (здесь Start).
Так как загрузка регистра CS номером сегмента, в котором находится команда, снабженная меткой, указанной в директиве END, выполняется операционной системой, то остается только загрузить регистр DS. Это выполняется с помощью команд
/иоу ах. Data; поместить в АХ номер сегмента Data
mov ds, ах; переслать АХ в DS.
Поэтапное выполнение этой функции вызвано тем, что в процессоре 8086 нет команды, позволяющей непосредственно загрузить регистр DS.
После загрузки регистров происходит двукратное обращение к функции системы DOS: вначале для вывода надписи Hello world, а затем с целью окончания выполнения программы. В каждом из этих случаев происходит выполнение системной функции, реализуемое прерыванием программы по команде int 21h.
Перед исполнением прерывания в регистрах процессора помещаются следующие параметры:
с целью выведения надписи Hello world
б АН - номер функции мвыведи надпись**: mov ah. 9
в DX - смещение надписи относительно DS: mov dx, OFF SET Greet
с целью окончания выполнения программы:
б АН - номер функции **возврат в системуи: mov ah, 4ch
в AL - код возврата: mov al, О
(что можно выразить проще командой: mov ах, 4c00h).
С целью преобразования приведенной программы к исполняемому виду необходимо
поместить ее в файл Greet.ASM;
скомпилировать, выдав команду tasm greet;
скомпоновать, выдав команду tlink greet.
После выполнения этих действии, которые приведут к созданию файла Greet.EXE, программу можно выполнять, вводя имя greet (в системе DOS маленькие и большие буквы в именах файлов не различаются)«
5.1. Процессоры
Наиболее распространенными процессорами микрокомпьютеров IBM PC и PC/XT являются Intel 8088 и Intel 8086. Эти процессоры установлены более чем в 10 миллионах компьютеров типа IBM PC, и, хотя минуло уже более 10 лет с момента их появления на рынке, они все еще доминируют на нем.
Типичным представителем этого семейства микропроцессоров является микропроцессор 8088, список команд которого идентичен микропроцессору 8086, Именно поэтому данный микропроцессор выбран за основу для программирования на языке Турбо Ассемблер.
Область адресов микрокомпьютера с микропроцессором 8088 имеет размер 1 Мбайт. Доступ к любому из 1.048.576 байт памяти осуществляется с помощью 20-бит адресов, состоящих из частей, называемых номером сегмента и смещением с сегменте.
Формирование адреса памяти основано на умножении номера сегмента на 16 и прибавлением к нему смещения.
В этом смысле адрес, представляемый условно как
segment: offset,
является по сути адресом байта с номером
segment* 16 + offset。
Так как использование адресов, получающихся сложением 16-бит номера сегмента и 16-бит смещения, очень удлинило бы код машинных команд,
применяется упрощение, основанное на том, что в большинстве команд предполагается, что сегментная часть команды находится в одном из сегментных регистров.
Благодаря этому предположению коды команд значительно сокращаются, но применение такой команды должно предваряться соответствующей загрузкой сегментных регистров.
Если программа короткая, т. е. ни ее команды, ни данные не занимают более 64 Кбайт памяти, загрузка регистров может быть одноразовой и выполняться, как правило, после начала выполнения программы. В противном случае может появиться потребность многократной загрузки сегментных регистров.
В микропроцессоре 80386 это затруднение практически устранено введением возможности использовать сегменты размером до 4 Гбайт.
Классификация регистров
Совокупность регистров микроп роцессора 8088 можно разделить %а следующие группы:
регистр фланков:FL
универсальные регистры: АХ.BXrСХ.DX. SI. DI, BP, SP
регистр счетчика:IP
сегментные регистры:CS,DS,ES,SS
Каждый из приведенных регистров имеет 16 бит. Независимо от этого регистр FL может быть представлен как комплекс из 16 регистров по 1 бит каждый, а каждый из регистров АХ, ВХ, СХ и DX - как комплекс двух 8- бит регистров (например, старшая часть регистра АХ является регистром АН, а младшая - регистром AL) и т. д.
АХвхСХDXАХвхСХDX
АХ
вх
СХ
DX
АХ
вх
СХ
DX
Независимо от проведенного разделения регистры ВХ и ВР называются базовыми, а регистры SI и DI - индексными.
Начальные значения регистров
Необходимо принять, что непосредственно после начала выполнения программы, осуществляемого интерпретатором команд, начальные значения универсальных регистров ие определены. Единственным исключением является регистр SP. В этом регистре помещается число байтов стека, зарезервированного программой. Значения регистра счетчика и сегментных регистров определены однозначно. Если программа, записанная на языке Турбо Ассемблер, содержит директиву END, в которой есть метка команды (например. Start), то регистр CS загружен номером сегмента, в котором находится эта команда (SEG Start), а регистр IP загружен смещением в сегменте именно этой команды (OFFSET Start). Благодаря этому выполнение программы начинается с указанной меткой команды. Именно в этот момент в регистрах DS и ES будет находиться номер 256-байт сегмента PSP, помещенного в оперативной памяти непосредственно перед первым байтом программы, а в регистре SS будет находиться номер сегмента, предназначенного для стека.
Внимание: В случае появления в программе директивы END без метки первоначальные значения указанных регистров следующие:
DS - ES - SEG PSP;
CS - DS + 10h;
IP - 0.
Регистр флажков (слово состояния процессора)
В регистре флажков хранятся данные о состоянии процессора, а также о результатах выполнения некоторых команд. Среди 16 бит этого регистра только 9 имеют определенную интерпретацию
FL I I I Im亜冲卜|网1Р1网
О - Overflow (бит переполнения)
D - Direction (бит направления)
I - Interrupt (бит прерывания)
Т - Trap (бит ловушки)
S - Sign (бит знака)
Z - Zero (бит нуля)
А - Auxiliary (бит переноса тетрады)
Р - Parity (бит четности)
С - Carry (бит переноса)
В момент начала выполнения программы I = 1, Т == 0. Значения остальных битов не определены.
Установка каждого из указанных битов в состояние 1 означает следующее:•
О - результат операции не помещается в регистре;
D - операции на числовых цепочках будут выполнены в направлении уменьшающихся адресов;
I - процессор реагирует на прерывание;
Т - после каждого выполнения команд происходит попадание в ловушку;
S - старший бит результата операции имеет значение 1;
Z - результатом операции является 0;
А - выполнение операции вызвало перенос из младшей тетрады результата;
Р - младшие 8 бит результата содержат четное число единиц;
С - выполнение операции вызвало перенос.
Универсальные регистры
Каждый из универсальных регистров может хранить 16-бит данные. Универсальны^ регистры АХ, ВХ, СХ и DX могут хранить пары 8-бит данных.
АХ
Регистр АХ является аккумулятором. Чаще всего он служит для выполнения арифметических, логических операций пересылки данных. Операции в 名том регистре оптимизированы и обычно выполняются быстрее, чем в остальных регистрах.
Примеры
mov ах,13 mov al,0 mov ax,[Fix]mov ах,13 mov al,0 mov ax,[Fix]поместить в АХ число 13
mov ах,13 mov al,0 mov ax,[Fix]
mov ах,13 mov al,0 mov ax,[Fix]
обнулить младший байт регистра АХ
загрузить данные из ячейки с адресом DS:Fix
BX
Регистр BX - базовый регистр. Содержит обычно смещение относительно начала сегмента, номер которого находится в выбранном сегментном регистре (согласно предположению в DS).
Пример
mov bx,3
mov ах, [Ьх ] ; загрузить данные из ячейки с адресом DS:3
СХ
Регистр СХ является регистром счетчика, обычно определяющим количество выполнении операций цикла.
хог Ьх. Ьх; обнуление регистра ВХ
mov cxrs;установка счетчика
Again:
mov [word ptr bx],13 ; ВХ - адрес слова
Inc bx; увеличение ВХ на 1
loop Again; выполнить согласно счетчику (5 раз)
DX
Регистр DX является регистром, используемым в операциях умножения н деления, а также единственным регистром, в котором можно указать адрес порта в командах ввода и вывода.
Пример
mov ах, 300 mul Ьх
;поместить в DX-AX величину АХ*ВХ
SI и DI
Регистры SI и DI являются индексными регистрами. Они содержат обычно смещения относительно начала выбранных сегментов оперативной памяти и тем самым позволяют выполнять операции на последовательности данных, чаще числовых.
Пример
mov ах, OFFSET String mov si( ax cld mov cxt -1 Again
mov al, [Si] inc ex Inc si and al, al Jnz Again
обнуление значения направления (DF) установка счетчика ненулевых байтов
загрузка байта из DS:SI
увеличение СХ
увеличение SI проверка на нуль повторение если не нуль
ВР
Регистр ВР является базовым регистром. Он, как жит обычно смещение относительно начала сегмента относится к сегменту стека, определяемому с помощью
и регистр ВХ, содер- с той разницей» что регистра SS.
mov bp, sp push ax add ax.[bp-2]SPmov bp, sp push ax add ax.[bp-2]SPпересылка SP в BP
mov bp, sp push ax add ax.[bp-2]
SP
mov bp, sp push ax add ax.[bp-2]
SP
поместить в стеке данные из АХ
прибавление к АХ данных с верхушки стека
Регистр SP является указателем стека. Он содержит смещение в сегменте, определенном регистром SS, младшего байта данных, отсылаемого в стек.
Пример
push ах #; неявное уменьшение SP на 2
Регистр счетчика IP
Регистр IP является счетчиком команд. Он содержит смещение в сегменте, определяемом регистром CS, команды, которая будет выполнена следующей. Каждое выполнение команды процессора вызывает увеличение счетчика IP на число байтов, необходимое для представления данной команды. Исключения из этого правила касаются команд перехода (см. дальше), указанных в описании регистра CS.
вычисление числа 25 изменение IPвычисление числа 25 изменение IPmov ах,1 mov сх,5 Again add ах,ах loop Again
вычисление числа 25 изменение IP
вычисление числа 25 изменение IP
Сегментные регистры
Сегментными регистрами являются CS, DS, ES, SS. Значение каждого из них (в сочетании со смещением в сегменте) определяет адрес байта оперативной памяти. Если принять, что seg представляет значение сегментного регистра, a off - смещение, то адресом байта является segzoff.
Внимание: С точки зрения принятого способа обозначения адреса (сдвиг seg и прибавление off) каждый адрес может быть представлен несколькими способами. В частности, адресом одного и того же байта является (выражая в шестнадцатеричной записи) 40:6 С и 46:0 С. Поэтому принято говорить об адресе нормализованном, т.е. о таком адресе, в котором смещение представлено числом меньше 16.
Регистр CS
Регистр CS содержит номер сегмента, из которого по адресу CS: IP будет выбрана и исполнена следующая команда. Начальные значения регистров CS
и IP установлены на основе номера сегмента и смещения для метки, указанной в директиве END. Изменение значения регистра CS может произойти только в результате выполнения таких команд, как CALL (вызов процедуры), JMP (переход в другой сегмент), RET (возвращение из процедуры) и INT (программное прерывание).
Пример
ASSUME CS: Codel
Start:Start:;здесь CS = SEG Codel, IP = OFFSET Start ; переход на метку Lab;здесь CS = SEG Codel, IP = OFFSET Start ; переход на метку LabCode SEGMENT
Start:
Start:
;здесь CS = SEG Codel, IP = OFFSET Start ; переход на метку Lab
;здесь CS = SEG Codel, IP = OFFSET Start ; переход на метку Lab
jnjp far ptr Lab Codel ENDS
Code2 SEGMENTLab:Code2 SEGMENTLab:ASSUME CS: CodeZ
Code2 SEGMENT
Lab:
Code2 SEGMENT
Lab:
;здесь CS = SEG Code2, IP = OFFSET Lab
mov ax, 4c00hmov ax, 4c00h; код возврата 0 \
mov ax, 4c00h
mov ax, 4c00h
int 21h\
Co6e2 ENDS
Stack_SEGMENT STACK)
DB 100H DUP(?) Stack_ENDS
END Start
Регистр DS
Регистр DS содержит номер сегмента данных, т. е. именно того сегмента, в который, согласно предположению, отсылается большинство команд взаимодействия с памятью.
Пример
Data SEGMENT Fix DB 13 Data ENDS
ASSUME CS: Code, DS:Data
Code SEGMENT
Start:; здесь DS = SEG PSP
mov ax. Data mov ds, ax mov al,[Fix]; здесь DS 匸 SEG Data-
15*15*mov ah, 4ch int 21h Code ENDS Stack SEGMENT STACK
15*
15*
db 100Н DUP(?) Stack_ENDS
END Start
Регистр ES
Регистр ES содержит номер добавочного сегмента, т. е. того сегмента, в который, согласно предположению, отсылаются некоторые команды для выполнения операции на цепочках данных.
Пример
DataScr SEGMENT
Src DB 13 幫 DataSrc ENDS
DataDst SEGMENT Dst DB?
DataDst ENDS
ASSUME CS: C^de, DS: DataSrc. ES: DataDst
Code SEGMENT Start:
пересылка байта из DS: SI в ES:DIполучение пересланного байтапересылка байта из DS: SI в ES:DIполучение пересланного байтаmov ax. DataSrc mov ds, ax wov ax, DataDst mov es» ax mov sit OFFSET Src mov di. OFFSET Dst mov sb mov ds. ax raov al,[Dst] niov ah. 4ch int 21b Code ENDS
пересылка байта из DS: SI в ES:DI
получение пересланного байта
пересылка байта из DS: SI в ES:DI
получение пересланного байта
Stack一SEGMENT STACK DB lOOh DUP(?)
Stack_ENDS
END Start
Регистр SS
Регистр SS содержит номер сегмента стека, т« е. того сегмента, к которому относятся все команды взаимодействия со стеком. Среди них push (положить в стек), pop (извлечь из стека), а также типичные команды, относящиеся к регистру ВР. ,
ASSUME CS: CodeASSUME CS: Code\
ASSUME CS: Code
ASSUME CS: Code
Code SEGMENT
Start:; здесь SS = SEG Stack_, SP ■ 100
mov ax. 7
push ax
vnov ax, 6 push ax mov bp, sp mov al, [bp+2]; возьми 7
add al, [bp]; добавь 6
mov ah, 4ch
int 21h
Code ENDS
Stack_SEGMENT STACK
DB i00h DUP(?)
Stack_ENDS
END Start
Использование префикса
Результатом отказа от использования в большинстве команд, обращающихся к памяти, явного номера сегмента является значительное сокращение кода этих команд. Сокращение также достигается благодаря договоренности, что для конкретной команды требуемый номер сегмента будет находиться в определенном регистре. В тех редких случаях, когда принятый порядок соответствия сегментных региегров команды оказывается неудобным, его можно изменить, проверяя адрес команды префиксом, имеющим вид названия сегментного регистра. Использование такого префикса (удлиняющего код команды на один байт) приводит к тому, что предполагаемый сегментный регистр заменяется сегментным регистром, определяемым префиксом.
Пользуясь префиксами, необходимо помнить о некоторых ограничениях:
использование префикса касается только аргументов команды;
не допускается, чтобы команды операций со стеком (push и pop) были реализованы с помощью пересылки в иной регистр, кроме SS;
-не допускается, чтобы применяемые в некоторых командах над цепочками данных (movs, emps, seas, stos) пересылки в регистр ES были заменены пересылками в любой другой регистр.
Пример
ASSUME CS: Code
Code SEGMENT
Fix DB 13
Start:
mov al, [cs:Fix];адресация относительно CS
mov ah, 4ch
int 21h
Code ENDS
Stack_SEGMENT STACK
DB 100h DUP(?)
Stack_ENDS
END Start
Так как метка Fix находится в сегменте, к которому можно адресоваться только через регистр CS, использование префикса CS излишне, поскольку команда mov al, [Fix] и так была бы заменена указанной командой.
Виды адресации
В микропроцессоре Intel 8086 существуют три вида адресации:
непосредственная адресация;
регистровая адресация;
адресация памяти (непосредственная н косвенная).
Непосредственная адресация
Непосредственная адресация связана с аргументами команд, которые являются постоянными выражениями. Значения этих выражений могут быть заданы перед началом выполнения программы.
Примеры. Непосредственная адресация
mov ах, 20; загрузка в регистр АХ числа 20
mov ах, OFFSETFix; загрузка в регистр АХ величины, равной смещению
адреса переменной Fix
int 21hint 21hгенерирование программного прерывания с номером 21h
int 21h
int 21h
Регистровая адресация
Регистровая адресация связана с аргументами команд, которые находятся непосредственно в регистрах процессора.
Примеры. Регистровая адресация
выполнение операции SI: ~ SI + 1
пересылка данных из регистра ВХ в регистр АХ
Адресация памяти
Адресация оперативной памяти может быть непосредственной или косвенной. В командах непосредственной адресации присутствуют атрибуты, представляющие адреса переменных и команд. В командах непосредственно访 адресации, кроме того, присутствуют атрибуты пересылки в базовые и индекс
ные регистры. В каждом случае имеются также неявные пересылки в сегментные регистры.
Непосредственная адресация переменных
Команды непосредственной адресации переменных опеределяют их адреса в виде
или
где " является постоянным выражением, содержащим символ переменной и определяющим смещение адреса переменной в сегменте.
Непосредственная адресация команд
При непосредственной адресации команд (переходы и вызовы процедур) адреса определяются б общем виде
где d является постоянным выражением.
Примеры непосредственной адресации памяти
mov ах. [Fix]; пересылка значения переменной Fix в регистр АХ
call Fun; вызов процедуры Fun
Косвенная адресация
Команды с косвенной адресацией определяют адреса переменных и команд, используя базовые (ВХ, ВР> и индексные (SI, DI) регистры. В общем случае адрес может быть выражен с помощью одного из 16 следующих выражений:
-м ш -и ^ш + + + + X X р р ь ь ь ь + + + + 口 W0 bxlbplsildil + + + + J J J J-м ш -и ^ш + + + + X X р р ь ь ь ь + + + + 口 W0 bxlbplsildil + + + + J J J J[Ьх] [Ьх + si] [bp] [Ьх + di] [si] [bp + si] [di] [bp + di]
-м ш -и ^ш + + + + X X р р ь ь ь ь + + + + 口 W0 bxlbplsildil + + + + J J J J
-м ш -и ^ш + + + + X X р р ь ь ь ь + + + + 口 W0 bxlbplsildil + + + + J J J J
в которых d представляет собой постоянное выражение.
Примеры. Косвенная адресация памяти
mov ах, [Ьх] ; пересылка в регистр АХ значения переменной, адрес которой находится в регистре ВХ
jmp[si]; переход на выполнение команды, адрес которой
находится в регистре SI
Вычисление эффективного адреса (непосредственного или косвенного) основано на суммировании всех его составляющих, определенных как постоянным выражением d, так и находящихся в указанных или предполагаемых регистрах процессора.
Пример. Вычисление эффективного адреса
mov ах. 5; ВХ : = 5
niov SIV -7; SI ; = -7
mov ах, [Fix + bx +si + 2]
Йоскольку вх + SI + 2 = 0, то выполнение данной команды с косвенной адресацией имеет такой же результат, как и команды с непосредственной адрсацией
mov ах. [FixO-
Внимание: Если явно не указано в описании команд (разд. 15.3), то необходимо принять, что косвенная адресация с использованием регистра ВР касается сегмента с номером, находящимся в регистре SS, а косвенная адресация с использованием регистров ВХ, SI и DI касается сегмента с номером, находящимся в регистре DS.
Представление адресов
Записывая адреса, относящиеся к меткам переменных и команд, необходимо помнить о соответствии размерности данных. В частности, если Fix является меткой двухбайтовой переменной, например
Fix DW 258,
то для загрузки регистра АХ словом данных из адреса Fix можно пользоваться командой mov ах, [Fix ]. Но для загрузки регистра AL байтом данных из адреса Fix необходимо преобразовать адрес слова Fix к адресу байта.
Такое преобразование можно осуществить оператором BYTE PRT, при этом команда пересылки младшего байта переменной Fix в регистр AL принимает вид
mov al, [byte ptr Fix].
В общем случае адресные части команд могут быть образованы не только из символов и названий регистров, но и сложных выражений и префиксов.
Существует довольно произвольный способ записи команд, обращающихся к памяти.
Подлежат исправлению следующие равнозначные команды:
mov ах, [word ptr ds : bp + st + 2] (предпочтительная версия)
mov ax,ds : word ptr[bp + si + 2]
mov ax. word ptr[ds : bp + st + 2]
mov ax, ds : [word ptr bp + st + 2]
mov ax, dx : [word ptr bp] [si + 2]
152 Программы
Каждая программа, записанная иа языке Турбо Ассемблер, состоит из строк вида
label directive comment
или
label : command comment,
где label - метка; directive и command - соответственно директива или команда; a comment - комментарий.
Метка, упреждающая команду, вместе с отделяющим ее знаком : (двоеточие) может быть записана в отдельной строке.
Комментарий является не транслируемой комбинацией любых символов, начинающихся знаком ; (точка с запятой). Наличие метки или комментария необязательно. Не является меткой идентификатор, с которого начинается последняя строка структурной директивы.
Пример. Директивы н команды
ASSUME CS : Code
Code SEGMENT
метка Code
Fix DB 13
Start:; метка Start
;
директива DB, снабженная меткой
mov ax. Code
обращение к метке Code
mov ds, ax
команда, не снабженная меткой
mov al, [Fix ]
обращение к метке Fix
mov ax, 4cOOh
команда, не снабженная меткой
ini 21h
команда, не снабженная меткой
Code ENDS
обращение к метке Code
Stack—SEGMENT STACK ; начало структурной директивы DB 100h DUP (?>; директива, не снабженная меткой
Stack—ENDS; конец структурной директивы
END Start; обращение к метке Start
Ключевые слова
Ключевым словом является слово определенного значения, с которого начинается каждая директива, а также команда. Ключевые слова, записанные с помощью строчных и прописных букв (например, mov,MOV, Mov), не различаются.
Перечень ключевых слов языка Турбо Ассемблер довольно широк. Большинство из них имеет вид буквенно-числового ряда, начинающегося с буквы, например,.
ASSUME, CS, SEGMENT, DB, mov, tnt. STACK, ENDS. END.
234Часть IY. Турбо Ассемблер
но некоторые из них, например
MODEL, % LIST
начинаются со знака . (точка) или % (процент).
Метки
Метка - это идентификатор, сопровождающий директиву или команду. Метка состоит из ряда букв и цифр, на чикающегося с буквы. Буквами, входящими в состав метки, могут быть большие и маленькие буквы английского алфавита, а также знаки
@, $, ?, -•
Запрещаемся, чтобы метка имела вид ключевого слова или чтобы она состояла только из знака ? {вопросительный знак) или $ (.доллар).
Все метки можно разделить на
-метки констант, например
Fatal EQU 13
-метки переменных, например
Value DB -13
-метки команд, например
Start : mov ах. 13
-метки сегментов, например
Data SEGMENT
…ENDS
-метки процедур, например
Fun PROC
... ENDP
-метки макроопределения
Shift MACRO
…ENDM
Если метки стоят перед командой, то они отделяются от нее знаком : (двоеточие). В каждом модуле данная метка может появляться только один раз. Однако ничто не препятствует многократному обращению к ней.
Пример. Метки
Code SEGMENT Plus DB '+* Minus DB '-'Start:mov al, [Plus] sub al, [Minus] mov ah, 4 ch int 21hCode ENDSCode SEGMENT Plus DB '+* Minus DB '-'Start:mov al, [Plus] sub al, [Minus] mov ah, 4 ch int 21hCode ENDS;метка плюс;метка минус;метка плюс;метка минус; обращение к метке плюс; обращение к метке минус; обращение к метке плюс; обращение к метке минус
Code SEGMENT Plus DB '+* Minus DB '-'
Start:
mov al, [Plus] sub al, [Minus] mov ah, 4 ch int 21h
Code ENDS
Code SEGMENT Plus DB '+* Minus DB '-'
Start:
mov al, [Plus] sub al, [Minus] mov ah, 4 ch int 21h
Code ENDS
;метка плюс
;метка минус
;метка плюс
;метка минус
; обращение к метке плюс
; обращение к метке минус
; обращение к метке плюс
; обращение к метке минус
В сегменте Code используются метки Plus и Start» Меткой не является символ Code перед ключевым словом ENDS.
Локальные метки
Значительное облегчение программирования обеспечивают локальные метки. Область действия каждой из них ограничена тем фрагментом модуля, который содержится между ближайшими нелокальными метками команд. Благодаря этому возможно использование в одном и том же модуле нескольких ие противоречащих друг другу, не идентичных меток.
Условием применения локальных меток является использование директивы LOCALS. В области ее действия каждая метка, начинающаяся двумя знаками @ (at), считается локальной. Интерпретация директивы NOLOCALS вызывает прекращение реагирования на локальные метки.
В момент начала компиляции предполагается директива NOLOCALS.
Пример. Использование локальных директив
LOCALS
mov ах, [Alpha]
Labi
cmp axv [Beta]
jg @@Sk1p; переход вперед
inc bx
@@Skip:
cmp ax. [Gamma]
Lab2:
jg 甌Skip
inc bx
@@SHp:
mov [Delta], bx
Lab3:
NOLOCALS
Областью действия первой метки @@Skip является фрагмент программы между нелокальными метками Labi и Lab2. Областью действия директивы LOCALS является фрагмент программы между этой директивой и строкой, содержащей директиву NOLOCALS.
Литералы
Литералы - это имена констант. Они делятся на арифметические, знаковые и цепные. Арифметические литералы делятся на целые и действительные. Целые б свою очередь делятся на десятичные, шестнадцатеричные и двоичные.
Обязательны следующие правила:
десятичный литерал состоит из ряда десятичных цифр;
шестнадцатеричный литерал состоит из ряда шестнадцатеричных цифр, заканчивающегося буквой Н (первым знаком литерала может быть десятичная цифра; 1#гфрн больше 9 записываются с помощью букв от А до F);
двоичный литерал состоит из ряда двоичных цифр, заканчивающегося буквой В;
действительный литерал состоит из целой части, точки, дробной части, буквы Е и показателя; мантисса состоит из рвда десятичных цифр, а показатель состоит из ряда цифр, предваряемого знаком + (плюс) или - (минус);
знаковый литерал состоит из знака кода ASCII, заключенного в кавычки или Апострофы.
цепной литерал состоит из знаков кода ASCII, заключечных в кавычки или апострофы;
строчные и прописные буквы, применяющиеся в арифметических литералах, не различаются.
Примеры
30
- литерал
целый десятичный
leh
-литерал
целый шестнадцатеричный
11110b
-литерал
целый двоичный
З.ОЕ + 1
-литерал
действительный
-знаковый литерал
'Helle'
-цепной
литерал
Первые четыре литерала представляют данные величиной 30.
Команды
Команда определяет действия процесора. Команды делятся на команды без аргументов, одноаргументные и двухаргументные. В соответствии с этим делением они записываются б одном из следующих видов:
mov sb1nt 21hmov ax. 13mov sb1nt 21hmov ax. 13action action arg action dst, src
mov sb
1nt 21h
mov ax. 13
mov sb
1nt 21h
mov ax. 13
Обозначения (мнемоника) команд являются ключевыми словами и поэтому мО1ут быть записаны как прописными, так и строчными буквами. В командах двухаргументных первый аргумент является приемником, а второй -
источником» Некоторые команды (например, mov sb) имеют условные аргументы. В этом случае деление на источник и приемник следует из описания команды.
В момент начала исполнения программы распознаются только команды микропроцессора Intel 8086 и сопроцессора 8087. Прием команд от иного микропроцессора требует использования директив выбора процессора. Каждая из иих состоит из знака . (точка), после которого следует номер процессора, например 80286, 80287 и т. д.
Примеры. Команды
xor alral;обнуление AL
mov al。bh;пересылка BH вAL
jmp Lab;переход на Lab
push ax;поместить AX встеке
ret;возврат из процедуры
Директивы
Интерпретация директивы вызывает декларирование постоянной или переменной, декларирование макроопределения или определение способа дальнейшей компиляции исходного модуля.
Обозначения (мнемоника) директив、(например, SEGMENT и DB) являются ключевыми словами, как и мнемоника команд, поэтому они могут быть записаны как строчными, так и прописными буквами. Некоторые директивы имеют структурный характер и должны выступать с другими родственными им директивами. К такой группе относятся среди прочих директивы условной компиляции, макродирективы, а также сегментные и процедурные директивы.
Директива SEGMENT
Директива SEGMENT имеет общий вид
lab SEGMENT align combine class body
lab ENDS
где lab - метка сегмента, aligh определяет способ помещения сегмента в оперативную память, combine определяет способ соединения нескольких сегментов, объединенных одной и той же меткой (но находящихся в разных исходных моцулях) в один сегмент, a class обеспечивает включение соединенного сегмента в соответствующую группу сегментоь.
Интерпретация сегментной директивы вызывает образование сегмента с названием lab. Если в первом модуле появляется несколько сегментных директив, предваряемых меткой lab, то все они неявно связаны в одну сегментную директиву. В таком случае аргументы align, combine и class должны выступать только в первой из директив, а если они появляются в последующих, то их игнорируют.
Если сегментные директивы с одной и той же меткой появляются более чем в одном исходном модуле, то явный или предполагаемый состав их аргументов должен быть идентичен.
Допускаются следующие значения указанных аргументов:
BYTE
-размещение сегмента на границе байта;
WORD
-размещение сегмента на границе слова;
DWORD
-размещение сегмента на границе двойного слова;
PARA
-размещение сегмента на границе параграфа, т.е. такой
области, адрес которой кратен 16 (такой способ размещения принят по умолчанию);
PAGE
-размещение сегмента на границе страницы, т.е. такой области, адрес которой кратен 256;
combine
PRIVATE^PUBLICCOMMONSTACKMEMORYAT expPRIVATE^PUBLICCOMMONSTACKMEMORYAT expзапрещение сочетания с сегментами иных модулей (такой способ принят по умолчанию);
PRIVATE^
PUBLIC
COMMON
STACK
MEMORY
AT exp
PRIVATE^
PUBLIC
COMMON
STACK
MEMORY
AT exp
соединение сегментов таким способом, чтобы размер созданного сегмента был равен сумме размеров составляющих его сегментов;
соединение сегментов таким способом, чтобы первые байты каждого из сочетаемых сегментов перекрывались бы и имели один начальный адрес, а размер созданного сегмента был равен размеру максимального сегмента;
соединение сегментов, как и в случае PUBLIC, для образования стека;
соединение сегментов, как и в случае PUBLIC, с размещением в оперативной памяти в конце загрузочного модуля;
размещение сегмента, начиная с вычисленного сегментного адреса - константы ехр.
Аргумент class имеет вид символа, заключенного в скобки или в апострофы. Этот символ является именем класса, в который будет зачислен данный сегмент.
Примеры. Директива SEGMENT
Программа одномодульная
ASSUME CS: Code, DS: Data
Data SEGMENT
Pair DB 13
Data ENDS
Code SEGMENT
Start:
mov ax. Data
mov ds, ax
mov ах, [word prt Pair]
Code ENDS
Data SEGMENT
DB 4ch
Data ENDS
Code SEGMENT
int 21h
Code ENDS
Stack_SEGMENT STACK
DB lOOh DUP(?) Stack_ENDS
END Start
Приведенная программа трактуется как программа
ASSUME CS: Code, DS: Data
Data SEGMENT PARA PRIVATE
Pair DB 13, 4ch
Data ENDS
Code SEGMENT PARA PRIVATE
Start:
mov ax. Data
mov dsf ax■
mov ax, [word prt Pair]
int 21h
Code ENDS
Stack_SEGMENT PARA STACK
DB lOOh DUP(?) Stack_ENDS
END Start
Программа двухмодульная
Первый модуль
ASSUME CS: Code. DS: Data
Data SEGMENT WORD PUBLIC
Pair DB 0
Data ENDS
Code SEGMENT BYTE PUBLIC
Start:
mov ax. Data
mov dsr ах
mov ах, [word ptr Pair] Code ENDS
END Start
Второй модуль
ASSUME CS: Code, DS: Data
Data SEGMENT WORD PUBLIC
DB 4ch
Data ENDS
Code SEGMENT BYTE PUBLIC
int 21h 弾
Code ENDS
Stack_SEGMENT STACK
DB lOOh DUP(?)
Stack_ENDS
END
Приведенная программа (после компоновки в очередности указанных модулей) трактуется как программа
ASSUME CS: Code, DS: Data
Data SEGMENT WORD
Pair DB 0. ?, 4ch
Data ENDS
Code SEGMENT BYTE
Start:
mov ax, Data
mov ds, ax
mov axD [word ptr Pair]
int 21h
Code ENDS
Stack_SEGMENT PARA STACK
DB IDOh DUP(?)
Stack_ENDS
END Start
Поскольку первый байт сегмента Data второго модуля должен быть размещен на границе слова, между байтами 0 и 4ch появляется байт неопределенного значения. Поэтому в регистр АН пересылаются данные неопределенного значения, а результат выполнения команды int 21h невозможно предвидеть. Если бы было принято размещение сегмента Data на границе байта, то программа была бы корректна.
Закрытие сегментов
ASSUME CS: Code. DS: Data
Data SEGMENT Fix DB13
Code SEGMENT
Start:
mov ax. Data mov ds, ax mov al. [Fix] mov ah. 4 ch
Code ENDS
Data ENDS
Stack一SEGMENT STACK
DB 100h DUP(?)
Stack_ENDS
Code SEGMENT
int Zlh Code ENDS
END Start
Приведенная программа трактуется как программа
ASSUME CS: Code, DS: Data
Data SEGMENT
Fix DB13
DATA ENDS
Code SEGMENT
Start:
mov axt Data
mov dsr ax
mov al, [Fix]
mov ah, 4ch
int 21h
Code ENDS
Stack_SEGMENT STACK
DB lOOh DUP(?),
Stack一ENDS
END Start
Использование директивы SEGMENT с аргументом ЛГ
Stack_SEGMENT STACK
16—764
DB 100h DUP(?)
Stack一ENDS
Screen SEGMENT AT ObOOOh
DW 1999 DUP(?)
Corner Char DB?
DB?
Screen ENDS
Code SEGMENT
ASSUME CS: Code, DS: Screen
Start:
mov ax. Screen
mov ds, ax
mov bxr。讦SET Corner Char
mov ax, 10000111b SHL 8 + ' mov[bx], ax
mov ax, 4c00h
int 21h
Code ENDS
END Start e
Выполнение программы вызывает высвечивание мигающего знака * (звездочка) в правом нижнем углу экрана монитора, управляемого платой монитора Hercules.
Директива GROUP
Директива GROUP имеет общий вид
name GROUP segname, segname,,.., segname
Где name - имя группы сегментов, состоящей из сегментов с именами segname, указанных после ключевого слова GROUP. Интерпретация директивы GROUP приводит к такому размещению сегментов с указанными именами, что они оказываются в смежном сегменте оперативной памяти размером не более 64 Кбайт. Благодаря принятому размещению доступ ко всем данным и командам этих сегментов может быть реализован с помощью одного сегментного регистра.
Если директива GROUP с одним и тем же именем группы будет использована многократно (даже в различных модулях), то в данную группу будут включены все сегменты, указанные в этих директивах. Пользуясь группами сегментов, необходимо помнить, что, несмотря на принадлежность сегмента к определенной группе, выполнение команды, содержащей выражение с оператором OFFSET, например
mov ах, OFFSET Fix.
определяет смещение относительно начала сегмента, а не относительно начала группы. Поэтому, если адресация осуществляется с помощью регистра, который не был связан с сегментом или с группой сегментов, то
для каждого из таких адресов требуется предварение адреса спецификацией группы^ состоящей из названия группы и двоеточия, например
mov axt OFFSET DGROUP: Fix
Пример. Директива GROUP
Pair GROUP Datai, Data2
ASSUME CS: Code, DS: Pair ; внимание: использовано DS:Pair
Data 1 Segment
Ref DW OFFSET Pair:Fix ; лишний OFFSET Pair
Data 1 ENDS
Data 2 SEGMENT BYTE
DB3
Fix DB
Data2 ENDS
Code SEGMENT
Start:
mov ax. Pair
mov dx, ax
mov bx,[Ref]; лишняя спецификация группы
moval,[bx];возьми 5
movbx,offsetPair:F1x;необходимоиспользовать OFFSET Pair:
/addal.[bx];добавь 5
mov ah, 4ch
int Zlh
Code ENDS
Stack_SEGMENT STACK
DB lOOh DUP(?)
Stack_ENDS
END Start
Программа заканчивается кодом возврата 10. Если бы из программы была убрана спецификация группы Pair, она заканчивалась бы кодом возврата 6.
Директива ASSUME
Директива ASSUME может иметь один из следующих видов:
ASSUME reg: name,reg: пате,…,reg ; name
ASSUME reg: NOTHING
ASSUME NOTHING
в которых каждый reg является именем сегментного регистра (CS, DS, ES, SS), а каждый пате - именем сегмента или группы сегментов.
Интерпретация директивы ASSUME относительно определенного регистра reg> после имени которого следует пате, является декларацией того, что во время выполнения каждой команды, находящейся в области действия этой директивы, в регистре reg будет находиться номер сегмента пате.
Если после reg следует ключевое слово NOTHING, в области действия такой директивы нельзя гарантировать, что во время выполнения программы в регистре reg находится номер сегмента.
Если директива ASSUME не содержит ни одного названия регистра, то отсутствие такой гарантии касается всех сегментных регистров. Поскольку отсылка к метке определенного сегмента возможна только тогда, когда в одном из регистров находится номер этого сегмента, непродуманное использование директивы ASSUME может исключить возможность доступа к снабженным меткой данным или в лучшем случае вызвать генерирование команды с префиксом (дольше выполняемой).
Пример. Директива ASSUME
ASSUME CS ; Code
Code SEGMENT
Fix DB13
Start:
mov ax. Code
mov ds, ax
mov al, [Fix] ; генерируя mov al, [cs : Fix]
mov ah, 4 ch
Int 21h
Code ENDS
Stack. SEGMENT STACK
OB 100h DUP(?)
Stack_ENDS
END Start
Обращение к переменной Fix требует использования номера сегмента, в котором декларирована метка (Fjx. Несмотря на то что во время выполнения программы этот номер сегмента находится в регистре DS, во время компиляции программы этот факт не учитывается (так как подразумевается ASSUME DS : NOTHING), поскольку Турбо Ассемблер генерирует команды с префиксами. Этого можно избежать, пользуясь директивой ASSUME CS: Code, DS: Code.
Директивы PUBLIC, GLOBAL и EXTRN
Использование указанных директив позволяет осуществлять передачу между модулями программ меток, констант, переменных и команд. Связь между модулями осуществляется таким способом, что в модуле, экспортирующем метку, используется директива PUBLIC, а в модуле импортирующем ~ директива EXTRN.
С тем же успехом можно в кахсдом из связанных модулей пользоваться директивой GLOBAL.
Директива PUBLIC имеет вид
PUBLIC symbol, symbol …,symbol,
где symbol является экспортируемой меткой.
Директива EXTRN имеет вид
EXTRN define, define^ ...» define, где каждый define представляется одной из следующих форм:
symbol ; type
symbol ; type : count,
四e symbol - импортируемая метка, type - один из следующих ключевых слон, опрсделя ющих тип ям портируемого объекта (идентичный с типом этого объекта в экспортирующем модуле):
ABC
-имя константы;
BYTE
-имя
переменной
тина
BYTE (1
байт);
WORD
-имя
переменной
типа
WORD (:
2 байт);
DWORD
-имя
переменной
типа
DWORD
(4 байт);
FWORD
-имя
переменной
типа
FWORD
(6 байт);
QWORD
-имя
переменной
типа
QWORD
(8 байт);
TWORD
-имя
переменной
типа
TWORD
(10 байт);
NEAR
-имя
близкой процедуры или команды;
FAR
-имя
далекой процедуры или команды;
count относится только к переменным и определяет количество переменных указанного типа, представленных импортируемым идентификатором.
Директива GLOBAL имеет вид
GLOBAL define, define, ...» define^
где каждый define такой же, как и директива EXTRN.
Директива GLOBAL, использованная в отношении к экспортируемому объекту, трактуется как PUBLIC, а использованная в отношении к импортируемому объекту - как EXTRN.
Пример. Экспортирование * импортирование объектов
Первый модуль
GLOBAL Result : BYTE, AddOne : FAR
PUBLIC Fixed
ASSUME CS : Code, DS : Data
Data SEGMENT Fixed DB 12
Data ENDS
Code SEGMENT
Start:
mov ax, Data
mov ds, ах
call far ptv AddOne; вызов процедуры
mov al. [Result]
mov ah, 4ch
int 21h
Code ENDS
END Start
Второй модуль
ASSUME CS : Code, DS : Data
GLOBAL Result : BYTE. AddOne : Far
EXTRN Fixed, BYTE
Data SEGMENT Result DB?
Data ENDS
Code SEGMENT
AddONE PRdt Far
mov ax. [Fixed]
1nc ah
mov [Result], ah
ret; возврат с процедуры
AddONE ENDP
Code ENDS
Stack_ SEGMENT STACK
DB lOOh DUP(?)
Stack一ENDS
END
Упрощенные директивы
Использование сегментных директив, а также директив GROUP и ASSUME позволяет конструировать модули с довольно сложной логической структурой, особенно модули, которые могут быть связаны с модулями, созданными компиляторами языков высокого уровня.
Учитывая это, Турбо Ассемблер расширен директивами .MODEL, .CODE, .DATA, .DATA?, .FARDATA, .FARDATA?, упрощающими запись программ.
Директива .MODEL
Использование директивы .MODEL предваряет введение упрощенных директив. В этой директиве общего вида
.MODEL model, language
или
.MODEL TPASCAL
model - имя модуля памяти, language - название языка программирования, с которого будут вызываться процедуры данного модуля.
Аргумент language может быть следующим: С, Pascal, Basic или Prolog. Если процедура модуля, записанного на языке Турбо Ассемблер, будет вызвана из программы, написанной на языке Турбо Паскаль, то директива .MODEL имеет вид
.MODEL TPASCAL .
В остальных случаях необходимо указать название языка, 2 также допустимую для него модель памяти. В частности, для языка Си это могут быть модели TINY, SMALL, MEDIUM, COMPACT, LARGE и HUGE.
В программах, целиком записанных на языке Турбо Ассемблер, достаточно ограничиться указанием модели памяти..
Использование директивы .MODEL позволяет заменить сегментные директивы, такие, как, например,
FAR- DATA SEGMENT PARA 'FAR-DATA' (текст сегмента)
FAR- DATA ENDS
упрощенными директивами
.FARDATA
(.текст сегмента),
а также позволяет учесть допущения некоторых других директив, в том числе GROUP и ASSUME,
В каждой из моделей памяти допускается использование упрощенных директив
.CODE
.DATA
•DATA?
.FARDATA
.FARDATA name
.FARDATA?
.FARDATA? name
.CONST
.STACK
а в моделях MEDIUM, LARGE и HUGE допускается, кроме того, директива
.CODE name
(name в директивах FARDATA, FARDATA? и CODE ■ имя сегмента).
В целях упрощения ссылки на имена сегментов данных вводятся следующие неявные определения:
@@@@@@@@Data Code FarData FarData?Data Code FarData FarData?-имя сегмента,-имя сегмента,-имя сегмента,-имя сегмента,-имя сегмента,-имя сегмента,-имя сегмента,-имя сегмента,определяемого .DATA, определяемого .CODE, определяемого .FarData, определяемого .FarData?определяемого .DATA, определяемого .CODE, определяемого .FarData, определяемого .FarData?
@@@@
@@@@
Data Code FarData FarData?
Data Code FarData FarData?
-имя сегмента,
-имя сегмента,
-имя сегмента,
-имя сегмента,
-имя сегмента,
-имя сегмента,
-имя сегмента,
-имя сегмента,
определяемого .DATA, определяемого .CODE, определяемого .FarData, определяемого .FarData?
определяемого .DATA, определяемого .CODE, определяемого .FarData, определяемого .FarData?
а также несколько других определении
@ FileName - имя компилируемого файла;
@ CurSeg - имя текущего компилируемого сегмента;
@ CodeSize - в моделях с коротким кодом TINY, SMALL и СОМРАСКТ число 0, в остальных - 1;
@ DataSize - в моделях с "короткими данными**: TINY и SMALL, MEDIUM - число 0, в моделях COMPACT и LARGE - 衬 число 1 и в модели HUGE - число 2;
??Data- дата компиляции;
??Time- время компиляции.
Как уже пояснялось, каждая из упрощенных директив замещает определенную расширенную директиву, а связь между ними устанавливается из следующего соответствия упрощенным директивам аргументов директивы SEGMENT .
Упрощение
Модель
Имя
Аргументы
-CODE
TINY
—TEXT
WORD PUBLIC 'CODE'
.CODE
SMALL
-TEXT
WORD PUBLIC CODE"
.CODE
MEDIUM
外岳一TEXT
WORD PUBLIC 'CODE'
.CODE name
MEDIUM
name
WORD PUBLIC 'CODE'
.CODE
LARGE
用e—TEXT
WORD PUBLIC 'CODE'
.CODE name
LARGE
name
WORD PUBLIC CODE
.CODE
HUGE
加e-TEXT
WORD PUBLIC CODE'
.CODE name
HUGE
name
WORD PUBLIC 'CODE'
Все модели
.DATA
-DATA
WORD
PUBLIC Data'
.DATA?
—BSS
WORD
PUBLIC BSS'
.FARDATA
FAR-DATA PARA
PRIVATE FAR-DATA*
.FARDATA name
name
PARA
PRIVATE 'FAR—DATA'
.FARDATA?
FAR-BSS
PARA
PRIVATE 'FAR—BSS'
.FARDATA? name
name
PARA
PRIVATE 'FAR—BSS,
.CONST
CONST
WORD
PUBLIC CONST,
.STACK
STACK
PARA
STACK STACK'
Внимание: Запись file в директивах .CODE является именем файла, содержащего эту директиву. В директиве .STACK можно указать число, .определяющее размер стека (по умолчанию 1024).
Кроме того, для каждой из моделей предполагается:
-директива GROUP,
которая в модели TINY имеет ввд
DGROUP GROUP -TEXT,—DATA, CONST,-BSS, STACK,
а в остальных моделях - вид
DGROUP GROUP -DATA, CONST,-BSS, STACK
-директива ASSUME,
в которой имеется регистр CS с сегментом, определяемым упрощенной директивой .CODE, a DS и SS связаны с группой DGROUP.
Внимание: После директивы .MODEL ТPASCAL могут появиться только упрощенные директивы .CODE и .DATA. Тогда обязательно следующее соответствие упрощенным директивам аргументов директивы SEGMENT:
УпрощениеИмя.Аргументы
.CODE .DATA.CODE .DATACODEDATACODEDATABYTE PUBLICWORD PUBLICBYTE PUBLICWORD PUBLIC
.CODE .DATA
.CODE .DATA
CODE
DATA
CODE
DATA
BYTE PUBLIC
WORD PUBLIC
BYTE PUBLIC
WORD PUBLIC
Пример. Директива .MODEL
Программа с упрощенными директивами
.MODEL SMALL .DATA
Fix OB 13 .CODE Start :
mov ax, @ Data
mov ds, ax
mov al. [Fix]
mov ah, 4 ch
int 21h .STACK lOOh END Start
Равнозначная программа с расширенными директивами
DGROUP GROUP DATA, STACK
ASSUME CS: TEXT, DS : DGROUP, SS : DGROUP
_DATA SEGMENT WORD PUBLIC. 'DATA' Fix DB13
一DATA ENDS
_TEXT SEGMENT WORD PUBLIC 'CODE' Start:
mov ax. DGROUP mov dsr ax
mov al. [Fix]
mov ah, 4 ch
int 21h
_TEXT ENDS
STACK SEGMENT PARA STACK *STACK'
DB lOOh DUP(?)
STACK ENDS
END Start
Директива DOSSEG
Директива DOSSEG состоит из ключевого слова
DOSSEG
Интерпретаци я директивы DOSSEG вызывает упорядочение сегментов результрирующей программы соответственно соглашениям, принятым фирмой Microsoft для языков высокого уровня.
Внимание: Если модули, написанные на языке Турбо Ассемблер, связаны с модулями, генерируемыми компиляторами этих языков, то использование DOSSEG излишне, поскольку и так будет обеспечено приведение к стандартным формам.
Стандартное упорядочение сегментов следующее:
-все сегменты класса 'CODE';
-все сегменты, не относящиеся к классу CODE и не принадлежащие группе DGROUP;
-сегменты группы DGROUP в следующей последовательности сегменты класса 'BEGDATA', сегменты, не относящиеся к классу BEGDATA, BSS, 'STACK', сегменты класса “BSS\ сегменты класса "STACK".
Пример. Стандартное упорядочение сегментов
.MODEL SMALL
DOSSEG
.STACK lOOh
.FAR DATA?
Res DW?
.CODE
.Start:
mov ax, ©Data
mov ds, ax
mov al, [Ast]
mov bx, SFarData?
mov ds. bx
ASSUME DS: @FarData?
mov [Res], ax
mov dxr OFFSET Res
mov ah, 9
int 21h
mov ах, 4c00h
int 21h
.DATA
Ast DW ('$' SHL8) + ・*'
END Start
Приведенная программа трактуется так, как если бы она имела вид
.MODEL SMALL .CODE.
Start:
mov ax, 6 Data
mov ds, ax
mov al, [Ast]
mov bx, 0FarData?
mov ds, bx
ASSUME DS: 6FarData?
mov [Res], ax
mov dx. OFFSET Res
mov ah, 9
Int 21h
mov ax, 4c00h
int 21h .FARDATA?
Res DW?
.DATA
Ast DW (*$ * SHL8) + *** STACK lOOh END Start
Директивы инициализации простых переменных
Директивами инициализации простых переменных являются DB, DW, DD и др. Каждая из них имеет общий вид
lab kind arg, 〃呜 …,arg,
где lab - метка; kind - название одной из указанных директив, а каждый arg является выражением, знаком вопроса (равнозначным выражению с неопределенной величиной) или имеет вид
count DUP(arg, arg,…,ar^t
Где count - количество повторений списка аргументов в скобках.
Интерпретация директив инициализации простых переменных вызывает резервирование памяти для переменных определенного типа
DB - для байтовых переменных (например, byte, unsigned char).
DW - для слов (например, integer, short int),
DD - для двух слов (например, longint, long int),
DF - для трех слов (например, real),
DQ - для четырех слов (например, double),
252Часть 衣 Турбо Ассемблер
DT - для пяти слов (например, extended)
и последующее приписывание им значений, определенных выражениями, указанными в директиве.
Если директивой является DB, а приписываемыми данными являются сим-* 1волы, то можно произвести упрощение, основанное на соединении последо- вателвности символов в цепной литерал, ограниченный знаками “ {кавычки} или ' (апостроф).
Примеры инициирования переменных
Greet
Greet
DB oa
也e ■ 1・J・ •Hello"
'o';
вид развернутый вид сокращенный
NumDW
3.%
4, 3f ?, 4. ?• 5
вид развернутый
NumDV
2 DUP(3, ?■ 4). ?. 5
вид сокращенный
RefDW
OFFSET Greet
бмд развернутый
Ref
DW
Greet
®ид сокращенный
DO
1ООСЭО
переменная без имени
Quote
DB,
переменная однознаковая
Директивы инициализации структурных переменных
Структурными переменными являются записи, структуры объединения. Для инициализации структурной переменной необходимо сначала описать структурный тип, а затем воспользоваться директивой инициализации переменных.
Типы и переменные записи
Описание записи имеет вид
name Record field, field,…,field,
где пате - имя записи, а каждый field - спецификация поля в одном из следующих видов:
id:size
id:size 出 Util,
где Id - идентификатор поля записи, size - размер поля, выраженный в байтах, a intt - начальное значение. Требуется, чтобы в данном модуле идентификаторы полей записей были уникальными, а общий размер полей каждой записи не превышал 16 бит.
Описание переменных типа запись имеет вид
lab пате а噂 arg, ..., arg.
где lab - метка, пате - имя записи, а каждый arg - начальное значение, состоящее из списка значений, взятых в треугольные скобки. Каждое из
этих выражений служит для инициализации одного поля записи. Если некоторое значение отсутствует, то предполагается значение, взятое из описания записи.
Поля записи упорядочены в последовательности их появления в описании записи. Записи, общий размер полей которых не превышает 8 бит, являются однобайтовыми, а остальные - двубайтовыми. Поля представлены в виде последовательности битов, помещенных в байте или в слове с правосторонним выравниванием.
Примеры описания записей
В области действия описания записи
Triple RECORD Left: 3f Center: 4=ofh, Right:2 выражение
Rec Тг〕р1е<2, 1>。 <2. 0ff0>
является описанием двух записей, первая из которых имеет имя Rec. Запись Rec занимает одно слово, в котором поле Right занимает два младших бита. В записи Rec поле Left имеет начальное значение 2, поле Center - начальное значение Ofh, а поле Right - начальное значение 1.
Так как в процессорах Intel 8086 нет возможности адресации определенных битов, отсылка к полям записей происходит нетипичным способом с использованием операторов MASK и WTDTH, а также имен полей записей.
В целях выполнения операций на полях записей принимается, что
-имя поля записи представляет константу со значением, равным общему размеру полей, следующих за этим полем;
-выражение
MASK id,
喏е id является идентификатором поля записи, представляет битовую маску, позволяющую выбрать поле id (эта маска устанавливает единицы в битах указанного поля и нули в остальных байтах);
-выражение
WIDTH U1,
где Id является идентификатором записи или идентификатором его поля, представляет константу, равную размеру записи или поля записи (выраженному в битах).
Пример. Операции над полями записей
В области действия описания записи Triple
Triple RECORD Left:2. Mid:3:Right:l
и описания переменной Rec этого типа
Rec Triple<l, 5. 0>
выполнение команд
mov al. [Rec] and al, MASK Mid mov alf Mid shr al. cl
приводит к размещению поля Mid записи Rec в младших разрядах регистра AL.
Структуры
Описание структуры имеет вид
name STRUC
field
field
field •
name ENDS
где name - имя описываемой структуры, а каждый field является описанием поля, идентичным описанию переменной, записи, структуры или объединения.
Учитывая, что описание объединения отличается от описания структуры только тем, что ключевое слово STRUC заменено в нем ключевым словом UNION, дальнейшее описание будет ограничено структурой. Необходимо однако помнить о существенной разнице структуры и объединения. В то время как структура состоит из всех полей^ указанных в ее описании, следующих одно за другим, объединение состоит в данный момент только из одного поля.
Поскольку объединение представляется как наложение всех его полей, ничто не мешает одновременному обращению к переменным, описанным 菱 разных полях.
Тем не менее лучше принять, что если некоторой переменной поля приписано конкретное значение, то при этом каждой переменной остальных полей приписаны неопределенные значения. Хотя такое предположение чисто гипотетическое, оно может значительно облегчить правильное использование объединений.
Описание переменных структурного типа имеет вид
lab name argt 〃侬…,argt
где lab - метка, name - имя структуры, а каждый arg - начальное значение, состоящее из списка значений, взятых в треугольные скобки. Каждое из этих значений служит для инициализации одного поля структуры. Если некоторое значение отсутствует, то предполагается соответствующее значение, взятое из описания структуры. Не допускается, чтобы размерность явно заданной величины превышала размер
соответствующего поля в описании структуры. Кроме того, запрещается использовать значение в виде текстового литерала, если описание поля не содержало подобного литерала.
Примеры. Описание структур
В области действия описания структуры Person
Person STRUC
Full Name DB 'John Walker'
Age DW40
Sex DB?
Person ENDS
выражение
Bob Person v Bob Smith '.•1>
является описанием структурной переменной Bob, состоящей из полей Full Name, Age и Sex, размер которых определяется описанием структуры и соответственно равных 11 (несмотря на то что "Bob Smith' имеет размер 9), 2 и 1. Поле Age имеет значение 40, а два младших байта поля Full Name являются пробелами. Требуется, чтобы в данном модуле имена полей структур и объединений были уникальными. В целях получения возможности обращаться к отдельным полям вводится оператор . {точка), который в сущности может трактоваться точно так же, как и оператор + (плю». Это следует из того, что имя поля структуры или объединения требуется как имя постоянной величины, равной смещению этого поля в пределах описания структуры.
Пример. Операции над полями структур
В области действия описания структуры Date
Date STRUC
Year DW?
Month DB?, -1
Day DW?
Date ENDS
The Day Date <1981, 12, 13>
выполнение команд
^ ^ w <^*^ ^ w <^*mov bx. OFFSET The Day mov axe [bx. Year] mov ah, [TheDay.Month] n>ov al, [byte ptr TheDay.Day] mov al, [TheDay.(Month+1)]
^ ^ w <^*
^ ^ w <^*
приводит к загрузке регистров, как указано в комментарии.
Директивы описания меток
С каждой меткой в директиве инициализации переменных связан ее тип, а именно
ДирективаТип
в w D F Q1DDDDDDв w D F Q1DDDDDDBYTE
в w D F Q1DDDDDD
в w D F Q1DDDDDD
WORD
DWORD
FWORD QWORD TWORD
Метка, «отделенная от команды знаком : (двоеточие), является типом NEAR, а метка, предваряющая директиву PROC (по сути описывающая процедуру), является явно определенной меткой в этой директиве (NEAR или FAR) или по умолчанию на основе модели памяти
NEAR - для модели TINT, SMALL, COMPACT
FAR - для модели MEDIUM, LARGE, HUGE, TPASCAL
Кроме того, тип метки может быть описан с помощью директивы LABEL.
Директива LABEL имеет вид
name LABEL type,
где пате 一 идентификатор описываемой метки, type - тип. Тип метки определяет, относится ли она к данным (например, BYTE, WORD, DWORD) или к командам (например, NEAR, FAR). Интерпретация директивы LABEL ведет к снабжению последующего байта компилируемого сегмента меткой name
Таким образом, идентифицированная метка может быть экспортирована в другой модуль.
Пример. Описание меток
В области действия описания
Lower LABEL BYTE
Fix DW13
Before LABEL FAR
Start: mov ax, eData
After LABEL NEAR
метками являются не только Fix и Start, но и Lower, Before и After. В частности, Lower является именем переменно血,состоящей из младшего байта переменной Fix, Before - метка команды mov. В отличие от метки Start, которая относится к типу NEAR, метка Before относится к типу Far.
Выражения
Выражения могут выступать как в аргументах директив инициализации переменных, так и в аргументах команд. Требуется, чтобы каждое выражение было выражением постоянным, т.е. чтобы его значение было определено перед началом выполнения программы. Благодаря этому в каждом месте программы, где может появиться число, может также появиться и выражение.
Состав выражений языка Турбо Ассемблер ближе к составу языка Турбо С, чем языку Турбо Паскаль. Проявляется это в том числе в том, что заключение о правильности и семантике выражения может быть проведено исключительно на основе приоритета использованных в нем операторов.
Упорядочение операторов в очередности уменьшающихся приоритетов следующее:
<> О [] LENGTH MASK SIZE WIDTH
+ - (одноаргументныи)
OFFSET type PTR SEG THIS TYPE
♦ / MOD SHL SHR
+ - {двухаргументный)
EQ GE GT LE LT NE
NOT
AND
OR XOR
SHORT
(type означает одно из следующих ключевых слов FAR, NEAR, BYTE, WORD, DWORD, FWORD, QWORD, TBYTE).
<>
Оператор <text> определяет литерал независимо от символов, составляющих text
Пример
В записи
Count<; a+b>
знак ; {точка с запятой) не начинает комментарий.
О
Придание большего приоритета выражению в скобках.
Пример
В выражении
а-(Ь+с)
сначала выполняется суммирование.
[]
Эквивалентность [expjt ][ехр2] и [expl + exp2]
Пример
Команда
mov ах, [bx][2]
равнозначна команде
mov DX. [bx+2]
LENGTH
Оператор LENGTH пате^ где пате - идентификатор переменной,
возвращает число единиц памяти, выделенной переменной, описанной с
помощью ключевого слова DUP, или равно 1, если в описании не
использовано это ключевое слово.
Пример
В области действия описания
Count DE 10 DUP(20 DUP (?)),1000 DUP(O)
оператор
length Count
возвращает значение 10.
MASK
Оператор MASK field, где field - имя поля записи, позволяет произвести выбор поля.
Пример
В области действия описания
Rec RECORD West:2. East:5
ППРПЯТПП
mask West
возвращает значение 01100000В.
SIZE
Оператор SIZE пате возвращает произведение (LENGTH name) * (TYPE name).
Пример
В области действия описания
Array DW 10 DUP(O). 30 DUP(l)
оператор
size Array
возвращает значение 20.
WIDTH
Оператор WIDTH fields 取е field - имя записи или идентификатор поля записи возвращает значение, равное числу битов этой записи или поля.
Пример
В области действия описания
Rec RECORD West:2. East:5.
операторы
width Rec и
width East
возвращают соответственно значения 7 и 5.
Оператор .field, где field - идентификатор поля структуры с записью + field.
Пример
В области действия описания
Child SIHUC Name DB ' * Age DB?
Child ENDS
Isa Child visa. 6> команда
mov ah. [Isa . Age] эквивалентна команде
mov ah, [Isa + Age].
HIGH
Оператор HIGH exp, где exp является выражением, возвращает старший байт постоянной, представленной ехр.
Пример
Оператор
high 1Ш000000001ШВ
возвращает значение 11110000В.
LOW
Оператор LOW exp, где exp является выражением, возвращает младший байт постоянной, представленной ехр.
Пример
Оператор
1OW Ш100000000Ш1В
возвращает значение 00001111В.
Оператор +expt где exp является выражением, эквивалентен ехр.
Пример
Выражение
2 т 3
равно -1.
Оператор -ехр, где ехр является выражением, эквивалентен 0-ехр.
Пример
Выражение
2+(-3)
равно -1.
Запись seg : ofs, где seg является именем сегментного регистра, сегмента или группы сегментов, a ofs - смещение, представляет адрес в соответствии с указанным регистром, сегментом или группой сегментов.
Пример
Если SI = 2, то в команде
jnov al, [es:si + 4]
произойдет обращение к шестому байту сегмента, определенного CS.
OFFSET
Оператор OFFSET addr, где addr является адресом памяти, возвращает смещение этого адреса относительно начала сегмента, в котором находится addr.
Пример
Оператор
offset DGROUP:Fix
262Часть IY. Турбо Ассемблер
представляет смещение адреса Fix относительно группы DGROUP.
type PTR
Оператор type PTR ехр, где type является обозначением типа
для данных: BYTE, WORD, DWORD, FWORD, QWORD, TBYTE для команд: NEAR, FAR, PROC
a exp является выражением, возвращает выражение типа type, локализующее то же место памяти, что и ехр.
Пример
В команде 口 inc[byte ptr bx] регистр BX локализует данные типа BYTE.
SEG
Оператор SEG addr, где addr является адресом памяти, возвращает номер сегмента, в котором находится этот адрес.
Пример
В области действия описания
Data SEGMENT-
DB? Fix DW 13 Data ENDS
как SEG Data, так и SEG Fix являются номером сегмента, в котором описана переменная Fix.
THIS
Оператор THIS 秘е, где type является обозначением типа
для данных: BYTE, WORD, DWORD, FWORD, QWORD, TBYTE для команд: NEAR, FAR, PROC
возвращает полный адрес {номер сегмента и смещение) в текущем месте компилирования текущего сегмента.
Пример
Директива
Неге EQU THIS FAR трактуется как директива
Here LABEL FAR
TYPE
Оператор TYPE exp, где exp является выражением, возвращает значение постоянной в соответствии со следующим соглашением:
Тип Значение постоянной
124681124681BYTE WORD DWORD FWORD QWORD TBYTE
124681
124681
NEAROffffh
FAROfffeh
Пример
В области действия описания
Fix DW ?
оператор
type Fix
возвращает значение 2.
Выражение expL * expR, в котором expL и expR являются постоянными выражениями, представляет их произведение.
Пример
В области описания
Fix DW 3 DUP(?), D
выражение
type Fix * length Fix возвращает значение 6.
/
Выражение expL / expR9 в котором expL и expR являются постоянными
выражениями, представляет их частное.
Пример
В области действия описания
Fix DQ 1, 2, 3
выражение
Size Ftx/2
г»
имеет значение 4.
MOD
Выражение expL MOD expR, в котором expL и expR являются
постоянными выражениями, представляет остаток от деления expL на expR.
Пример
Выражение
12 mod 5
равно 2.
SHL
Выражение expL SHL expR, в котором expL и expR являются
постоянными выражениями, определяет сдвиг двоичного представления expL
на expR позиций влево.
Пример
Выражение
13 SHL 2
равно 52.
SHR
Выражение expL SHR expR, в котором expL и expR являются постоянными выражениями, определяет сдвиг двоичного представления expL
на expR позиций вправо.
Пример
Выражение
13 SHR 2
равно 3.
Выражение expL + expR, в котором expL и expR являются постоянными выражениями, представляет их сумму.
Пример
Выражение
13 + 2
равно 15.
Выражение expL - expR, в котором expL и expR являются постоянными выражениями, представляет разность expL и expR.
Пример
Выражение
13-2
равно 11.
EQ
Выражение expL EQ expR, в котором expL и expR являются постоянными выражениями, принимает значение -1, если expL равно expR, или 0 в противном случае.
Пример
Выражение
12 EQ 2 + 10
равно -1.
GE
Выражение expL GE expR, в котором expL и expR являются постоянными выражениями, принимает значение -1, если expL больше или равно expR, или 0 в противном случае.
Пример
Выражение
12 GE 2 + 10
равно -1.
GT
Выражение expL GT expR, в котором expL и expR являются постоянными выражениями, равно -1, если expL больше, чем expR、или 0 в противном случае.
Пример
Выражение
12 GT 12
равно 0.
LE
Выражение expL LE expR, в котором expL и expR являются постоянными выражениями, принимает значение -1, если expL меньше или равно expR, или 0 в противном случае.
Пример
Выражение
LE 5 равно 0.
LT
Выражение expL LT expR, в котором expL и expR являются постоянными выражениями, равно -1, если expL меньше, чем expR, или 0 в противном случае.
Пример
Выражение
LT - 1
равно 0.
NE
Выражение expL NE expRb в котором expL и expR являются постоянными выражениями, принимает значение -1, если expL не равно expR , или 0 в противном случае.
Пример
Выражение
12 NE 2
равно -1.
NOT
Выражение NOT ехр, в котором ехр является постоянным выражением, является инверсией двоичного представления ехр, т.е. в каждом бите 1 меняется на 0 и наоборот.
Пример
Выражение
NOT -6
равно 5.
AND
Выражение expL AND expR, в котором expL и expR являются постоянными выражениями, представляет поразрядное логическое произведение expL и expR (произведение битов равно 1 /тогда, когда оба аргумента равны 1).
Пример
Выражение
10 AND 6
равно 2.
OR
Выражение expL OR expR, в котором expL и expR являются постоянными выражениями, представляет поразрядное логическое сложение expL и expR (логическая сумма битов равна 0 тогда, когда оба аргумента равны 0).
Пример
Выражение
10 0R 6
равно 14.
XOR
Выражение expL XOR expR、 в котором expL и expR являются постоянными выражениями, представляет поразрядное логическое сложение по модулю 2 (ИСКЛЮЧАЮЩЕЕ ИЛИ) выражении expL и expR (сложение битов по модуЛю 2 равно 1 только тогда, когда оба аргумента принимают различные значения).
Пример
Выражение
10 AND 6
равно 12.
SHORT
Выражение SHORT exp, в котором ехр является постоянным выражением, представляет смешение, отличающееся от текущего смещения в компилируемом сегменте не больше чем на 127 и не меньше чем на - 128.
Пример
Команда
jmp short Lab
является командой короткого перехода.
Внимание: Такие выражения, как, например,
OFFSET Fix
и SEG Fix,
в которых Fix является меткой переменной, являются по сути постоянными выражениями. Значение первого из них (определяющее смещение в сегменте переменной Fix) и так известно уже на первом этапе компиляции программы, а значение второго (определяющее номер сегмента, в котором находится рассматриваемая переменная) известно в момент загрузки программы.
Примеры. Выражения
(After - Before)/?
WORD PTR Fix+1 Fix EQ Res 2—3
Назначение имен постоянным
Для назначения имен постоянным служат директивы EQU и 工(равно). С помощью директивы EQU можно назначать имена символам, символьным литералам, числам и меткам, а с помощью директивы ^ (равно) можно назначать только имена числам. В общем случае директива EQU имеет вид name EQU ехр,
а директива - {равной имеет вид
пате = ехр, где пате является назначаемым именем постоянной, а ехр - постоянным выражением. Запрещается, чтобы идентификатор, определяющий имя постоянной, назначаемое с помощью директивы EQU, был бы описан снова. Это ограничение не касается имени постоянной, назначаемого с помощью ДИреКТИВЫ - (pQGilS •
Примеры
Описание постоянных
В области действия описания
Fix DW 13
Lab:mov ах. 2
Могут быть изменены следующие назначения постоянных:
Count = О
Higher EQU OFFSET Fix + 1
Greet EQU •Hello*
Lower EQU Higher - 1
Count = cbunt + 1
Next EQU Lab + 2
270Часть IY. Турбо Ассемблер
Символ $
Символ $ (доллар принадлежит к той же категории, что и указанные выше символы @Data, @FarData и т. д. Этот символ является именем постоянной, равной по значению действительному смещению в компилируемом сегменте.
Пример. Использование символа $
Greet DB *Hello World*
Span EQU $ - Greet; Span = 11
Адресация переменных
В предыдущих примерах использовались очень простые адреса данных и команд. В общем случае адрес данных может быть представлен с помощью выражения вида
База + Индекс + Смещение,
тде база и индекс являются соответственно именами базового (ВХ, ВР) и индексного (SI, DI), регистр смещение - постоянным выражением.
Пример. Адресация переменной
Если принять, что в области действия упрощенной директивы .DATA находится описание
Greet DB 'НеПо',
а в регистре DB находится номер сегмента @Data, помещенный туда, например, с помощью двух команд
mov ах. @ Data
mov ds. ах, то выполнение каждой из следующих последовательностей команд вызывает загрузку в регистр al одних и тех же данных:
mov al. "О'
mov al. [Greet + 4]
mov s1r (OFFSET Greet) + 4 mov alr [si]
mov bx, OFFSET Greet + 4 mov al. [bx]
mov s1f OFFSET Greet
mov bxt 4
mov al. [si + bx]
niov di, 1
mov bxr 1
niov al {bx + Greet + di + 2]
niov bp, 1
niov d1, OFFSET Greet + 2
fiov al. [ds : bp + di + 1]
Адрес переменной должен быть выражен таким способом, чтобы было видно соответствие типа переменной и использованной команды. В частности, это означает, что с 8-бит переменной можно обращаться только с помощью команды загрузки 8-бит данных, а пересылка данных из памяти в стек процессора может касаться только 16-бит переменной. Кроме того, требуется, чтобы на основе анализа записи комацды можно было выяснить размер данных, которых касается эта команда.
В целях выполнения указанных требований возникает необходимость использования операторов группы type PTR в контексте
type PTR exp,
что вызывает преобразование выражения ехр в тип type.
Примеры. Преобразование типа выражения
а Если в области действия директивы
Fix DW 13
находится команда пересылки 8-бит данных mov al, [Fix ], то она использована неверно, поскольку Fix представляет 16-бит данные. Эту ошибку можно исправить, заменив рассматриваемую команду командой
niov al. [byte ptr Fix]
Команда вида
inc [bx]
неверна, поскольку на основе ее анализа нельзя определить относится ли она к 8- или 16-бит переменной. В первом случае ее необходимо представить в виде
Inc [byte ptr bx].
а во втором - в виде
inc [word ptr bx].
Команда вида
mov ax. [bx]
верна, поскольку на основе ее анализа можно судить, каков размер данных (16 бит).
г. Команда вида
push Fix,
где Fix является именем переменной типа BYTE, неверна, поскольку в стеке могут быть помещены только слова. Ошибка может быть исправлена заменой рассматриваемой команды командой
push word ptr Fix.
Адресация команд
Адресация 1&манд нарушается в связи с выполнением переходов и вызова процедур. Если в команде перехода имеется ключевое слово SHORT, это означает компиляцию короткого перехода, а если ключевое слово NEAR, то компиляцию близкого перехода. В каждом из этих случаев выполнение перехода вызывает только изменение значения регистра IP и не нарушает регистра CS {короткие команды занимают меньше места, чем близкие^ но позволяют выполнять переходы на расстояние не больше тем 128 байт от места появления команды).
Если в команде имеется ключевое слово FAR, то это означает компиляцию дальнего перехода» Его выполнение вызывает загрузку как регистра CS, так и IP.
Во время компилирования команд перехода, не содержащих указанных ключевых слов, подразумевается ключевое слово NEAR, поскольку переход происходит в известную уже метку, имеющую атрибут FAR. В этом случае компилируется дальний переход.
Внимание; Необходимо избегать близких и коротких команд межсегментных переходов, так как их использование в большинстве случаев не имеет смысла.
Пример
ASSUME CS: Code 1
Codel SEGMENT
Start:
jmp short Labi
Lab3:
Jmp Lab4; jmp short Lab4 и nop
Lab6 LABEL FAR
jmp near ptr Lab7; требование near ptr
Lab8 LABEL FAR
niov ax, 4cooh
int 21h
; без short было бы far ptr; без short было бы far ptrили ASSUME CS: NOTHINGили ASSUME CS: NOTHINGLab7 LABEL FAR jmp short Lab8 Labi:
; без short было бы far ptr
; без short было бы far ptr
или ASSUME CS: NOTHING
или ASSUME CS: NOTHING
jmp far ptr Lab2
Lab4:
jmp far ptr Lab5
Codel ENDS
ASSUME CS: Code2
CodeZ SEGMENT
Lab2:
jmp far ptr Lab3
Lab5 LABEL FAR
jmp Lab6
Code? ENDS
Stack SEGMENT STACK DBlODh DUP(?)
Stack _ENDS
END Start
15.3. Процедуры
Процедура является частью программы, реализирующей отдельный фрагмент алгоритма. Она сконструирована так, чтобы могла вызываться из различных мест программы и после ее выполнения могло произойти возвращение в место ее вызова.
Вызов процедуры происходит с помощью команды call. Ее выполнение имеет тот же результат, что и выполнение команды jmp, с той лишь разницей, что происходит дополнительная пересылка в стек процессора места возврата из процедуры, т.е. ближнего или дальнего адреса того байта памяти, который следует после команды call.
Ближний адрес состоит только из смещения в сегменте, а дальний - из номера сегмента и смещения. В случае запоминания дальнего адреса (в стек) сначала отсылается номер сегмента, затем смещение в сегменте.
Возврат из вызванной процедуры по ближнему адресу происходит с помощью команды retn, а по дальнему адресу - с помощью команды retf・ Если будет использована процедура ret, то она будет трактоваться как retn или retf в зависимости от того, как была описана процедура: далекая или близкая.
Описание процедуры упрощенно имеет вид
name PROC type
body
name ENDP,
где пате является именем процедуры, type — определением типа процедуры (NEAR - близкая, FAR - далекая), a body - телом процедуры.
Интерпретация описания процедуры вызывает генерирование кода, определяемого телом процедуры.
Если в заголовке или теле процедуры имеются аргументы, то в модели (для процессоров 8088 и 8086) подразумевается тело процедуры вида
push bp;Пролог процедуры
niov bp. sp;
body;
а каждая команда ret процедуры, находящаяся в body, заменяется командами
pop bp 秆;Эпилог процедуры
reft size;
где size является числом, определяющим размер области, занятой аргументами. Подразумеваемый пролог и эпилог процедуры подвергаются оптимизации (например, пустое тело процедуры генерирует только команду retf).
Тип процедуры
Наличие в заголовке процедуры слова type определяет ее близкой, поскольку описание находится в области действия директивы .MODEL, а это
для моделей TINY, SMALL, COMPACT означает
признание процедуры за близкую,
а для моделей MEDIUM, LARGE, HUGE, TPASCAL
процедура определяется как далекая.
Требуется, чтобы вызов близкой процедуры происходил по ближнему адресу, а дальней процедуры - по дальнему. Близкий адрес создается при 16-бит аргументе, а дальний - при 32-бит аргументе команды call.
Примеры. Вызов процедур (эта несколько странная программа ставит целью только иллюстрацию различных вариантов команды call)
.MODEL LARGE
■STACK lOOh
.DATA
Ref DW Rise
DD BigRise
-Code
Rise PROC NEAR inc cl and cl, cl
jz FarExit
ret
BigRIse add cl ДО retf
MOVE LABEL FAR niov al. cl
一 FarExit retf Rise ENDP Start:
;далекий вызов;близкий вызов;близкий вызов;близкий вызов;далекий вызов;далекий вызов;далекий вызов;близкий вызов;близкий вызов;близкий вызов;далекий вызов;далекий вызовmov ax. Data niov dsr ax niov cl. -1 call far ptr Rise call Rise
;далекий вызов
;близкий вызов
;близкий вызов
;близкий вызов
;далекий вызов
;далекий вызов
;далекий вызов
;близкий вызов
;близкий вызов
;близкий вызов
;далекий вызов
;далекий вызов
mov ax( OFFSET Rise call ax
niov bx. OFFSET Ref call [word ptr bx] mov bx, 2
call [dword ptr Ref+bx] call Move mov ah°4ch int 21h
END Start
Выполнение программы заканчивается кодом возврата 13.
Если вызов касается процедуры, тип которой еще не известен, то в моделях MEDIUM, LARGE, HUGE и TPASCAL требуется явное указание типа процедуры, например.
call far ptr Routine,
а в остальных случаях подразумевается тип near. Требуется, чтобы указанный или подразумеваемый тип процедуры соответствовал фактическому типу.
Пример
.MODEL TPASCAL
.CODE
Start:
call far ptr Nil
mov ah. 4ch
int 21h
Nil PROC
ret
Nil ENDP
.STACK lOOh
END Start
Приведенная программа правильна. Если бы в команде вызова процедуры использовался оператор far ptr, то программа стала бы ошибочной.
276Часть “ Турбо Ассемблер
Описание аргументов и результатов
Способ передачи аргументов и получение результатов зависит от программиста. Аргументы обычно указываются в регистрах или стеке процессора и оттуда извлекаются. Необходимо помнить, что в стеке находится адрес возврата из процедуры. В момент выполнения команды возврата из процедуры этот адрес должен находится в верхушке стека процессора. Приведение указателя стека SP в положение, в котором он находился перед отсылкой в стек аргументов процедуры, может осуществляться как в процедуре вызывающейся, так и вызванной. В процедурах, написанных на языке Турбо Паскаль, применяется первое, а в процедурах, написанных на языке Турбо Си, - второе правило.
В каждом из указанных языков аргументы указываются с помощью стека, а результаты процедур остаются в регистрах (AL, АХ, DX-AX, DX-BX-AX), в стеке или 『статичной области памяти. В целях облегчения выполнения операций с аргументами процедур, переданных способом, принятым в языках высокого уровня, в языке Турбо Ассемблер вводятся вспомогательные директивы ARG и LOCAL,
Директива ARG
Директива ARG имеет общий вид
ARG arg, arg,…,arg 工 size RETURNS res, resf ..., res
где каждый arg является описанием аргумента процедур, каждый res - описанием результата (который по окончании выполнения процедуры будет оставлен в стеке процессора), a size - идентификатором, с которым будет связано число, определяющее размер области, занимаемой в стеке процессора аргументами arg. В рассматриваемой директиве должно присутствовать как минимум одно описание arg, но выражение arg * size, а также
RETURNS res, res, ...» res
могут быть ие упомянуты. Аргументы должны быть приведены в той последовательности, в какой выступали бы в языке высокого уровня (т. е. всегда слева направо), кроме того, принимается, что в случае модели TPASCAL
первый аргумент находится в старшем адресе,
в остальных случаях (в том числе при отсутствии директивы .MODEL)
первый аргумент находится в младшем адресе.
Принимается, что независимо от использованной модели первый результат находится в младшем адресе.
Каждое из описаний аргумента и результата имеет один из следукнцих видов:
патепате : typeпатепате : type»»
пате
пате : type
пате
пате : type
»
»
name : type : count,
где name является идентификатором (локальным в данной процедуре), type является обозначением типа, a count - счетчиком переменных типа type. Если тип переменной является указательным, то она начинается обычно ключевыми словами NEAR PTR или FAR PTR (например, FAR PTR WORD является дальним указателем переменной типа WORD). Если описание начинается ключевым словом PTR, то для моделей TINY, SMALL, MEDIUM и TPASCAL подразумевается NEAR, а для моделей COMPACT, LARGE и HUGE - FAR. Если определение типа не будет упомянуто, то подразумевается тип WORD.
Счетчик count является постоянным выражением, определяющим число переменных указанного типа. Если он будет пропущен, то подразумевается счетчик со значением 1; если типом аргумента является BYTE, то подразумевается счетчик со значений 2. Это несколько странное предположение вытекает из факта, что пересылка в стек всегда осуществляется байтами по парам.
Интерпретация директивы ARG вызывает связь с каждым идентификатором пате, выражения вида
[bp + offset],
в которой offset является смещением младшего значащего байта, занимаемого рассматриваемым аргументом или результатом, от младшего из пары байтов, в которые в прологе процедуры было переслано содержимое регистра ВР
Директивы ARG в данной процедуре могут выступать многократно. Разрешается также помещать эти директивы непосредственно в заголовки процедур, но без ключевого слова ARG. Если более чем в одной из таких директив выступает определенный идентификатор аргумента, то принимается, что вышеописанная связь касается только последнего их появления. В частности, это означает, что пара директив
ARG i: WORDJ : DWORD.k
ARG j, 1
трактуется как пара директив
ARG dummy: BYTE; G,k
ARG 九 1,
me dummy является уникальным идентификатором, не выступающим в данной процедуре.
Примеры. Использование директивы ARG
Простая директива ARG в модели TINY
ARG 1: bytep j
...; равнозначно mov al, [bp + 4]
mov al. 1
add al, byte ptr j; равнозначно add al [byte ptr bp + 6]
Принимается, что непоцэедственно после отсылки в стек процессора содержимого регистра ВР там находятся
ВР- по адресу SS:SP + 0 <2 байт)
адрес возврата - по адресу SS:SP + 2 (2 байт)
i- по адресу SS:SP + 4 (2 байт)
j~ по адресу SS:SP + 6 (2 байт)
Директива ARG в модели TPASCAL
ARG a: word, b: far ptr qword:4, c:dword * s
niov ax, a; niov ax, [bp+26]
niov al, byte ptr a; niov al. [byte ptr bp+26]
les si. b; les st. [bp+10]
niov bx, wortFptr c; niov bx. [word ptr bp+6]
niov axt s; niov ax, 22
Принимается, что непосредственно после отсылки содержимого регистра ВР в стек там находятся
ВР .- по адресу SS:SP+O (2 байт)
адрес возврата - по адресу SS:SP+2 (4 байт)
с-поадресуSS:SP+6 (4 байт)
b-поадресуSS:SP+1O(16 байт)
а-поадресуSS:SP+26(2 байт)
Директива ARG вмодели LARGE
ARG a: word, b:far ptr qword:4. c:dword = s
mov ax, a; niov axr [bp+6]
niov al, byte ptr a; niov al. [byte ptr bp+6]
les sit b; les s1t [bp+8]
niov bx, word ptr c; niov bxt [word ptr bp+24]
niov axt s; niov axr 22
Принимается, что непосредственно после отсылки в стек содержимого регистра ВР там находится
ВР- по адресу SS:SP+O (2 байт)
адрес возврата - по адресу SS:SP+2 (4 байт)
а-поадресуSS:SP+6<2 байт)
d-поадресуSS:SP+8(16байт)
с-поадресуSS:SP+24 (4байт)
Директива ARG сфразой RETURNS
ARG a: byte RETURNS p:byte:1, q:word
В модели SMALL принимается следующая интерпретация содержимого стека打
BP- по адресу SS:SP+O (2 байт)
адрес возврата - по адресу SS:SP+2 (2 байт) а-поадресуSS:SP+4 (2 байт)
р-поадресуSS:SP+6 (1 байт)
q-поадресуSS:SP++7 (2 байт)
Программа с директивой ARG (модель ТPASCAL)
Stack — SEGMENT SRACK
DB 160h DUP(?)
Stack — ENDS .WODEL~TPASCAL
.CODE
Select PROC a: WORD, b:WORD
mov ax, a ; mov ax. [bp+8] shl ax, 1
add ax, b ; mov ax. [bp+6]
ret; retf 4
Select ENDP
Start:
mov ax,2
push ax niov ax.3 push ax call Select; return code?
mov ah, 4ch int Zlh
END Start
Программа с директивой ARG (модель LARGE)
.MODEL LARGE .CODE
Select PROC a: WORD, b:WORD
push bp
niov bp, sp; niov ax, [bp+6]
niov ax,a
shl ax.l
add ax,b; add ax, [bp+8]
pop bp
ret; retf
Select ENDP
Start:
niov ax.2
push ax
niov ax,3 push ax call Select; return code8
add sp,4
mov ah, 4ch
int 21h
.STACK lOOh
END Start
Директива LOCAL
Директива LOCAL имеет общий вил
local arg, arg,…,arg = size
где arg является описанием локальной переменной процедуры, a size - идентификатором, с которым связан размер поля, занимаемый локальней переменной (выраженный в байтах).
Каждый arg имеет один из следующих типов:
пате
name: type
name: type: count, *
где пате9 type, count интерпретируются так же, как и в директиве ARG. Интерпретация директивы LOCAL вызывает связь с каждым идентификатором пате выражения вида
[Ьр - offset},
哨е offset является смещением младшего значащего байта, занимаемого рассматриваемым аргументом или результатом, от младшего из пары байтов, в которые в прологе процедуры было переслано содержимое регистра ВР. Принимается, что переменные, указанные в директиве LOCAL, размещены в стеке таким образом, чтобы в модели TPASCAL первая переменная находилась в младшем адресе, в остальных случаях (в том числе при отсутствии директивы .MODEL) первая переменная находится в старшем адресе.
Вопреки возможному предположению, интерпретация директивы LOCAL не вызывает фактического резервирования места для локальных переменных процедуры. Исключение из этого правила составляет модель TPASCAL, в которой происходит генерирование команды
sub sp,size,
в которо访 size является явным или подразумеваемым идентификатером, с которым связано число, определяющее размер области локальных переменных. Остается добавить, что директивы LOCAL могут в данной процедуре выступать многократно. В этом случае принимается, что каждая пара следующих друг за другом директив, например%
LOCAL argl9 argl, ..., argl
и
LOCAL a『g2, arg2, ..», arg2
равнозначны директиве
LOCAL argl, arglt ..., arg2, arg2,…,arg2.
Примеры. Использование директивы LOCAL
Директива LOCAL вне зоны действия директивы .MODEL
LOCAL a: near ptr word:5, b: byte:3
mov ax. amov al. b+1mov ax. amov al. b+1; равнозначно mov ax. [bp-10]
mov ax. a
mov al. b+1
mov ax. a
mov al. b+1
;равнозначно mov al, [bp-12]
Программа с директивой LOCAL (модель TPASCAL)
Stack_SEGMENT STACK DB lOOh DUP(?)
Stack_ENDS
.MODEL TPASCAL .CODE
Select PROC
LOCAL a:WORD. b:WORD
mov a,2:nx)v[bp-4],2
mov b,3;mov[bp-2],3
mov ax, [bp-2]
ret;retf4
Select ENDP
return code 3return code 3Start: call Select
return code 3
return code 3
mov ah, 4ch
int 21h
END Start
Программа с директивой LOCAL (модель LARGE)
.MODEL LARGE
.CODE
Select PROC
LOCAL a: WORD, b: WORD
push bp
mov bp, sp
mov af 2; mov[bp-2], 2
mov b. 3; mov[bp-4]r 3
mov ax, [bp-2]
pop bp
ret; retf
Select ENDP
Start:
call Select; return code 2
mov ah. 4ch
int 21h
.STACK lOOh
END Start
Гибридное программирование Ассемблер-Паскаль
Программа, написанная на языке Турбо Паскаль, состоит (в порядке размещения в оперативной памяти) из следующих частей:
префикса программы (PSP);
сегмента кода главного модуля (CODE);
сегмента ^кода библиотечного модуля;
сегмента кода резидентной библиотеки;
сегмента глобальных данных (DATA);
сегмента стека;
буфера наложения;
~ кода.
Первый б.йт префикса программы указывается описанием глобальной переменной PrefixSeg. Каждый из сегментов, конечно, не может занимать больше 64 Кбайт памяти, а их общий размер не превышает 1 Мбайт.
Размер сегмента стека по умолчанию - 16 Кбайт, размер кода определяется числом байтов памяти, находящихся над стеком. Размер стека и кода может быть явно определен с помощью директив процессора.
Регистры
Процедура вызова из наскального модуля должна сохранять содержание регистров DS, SS, SP и ВР. Принимается, что регистр SS содержит номер сегмента стека, регистр DS - номер сегмента глобальных данных, а регистр ВР (перед переходом к выполнению пролога процедуры) - указание места в стеке процессора, где хранится содержимое регистра ВР той процедуры, которая вызвала данную процедуру.
Переменные, метки, процедуры
Переменные и процедуры, описанные в главном модуле вне процедур, а также переменные и процедуры, описанные в общей части библиотечного модуля, могут стать доступными в модуле ассемблера. Условием доступности является применение в модуле ассемблера директивы EXTRN. Переменные, описанные в модуле ассемблера, доступны по их именам только в этом модуле.
Однако ничто не мешает обращаться к ним с помощью процедур или глобальных указывающих переменных. Требуется, чтобы рассматриваемые переменные были описаны без инициализации (задания начальных значений). Описанные в паскальном модуле метки не доступны в модуле ассемблера. Описанные в модуле ассемблера метки могут быть доступны в паскальном модуле только тогда, когда они являются метками процедур. Описанная в модуле ассемблера процедура доступна в паскальном модуле тогда и - ^только
тогда, когда
в модуле ассемблера идентификатор процедуры выступает в директиве PUBLIC или GLOBAL;
в наскальном модуле имеется описание, предваряющее эту процедуру ключевым словом external;
в пасхальном модуле имеется директива компилятора, определяющая имя файла с расширением .OBJ, в котором находится скомпилированная связка ассемблер процедура.
Описанные в главном модуле процедуры, а также процедуры, описанные в личной часги библиотечных модулей, считаются близкими, описанные в общей части библиотечных модулей процедуры - далекими. Этот факт должен учитываться при вызове их из модуля ассемблера.
Аргументы и результаты
Аргументы процедуры Паскаль указываются в стеке процессора и сопроцессора. Результаты остаются в регистрах, в стеке процессора или в стеке сопроцессора.
Если параметр связан с постоянной, то
аргумент целого типа, аргумент типа real и аргумент указательного типа указываются в стеке процессора (если есть тип byte, то перед - выполнением этой операции аргумент дополняется старшим байтом неопределенного значения);
аргументы типа single, double, extended и comp указываются в стеке сопроцессора;
аргумент типа цепочки указывается с помощью указателя, помещенного в стеке процессора;
аргумент табличного типа и типа записи размерами 1, 2 либо 4 байт указываются в стеке процессора, остальные аргументы этого типа (в том числе 3-байт аргументы) указываются с помощью указателя, размещенного в стеке процессора;
аргумент многословного типа указывается с помощью указателя его 32- бит эквивалента, размещенного в стеке процессора. Если параметр связан с переменной, то независимо от типа аргумента в стеке помещается его указатель.
Внимание: Однобайтовые аргументы указываются как двубайтовые с неопределенным значением старшего байта.
Результат процедуры остается в следующих местах:
результат целого типа остается в регистре AL (если однобайтовый), в регистре АХ (если 2-байт), в паре регистров DX-AX (если 4-байт);
результат типа real остается в DX-BX-AX;
результат типа single, double, extended и comp остается в верхушке стека сопроцессора;
результат типа цепочки остается в стеке процессора в месте, зарезервированном перед вызовом процедуры;
результат указательного типа остается в DX-AX.
Рекомендуется использование следующих сочетаний параметров и аргументов процедур:
Турбо Ассемблер
BYTE WORD BYTE WORD WORD FWORD DWORD TBYTE QWORD DWORDBYTE WORD BYTE WORD WORD FWORD DWORD TBYTE QWORD DWORDbyte word
BYTE WORD BYTE WORD WORD FWORD DWORD TBYTE QWORD DWORD
BYTE WORD BYTE WORD WORD FWORD DWORD TBYTE QWORD DWORD
shortint integer real single double extended comp pointer
Примеры. Гибридные программы
) Простая гибридная пр^мрамма
Модуль языка Паскаль
program TPASCAL
{SL L:bra}
function Fun : integer external;
begin
Vrlteln(Fun)
end
Модуль ассемблера Libra
.MODEL TPASCAL
PUBLIC Fun .CODE
Fun PROC NEAR mov ax,13 ret
Fun ENDP END
Выполнение программы приводит к выводу числа 13.
) Связь программ
Модуль языка Паскаль program Mixed {SL LIB.OBJ} procedure Put (Fix zinteger);
external;
function Get(var Res: integer) : integer; external;
var
Res : integer;
begin
Put(13);
Wr1teln(Get(Res));
Writeln(Res) end
Модуль ассемблера LIB
.MODEL TPASCAL PUBLIC Get. Put .DATA;
Loc DW? .CODE Put PROC NEAR
ARG Vai: WORD
mov axr Vai mov Loc( ax ret Put ENDS Get PROC NEAR Ref:DWORD les di. Ref mov ax. LOC mov [es:di] ax ret
Get ENDP END
Гибридное программирование Ассемблер-Си
Программа, написанная на языке Турбо Си, состоит (в порядке размещения в оперативной памяти) из следующих частей:
префикса программы (PSP);
сегментов класса 'CODE,;
сегментов не класса 'CODE' и не принадлежащих группе DGROUP;
сегментов группы DGROUP, не являющихся классом 'STACK';
в моделях TINY, SMALL и MEDIUM области, близкой к коду;
сегмента стека;
в моделях COMPACT, LARGE и HUGE области, далекой от кода.
Регистры
Процедура, вызванная из модуля на языке Си должна сохранить содержимое регистров DS, SS, SP и ВР. Если в модуле Си использованы регистры SI и DI, то их содержимое также должно быть сохранено в процедуре на языке ассемблер. В момент вызова процедуры на языке Си в регистре DS находятся следующие номера сегментов:
Модель
DS
TINY
dgroup
SMALL
dgroup
COMPACT
dgroup
MEDIUM
dgroup
LARGE HUGELARGE HUGEdgroup cf1le_DATA
LARGE HUGE
LARGE HUGE
{dproup является именем первого сегмента группы DGROUP, a cfile - именем вызванного модуля)
Принимается, что регистр SS содержит номер сегмента стека, а регистр ВР (перед выполнением пролога процедуры) - указание места в стеке процессора, ще сохраняется содержимое регистра ВР вызванной процедуры.
Переменные, функции, метки
Те переменные и ■ функции в модуле языка Си, которые относятся к классу extern, могут стать доступными с помощью их идентификаторов в модуле ассемблера. Условием доступности является использование в модуле ассемблера директивы EXTRN, в которой идентификатор переменной или функции язык》Си предварен знаком — {подчеркивание).
Переменные, функции и метки, описанные в модуле ассемблера, могут стать доступными с помощью их идентификаторов в модуле языка Си. Условием доступности является, чтобы каждый такой идентификатор
в модуле ассемблера начинался знаком — (подчеркивание);
в модуле ассемблера был указан в директиве PUBLIC или GLOBAL;
в модуле языка Си был указан в директиве extern.
Ни один идентификатор метки, описанный в модуле языка Си и ни один идентификатор класса auto, register и static не может быть доступным в модуле ассемблера.
Внимание: Компиляция модуля ассемблера должна быть выполненна с опцией /МХ или /ML, а в системе Турбо Си должен быть создан проект, в котором будет указан модуль языка Си и модуль ассемблера с расширением .OBJ.
Аргументы и результаты
Аргументы функции языка Си указываются в стеке процессора. Результаты остаются в регистрах. Однобайтовый результат остается в регистре AL, двухбайтовый - в регистре АХ, 4-байт результат (за исключением результата типа float) - в паре регистров DX-AX, а результат с плавающей точкой - в верхушке стека сопроцессора. Результат любого другого вида ( в том числе 3-байт структура) остается в статичной области с указателем в регистре АХ или в паре регистров DX-AX.
Внимание: Аргументы однобайтовые указываются как двубайтовые с неопределенным значением старшего байта.
Рекомендуется использование следующих сочетаний параметров и аргументов процедур:
Турбо СиТурбоАссемблер
unsigned charBYTE
charBYTE
enum
WORD
unsigned short
WORD
short
WORD
unsigned int
WORD
int
WORD
unsigned long
DWORD
long
DWORD
float
DWORD
double
QWORD
long double
TBYTE
near*
WORD(также type (near*)() WORD)
far
DWORD(также type (far)*() DWORD)
Примеры. Смешанные программы
Простая смешанная программа
Модуль С〃
•Include vstdio.h〉
extern int Fun(void);
main()
{
printf("%dMf Fun()); return 0;
Модуль Ассемблера
.MODEL SMALL
PUBLIC一FUN
CODE
一FUN PROC NEAR
mov ax.13
ret
_Fun ENDP
END
Выполнение программы приводит к выводу числа 13. Для ее выполнения необходимо: скомпилировать модуль ассемблера в файл LIBRA.OBJ (с опцией /МХ), а в системе Турбо Си (например, в модели SMALL) создать проект, содержащий название LIBRA.OBJ.
Связь программ
Модуль Си
finclude <stdio.h>
extern void Put(1nt Fix);
extern int Get(int*Res);
int Res;
main()
{
Put(13);
print(M%dM, Get(&Res));
pr1ntf(”%d”, Res);
return 0;
Модуль ассемблера
.MODEL LARGE PUBLIC_Getf_Put .DATA Loc DW?
.CODE
Put PROC
ARG VOL: WORD push bp и nx)v bp, sp mov axf Vai mon Loc, ax pop bp ret
_Put ENDP
Get PROC Ref: DWORD push bp mov bp, sp les di. Ref nx)v ax, Loc mov [es:di}f ax pop bp ret
_Get ENDP END
Команды
В общем случае элементами приведенных здесь описаний команд являются
Имя
СинтаксисСинтаксисОписание Замечании Аргументы ПримерОписание Замечании Аргументы ПримерМнемоника команды, состояние регистра флажков FL после ее выполнения (указанные разряды установлены в 1, вопросительный знак означает неопределенное состояние данного разряда).
Синтаксис
Синтаксис
Описание Замечании Аргументы Пример
Описание Замечании Аргументы Пример
Описание результатов выполнения команды.
Дополнительный комментарий.
Структура аргументов, их возможные виды.
Фрагмент программы, содержащий указанную команду.
15. Ассемблер289
Команды микропроцессоров Intel 80S8 и Intel! 80286 {real mode)
AAA
Синтаксис Описание
ааа FL: а с, о=? р=? s=? z=?
Коррекция суммы двух неупакованных цифр в коде BCD.
Замечания
Если AF н 1 или (AL AND Ofh)>9, то выполняются следующие операции:
AL в AL + 6
АН := АН + 1
AF := 1, АС > 1 в противном случае операция AF := 0, АС = 0.
Затем выполняется операция
AL := AL AND ofh
Аргументы отсутствие
ааа
Пример mov ax, 9 add ax, 4
ааа
;АН«1, AL=3, т.е. 9+4=13
AAD
Синтаксис Описание
aadFL: р s z, а=? с=? о=?
Подготовка двух неупакованных цифр в коде BCD (младшая часть в AL, старшая в АН) для выполнения деления, результат которого также будет неупакован.
Замечания
Выполнение следующих операций:
AL := 10 * АН + AL
АН := 0
Аргументы отсутствие
Пример
aad.
mov ah, 3
nx)v al. 2
aad
;АХ = 32
AAM
Синтаксис Описание
aamFL р s z, а=? с==? о=?
Получение двух неупакованных цифр в коде BCD (старшая часть в АН и младшая в AL) после выпол
Замечания
нения умножения двух неупакованных цифр. Выполнение следующих операций:
AH 尸 AL DIV 10
AL 尸 AL MOD 10
Аргументы отсутствиеПример mov al, 25 аамАргументы отсутствиеПример mov al, 25 аамаам;АН « 2, AL « 5аам;АН « 2, AL « 5AASAASСинтаксисОписаниеЗамечанияСинтаксисОписаниеЗамечанияaasFL: a c. 。=? p=? s=? ze?Выполнение коррекции разности двух неупакованных цифр в коде BCD.Если AF = 1 или (AL AND Ofh)> 9, то выполняются следующие операции:AL 产 AL-6АН := АН-1AF := 1. CF 尸 1в противном случае операцииAF := О, CF 尸 О, Затем выполняется операцияAL := AL AND OfhaasFL: a c. 。=? p=? s=? ze?Выполнение коррекции разности двух неупакованных цифр в коде BCD.Если AF = 1 или (AL AND Ofh)> 9, то выполняются следующие операции:AL 产 AL-6АН := АН-1AF := 1. CF 尸 1в противном случае операцииAF := О, CF 尸 О, Затем выполняется операцияAL := AL AND OfhАргументы отсутствиеПример mov ах, 34h sub alr 15h aasАргументы отсутствиеПример mov ах, 34h sub alr 15h aasaasaas;AL = 09 h;AL = 09 hADCADCСинтаксис Описание Замечания Аргументы reg, con mem, con reg, reg reg, mem mem, regПример mov ax, -1 shl ax, 1 adc ax, 1Синтаксис Описание Замечания Аргументы reg, con mem, con reg, reg reg, mem mem, regПример mov ax, -1 shl ax, 1 adc ax, 1adc dst, src rL: а с о р s zСложение двух целых чисел с учетом переноса dst к dst + src + CFadc dst, src rL: а с о р s zСложение двух целых чисел с учетом переноса dst к dst + src + CF2lx+F6 +iby+ о 31X1,b.[IX- b [ a b [ сексе d d d d d a a a a a ;2lx+F6 +iby+ о 31X1,b.[IX- b [ a b [ сексе d d d d d a a a a a ;Синтаксис Описание ЗамечанияСинтаксис Описание Замечания
Аргументы отсутствие
Пример mov al, 25 аам
Аргументы отсутствие
Пример mov al, 25 аам
аам
;АН « 2, AL « 5
аам
;АН « 2, AL « 5
AAS
AAS
Синтаксис
Описание
Замечания
Синтаксис
Описание
Замечания
aasFL: a c. 。=? p=? s=? ze?
Выполнение коррекции разности двух неупакованных цифр в коде BCD.
Если AF = 1 или (AL AND Ofh)> 9, то выполняются следующие операции:
AL 产 AL-6
АН := АН-1
AF := 1. CF 尸 1
в противном случае операции
AF := О, CF 尸 О
, Затем выполняется операция
AL := AL AND Ofh
aasFL: a c. 。=? p=? s=? ze?
Выполнение коррекции разности двух неупакованных цифр в коде BCD.
Если AF = 1 или (AL AND Ofh)> 9, то выполняются следующие операции:
AL 产 AL-6
АН := АН-1
AF := 1. CF 尸 1
в противном случае операции
AF := О, CF 尸 О
, Затем выполняется операция
AL := AL AND Ofh
Аргументы отсутствие
Пример mov ах, 34h sub alr 15h aas
Аргументы отсутствие
Пример mov ах, 34h sub alr 15h aas
aas
aas
;AL = 09 h
;AL = 09 h
ADC
ADC
Синтаксис Описание Замечания Аргументы reg, con mem, con reg, reg reg, mem mem, reg
Пример mov ax, -1 shl ax, 1 adc ax, 1
Синтаксис Описание Замечания Аргументы reg, con mem, con reg, reg reg, mem mem, reg
Пример mov ax, -1 shl ax, 1 adc ax, 1
adc dst, src rL: а с о р s z
Сложение двух целых чисел с учетом переноса dst к dst + src + CF
adc dst, src rL: а с о р s z
Сложение двух целых чисел с учетом переноса dst к dst + src + CF
2lx+F
6 +
iby+ о 31X1,b.[IX- b [ a b [ сексе d d d d d a a a a a ;
2lx+F
6 +
iby+ о 31X1,b.[IX- b [ a b [ сексе d d d d d a a a a a ;
Синтаксис Описание Замечания
Синтаксис Описание Замечания
ADD
add dst, src FL: а с о p s z Сложение двух целых чисел dst := dst + src
】5. Ассемблер291
Аргументы reg, con mem, con reg, reg reg, mem mem, reg
add Ы,3
add [byte ptr Fix + di], 300
add ax, ax一
add bh, [byte ptr Fix]
add [byte ptr Fixt + si], al
Пример mov ax, 257 mov bl, 3 add ah, bl
;AH = 4
AND
Синтаксис Описание Замечания
and dst, src FL: c=0, o=0, pszt a=?
Поразрядное логическое произведение dst 尸 dst AND src
CF := 0. OF 户 0
Аргументы reg, con mem, con reg. reg reg, mem mem. reg
Пример mov ax, -1 and al, -1
and axr -1
and [byte ptr Fix +2]₽ offfh
and ax’ ax
and bx. [Fix - 2]
and [Fix + s1]₽ bx
;AX = 255
BOUND
286
Синтаксис Описание Замечания
bound reg, dst FL: без изменений
Проверка - индекса массива.
Если индекс, содержащийся в указанном регистре, не помещается в интервале, ограниченном двумя последовательными словами, находящимися по адресу dst, то генерируется прерывание с номером 5.
Аргументы
reg, mem
bound d1t [bx]
Пример
mov [word ptr Arr - 4]. 5
mov [word ptr Arr - 2], 7
mov bx, 2
bound bx, [Arr - 4]; происходит прерывание
CALL
Синтаксис Описание
call dstFL: без изменений
Вызов процедуры.
292
Часть IY. Турбо Ассемблер
ЗамечанияЕсли аргумент является меткой (lab 16 - близкой, или
1аЬ32 - далекой), то происходит переход на команду, определенную этой меткой. В остальных случаях происходит переход на команду, адрес которой находится в регистре или в области памяти. Если аргументом команды call является 1аЬ32 или mem32, то происходит изменение содержимого регистра CS. В случае вызова близкой процедуры адрес возврата состоит из одного слова, извлекаемого из стека в регистр IP, а в случае вызова далекой процедуры 一 извлекается также слово и в регистр CS. Только вызовы с аргументами 1аЫ6 осуществляются со смещением относительно IP.
Аргументы
1аЫбcallhear ptr Here
lab32callfar ptr There
regl6 阻callax
meml6call[word ptr bx]
mem32call [dword ptr Ref + bx]
Пример call near ptr Lab Lab LABEL NEAR pop ax; AX = OFFSET Lab
CBW
Синтаксис
cbwFL: без изменений
Описание
Расширение знака байта регистра AL, образуя слово в регистре АХ.
Замечания .
В регистре АХ образуется слово в дополнительном коде.
Аргументы
отсутствие Пример
cbw
mov al, 255 cbw
;АХ = -1
CLC
Синтаксис
clcFL: c = 0
Описание
Сброс флажка переноса с
Замечания
Аргументы
CF户0
отсутствие Пример
mov al, -1
clc
clc
rd al. 1
;AL = -2
CLD
СинтаксисОписаниеЗамечанияАргументы…отсутствие'"Примерmov di, 10cldmovsw
cldFL: d = 0
Сброс флажка направления d.
DF := 0
;DI = 12
CLI
Синтаксис Описание Замечания
cliFL: i = 0
Сброс флажка прерывания i.
IF := 0
Аргументы отсутствиеcl i
Пример (для системы DOC) mov ax. 40 h mov ds, ax mov bx, 6ch cli mov ax, [bx] mov dx, [bx + 2]; DX - AX = время суток
CMC
Синтаксис Описание Замечания Аргументы отсутствие
cmcFL: с
Инверсия флажка переноса с.
CF := NOT CF
СПС
Пример
mov ах, 0
cic
стс
adc ах, 0
;АХ = X
СМР
Синтаксис ОписаниеСинтаксис Описание
Синтаксис Описание
Синтаксис Описание
cmp dst, src FL: а с о р s z Определение разности dst флажков регистра FL без результата операции.
-src с целью установки размещения 1де-либо
294
Часть IY. Турбо Ассемблер
Замечания
О результате сравнения аргументов, трактуемых
Аргументы reg, con
как числа со знаком, можно судить с помощью команд
Jg. jge, jl. J1e, jng, Jnge,加1. jnle, а о результате сравнения аргументов, трактуемых как числа без знака, - с помощью команд
Ja. Jae. jb, Jbe. jna, jnae, Jnb, jnbe.
О результате сравнения аргументов на их равенство и не равенство можно судить с помощью команд je и jne.
cmp bh, 20
mem. con
cmp [word ptr Fix - 2 + si], -2
reg, reg
cmp ax。 dx
reg. mem
cmp bx, [si]
mem, reg
cmp [si + r], al
Пример 狰 mov ax. 3 cmp ax, 4 jl Lab
; переход будет выполнен
CMPSB
Синтаксис
cmpsbFL: а с о p s z
Описание
Сравнение байтов на основе разности
Замечания
[byte ptr ds:si] - [byte ptr es:di] а затем,
если df = о, увеличение si и DI на 1, если DF = 1, уменьшение si и DI на 1. О результате сравнения байтов как чисел со
Аргументы отсутствие
знаком можно судить с помощью команд
jg, jge. jl. ]le. jng, jnge₽ jn1, Jnle.
а о результате сравнения байтов как чисел без
знака можно судить с помощью команд
ja, jae, jb, jbe, jna, jnae, jnb, jnbe.
О результате сравнения на равенство и не равенство можно судить с помощью команд je и jne.
cmpsb
Пример
mov ах, ds
mov esr ах
mov d1t OFFSET Trg mov si. di cmpsb
je Lab
; переход будет выполнен
CMPSW
Синтаксис
cmpsw FL: а с о р s z
Описание
Сравнение слов на основе разности
Замечания
[word ptr ds:s1] - [word ptr es:d1].
а затем, если DF=O, увеличение SI и di на 2, если DF«1, уменьшение SI и DI на 2.
О результате сравнения слов как чисел со знаком
Аргументы отсутствие
Пример mov ах. ds mov es, ах mov di OFFSET Trg mov s1, d1 cmsw jz Lab
можно судить с помощью команд
Jg・ Jge・ jl, jle. jng, jnge, Jn】. jnle, о результате сравнения слов как чисел без знака можно судить с помощью команд
ja, jae, jb. jbe, Jna. jnaer 加b, jnbe.
О результате сравнения на равенство и не равенство можно судить с помощью команд je и jne.
cmpsw
; переход будет выполнен
CWD
Синтаксис Описание
Замечания
Аргументы отсутствие
Пример mov ах. -1 cwd
cwdFL: без изменений
Расширение знака слова регистра АХ до двойного слова в паре регистров DX - АХ.
В паре регистров DX - АХ образуется двойное слово в дополнительном коде.
cwd
;DX « -1, АХ « -1
DAA
Синтаксис
daaFL: а с о р с z, о а ?
Описание
Выполнение коррекции после размещения в регистре AL суммы двух упакованных цифр в коде BCD.
Замечания
Если AF = 1 или (AL AND ofh) > 9, то выполняются следующие операции:
AL := AL + 6, AF := 1.
Затем, если CF = 1 или AL > 9fh, выполняются операции
AF := AL + 60h,
CF := 1.
Аргументы отсутствиеПримерmov alf 19h add al, 19h daaАргументы отсутствиеПримерmov alf 19h add al, 19h daa
Аргументы отсутствие
Пример
mov alf 19h add al, 19h daa
Аргументы отсутствие
Пример
mov alf 19h add al, 19h daa
daa
DAS
Синтаксис
dasFL := a c p s z, O=?
Описание
Выполнение коррекции после размещения в регистре
AL разности двух упакованных цифр в коде BCD.
Замечания
Если AF = 1 или (AL AND ofh) > 9, то выполняются
следующие операции:
衬
AL := AL-6.
AF := 1.
Затем, если CF = 1 или AL〉9fh, выполняются
операции
AL := AL - 60h.
CF := 1.
Аргументы
отсутствие
das
Пример
mov alr 12h
sub al. 03h
das
;AL = 09h
DEC
Синтаксис
dec dstFL: a о p s z
Описание
Уменьшение на единицу значения переменной,
определенной аргументом.
Замечания
dst := dst - 1
Аргументы
reg
dec ex
mem
dec [byte ptr Fix + si + di + 2]
Пример
mov ax, о
dec al
;AX = 255
DIV
Синтаксис
d1v dstFL: a-? c-? o-? p-1? s-E z-?
Описание
Получение частного от деления делимого в
регистре АХ (или в паре регистров DX-AX) на
делитель, определенный аргументом dst.
Трактовка делимого, делителя, частного и остатка
как данных без знака.
;AL - 38 h
ЗамечанияЗамечанияАргументы reg memПример mov ах, 32 mov Ы, 6 div ЫАргументы reg memПример mov ах, 32 mov Ы, 6 div ЫВ случае 8-6ит аргумента выполнение операции
Замечания
Замечания
Аргументы reg mem
Пример mov ах, 32 mov Ы, 6 div Ы
Аргументы reg mem
Пример mov ах, 32 mov Ы, 6 div Ы
temp := АХ
АН := temp MOD dst
AL := temp DIV dst.
а в случае 16-бит аргумента выполнение операции temp := DX ~ АХ
DX :»: temp MOD dst
АХ: к temp DIV dst.
Если частное не помещается в регистре, то
происходит прерывание с номером 0.
div ах
div [byte ptr Fix]
ENTERENTERСинтаксис Описание ЗамечаниеСинтаксис Описание ЗамечаниеАргументы coni6, con8Пример enter 4,0Аргументы coni6, con8Пример enter 4,0enter con, 1 FL: без измененийСоздание рамки вызова процедуры.Копирование в стек I указателей предварительных рамок и резервирование con байтов для локальных переменных. В общем виде выполнение следующих действий:Zev := / MOD 32push BPptr := SP.Если ley > 0, выполнение lev - t раз операцииBP := BP - 2push [BP],Затемpush ptr.В каждом случае выполнение операцииBP := ptrSP := SP-conenter 20,2; равнозначно выполнению команд push bpmov bp, spsub sp. 4enter con, 1 FL: без измененийСоздание рамки вызова процедуры.Копирование в стек I указателей предварительных рамок и резервирование con байтов для локальных переменных. В общем виде выполнение следующих действий:Zev := / MOD 32push BPptr := SP.Если ley > 0, выполнение lev - t раз операцииBP := BP - 2push [BP],Затемpush ptr.В каждом случае выполнение операцииBP := ptrSP := SP-conenter 20,2; равнозначно выполнению команд push bpmov bp, spsub sp. 4ESCESCСинтаксисesc id, dst FL: без измененийОписание 一 Размещение на адресной тине команд сопроцессора.Синтаксисesc id, dst FL: без измененийОписание 一 Размещение на адресной тине команд сопроцессора.;АН = 2. AL = 5
ENTER
ENTER
Синтаксис Описание Замечание
Синтаксис Описание Замечание
Аргументы coni6, con8
Пример enter 4,0
Аргументы coni6, con8
Пример enter 4,0
enter con, 1 FL: без изменений
Создание рамки вызова процедуры.
Копирование в стек I указателей предварительных рамок и резервирование con байтов для локальных переменных. В общем виде выполнение следующих действий:
Zev := / MOD 32
push BP
ptr := SP.
Если ley > 0, выполнение lev - t раз операции
BP := BP - 2
push [BP],
Затем
push ptr.
В каждом случае выполнение операции
BP := ptr
SP := SP-con
enter 20,2
; равнозначно выполнению команд push bp
mov bp, sp
sub sp. 4
enter con, 1 FL: без изменений
Создание рамки вызова процедуры.
Копирование в стек I указателей предварительных рамок и резервирование con байтов для локальных переменных. В общем виде выполнение следующих действий:
Zev := / MOD 32
push BP
ptr := SP.
Если ley > 0, выполнение lev - t раз операции
BP := BP - 2
push [BP],
Затем
push ptr.
В каждом случае выполнение операции
BP := ptr
SP := SP-con
enter 20,2
; равнозначно выполнению команд push bp
mov bp, sp
sub sp. 4
ESC
ESC
Синтаксисesc id, dst FL: без изменений
Описание 一 Размещение на адресной тине команд сопроцессора.
Синтаксисesc id, dst FL: без изменений
Описание 一 Размещение на адресной тине команд сопроцессора.
ЗамечанияАргументы con, reg con, memПример esc 8, clЗамечанияАргументы con, reg con, memПример esc 8, clПервый аргумент должен быть не больше 6 бит. Он определяет операционную часть команды сопроцессора.
Замечания
Аргументы con, reg con, mem
Пример esc 8, cl
Замечания
Аргументы con, reg con, mem
Пример esc 8, cl
esc 2. al
esc 6. [word ptr Fix + si]
; команда fid st(l)
HLT
Синтаксис Описание Замечания яАргументы отсутствиеПример hitСинтаксис Описание Замечания яАргументы отсутствиеПример hitIDIVIDIV
Синтаксис Описание Замечания я
Аргументы отсутствие
Пример hit
Синтаксис Описание Замечания я
Аргументы отсутствие
Пример hit
IDIV
IDIV
hitFL: без изменений
Задержка выполнения команд.
Возобновление выполнения команд наступит после устранения прерывания.
hit
;без комментария
СинтаксисОписаниеСинтаксисОписаниеidiv dst FL: a=? c=? o=? p=? s=? z=?
Синтаксис
Описание
Синтаксис
Описание
ЗамечанияЗамечанияПолучение частного от деления делимого в регистре АХ (или в паре регистров DX-AX) на делитель, определенный аргументом dst. Трактовка делимого, делителя, частного и остатка как данных со знаком.
Замечания
Замечания
В случае 8-бит аргумента выполнение операции temp := ах
AN := temp MOD dst AL := temp DIV dst.
а в случае 16-бит аргумента выполнение операции temp : н DX - АХ DX :s temp MOD dst АХ := temp Div dst.
Аргументы reg memПример mov ах, 10 mov blt -4 Idiv beАргументы reg memПример mov ах, 10 mov blt -4 Idiv beЕсли частное не помещается в регистре, то происходит прерывание с номером 0.
Аргументы reg mem
Пример mov ах, 10 mov blt -4 Idiv be
Аргументы reg mem
Пример mov ах, 10 mov blt -4 Idiv be
1d1v ah idiv [word ptr Fix]
;AH = 2. AL н -2
IMULIMULСинтаксисСинтаксисimul dstimul dstFL: c o, a=?片? s=? z=?FL: c o, a=?片? s=? z=?
IMUL
IMUL
Синтаксис
Синтаксис
imul dst
imul dst
FL: c o, a=?片? s=? z=?
FL: c o, a=?片? s=? z=?
ОписаниеОписаниеЗамечанияЗамечанияАргументы reg memПример mov al. 2 mov ah, -4 imul ahАргументы reg memПример mov al. 2 mov ah, -4 imul ahПолучение произведения содержимого регистра AL (или ах) и операнда, определенного аргументом dst. Трактовка множителей и произведения как данных со знаком.
Описание
Описание
Замечания
Замечания
Аргументы reg mem
Пример mov al. 2 mov ah, -4 imul ah
Аргументы reg mem
Пример mov al. 2 mov ah, -4 imul ah
В случае 8-бит аргумента выполнение операции АХ :« AL * dst,
а в случае 16-бит аргумента выполнение операции DX-AX :» АХ * dst.
Кроме того, если после выполнения операции левая половина результата повторяет старший бит правой половины, то выполняется операция
CF 产 о, OF := 0f в противном случае CF := 1. OF := 1.
imul si
imul [byte ptr Fix + bx]
;Ax = -8. CF = 0, OF = 0
IN
Синтаксис Описание
Замечания
in accr sre FL: без изменений
Введение в аккумулятор (только AL или АХ) данного из порта, определенного аргументом src. Аргумент src может быть только номером порта или именем регистра DX (в котором находится номер порта).
Аргументы есс₽ con 8 асе, DX
Пример mov dx, 32 1n al. dx
INC
in а1г 32 in ах. dx
; ввод данного из порта 32
Синтаксис Описание
Замечания
Аргументы reg mem
Пример mov al, 0 inc al
Inc dstFL: a о p s z
Увеличение на единицу значения переменной, определенной аргументом.
dst: =« dst + 1
inc ch
inc [word ptr Fix + di + 2]
;AL = 1
300
Часть IY. Турбо Ассемблер
INSB
Синтаксис
insbFL: без изменений
Описание
Введение байта данных из порта с номером в
регистре DX и размещение его по адресу ES: DI.
Если DF=O, DI увеличивается на 1, в противном случае DI уменьшается на 1.
Замечания
Команда insb может быть предварена знаком повторения, но не может быть снабжена префиксом.
Аргументы
отсутствие Пример
insb
les di. *ef] mov dx. 32 cld
rnov ex, 3 rep Insb
;ввод 3 знаков из порта с номером 32
INSW
286
Синтаксис
inswFL: без изменений!
Описание
Введение слова данных из порта с номером в
регистре DX и размещение его по адресу ES: DI. Если DF = 0, то DI увеличивается на 2, в противном случае DI уменьшается на 2.
Замечания
Команда insb может быть предварена знаком повторения, но не может быть снабжена префиксом.
Аргументы
отсутствуют
Пример
1nsw
les dt. [Ref] mov dxr 32 insw
; ввод слова из порта с номером 32
INT
Синтаксис
int numFL: it
Описание
Генерирование программного прерывания с номером, определенным аргументом num.
Замечания
Пересылка в стек процессора содержимого регистра FL, обнуление IF и TF, затем пересылка в стек содержимого регистров CS и IP, а также загрузка регистров CS: IP данными из двух слов из адреса 0:4 * num.
Аргументы
int con 8
1nt 21 h
Пример
mov ах. 4 cOOh
int 21 h; окончание выполнения программы
INTO
Синтаксис
Описание
intoFL: без изменений
Если OF*1, генерирование программного прерывания с номером 4.
Замечания
Пересылка в стек процессора содержимого регистра FL, обнуление IF и TF, затем пересылка в стек содержимого регистров CS и IP, а также загрузка CS: IP данными из двух слов из адреса 0:16.
Аргументы
отсутствие Пример
into
mov al. 127
add al, al into
; прерывание будет выполнено
IRET
Синтаксис Описание Замечания
iretFL:???
Возврат из прерывания.
Извлечение из стека трех слов и размещение их в очередности извлечения в регистрах ip, CS, FL.
Аргументы отсутствие
Пример iret
iret
;без комментария
Jcond - например,
JA, JG, JE, JZ, JC
Синтаксис
Описание
jcond labFL: без изменений
Выполнение условного перехода на команду,
снабженную меткой lab.
Замечания
Переход реализуется как короткий и умеренный. В записи команды определено условие выполнения перехода. Если оно не выполнено, то продолжается выполнение программы. В указанных ниже сочетаниях определения выше - ниже касаются переходов, выпол няемых после сравнения данных без знака, а опреде ления больший - меньший касаются переходов, выпол няемых после сравнения данных со знаком.
Команда Условие jaперейти,есливыше
jaeперейти,есливышеилиравно
jbперейти,еслиниже
jbeперейти,еслинижеилиравно
перейти, перейти, перейти, перейти, перейти, перейти, перейти, перейти, перейти, перейти, перейти, перейти, перейти, перейти, перейти, перейти, перейти, перейти, перейти, перейти, перейти, перейти, перейти, перейти, перейти, перейти, перейти.перейти, перейти, перейти, перейти, перейти, перейти, перейти, перейти, перейти, перейти, перейти, перейти, перейти, перейти, перейти, перейти, перейти, перейти, перейти, перейти, перейти, перейти, перейти, перейти, перейти, перейти, перейти.Аргументы labПример mov ах, 255 and al. al js NextАргументы labПример mov ах, 255 and al. al js Nextесли есть перенос если СХ равно О если равно если больше если больше или равно если меньше
перейти, перейти, перейти, перейти, перейти, перейти, перейти, перейти, перейти, перейти, перейти, перейти, перейти, перейти, перейти, перейти, перейти, перейти, перейти, перейти, перейти, перейти, перейти, перейти, перейти, перейти, перейти.
перейти, перейти, перейти, перейти, перейти, перейти, перейти, перейти, перейти, перейти, перейти, перейти, перейти, перейти, перейти, перейти, перейти, перейти, перейти, перейти, перейти, перейти, перейти, перейти, перейти, перейти, перейти.
Аргументы lab
Пример mov ах, 255 and al. al js Next
Аргументы lab
Пример mov ах, 255 and al. al js Next
если меньше или равно если не выше
если не выше или равно если не ниже
если не ниже или равно если нет переноса если не равно если не больше
если не больше или равно если не меньше
если не меньше или равно если нет переполнения если нечетное
если не отрицательное если не нуль
если есть переполнение если четное
если четное если нечетное если отрицательное если нуль
jg short Skip
JMPJMP; условный переход будет выполнен
JMP
JMP
Синтаксис ОписаниеЗамечанияСинтаксис ОписаниеЗамечанияАргументы1аЬ81аЫ61аЬ32regl6Аргументы1аЬ81аЫ61аЬ32regl6
Синтаксис Описание
Замечания
Синтаксис Описание
Замечания
Аргументы
1аЬ8
1аЫ6
1аЬ32regl6
Аргументы
1аЬ8
1аЫ6
1аЬ32regl6
Jmp dstFL: без изменений
Переход на команду, адрес которой определен архументом.
Если архумент является меткой (1аЬ8 - очень близкой, 1аЬ16 - близкой, 1аЬ32 - далекой), то происходит переход на команду, снабженную этой меткой. В остальных случаях происходит переход на команду, адрес которой находится в регистре или в области памяти. Если аргументом команды является 1аЬ32 или ment32, то происходит изменение содержимого регистра CS. Только переходы с архументами 1аЬ8 и 1аЫб осуществляются со смещением относительно IP.
Jmp short Close jmp near There jmp far Here jmp ax
meml6jmp [word ptr bx + di]
mem32jmp [dword ptr Ref + bx]
Пример
jmp short skip; обход директивы DB
Value DB13
Skip
mov alr [cs: Value]
LAHF
Синтаксис Описание Замечания
lahfFL: без изменений
Загрузка в регистр АН содержимого регистра FL.
Загрузка касается только флажков
s z а р d
Они будут помещены в АН следующим способом:
Аргументы отсутствие
Пример stc lahf гсг ah jc Skip
1 s|z| |а| |р| |с 1
lahf
; переход будет выполнен
LDS
СинтаксисIds reg, memFL: без изменений
ОписаниеЗагрузка в регистр reg слова данных из адреса,
определенного mem и в регистр DS слова данных, непосредственно следующего за уже загруженным.
ЗамечанияКоманда дает возможность быстрой загрузки
дальнего адреса.
Аргументы
regl6, mem32Ids si, [dword ptr Fix + bx]
Пример
Ids di, [dword ptr Ref]
mov ax, [di]; промежуточная загрузка слова
LES
Синтаксис
Описание
Замечания
les reg, memFL: без изменений
Загрузка в регистр reg слова данных из адреса, определенного mem, и в регистр ES слова данных, непосредственно следующего за уже загруженным. Команда дает возможность быстрой загрузки дальнего адреса.
Аргументы
_ -regl6. mem32 les s11 [dword ptr Fix + bx]
Пример
les di [dword ptr Ref + bx]
mov cl, [es:di + 2]; промежуточная загрузка байта
LEA
Синтаксис Описание Замечания
諸
Аргументы regl6, meml8 regl6, m*ml6 regl6, mem32 и Т.Д.
Пример lea bx, [Ref] jmp [bx]
1еа regt memFL: без изменений
Загрузка в регистр reg эффективного адреса Несмотря на то что выполнение, например,
lea bxr [word ptr Fix]
имеет тот же результат, что и выполнение mov bxr OFFSET Fix.
команда 1еа более общая, поскольку, например,команда
mov bx. OFFSET [byte ptr Fix + dx] ошибочна, но команда
lea bx. [byte ptr Fix+dx] верна.
lea si, [byte ptr Fix]
lea di. [si]
lea ax( [qword ptr Fix+bx+1]
; равнозначно jmp [word ptr Ref]-
mem.
команды
команды
LEAVE
286
Синтаксис Описание Замечания
Аргументы отсутствие
Пример enter 0.2 leavs
leaveFL: без изменений
Возврат из процедуры высокого уровня.
Выполнение операции
mov sp, bp pop BP
leave
; восстановлено состояние стека
о
LOCK
Синтаксисlock FL: без изменений
ОписаниеБлокирование остальных процессов во время
выполнения команды, следующей после LOCK.
ЗамечанияВыполнение команды не вызывает других
результатов, кроме введения блокировки.
Аргументы отсутствие
Пример mov al, 1 Check: lock xc hg Flare, test al, al jnz Check
lock
al; установка семафора
;критический район
mov Flare, 0
LODSB
СинтаксисlodsbFL: без изменений
ОписаниеЗагрузка в регистр AL байта из адреса DS: SI.
Если DF = о, увеличение SI на 1, в противном случае уменьшение SI на 1.
ЗамечанияКоманда lodsb может быть предварена знаком
повторения, но пригодность его сомнительна.
Аргументы
отсутствиеlodsb
Пример
Ids si, [dword ptr Ref]
lodsb; промежуточная загрузка байта
LODSW
Синтаксис
lodswFL: без изменений
Описание
Загрузка в регистр AL байта из адреса DS: SI. Если DF = о, увеличение si на 2, в противном случае уменьшение SI на 2.
Замечания
Аргументы
Команда lods может быть предварена знаком повторения, но пригодность его сомнительна.
отсутствие Пример
lodsw
Ids di r [dword ptr Ref]
lodsw
; промежуточная загрузка слова
LOOPcokd
Синтаксис
loopcond lab FL: без изменений
Описание
Уменьшение содержимого регистра СХ на 1, затем, если содержимое СХ не равно 0, а также выполнено условие, указанное в команде, переход на команду, снабженную меткой lab."
Замечания
Переход реализуется как короткий и умеренный.
20—764
В записи команды определено условие выполнения
СинтаксисОписание ЗамечанияСинтаксисОписание ЗамечанияАргументыАргументыreg, con mem. con reg, reg reg, mem mem, regПример mov axr 12 mw ds. axreg, con mem. con reg, reg reg, mem mem, regПример mov axr 12 mw ds. axСинтаксисОписаниеСинтаксисОписаниеЗамечанияАргументы отсутствиеЗамечанияАргументы отсутствие
Синтаксис
Описание Замечания
Синтаксис
Описание Замечания
Аргументы
Аргументы
reg, con mem. con reg, reg reg, mem mem, reg
Пример mov axr 12 mw ds. ax
reg, con mem. con reg, reg reg, mem mem, reg
Пример mov axr 12 mw ds. ax
Синтаксис
Описание
Синтаксис
Описание
Замечания
Аргументы отсутствие
Замечания
Аргументы отсутствие
перехода.
Если оно
не выполняется, то продолжается
выполнение программы.
Команда
Условие
loop
переход.
если сх # 0
loopne
переход.
если СХ # 0 и не равно (ZF=0)
loopnz
переход.
если СХ # 0 и не равно (ZF=0)
loope
переход,
если СХ f 0 и равно (ZF=1)
loopz
переход,
если СХ # 0 и равно (ZF«1)
Аргументы
1аЬ6
loop Again
Пример
nwv GX* 2
mov ах, 1
Again:
shl ах,卜
loop Again
nop
;АХ = 4
MOV
mov dst, src FL: без изменений Пересылка содержимого src в dst. Если dst является сегментным регистром, то содержимое src не может быть представлено постоянным выражением, а также не может содержаться в сегментном регистре. Если dst является регистром SS, то происходит блокирование прерываний на время выполнения следующей команды.
mov ahr 20
mov [word ptr Fix * 2], 3
mov ds. di
mov di。 (word ptr bx]
mov [bp + si], sp
;DS н 12
MOVSB
movsbFL: без изменений
Пересылка байта из адреса DS:SI в адрес ES:DI. Кроме того, если df = о, увеличение SI и di на 1, а если DF = 1, уменьшение SI и DI на L Команда movsb может быть предварена знаком повторения.
ntovsb
;пересылка трех;последовательных байтов;вперед;пересылка трех;последовательных байтов;впередСинтаксисОписаниеСинтаксисОписаниеmovs*movs*FL: без измененийFL: без измененийЗамечанияЗамечанияАргументы отсутствиеПримерIds si, [dword ptr SrcRef] les di. [dword ptr DstRef] std movsw ibovsw movswАргументы отсутствиеПримерIds si, [dword ptr SrcRef] les di. [dword ptr DstRef] std movsw ibovsw movswПересылка слова из адреса DS: SI по адресу ES: DI. Кроме того, если DF«0, увеличение SI и di на 2, а если DF м 1, уменьшение SI и DI на 2.Команда movsw может быть предварена знаком повторения.Пересылка слова из адреса DS: SI по адресу ES: DI. Кроме того, если DF«0, увеличение SI и di на 2, а если DF м 1, уменьшение SI и DI на 2.Команда movsw может быть предварена знаком повторения.1KVSW1KVSWперенос трех последовательных байтов назадперенос трех последовательных байтов назад
;пересылка трех
;последовательных байтов
;вперед
;пересылка трех
;последовательных байтов
;вперед
Синтаксис
Описание
Синтаксис
Описание
movs*
movs*
FL: без изменений
FL: без изменений
Замечания
Замечания
Аргументы отсутствие
Пример
Ids si, [dword ptr SrcRef] les di. [dword ptr DstRef] std movsw ibovsw movsw
Аргументы отсутствие
Пример
Ids si, [dword ptr SrcRef] les di. [dword ptr DstRef] std movsw ibovsw movsw
Пересылка слова из адреса DS: SI по адресу ES: DI. Кроме того, если DF«0, увеличение SI и di на 2, а если DF м 1, уменьшение SI и DI на 2.
Команда movsw может быть предварена знаком повторения.
Пересылка слова из адреса DS: SI по адресу ES: DI. Кроме того, если DF«0, увеличение SI и di на 2, а если DF м 1, уменьшение SI и DI на 2.
Команда movsw может быть предварена знаком повторения.
1KVSW
1KVSW
перенос трех последовательных байтов назад
перенос трех последовательных байтов назад
Пример
Ids si. [dword ptr SrcRef] les di, [dword ptr DstRef] cld movsb nnvsb movsb
MOVSW
СинтаксисОписаниеСинтаксисОписаниеЗамечанияЗамечанияАргументы reg memПример mov al, 3Аргументы reg memПример mov al, 3
Синтаксис
Описание
Синтаксис
Описание
Замечания
Замечания
Аргументы reg mem
Пример mov al, 3
Аргументы reg mem
Пример mov al, 3
MUL
nul dstFL: c ov a«? p=? s«=? z*?
Получение произведения содержимого регистра AL или АХ и операнда, определенного аргументом dst. Трактовка множителей и произведения как данных без знака.
В случае 8-бит аргумента выполнение операции
АХ :>= AL * dst, а в случае 16-бит аргумента - операции DX - АХ: • АХ * dst.
Если результат операции представлен болыпим числом битов, чем ар1умент, то
CF :- 1, OF :« 1, в противном случае CF п О, OF :- 0.
mul bh mul [word ptr Fix]
308
Часть /К Турбо Ассемблер
mul al
;АХ*9, CF. 0F«0
NEG
Синтаксис Описание Замечания
neg dstFL: а с о P s z
Изменение знака операнда dst на обратный.
Изменение знака основано на инверсии всех битов операнда и прибавлении числа 1.
Аргументы reg mem Пример
neg ах
neg [ds: byte ptr Fix + 6p]
mov bx. -J neg bh
;BX = 511
NOP
Синтаксис Описание * Замечание
nopFL: без изменений
Выполнение пустой операции.
Выполнение команды не приводит к каким-либо результатам.
Аргументы отсутствие
Пример
пор
пор
;без комментария
NOT
Синтаксис Описание Замечания Аргументы reg пет
Пример
not dstFL: без изменений
Инверсия (отрицание) битов операнда dst.
Бит со значением 1 меняется на 0 и наоборот.
not di
not [byte ptr bx-3]-
mov bx( -2
not bx
;BX=1
OR
Синтаксис
Описание
or dst, srcFL: psz. c=, o=0, a=?
В dst записывается результат поразрядной логической суммы dst и src.
Замечания
Логическая сумма вычисляется в соответствии со следующей таблицей:
Bit dstBtr src Bit dst OR src
000
011
101
111
Если src является 8-бит операндом, a dst - 16-бит, то операнд, представленный src, расширяется влево знаковым битом.
Аргументы rg, con memr con reg, mem mem, reg
Пример mov ax. Och or ah, Ofh
or bx, Offfh
or [word ptr si]f Of or ax. [word ptr Fix] or [byte ptr bx]₽ ch
;AX = OfOch
OUT
Синтаксис
Описание
out num, accFL: без изменений
Вывод в порт с номером num данного из аккумулятора асе.
Замечания
Архумент port может быть только именем регистра DX или постоянным выражением со значением меньше чем 256.
В зависимости от того, является ли асе регистром AL или АХ, в порт выводится байт или слово.
Аргументы 8n8, AL con8, AX DXt AL DX, AX
Пример
out 32, al out 20. ах out 40, al out dx, ax
mov dx, 32 mov ax, offfh out dx, ax
; вывод Offfh в порт 32
OUTSB
Синтаксис
Описание
outsbFL: без изменений
Вывод в порт с номером, указанным в DX, байта из адреса DS: SI. Если DF = 0, увеличение SI на 1,
Замечания
в противном случае уменьшение SI на 1.-•■
Команда outsb может быть предварена знаком
Аргументы отсутствие
Пример
повторения.
outsb
Ids s1( [Ref]
OUTSW
Синтаксис
outswFL: без изменений
Описание
Вывод в порт с номером в DX слова из адреса DS: SI. Если DF « о, увеличение si на 2, в противном случае уменьшение SI на 2.
Замечания
Аргументы
Команда outsw может быть предварена знаком повторения.
отсутствие Пример
Ids si, [Ref] mov dx, 32 mov ex, 2 cld
outsw
rep outsw
; вывод в порт 32 двух слов
POP
Синтаксис
pop dstFL: без изменений
Описание
Извлечение из стека процессора в dst одного слова. Увеличение SP на 2.
Замечания
Аргументы
Извлекаются два байта, сначала младпшй, затем ставший. Ар^ментом команды не может быть регистр CS.
reg
pop ах
seg
pop ds
mem
Пример mov ax, 22 push ax mov ax, 0
pop [word ptr Fix]
pop ax
;AX = 22
POPA
Синтаксис
popaFL: без изменений
Описание
Извлечение из стека 8 слов и размещение их в регистрах процессора. Увеличение SP на 16.
Замечания
Извлеченные из стека слова размещаются последовательно в следующих регистрах DIr SI. BP, *, BXr DX, ex。AX (знаком * обозначено слово, которое, вместо того чтобы быть помещенным в SP, игнорируется).
mov dx, 32 outsb
; вывод в порт 32 одного байта
Аргументы отсутствие
Пример pusha
popa
sub sp. 2
popa
; регистр SP без изменений
POPF
Синтаксис Описание
popfFL: все
Извлечение из стека процессора одного слова и размещение его в решстре FL. Увеличение SP на 2.
Замечания
Размещение флажков в регистре FL следующее: 1 1 1 |o|d|1|t|s|z| |а| |р| |c 1
Аргументы отсутствие
Пример хог ах, ах
PM
push ax.
popf
; обнуление регистра флажков
PUSH
Синтаксис
Описание
push dstFL: без изменений
Пересылка в стек процессора данного, представленного dst. Уменьшение SP на 2.
Замечания
Пересылаются два байта. Сначала старший байт, затем младший. Выполнение команды push sp вызывает пересылку нового значения в регистр SP.
Аргументы reg seg (также CS) глет
Пример push es push ds pop es pop ds
push bx
push es
push [word ptr Fix + si]
; обмен значений ES и DS.
PUSH
286
Синтаксис Описание
push dstFL: без изменений
Пересылка в стек процессора данного, представленного dst. Уменьшение SP на 2.
Замечания
Пересылаются два байта. Сначала старший байт.
затем младший. Выполнение команды push sp вызывает пересылку старого значения регистра SP.
Аргументы con reg seg (также CS) rnem
Пример push -2 pop ax
push 30
push bx push es.
push [word ptr Fix + s1]
;AX « -2
PUSHA
286
Синтаксис
Описание 修
pushaFL: без изменений
Пересылка в стек процессора содержимого следующих регистров: АХ, СХ₽ DXr BXf SPf BD, SIe DI. Уменьшение SP на 16.
Замечания
Регистры пересылаются в указанной очередности. Пересылка касается старого значения SP.
Аргументы.
отсутствие
pusha
Пример * mov ах. 2 pusha
mov ах, 7 рора
;AX^2
PUSHF
Синтаксис
Описание
pushfFL: без изменений
Пересылка в стек процессора содержимого регистра FL
Замечания
Размещение флажков в регистре FL следующее:
Illi |oH|i|t|s|z| |.| |р| |c I
Аргументы отсутствие
Пример stc pushf pop ах and ах. lh
pushf
;AX = 1
RCL
Синтаксис Описание
rd dst, entFL: с о
Циклический сдвиг содержимого dst через перенос CF на ent позиций влево.
Замечаний.
Аргумент ent должен быть постоянным выражением
Аргументыreg» 1mem, 1reg, CLmem. CLПримерmov ah, -128 clcrd ah, 1Аргументыreg» 1mem, 1reg, CLmem. CLПримерmov ah, -128 clcrd ah, 1RCRRCR;AH = 0, CF = 1, OF = 1;AH = 0, CF = 1, OF = 1
Аргументы
reg» 1
mem, 1
reg, CL
mem. CL
Пример
mov ah, -128 clc
rd ah, 1
Аргументы
reg» 1
mem, 1
reg, CL
mem. CL
Пример
mov ah, -128 clc
rd ah, 1
RCR
RCR
;AH = 0, CF = 1, OF = 1
;AH = 0, CF = 1, OF = 1
co значением 1 или именем регистра CL, содержимое которого определяет число сдвигов. Во время каждого сдвига старший бит dst заносится в CF, а бит из CF занимает младшую позицию dst. Если выполняется сдвиг на одну позицию, и после этого старший бит результата отличается от бита CF, то выполняется операция
OF :« 1.
В противном случае выполняется операция OF := 0.
rd axr 1
rcl [byte ptr Fix]; 1
rcl bh, cl
rcl [word ptr Fix + bx]e cl
Синтаксис ОписаниеЗамечанияСинтаксис ОписаниеЗамечанияАргументы reg 1 rnem 1 reg, CL rnem, CLПример mov ax,0 stc гсг агуИГАргументы reg 1 rnem 1 reg, CL rnem, CLПример mov ax,0 stc гсг агуИГ
Синтаксис Описание
Замечания
Синтаксис Описание
Замечания
Аргументы reg 1 rnem 1 reg, CL rnem, CL
Пример mov ax,0 stc гсг агуИГ
Аргументы reg 1 rnem 1 reg, CL rnem, CL
Пример mov ax,0 stc гсг агуИГ
rcr dst. ent FL: с о
Циклический сдвиг содержимого dst через перенос CF на ent позиций вправо.
Аргумент ent должен быть постоянным выражением со значением 1 или именем регистра CL, содержимое которого определяет число сдвигов. Во время каждого сдвига бит CF заносится в старший разряд dst, а младший бит dst заносится в CF. Если сдвиг единичный и после его выполнения два старших бита результата не идентичны, то выполняется операция
OF := 1.
В противном случае выполняется операция
rsr al, 1
rcr [word ptr Fix], 1
rcr bx, cl
rcr [byte ptr Fix + bx]( cl
;A = -32768, CF = 0, OF = 1
REP
Описание
Замечания
Многократное выполнение команды, следущей за rep. Кратность повторения определяется содержимым регистра СХ.
После каждого выполнения команды, следующей после гер, выполняется операция
СХ := СХ - 1.
Если в момент выполнения команды гер регистр сх имеет значение 0, то повторение имеет краткость 0.
Аргументы отсутствие
Пример Ids si, les di, cld
IftOV ex.
rep movsb
[dword ptr SrcRef] [dword ptr DstRef]
20
rep movsb
пересылка 20 байт
REPcozid
Синтаксис
Описание
repccnd
FL: без изменений
Замечания
Многократное выполнение команды, следующей после repcond. Кратность повторения определяется содержимым регистра СХ. Прекращение выполнения при СХ = 0, либо когда перестанет действовать условие cond.
После каждого выполнения команды, следующей после гер, выполняется операция
СХ := СХ-1.
Если в момент выражения команды гер регистр СХ имеет значение 0, то повторение имеет кратность 0. Условие cond определяется следующим способом.
Аргументы отсутствие
Пример
les di, [dword ptr TrgRef] cld
iftov cxr 200
xov al, al repne scasb jne Fail nov al, [es:di-2]
Команда
Условие
гере
повторять операцию, пока равно (zf=1 )
герг
повторять операцию, пока нуль (ZF=1)
герое
повторять операцию, пока не равно (ZF-O)
repnz
повторять операцию, пока не нуль (ZF=O)
repne scasb
AL - последний символ цепочки
RET
Описание
Замечания
Аргументы отсутствие соп8
Пример mov, ах, OFFSET Lab ■ push ах ret
Возврат из процедуры.
Возврат из близкой процедуры вызывает извлечение одного слова из стека процессора и помещение его в регистр ip. Возврат из далекой процедуры вызывает извлечение дополнительного слова из стека процессора и помещение его в регистр CS。 Если имеется аргумент ent, то дополнительно выполняется операция
SP := SP + ent (ent должно быть постоянным 16-бит выражением).
ret ret 2
Lab; Переход на lab.
Lab:
RETF
Синтаксис Описание Замечания
Аргументы отсутствие соп8
Пример Fun PROC NEAR retf 2
Fun ENDP
retf ent FL: без изменений
Возврат из далекой процедуры
Возврат из далекой процедуры вызывает извлечение одного слова из стека процессора и помещение его в регистр IP, а затем извлечение второго слова и помешение его в регистр CS. Если имеется аргумент ent, то дополнительно выполняется операция SP := SP + ent
(ent должно быть постоянным 16-бит выражением) °
retf retf5
; ret 2 было бы принято за retnZ
RETN
Синтаксис Описание Замечания
retn ent FL: без изменений
Возврат из близкой процедуры.
Возврат из близкой процедуры вызывает извлечение одного слова из стека процессора и помещение его в регистр IP.
316
Часть /К Турбо Ассемблер
Если имеется аргумент ent, то дополнительно выполняется операция
SP :« SP + ent
(ent должно быть постоянным 16-бит выражением).
Аргументы отсутствие соп8
Пример
Fun RROC FAR
retn
retn5
retn 2
; ret 2 было бы принято за retf 2.
ROL
Синтаксис Описание
rol dst, ent П: с о
Циклический сдвиг содержимого dst на ent позиций влево.
Замечания
Аргумент ent должен быть постоянным выражением со значением 1 или именем регистра CL,
содержимое которого определяет число сдвигов. Во время каждого сдвига старший бит dst зано сится в CF и в младший разряд dst. Если сдвиг единичный и после его выполнения старший бит результата отличается от бита CF, то выполняется операция
OF := 1.
В противном случае выполняется операция OF := 0.
Аргументы reg,l mem.l reg, CL mem, CL
Пример mov ax, -32767 rol ax,l
rol axt 1
rol [byte ptr Fix], 1
rol bh, cl
ro] [word ptr Fix + bx]B cl
;AX=3, CF”,0F=l
ROR
Синтаксис Описание
ror dst, ent FL: с о
Циклический сдвиг содержимого dst на ent позиций вправо.
Замечания
Аргумент ent должен быть постоянным выражением со значением 1 или именем регистра CL, содержимое которого определяет число сдвигов. Во время каждого сдвига младший бит dst заносится в CF и в старший разряд dst.
Если сдвиг единичный и после его выполнения старший бит результата отличается от CF, то
Аргументы reg.l mem.l reg, CL mem, CL
Пример mov bh, -127 ror bhf 1
выполняется операция
OF :« 1.
В противном случае выполняется операция OF :■ 0.
гог ах. 15
ror [byte ptr Fix], 1
ror bh( cl
ror [word ptr Fix + bx], cl
;BH = -64, CF = 1, OF = 0
SAHF
Синтаксис
Описание
sahfFL: a c p s z
Размещение пересылаемых битов в регистре АН следующее:
Аргументы отсутствие
Пример mov ah, 4 sahf jp Lab
1 s|z|
al |p| |c J
sahf
; переход будет выполнен
SAL
Синтаксис Описание
Замечания
Аргументы гедД msm.l
sal dst, entFL: copsz, a=?
Арифметический сдвиг содержимого dst на ent позиций влево.
Аргумент ent должен быть постоянным выражением со значением I или именем регистра CL, содержимое которого определяет число сдвигов. Во время каждого сдвига старший бит dst заносится в CF, а в младший разряд записывается 0. Если сдвиг единичный и после его выполнения старший бит результата отличается от CF, то выполняется операция 0F :» 1.
В противном случае выполняется операция 0F :* 0.
sal ах,1
sal [byte ptr Fix]» 1
reg, CL
mem, CL
Пример
iftov [byte ptr Fix],10
BL н 40. CF - 0, DF = 0BL н 40. CF - 0, DF = 0sal [byte ptr Fix]r2 mov Ы, [byte ptr Fix]
BL н 40. CF - 0, DF = 0
BL н 40. CF - 0, DF = 0
SAR
Синтаксис Описание
sar dst entFL: copsz, a«?
Арифметический сдвиг содержимого dst на ent позиции вправо.
Замечания
Аргумент ent должен быть постоянным выражением со значением 1 или именем
州
регистра CL, содержимое которого определяет число сдвигов. Во время каждого сдвига младший бит dst заносится в CF, а в старшем разряде дублируется знак операнда dst.
Если сдвиг выполняется одни раз, то выполняется операция 0F :« 0
Аргументы reg, 1 mem.l reg, CL men, CL
Пример
sar ah.l
sar [word ptr Fix],l
sar bx. cl
sar [byte ptr Fix + di]e cl
iftov ax, -5
sar ax. 1
;AX - -3r CF=1, DF=O
SBB
Синтаксис Описание
sbb dst, sre FL: acopsz
Вычитание из содержимого dst содержимого sre, а также CF.
Замечания
Выполнение операции
dst: = dst - sre - CF
Аргументы reg. con men, com reg. reg reg, mem mem, reg
Пример stc
sbb bl,3
sbb [word ptr Fix + di]. 300
sbb axr ax
sbb bhr [byte ptr Fix]
sbb [byte ptr Fix + si], al
iftov ax, 0 sbb ax» ax
;AX « -1
SCASB
Синтаксис
scasb
FL: acopsz
Описание
Сравнение
байта, содержащегося в регистре AL, с
байтом по
адресу ES:DI путем образования
разности
AL-[byte ptr ES:DI],
а затем, если df « 0» увеличение DI на 1, а если
DF=1° уменьшение DI на 1.
Замечания
Команда м
【9永ет быть предварена знаком
повторений
Аргументы
отсутствие
scasb
Пример
mov схг 200
les di, [dword ptr Ref]
std
xor al. al
repe scasb
je Fail
1nc di
inc di
; адрес первого нулевого байта
SCASW
Синтаксис
scasw
FL: asopsz
Описание
Сравнение
слова, содержащегося в регистре АХ,
со словом
по адресу ES: DI путем образования
разности
АХ-[word ptr ES:DI],
а затем, если DF = о, увеличение DI на 2, а если
DF н 1, уменьшение DI на 2.
Замечания
Команда может быть предварена знаком
повторения.
Аргументы
отсутствие
scasw
Пример
mov сх. 100
les di. [dword ptr Ref]
cld
xor axv ax
repne scasw
jne Fail
sub di, 2
;ES:DI -
адрес нулевого слова
SHL
Синтаксис
shl dst ent Fl: copsz, a«?
ОписаниеЗамечанияОписаниеЗамечанияЛогический сдвиг содержимого dst на ent позиций влево.Аргумент ent должен быть постоянным выражением со значением 1 или именем регистра CL, содержимое которого определяет число сдвигов. Во время каждого сдвига старший бит det заносится в CF, а в младший разряд записывается 0. Если сдвиг единичный и после его выполнения стартм访 бит результата отличается от CF, то выполняется операция 0F :« 1.В противном случае выполняется операция 0F 尸 0.Логический сдвиг содержимого dst на ent позиций влево.Аргумент ent должен быть постоянным выражением со значением 1 или именем регистра CL, содержимое которого определяет число сдвигов. Во время каждого сдвига старший бит det заносится в CF, а в младший разряд записывается 0. Если сдвиг единичный и после его выполнения стартм访 бит результата отличается от CF, то выполняется операция 0F :« 1.В противном случае выполняется операция 0F 尸 0.Аргументыreg,lгоетД 国reg, CLme 吸 CLПримерiftov [byte ptr Fix], 10n)ov cl Jshl [byte ptr Fix], cl mov bl, fbyte ptr Fix]Аргументыreg,lгоетД 国reg, CLme 吸 CLПримерiftov [byte ptr Fix], 10n)ov cl Jshl [byte ptr Fix], cl mov bl, fbyte ptr Fix]shl ахДshl[byte ptr F仪].1shl bh, clshl [word ptr Fix + bx], clshl ахДshl[byte ptr F仪].1shl bh, clshl [word ptr Fix + bx], cl:BL=20. CF=O, 0F=0:BL=20. CF=O, 0F=0SHRSHRСинтаксис ОписаниеЗамечанияСинтаксис ОписаниеЗамечанияАргументы reg.l mem.l reg, CL Diem, CLПример iftov ax, -1 IftOV clr 1 shr axv clАргументы reg.l mem.l reg, CL Diem, CLПример iftov ax, -1 IftOV clr 1 shr axv clshr dst. ent FL: cepsz. a=?
Описание
Замечания
Описание
Замечания
Логический сдвиг содержимого dst на ent позиций влево.
Аргумент ent должен быть постоянным выражением со значением 1 или именем регистра CL, содержимое которого определяет число сдвигов. Во время каждого сдвига старший бит det заносится в CF, а в младший разряд записывается 0. Если сдвиг единичный и после его выполнения стартм访 бит результата отличается от CF, то выполняется операция 0F :« 1.
В противном случае выполняется операция 0F 尸 0.
Логический сдвиг содержимого dst на ent позиций влево.
Аргумент ent должен быть постоянным выражением со значением 1 или именем регистра CL, содержимое которого определяет число сдвигов. Во время каждого сдвига старший бит det заносится в CF, а в младший разряд записывается 0. Если сдвиг единичный и после его выполнения стартм访 бит результата отличается от CF, то выполняется операция 0F :« 1.
В противном случае выполняется операция 0F 尸 0.
Аргументы
reg,l
гоетД 国
reg, CL
me 吸 CL
Пример
iftov [byte ptr Fix], 10
n)ov cl J
shl [byte ptr Fix], cl mov bl, fbyte ptr Fix]
Аргументы
reg,l
гоетД 国
reg, CL
me 吸 CL
Пример
iftov [byte ptr Fix], 10
n)ov cl J
shl [byte ptr Fix], cl mov bl, fbyte ptr Fix]
shl ахД
shl[byte ptr F仪].1
shl bh, cl
shl [word ptr Fix + bx], cl
shl ахД
shl[byte ptr F仪].1
shl bh, cl
shl [word ptr Fix + bx], cl
:BL=20. CF=O, 0F=0
:BL=20. CF=O, 0F=0
SHR
SHR
Синтаксис Описание
Замечания
Синтаксис Описание
Замечания
Аргументы reg.l mem.l reg, CL Diem, CL
Пример iftov ax, -1 IftOV clr 1 shr axv cl
Аргументы reg.l mem.l reg, CL Diem, CL
Пример iftov ax, -1 IftOV clr 1 shr axv cl
Логический сдвиг содержимого dst на ent позиций вправо.
Аргумент ent должен быть постоянным выражением со значением 1 или именем регистра CL, содержимое которого определяет число сдвигов. Во время каждого сдвига младший бит dst заносится в CF, а в старший бит записывается 0・ Если сдвиг единичный и после его выполнения два старших бита результата различаются, то выполняется операция 0F := 1.
В противном случае выполняется операция 0F := 0.
shr dx,l
shr [word ptr Fix]. 1
shr ch, c!.
shr [word ptr Fix + bx], c1
;AX= 32767. CF=1. 0F=l
STC
Синтаксис Описание Замечания Аргументы отсутствие
Пример stc
Jc Lab
stcFL: c=l
Установка флажка переноса с. Выполнение операции CF:«1-
stc
;переход будет выполнен,
STD
Синтаксис Описание Замечания
stdFL: d=l
Установка флажка направления d. Выполнение операции
DE :н 1.
Аргументы отсутствие
Пример std xor si, si lodsw mov ax, si
std
;Sb-2
STI
Синтаксис Описание Замечания
stiFL: i»l
Установка флажка прерывания i. Выполнение операции
IF := 1.
Аргументы отсутствие
Пример
sti
sti
;деблокирование прерывания
STOSB
Синтаксис
Описание
stosb FL: без изменений
Пересылка по адресу ЕС:01 байта из регистра AL. Если of н 0, увеличение DI на 1, а если DF = i, уменьшение DI на 1.
Замечания
Команда может быть предварена знаком
Аргументы отсутствие
повторения.
stosb
Пример
les di [dword ptr Ref]
mov al, [byte ptr Fix] std stosb stosb; промежуточное запоминание двух
байтов-4-й.'.
STOSW
Синтаксис
stoswFL: без изменений
Описание
Пересылка по адресу ES:DI слова из регистра АХ. Если DF * 0, увеличение 01 на 2, а если DF = 1, уменьшение DI на 2.
Замечет呼
Команда может быть предварена знаком повторения.
Аргументы
отсутствие
stosw
Пример
les di. [dword ptr Ref] mov axJ[word ptr Fix] stosw - *
stosw
;промежуточное запоминание двух слов
SUB
Синтаксис
sub dst. src FL: а с о р s z
Описание
Вычитание двух целых данных.
Замечания
Выполнение операции dst:* dst - src
Аргументы
reg, con
sub Ы(3
mem, con
sub [byte ptr Fix + di], 30
reg, reg
sub ax, ax
reg, men
sub bh, [byte ptr Fix]
men, reg
sub [byte ptr Fix + si], al
Пример mov ax. 257 mov Ы, 3
sub a1t bl
;AH » -2
TEST
Синтаксис ОписаниеСинтаксис ОписаниеЗамечания.Замечания.test dst. src FL: c=0 o=0 p s z. a=?
Синтаксис Описание
Синтаксис Описание
Замечания.
Замечания.
Вычисление поразрядного логического произведения аргументов с целью установки флажков регистра FL.
Выполнение операции dst AND src без пересылки куда-либо ее результатов.
Аргументы
reg, 8n
test
ax,-l
mem, con
test
[word ptr Fix + 2], Offfh
reg, reg
test
al, al
reg, mem
test
bx, [word ptr Fix -2]
memr reg
test
[word ptr Fix + si], bx
Пример
mov axt -2
test ax, ax
js Lab
;переход будет выполнен
WAIT
Синтаксис
waitfl: без изменений
Описание
Задержка выполнения команд процессора»
Залзак 〃兄
Продолжение выполнения команд процессора
Аргументы отсутствие
происходит после получения сигнала о завершении внешней операции, выполняемой, например, сопроцессором.
wait
Пример wait
;без комментария
XCHG
Синтаксис
xchg dst src FL: без изменений
Описание
Обменять содержимое dst и src.
Замечания
Выполнение операции temp :® dst dst :® src src 尸 temp
Аргументы
reg, reg
xchg ax, bx
reg, mem
xchg ax. [sp]
mem, reg
xchg [byte ptr Fix], bh
Пример mov axf -33
xchg ax, bx
;BX=~33
XLAT
Синтаксис ОписаниеЗамечанияАргументыСинтаксис ОписаниеЗамечанияАргументыотсутствиеотсутствиеxlatFL: без изменений“
Синтаксис Описание
Замечания
Аргументы
Синтаксис Описание
Замечания
Аргументы
отсутствие
отсутствие
Проведение преобразования массива байтов в соответствии с задаваемой таблицей.
Выполнение операции
AL 尸[byte ptr ВХ + AL].
xlat
Пример
Table DB lt 3, 5, 7, 9
tov bx. OFFSET Table mov al. 3 xlat
;AL « 7;AL « 7XOR
;AL « 7
;AL « 7
Синтаксис ОписаниеЗамечанияСинтаксис ОписаниеЗамечанияАргументы reg, con ♦ mem, con reg, reg reg( mem mem, regПример mov ax. -2 xov al. alАргументы reg, con ♦ mem, con reg, reg reg( mem mem, regПример mov ax. -2 xov al. alxor dst src FL: c=o ь»0 p в z( a®?
Синтаксис Описание
Замечания
Синтаксис Описание
Замечания
Аргументы reg, con ♦ mem, con reg, reg reg( mem mem, reg
Пример mov ax. -2 xov al. al
Аргументы reg, con ♦ mem, con reg, reg reg( mem mem, reg
Пример mov ax. -2 xov al. al
Размещение в dst результата поразрядного сложения по модулю 2 содержимого dst и src.
Сложение по модулю 2 вычисляется в соответствии со следующей таблицей:
Bit dst Bit src Bit dst XOR src ODD 011
101
11D
xor ax. -I
xor [byte ptr Fix + 2] Offh xor axv ax
xor bx. [word ptr Fix -2] xor [word ptr Fix + si] bx
AL-0
Включение файлов, условная компиляция
Иногда возникает необходимость включения в компилированный модуль фрагмента п редьарительно подготовленного текста ассемблера. Это может быть, например, когда в несколько модулей многомодульной программы предполагается включить комплект директив GLOBAL. Это задание можно легко реализовать, пользуясь директивой INCLUDE. Директива. INCLUDE имеет в общем случае вид
INCLUDE пате,
где пате является именем текстового файла. Если название пате не содержит расширения, то подразумевается расширение .ASM. Интерпретация директивы INCLUDE вызывает включение в месте ее появления содержимого файлов name. Ничто не мешает, чтобы присоединяемый текст также содержал директиву INCLUDE. •
Пример. Использование директивы INCLUDE файл INSERT. ASM
GLOBAL FIX : BYTE
файл
DATA.ASM .MODEL SMALL INCLUDE INSERT .DATA
FIX DB 13 END
файл
CODE.ASM .MODEL SMALL INCLUDE INSERT.ASM .CODE Start: mov ax. 0Data mov ds, ax mov al. [Fix] mov ahr 4ch int 21h
End Start
Модуль DATA трактуется таким образом, как если бы имел вид
.MODEL SMALL GLOBAL Fix: BYTE .DATA
Fix DB 13
END
а модуль CODE трактуется как
.MODEL SMALL-
GLOBAL FixxBYTE
-CODE
Start: mov axv 8 Data mov ds. ax mov al, [Fix] mov ah, 4ch Int 21h END Start
.Включение текста ассемблера с помощью директивы INCLUDE является безусловным. В тех случаях, когда включение содержимого файла или ■ определенного фрагмента основного модуля должно зависеть от определенных условий, можно пользоваться директивой условной компиляции.
Директивы условной компиляции выступают в нескольких вариантах, отличающихся главным образом начинающим их ключевым словом. В общем виде каждая из таких директив имеет вид
head
text
ELSEIF expl
text!
ELSEIF exp2
IF ехрIFE ехр нIFDEF symIFNDEF syntIFB <arg>IFNB <arg> *IFION <argL>, <argR>IFDIF <argL>, vargR>IFlDNKargL>9<aegR>imFl<argL>f<argR>IF ехрIFE ехр нIFDEF symIFNDEF syntIFB <arg>IFNB <arg> *IFION <argL>, <argR>IFDIF <argL>, vargR>IFlDNKargL>9<aegR>imFl<argL>f<argR>
IF ехр
IFE ехр н
IFDEF sym
IFNDEF synt
IFB <arg>
IFNB <arg> *
IFION <argL>, <argR>
IFDIF <argL>, vargR>
IFlDNKargL>9<aegR>
imFl<argL>f<argR>
IF ехр
IFE ехр н
IFDEF sym
IFNDEF synt
IFB <arg>
IFNB <arg> *
IFION <argL>, <argR>
IFDIF <argL>, vargR>
IFlDNKargL>9<aegR>
imFl<argL>f<argR>
text2
ELSE IF expn textn
ELSE textO
ENDIF
где каждый text является произвольной совокупностью команд и директив (в том числе директив условной компиляции), каждый ехр - выражением, а head - одной из следующих фраз, начинающих рассматриваемую директиву:
компилировать при условии, что выражение ехр не равно 0;
компилировать при условии, что выражение екр равно 0;
компилировать при условии, что символ sym определен;
компилировать при условии, что символ sym не определен;
компилировать при условии, что аргумент arg пустой;
компилировать при условии, что аргумент arg не пустой;
компилировать при условии, что аргумент argL равен аргументу argR\
компилировать при условии, что аргумент argL не равен аргументу argR;
компилировать при условии, что без различия больших и маленьких букв аргумент argL равен аргументу argR\
компилировать при условии, что без различия маленьких и больших букв аргумент argL отличен от аргумента argR.
В приведенной общей записи фраза
ELSE
text
трактуется как сокращенная запись фразы
ELSEIF 1
text.
а каждая из фраз, начинающихся ключевым словом ELSEIF (в том числе преобразованная фраза, начинающаяся ключевым словом ELSE), может быть опущена. В этом смысле верны среди прочих такие директивы, как
IF ехр text
ENDIF
а также
IF exp
text!
ELSE
text2
ENDIF
Если в заголовке директивы условной компиляции имеется символ sym, то принимается, что он определен, если использован в значении метки, а если имеются argL и argR, то принимается, что они являются выражениями.
Интерпретирование директивы условной компиляции происходит следующим способом:
определяется истинность условия, выраженного head;
если условие выполнено, компилируется фрагмент text и на этом заканчивается интерпретация рассматриваемой директивы условной компиляции;
если условие не выполнено, определяются поочередно значения выражений ехр9 содержащихся во фразах, начинающихся ключевыми словами ELSEIF (и преобразованной фразы, начинающейся ключевым словом ELSE), до обнаружения выражения expj со значением, отличным от 0, после чего компилируется фрагмент text) и на этом кончается интерпретация директивы условной компиляции;
если поиск выражения expj со значением, отличным от 0, не заканчивается успешно, то завершается интерпретация директивы.
Примеры. Директивы условной компиляции
Простая директива
IF а+Ь-2
One DW 13
Two DB О
ELSE
One DB 13
Two DW 0
END
Если выражение a+b~2 не равно 0, то интерпретация приведенной директивы вызовет компиляцию фрагмента
One DW 13
Two DB О
а в противном случае компиляцию
One DB 13
Two DW О
Вложенная директива
IFDEF Fix
mov axr [Fix}
IFE b
J nip short Skip
Lab DB 13
Skip:
ENDIF
ELSEIF b+2
mov bx, 0
ENDIF
Если символ Fix определен и переменная b равна 0, то компилируется фрагмент
mov ах, [Fix]
jmp short Skip
Lab DB 13 弟
Skip:
Если символ Fix определен, b отлично от 0, то компилируется
mov ах. [Fix}
Если символ Fix не определен, ь+2 отлично от 0, то компилируется
mov bx, О
Если символ Fix не определен, Ь + 2 равно 0, то интерпретация приведенной директивы условной компиляции не будет иметь никаких результатов.
15.6 Макроопределения и макровызовы
Значительным облегчением программирования на языке ассемблер является возможность обращения к макроопределениям, т.е. к тем фрагментам базового модуля, которые без изменений или с небольшими изменениями могут быть компилированы. Макроопределения могут быть размещены непосредственно в компилируемом базовом модуле или могут поступать из предварительно подготовленных файлов, включаемых в месте появления директив INCLUDE. Независимо от источника его происхождения макроопределение имеет в общем случае вид
name macro par, par, ..., par body
ENDM
где name является именем макроопределения, каждый par - его параметром, a body - телом макроопределения. Каждый из параметров макроопределения является идентификатором. Тело является совокупностью команд, содержащих обращения к параметрам. Возможны макроопределения, в которых список параметров пуст.
Интерпретация макроопределения вызывает только регистрацию ее наличия. Собственно использование макроопределения наступает только в месте
《б вызова. Вызов макроопределения имеет вид name arg, arg,…,arg,
ще name является именем предварительно описанного макроопределения, а каждый arg - аргументом его вызова.
Интерпретация вызова макроопределения осуществляет
一 связь каждого параметра par с соответствующим ему аргументом arg (первый параметр с первым аргументом, второй со вторым и т.д.);
-интерпретацию тела макроопределения после предварительной замены каждого идентификатора параметра соответствующим этому параметру аргументом.
Примеры макровызовов
В области действия макроопределения
Swap MACRO Dst, Src push Dst mov Dst Src pop Src ENDM
интерпретация макровызова
Swap ds. es
вызывает компиляцию аргумента
push ds mov dsr es pop es
В области действия макроопределения:
LongSHL MACRO de shl axJ rd dx,l ENDM интерпретация макровызова
LongSHL вызывает компиляцию
clc shl ax,l rd dx.l
В области действия макроопределения
Swap MACRO Dst, src
IFDIFI <Dst>. <Src> xchg Src. Dst
ENDIF stc ENDM
интерпретация макровызова
Swap bx. CX вызывает компиляцию xchg CX. bx H stc
а интерпретация макровызова swap ax, ax - компиляцию команды stc
Специальные макроопределения
К категории специальных макроопределений здесь относят макроопределения, начинающиеся ключевыми словами REPT, IRP и irpc. Их специальный характер состоит в том, что каждое из них вызывает дополнительные предположение и интерпретацию макроопределения.
Непосредственно после такой интерпретации специальное макроопределение перестает существовать^ поэтому нет необходимости назначения ему имени.
REPT
Макроопределение REPT имеет вид
REPT count
body
ENDM
где count является постоянным выражением, не содержащим обращений вперед, a body - телом макроопределения. Интерпретация макроопределения REPT вызывает включение в месте его появления с целью компиляции фрагмента, состоящего из count количества тела макроопределения.
Пример. Макроопределение REPT
Интерпретация макроопределения
REPT 3
shr ах,1
ENDM
вызывает компиляцию команд
shr ax.l shr ax.l shr ax.l
IRP
Макроопределение IRP имеет вид 丿.
IRP par, <arg, arg, ...» arg> body
ENDM
где par является идентификатором параметра макроопределения, каждый arg - аргументом, a body - телом макроопределения. Аргументы arg могут быть произвольными выражениями. Интерпретация макроопределения IRP вызывает включение в месте его появления с целью компиляции фрагмента, состоящего из такого количества body, сколько имеется аргументов, путем замены параметра par, находящегося в body、очередным аргументом arg.
Пример. Макроопределение IRP
Интерпретация макроопределения
IRP Child 〈Тош. Bob, Ann* Child DB?
ENDM
вызывает компиляцию
Tom DB?
Bob DB? Ann DB?
IRPC
Макроопределение irpc имеет вид
IRPC par, string body
ENDM •
Гце par является идентификатором параметра макроопределения, string - произвольной строкой символов, a body - телом макроопределения. Интерпретация макроопределения irpc вызывает включение в месте его появления с целью компиляции фрагмента, состоящего из такого количества появлений команд body, сколько знаков насчитывает string, путем замены параметра par, выступающего в body、очередным символом из string.
Пример. Макроопределение IRPC
Интерпретация макроопределения
IRPC Digit 1989
DB Digit ENDM
вызывает компиляцию фрагмента
DB1
DB9
DB8
DB9
Слияние (конкатенация) параметров
Если во время интерпретации тела макроопределения встречается знак 矗 (амперсанд) непосредственно перед или после параметра макроопределения, то после замёны параметра аргументом этот знак снимается. Это правило касается также появлений рассматриваемого знака перед параметрами, находящимися в пределах знаковых литералов, позволяющих как соединение надписей и аргументов, так и использование литералов с параметрами.
Пример. Конкатенация и параметризация
В области Действия макроопределения
Child MACRO Lab, Siz, Str
Lab&ber D&Siz 13
DB *»= &Str& =='
ENDM
интерпретация макровызова
Child Nun, W, Tom
вызывает компиляцию аргумента
Number DW 13
DB *»= Tom g'
Директива LOCAL
Для того чтобы во время очередных вызовов одного и того же макроопределения не был скомпилирован фрагмент, содержащий уже определенную метку, что, конечно же, недопустимо, необходимо использовать директиву LOCAL, предусмотренную для определения локальных символов макроопределения.
Директива LOCAL имеет вид
LOCAL symbol, symbol,…,symbol,、
ще каждый symbol является локальным символом*
Интерпретация директивы LOCAL приводит к тому, что с каждым указанным в ней символом связан уникальный символ вида ?? number
Gmmber является числом), который в компилируемом модуле заменяет первичный символ, с которым его связывали. Благодаря этому можно избежать использования одних и тех же меток.
Пример. Использование директивы LOCAL
В области действия макроопределения
Display MACRO Message LOCAL Lab •DATA
Lab D8 Message DB 13. 10, 。$, .CODE mov dxf OFFSET Lab mov ah, 9 int 21h ENDM
интерпретация вызовов
Display "Hello'* Display "world"
вызывает компиляцию, например, следующего типа:
.DATA
?? 00025 DB "Hello* DB 13. 10. $ .CODE mov dx, OFFSET ??00025 mov ah( 9 1nt Zlh .DATA
??00026 DB "world*' DB 13. 10, S' .CODE
mov dx, OFFSET 7700026
mov ah,9
1nt Zlh
Специальные -операторы
Кроме указанного выше оператора для конкатенации параметров (&) специальными операторами являются также
Оиспользование которого вызывает буквальное трактование
символов, содержащихся в угловых скобках, например в макровызовы Show 2. V; text> знак ; (точка с запятой) не является началом комментария* !использование которого вызывает трактовку следующего за ним
символа как интервала, а не как имени, например в макровызове
Show а!, Ь, с имеются два аррмента :<а,Ь> и <с>. %использование которого преобразовывает аргумент в число,
представляющее значение аргумента, например в макровызове
Show Х2+3, 2+3 аргументы <5> и <2+3>.
Директива EXITM
Директива EXITM имеет вид EXITM. Она может находится только в теле макроопределения.
Интерпретация директивы EXITM вызывает немедленное завершение макрорасширения, не дожидаясь его конца.
Пример. Директива EXITM
FastMul MACR炉 Factor
IF Factor EQI cbw EXITM
ENDIF
Fast=0 Count=l Bit=2 • REPT16
IF Factor EQ Bit Fast=l EXITM
ENDIF
Count=Count+l
Bit=Bit SHL1
ENDM IF Fast xor dx, dx REPT Count shl ax, 1 rcl dxrI
ENDM ELSE mov dx. Factor mu J dx
ENDIF
ENDM
Макроопределение осуществляет умножение содержимого регистра АХ на постоянную. Если постоянная является степенью числа 2, то умножение выполняется ускоренным способом (с помощью сдвигов). В частности, вызов
FastMul 4
вызывает компиляцию фрагмента
xor dx, dx
shl ax.l rel dx.l shl ахД rcl dx,l
Организационные директивы
К категории организационных директив относятся те директивы, интерпретация которых не влияет на генерацию кода и данных. Это прежде всего директивы управления листингом и генерации сообщений.
Директива %РAGESIZE
Директива XPAGESIZE имеет вид
%PAGESIZE rows, cols,
тде rows и cols являются числами. Интерпретация директивы % PAGESIZE определяет размер страницы листинга компиляции в rows строк (как минимум 10) и cols столбцов (как минимум 59). Если один из аргументов отсутствует, то новое значение придается только второму из них.
Пример. Определение размеров страницы
XPAGESIZE, 72
Число строк остается без изменений, число столбцов листинга равно 72.
Директивы %TITLE и %SUBTTL
Указанные директивы имеют соответственно вид %TITLE text
и
%SUBTTL text
где text является производным текстом. Интерпретация директивы % TITLE определяет text как заголовок, который будет помещен в начале каждой страницы листинга компиляции (сразу же после номера страницы), а интерпретация директивы %SUBTTL - подзаголовок каждой страницы.
Пример. Заголовок и подзаголовок
XTITLE Sort and Merge XSUBUL Sort
Директивы %LIST и %NOLIST
Указанные директивы имеют соответственно вид
%LIST
%NDLIST.
Интерпретация директивы % LIST создает файл листинга компиляции, определенный в команде вызова компилятора, а интерпретация директивы %NOLIST вызывает прекращение вывода листинга. В начале компиляции по умолчанию предлагается директива % LIST.
Пример. Выборочное создание листинга компиляции
%NOLIST
mov ах, BDATA
XLIST
mov dsr ах 箱
Исключение из листинга компиляции информации о первой из приведенных команд.
Директивы %INCL и %NOINCL
Директивы %INCL и %NOINCL имеют соответственно вид
%INCL
%NOINCL.
Интерпретация директивы %INCL вызывает включение в листинг компиляции текстов, содержащихся в файлах, включенных в директиву INCLUDE, а интерпретация директивы %NOINCL - прекращение такого включения. В начале компиляции по умолчанию предполагается директива %INCL.
Пример. Включение файлов
Интерпретация директив
%NOINCL
INCLUDE One
%INCL
INCLUDE Two
вызывает исключение из листинга компиляции содержимого файла One и включение в листинг компиляции содержимого файла Two.
Директивы %MACS и %NOMACS
Директивы % MACS и %nomacs имеют соответственно вид
% MACS
%NOMACS.
Интерпретация директивы % MACS вызывает включение в листинг компиляции также и тех директив, содержащихся в макроопределениях, которые не генерируют код. Интерпретация директивы %NOMACS вызывает прекращение дальнейшего включения таких директив в листинг компиляции. В начале компиляции по умолчанию принимается директива % NOMACS.
Пример. Исключение директив
В области действия макроопределения
Set MACRO One, Two
XNOMACS
First = One
%MACS
Second = Two
ENDM
интерпретация макровызова
Set 10, 20
не включает в листинг компиляции строки
First = 10
Директивы %CONDS и %NOCONDS
Директивы %CONDS и %NOCONDS имеют соответственно вид
%CONDS
%NOCONDS.
Интерпретация директивы %CONDS включает в листинг компиляции также и тех строк директив условной компиляции» которые не подлежали интерпретации, а директива % NOCONDS прекращает включение таких строк. В начале компиляции по умолчанию принимается директива %CONDS.
Пример. Исключение неинтерпретируемых строк
В области действия макроопределения
Move MACRO Reg. Vai
mov ax, Vai
IFIDN <Reg>, <DS>
mov ds, ax
ENDIF
ENDM
интерпретация
%NOCONDS
Mov ах. 13
не включает в листинг компиляции строку
mov ds. ах.
Директивы %CTLS и %NOCTLS
Директивы %CTLS и %NOCTLS имеют соответственно вид
%CTLS
%NOCTLS.
Интерпретация директивы %CTLS вызывает включение в листинг компиляции директив управления листингом (таких, как, например, % LIST % CON 叫 и т. д.), а директива %NOCTLS вызывает прекращение такого включения. В начале компиляции по умолчанию принимается директива %NOCTLS.
Пример
Интерпретация
%CTLS
XNOLIST
mov axr 13
XNOCTLS
XCONDS
исключает из листинга компиляции информации о директиве %CONDS.
Директивы %PUSHCTL и %POPCTL
Директивы %PUSHCTL и %popctl имеют соответственно вид
%PUSHCTL
%POPCTL.
Интерпретация директивы % PUSHCTL вызывает запоминание в локальном стеке компилятора информации о результатах использования директив, управляющих листингом компиляции (таких, например, как %LIST, % MACS, %CONDS), а директива %POPCTL сохраняет в стеке результаты использ(даания таких директив.
1$. Ассемблер'339
Пример. Использование локального стека компилятора
Если файл, включенный в базовый модуль с помощью директивы INCLUDE, имеет вид
%PUSHCTL
body
%POPCTL
где body не содержит директив %PUSHCTL, %POPCTL и INCLUDE, то включение его не вызывает замены способа генерирования листинга компиляции.
. Версии Masm и Ideal
До сих пор описание Турбо Ассемблера ограничивалось теми его конструкциями, которые в равной степени касаются компилятора MASM (Microsoft) и TASM (Borland). Однако необходимо обратить внимание, что те программисты, которые собираются пользоваться только языком ассемблер TASM, мо!ут лишиться некоторых новых интересных возможностей, проявляющихся при использовании директивы IDEAL.
Директивы IDEAL и KASM
Директивы IDEAL и MASM имеют соответственно вид
IDEAL
MASH
Интерпретация директивы IDEAL вызывает компиляцию в версии ideal, а интерпретация директивы NASH - компиляцию в версии Masm. В начале компиляции подразумевается версия Masm.
Использование ideal не требует знания новых правил программирования на ассемблере, поскольку отличия ideal от Masm минимальны. Достоинствами версии ideal являются повышение уровня контроля за достоверностью программ, исключение определенных усложненных требований версии Masm и использование более естественного состава некоторых директив.
Точечные директивы
В версии ideal нельзя использовать директивы, начинающиеся знаком . (точка), называемые здесь точечными. Каждая из них имеет свой эквивалент, начинающийся с буквы, а именно
Masm
Ideal
•MODEL .CODE .DATA .DATA?
.FARDATA- .FARDATA?
MODEL CODESEG DATASEG UDATASEG FARDATA UFARDATA
.STACKSTACK
.8086Р8086 (и аналогично другие директивы этой группы)
Пример. Программа в версии /с/еа/
IDEAL
MODEL SMALL
STACK lOOh
DATASEG
Greet DR "Hello”. '$'
CODESEG
Start:
mov ax, @Dat日
mov dsf ax
mov dx, OFFSET Greet
hjov ah, §
int 21h
mov ax, 4c00h
1nt 21h
END Start
Директива SEGMENT
В версии ideal директива SEGMENT имеет вид
SEGMENT name align combine 'class'
body
ENDS •
Пример
SEGMENT Data WORD PUBLIC 'DATA,
Fix DB 13
Arr DW 20 DUP(?)
END
Директива PROC
В версии ideal директива PROC имеет вид
PROC name dlst 〃侬 arg,…,arg RETURN? res, res, ..., res body
ENDP *
Пример
PROC Sum NEAR One, Two
push bp
mov bp. sp
mov axv One
add ax. Two
pop bp
ret
END
Директива MACRO
В версии Idea] директива MACRO имеет вид
MACRO name par, par, ..., par
body
ENDM
Пример
MACRO Sum One, Two
mov ax, [word ptr One]
add ax, [word ptr Two]
ENDM
Директива RECORD
В версии Ideal директива RECORD имеет вид
RECORD name fields field,…,field
Пример
RECORD Wordl6 Left 9Mid2:2=3, Right4:4
Директива STRUC
В версии ideal директива STRUC имеет вид
STRUC name
field field
field
ENDS
Допускается, чтобы идентификаторы полей в отдельно описанных структурах были идентичны.
Пример
В области действия описания
STRUC Pair
First DB?
Last DB 0
ENDS
STRUC Quartet
Before DW О
Mid Pair
After DW О
Last DB 2
ENDS
One Pair <2, 2>
Two Quartet <>
Struct Quartet <>
верны следующие команды:
mov al, [One, Last]
mov al. [Two.Last]
mov axr [wor(|b ptr Struct.Mid.First]
mov ah. [(Pair ptr bxJ.Last]; оператор Pair ptr
mov al, [(Quartet ptr di).Last]; оператор Quartet ptr
Директива UNION
В версии Ideal директива UNION имеет вид
UNION name
field
field
field
ENDS
Допускается, чтобы идентификаторы полей в отдельно описанных объединениях были идентичны.
Пример
В области действия описания
Union Quartet
First DW О
STRUCT Pair
Middle DB 0.0
ENDS
Last DB 5
ENDS
Uni Quartet о
верны следующие команды:
mov al. [Uni.Last]
mov ah, [Uni.Mlddle+1]
Директива EQU
В версии Ideal директива EQU имеет вид
name EQU exp. Значение выражения exp определяется только в месте обращения к пате.
Пример
В области дейсгвия следующих описаний:
Count»?
Save EQU Count
Count=3
команда
mov ax. Count
в версии ideal трактуется как команда mov ах. 3.
а в версии Nasm - как команда mov ах,2.
Сегменты и группы
В версии ideal смещение каждой переменной, входящей в состав группы, отсчитывается относительно начала группы.
В версии Masm (в результате ошибки реализации, которую не устранила фирма 4*Майкрософт**) выражение
OFFSET symbol, где symbol является именем переменной, представляет в команде mov axt OFFSET Fix смещение в сегменте, а в описании переменной^ например
Ref DW OFFSET Fix,
-смещение в группе.
Как в версии Ideal, так и в Masm в целях аннулирования принятых предположений можно пользоваться префиксами для имен группы или сегмента.
Пример
В области действия описания переменной Fix, Fix DW 13r
находящейся в группе DGROUP, команда
mov ах. OFFSET Fix.
записанная в версии Ideal, равнозначна команде
mov ах. OFFSET DGROUP:Fix,
записанной в версии Masm.
Выражения
Способ интерпретации выражений в версии Ideal несколько отличается от способа их интерпретации в версии Masm, поскольку отличаются приоритеты операторов, а именно (в очередности от высшего к низшему)
()[]LENGTH MASK OFFSET SEG SIZE WIDTH
High Low'
+ - (одноаргументное)
* / HOD SHL SHR
+ - (двухаргументное)
EQ GE GT LE LT NE
NOT
AND.
OR XOR
type PTR SHORT
В версии ideal способ интерпретации оператора SIZE иной, чем в Masm. Принимается, что
SIZE var,
гце var является именем сложной или простой переменной, выступающей после таких директив, как DB и DW, представляет размер этой переменной, а не произведение
TYPE var • LENGTH var,
как это имеет место в версии Masm.
Пример
В области действия описания
herName DB ’Isabel', 6
herAge DB 6. 'Isabel'
в версии Ideal: SIZE herName » 6. SIZE herAge « 1; в то время как в версии Masm: SIZE herName 匸 1, SIZE herAge 匸 1.
Команды
В версии ideal запрещается обращаться к переменной без заключения имени переменной в квадратные скобки. Поэтому, например, допустимая в версии Masm команда
mov ах. Fix; должна быть записана, как
mov ах. [Fix].
Кроме того, запрещается использование таких аргументов, в которых оператор [] (пара квадратных скобок) трактуется как оператор + (.плюс), а также появление префикса и оператора преобразования типа (например, BYTE PTR) перед квадратными скобками.
Пример
Приведенные ниже сравнения определяют допустимые виды команд в версии Masm и их эквиваленты в версии Ideal.
Masm
Ideal
mov ах. mov ах( mov ах. mov ах, mov ах.
[bx][si]movax([bx+sl]
es:[bx]movaxv[es:bx]
6[bx]movax,[bx+6}
es:[bp+8][si]movaxf[es:bp +si+8]
word ptr[bx]movaxB[wordptrbx}
ЧАСТЬ V- ТУРБО ОТЛАДЧИК
Отладчик
Существенным расширением возможностей, предлагаемых системой Турбо, является программа отладчика (англ, debugger).
Отладчик Турбо принадлежит к категории символьных отладчиков высокого уровня. Он позволяет, кроме прочего:
следить 最 итоговой программой;
выполнять программу в шаговом режиме (команду за командой, процедуру за процедурой или до останова};
расставлять ловушки, в том числе ловушки местные и глобальные^
выявлять значения переменных;
обозначать значения выражений, содержащих обращения к переменным базовой программы;
следить з5 приписыванием данных и вызовами процедур;
выявлять развитие инструкций ассемблера, содержимое ячеек оперативной памяти и регистров процессора и сопроцессора;
знакомиться с содержанием текстовых файлов;
регистрировать и воспроизводить последовательности нажатий клавиш (макроопределения и макровызовы);
преобразовать конфигурацию расположения окон отладчика;
использовать расширенную память, а также средства для вспомогательной отладки (дистанционное и техническое оборудование).
Вызов отладчика
Вызов отладчика имеет вид
TD opt name argst
где ор£ являются опциями, пате - именем запускаемой программы, a args - ее аргументами.
Опции могут быть указаны явно в директиве TD или приняты по умолчанию из файла конфигурации TDCONFIG. Этот файл можно создать с помощью программы установки TDINST или непосредственно при отладке (Options/Save). Файл конфигурации разыскивается последовательно: 1) в текущем каталоге; 2) в каталоге, определенном с помощью TDINST; 3) в каталоге, содержащем отладчик. Если файл конфигурации не будет найден, то будут использованы предложения по умолчанию.
Пример. Использование программы установки
Поскольку отладчик не имеет встроенного редактора, его можно указать специально. С этой целью необходимо вызвать программу TDINST, в кото-
Рис. 42. Визитная карточка отладчика.
рой послё выбора опции Options и Editor можно указать директиву системы DOS, активизирующую выбранную редакторскую программу, например
C:\UTIL\SEE.
Если после выполнения такой установки (ведущей к запоминанию в отладчике имени указанного редактора) требуется осуществление редактирования определенного файла name, то это реализуется с помощью директивы
C:\UTIL\SEE пате
и тем самым вызывается редактор.
Подготовка программы
Способ подготовки программы, которая должна быть отлажена, зависит от того, используются ли интегрированные средства либо внешние директивы.
В первом случае необходимо выполнить компиляции со следующими опциями:
Турбо Си
Debug/Source debugging On,
в。втором - выполнить компиляции с соответственно выбранной опцией.
Турбо Паскаль
Debug/Standalone debugging On
Options/Comp11er/Debug Information On
Opt 1 ons/Conip 1 ler/Loca 1 Symbols On
(последняя из указанных опций необходима только тогда, когда подразумевается символьное обращение к локальным переменным функции и процедур);
Турбо Си: -V
Турбо Паскаль: /v Турбо Ассемблер: -zi.
Если компиляции подлежит программа на языке ассемблер, то необходимо скомпоновать ее, используя компоновщик TLINK, вызванный с опцией /v. w
Поскольку условием работы отладчика является доступ к базовым модулям, необходимо обеспечить, чтобы эти жхдули находились в области действия отладчика. Имея это в виду, необходимо помнить, что файлы, содержащие базовые модули, разыскиваются последовательно: 1> в каталоге, в кото-
Run Breakpoints Data Hindow OptionsRun Breakpoints Data Hindow Options■ds: 0004 = Ш)р■ds: 0004 = Ш)рix «ио^ЪЬ!ix «ио^ЪЬ!cs:D106 cs:0107 cs:0109 cs:010C cs:D10F cs:011D cs:0112 cs:0114 cs:0116 cs:011AC5:011Bcs:D106 cs:0107 cs:0109 cs:010C cs:D10F cs:011D cs:0112 cs:0114 cs:0116 cs:011AC5:011B0000 007A04 086C00 60 QOQA 0000 0004 00066100 0600000000 007A04 086C00 60 QOQA 0000 0004 00066100 060000[si],ch bx[bxtsil, al [bp+si+04J,bhCsiLch[si],ch bx[bxtsil, al [bp+si+04J,bhCsiLchTurbo DebuggerTurbo Debuggerax hx ex dx si diax hx ex dx si di0000 00000000 00000000 00000000 00000000 00000000 0000т c-0 z=0 s:0т c-0 z=0 s:02阿:?i2阿:?iVersion 1.0Copyright <c) 1988Borland hiternationalVersion 1.0Copyright <c) 1988Borland hiternational
Run Breakpoints Data Hindow Options
Run Breakpoints Data Hindow Options
■ds: 0004 = Ш)р
■ds: 0004 = Ш)р
ix «ио^ЪЬ!
ix «ио^ЪЬ!
cs:D106 cs:0107 cs:0109 cs:010C cs:D10F cs:011D cs:0112 cs:0114 cs:0116 cs:011A
C5:011B
cs:D106 cs:0107 cs:0109 cs:010C cs:D10F cs:011D cs:0112 cs:0114 cs:0116 cs:011A
C5:011B
0000 007A04 086C00 60 QOQA 0000 0004 00066100 06
0000
0000 007A04 086C00 60 QOQA 0000 0004 00066100 06
0000
[si],ch bx
[bxtsil, al [bp+si+04J,bh
CsiLch
[si],ch bx
[bxtsil, al [bp+si+04J,bh
CsiLch
Turbo Debugger
Turbo Debugger
ax hx ex dx si di
ax hx ex dx si di
0000 0000
0000 0000
0000 0000
0000 0000
0000 0000
0000 0000
т c-0 z=0 s:0
т c-0 z=0 s:0
2阿:?i
2阿:?i
Version 1.0Copyright <c) 1988Borland hiternational
Version 1.0Copyright <c) 1988Borland hiternational
ds:0000CD2000
ss:0064 6E69 ss:0062 616D ss:008»0D00ss:0064 6E69 ss:0062 616D ss:008»0D00ds: 0008IDF0ZF01B4ОСОС00心扌田*
ss:0064 6E69 ss:0062 616D ss:008»0D00
ss:0064 6E69 ss:0062 616D ss:008»0D00
ds: 00109F4CZF02A84SBB2EfL/必中
ds: 00160101010002050БFF@的 0H
Alt: FZ-ВкрГ af j^Nod F^Artim F^User FG-tndo Й-Instr FB-Rtri F9-To ritkUcai
Рис. 43. Визитная карточка отладчика на фоне окна ЦПУ.
ром находился их компилятор; 2) в каталоге, определенном с помощью опции Optlons/Path; 3) в текущем каталоге; 4) в каталоге, из которого запускается программа.
Если базовый набор не будет найден, то отладка может происходить только на уровне команд ассемблера. В таком случае непосредственно после вызова отладчика на экране появляется окошко CPU, содержащее команды ассемблера, а не, как обычно, окошко Module, содержащее базовые инструкции.
Остается добавить, что отладчик может быть вызван также и без указания имени файла. Тогда его визитная карточка высвечивается на фоне окна CPU、 Такая визитная карточка появляется также тогда, когда запускаемая исполнительная программа не содержит информации, позволяющей осуществить отладку (поскольку, например, компоновка выполнена без опции /v).
Вниманием Поскольку отладчик является универсальной программой, приспособленной для отладки программ, написанных на разных языках программирования, то в приведенном ниже описании будет использована следующая терминология: •
-базовые модули языка Си и ассемблера9 а также библиотечные модули языка Паскаль будут называться модулями;
-функции языка Си, а также функции и процедуры языка Паскаль будут называться процедурами»
16Л. Система меню
Система меню организована иерархически. Непосредственно после вызова отладчика, а также после нажатия в произвольный момент клавиши F10 активизируется главное меню. Оно высвечивается на первой строке зкрана, всегда видно и служит для выбора промежуточных меню.
В данный момент дейсгвует, самое большое, одно меню: главное или меню, выделенное с помощью двойной обводки. Если после активизации определенного меню снова нажимается клавиша F10, то это вызывает активизацию последнего активного окна.
Каждое меню состоит из полей, содержащих опции меню. Одно из этих полей, называемое текущим^ выделяется с помощью инверсной подсветки. Для выбора опции, определенной таким полем, достаточно нажать клавишу Enter. Выбор другой опции требует изменения поля. В этих целях можно воспользоваться клавишами со стрелками или клавишами, обозначенными Ноте и End. Нажатие клавиши со стрелкой вызывает сдвиг на одну позицию, а нажатие клавиш Ноте и End - перемещение выделенного поля соответственно на первую или последнюю позиции меню. Другой способ выбора опции, кроме как с помощью клавиш со стрелками и клавиши Enier^ это нажатие произвольной клавиши, обозначенной светлой буквой поля меню.
Выбор меню, непосредственно подчиненных главному меню» может быть значительно ускорен с помощью клавиши Alt. Нажатие ее в произвольный момент вместе с первой буквой поля главного меню сразу же вызывает высвечивание подчиненного меню. Это означает, в частности, что в целях высвечивания подчиненного меню, которое зависит от поля File главного Меню, достаточно нажать клавишу Alt-F (вместо нажатия сначала клавиши F10, а затем клавиши /)♦
Рис. 45. Второстепенное (подчиненное) меню.
QuitQuitFl-Index 4-1-Select PgUp-Previous page Ctrl PgUp-First page Esc-ExitFl-Index 4-1-Select PgUp-Previous page Ctrl PgUp-First page Esc-ExitРис. 46. Справочное окно.Рис. 46. Справочное окно..h>.h>MHN.e週MHN.e週哒’/出И1蝴哒’/出И1蝴Load...Change dir...6et inf,_耳心粕■Load...Change dir...6et inf,_耳心粕■―匠 View RunBreakpoints Rata Hindow Options―匠 View RunBreakpoints Rata Hindow OptionsHun Breakpoints Data Rindow OptionsHun Breakpoints Data Rindow OptionsLoad...Change dir...Cet i吗1 ОПРУLoad...Change dir...Cet i吗1 ОПРУQuit AQuit A
Quit
Quit
Fl-Index 4-1-Select PgUp-Previous page Ctrl PgUp-First page Esc-Exit
Fl-Index 4-1-Select PgUp-Previous page Ctrl PgUp-First page Esc-Exit
Рис. 46. Справочное окно.
Рис. 46. Справочное окно.
.h>
.h>
MHN.e週
MHN.e週
哒’/出И1蝴
哒’/出И1蝴
Load...
Change dir...
6et inf,_耳心粕■
Load...
Change dir...
6et inf,_耳心粕■
―匠 View RunBreakpoints Rata Hindow Options
―匠 View RunBreakpoints Rata Hindow Options
Hun Breakpoints Data Rindow Options
Hun Breakpoints Data Rindow Options
Load...
Change dir...
Cet i吗1 ОПРУ
Load...
Change dir...
Cet i吗1 ОПРУ
Quit A
Quit A
The OS Shell command starts a DOS command processor so that you can type commands exactly as if you were at the normal DOS prompt. Mbem you have finished entering DOS commands, type "exit" to return to lurbo Debugger.
The memory occupied by your program iwy have to be swapped to disk to make room to run the DOS conmand processor. Expect a small delay al the start and end of this command if youi' program is swapped to and from the disk.
HELP I№EX
Help on Help Assembler Assembler constants Й55епЫег expressions Assembler cperatars Assembler strings Assembler variables Auto variables
Byte lists C constants C Debugging tips
•PgUp/Pqlhi
Fl-Index 4-1-Select PgUp-Previous page Ctrl PgUp-First page Esc-Exit
Phc. 47. Алфавитный указатель справочного окиа.
В случае ошибочного выбора подменю можно попасть на высший уровень меню, нажав клавишу Esc. Нажатие этой клавиши в главном меню вызывает восстановление последнего активного информационного окна. Так же как это происходит в интегрированных средах таких систем, как Турбо Паскаль и Турбо Си, если после выбора определенного поля главного меню (например, с помощью клавиши Enter или клавиши, обозначенной стрелкой, направленной вниз) будут использованы клавиши со стрелками, то это вызовет активизацию соседних подменю главного меню. Это очень облегчает локализацию важнейших функций системы меню.
Другого вида облегчением является постоянное высвечивание в нижней строчке экрана информации о важнейших функциях клавиш, а также возможность пользоваться справочными окнами.
Справочное окно высвечивается после нажатия клавиши FL Указываемые в них пояснения подбираются соответственно контексту, в котором произошло нажатие указанной клавиши. Правила перемещения между справочными ^окнами аналогичны правилам перемещения между окнами меню. В частности, нажатие клавиш PgDn и PgUp позволяет ознакомиться с текстом, не помещающимся в окне, нажатие клавиши AltrFl позволяет ознакомится с предыдущим справочным окном, а новое нажатие клавиши Fl позволяет познакомиться с алфавитным указателем справочных окон. Для возврата в место, в котором первоначально была нажата клавиша ГЦ необходимо нажать клавишу Esc.
Классификация окон
Окна отладчика можно разбить на следующие категории:
справочные окна;
окна меню - глобальные;
окна меню - локальные;
окна отладчика - информационные; ”
- окна отладчика - инспекционные.
Справочными окнами являются окна, высвечиваемые после нажатия клавиши /7.
Глобальными окнами меню являются окна, выбираемые непосредственно из главного меню (например, после нажатия клавиш F10 и V или AlhV). Они характеризуются тем, что их содержание неизменно. Служат для выбора очередных подменю и опций.
Локальными окнами меню являются окна, высвечиваемые после нажатия клавиши АН-10 или Ctrl-F 10 (или ускоренным способом нажатием клавиш Cirl-j, где / - клавиша, обозначенная выделенной буквой опции меню). Локальные окна могут быть вызваны в произвольный момент.
Информациоными окнами отладчика являются окна, выбранные из глобального меню View. Всего их 12. В момент активизации отладчика высвечиваются два из них: модульное и обзора. Инспекционными окнами отладчика являются окна, высвечиваемыме после нажатия клавиши Ctrl-L Они позволяют знакомиться со значениями переменных и выражений..
Отдельную категорию составляют окна диалога. Они появляются тогда, когда необходимо дать ответы на поставленные вопросы или произвести выбор ответа. Типичное диалоговое окно содержит показ предварительно данных ответов. Если собираются дать ответ, идентичный одному из уже данных ответов, то достаточно осуществить его выбор с помощью клавиш со стрелками, а затем нажать клавишу Enter. В момент последующего вызова
Рис 48. Глобальнее окно File.
File
Л^й Run Brea^oints
®ata Window Spti&asX^S
breakpoints
Slack
Log
Hatches
Diabies
И:用ffi聯蹈蜜資餾礴
File...
CPU
0u»p
Registers
Numeric processor
User semen AII-F5
ftrro ther
Fl-Help Ё«© Abart
三法三W法夢注三申三沁三三三::扌::匸:三::三:三:立W次芯三彩1代三三 ’笠靄發幾斐■■送課五^裝秀茨斐造塗憂逗接^主裂三三沼三次考發三亍法;三
Рис. 50. Глобальное окно Run.
Рис. 51. Глобальное окно Break.
Рис- 52. Глобальнее окио Data.
File蜿®刎Kun breakpoints Ma
^{УЩ^ Optioifts
Window pick Alt-0
Next 冲teТай
itovo/Resiae ScrLk
EloseF3
Undo close Alt-FS
^^^Ш»
Ktstcre standard
Screen repaint
攀貿齧登■繕幾■嚣密i鑫i型hМИ整鎏■藝
?三;三三W2W3WWW3三史三
:^С&^й^^5^?^Й????^?Й5
W毒就逗逗芸藝右:
Рис 53. Глобальное окно Window,
Рис. 54. Глобальное окно Options.
Fl-Help Ese-Abort
_ 1Ш_ 1Ш
_ 1Ш
_ 1Ш
File ^iew Run breakpoints甌 £aWindow Options
rflodule: MHN File: MAIM.C 5
ds:0000
П-Help Esc-Abort
#include <5ldiq. h> main(「手t
Me駿 cs:ip AssenM® … ИЛ)
cs:0200 cs:0Z01 cs:0Z04
MAIN#6: гcs:0Z05cs:0207
MAIN#?: >cs:0Z09cs:020AIOERROScs:CZ0B
тп—иии
Origin
Follow
Caller
Previous
Search
Wiew source
Mixed Ves
1
ax jprintf ex
4X,&X
МЯ№7 (0209)
如
bp
72 62
Tixrb
ds: 0008 6F ZD 43 20 ZD 20 43 6F o-C - Co ds:0010 70 79 72 69 67 68 74 20 pyright ds:0018 28 63 29 2U 31 39 38 38 (c) 1988
ах 0000
c=0
bx 04ВЕ
z二0
ex 0015
5二1
dx 3327
o-Ol
si 0033
口
di 0Ж
羅二I
bp FFD8
i二 1
sp FH)8
d=0
ds 6COS
05 6C08
55 6C0fi
cs 6АЙ2
ip 01O
ss:FM КШ 55: me ooni ss:Fm CUD SS:FFWFFE4
Рис. 56. Локальное окно II.
File View Run Breakpoints 陋 la Window Options
rffodule: TON File: RAIN.C 5———
#include
<stdi0.h>
ОП2О0一 一С
►pri
ret >
МА1НЙ51 рг1п1£(иНе11о from ®ebuggern);
C5:01W^9401mov •ax,0194
C£:0^OO 50pugbax
cszOZOl E8BB08caUjprintf
&x 0000 bx 0Ш ex 0015 dx 3327
c=0 z=0
5=1 0印
1;
pop ©х
si 0033 di 04BZ bp"晓 sp跟佣 ds 6C08 es 6C08 ss 6C08 cs 6ADZ ip 01F9
P=1 a: 1 1=1 dzO
~1
謊諸醤7 <0209)
pot Ьр
г®1
испеки,'
'Becrement
Zero
Change
Registers 32-bit No
ds 6C98 es 6C08 ss BCOS cs Ш2 ip Й1ГВ
j^wtsh bp
0 00 54 75 ?2 62 Turb 3 20 2D го 43 6F о-С - Со 2 69 67 £8 74 20 pyright
9 Z0 31 39 38 38 (с> 1988
55: FFWE FFE2 5s:FFPC 0001 55: rm DUD 55:ПШПЕ4
Fl-Help Ё5С-ДЪог1
tethertether$!a£s蹤s・$!a£s蹤s・?1-Help It-PJpv» f^-Selest Letters-'Natch Es^-AboH?1-Help It-PJpv» f^-Selest Letters-'Natch Es^-AboHfiinc mainfiinc mainFiie... Ш 恥哽 Registers Numeric processor User screen Alt~F5Fiie... Ш 恥哽 Registers Numeric processor User screen Alt~F5用® 阪歯 Ruirt Brealkpoints Data Hindoo Options用® 阪歯 Ruirt Brealkpoints Data Hindoo OptionsРис. 58. Диалоговое окно I.Рис. 58. Диалоговое окно I.Pick a module1ЖШШPick a module1ЖШШ
tether
tether
$!a£s蹤s・
$!a£s蹤s・
?1-Help It-PJpv» f^-Selest Letters-'Natch Es^-AboH
?1-Help It-PJpv» f^-Selest Letters-'Natch Es^-AboH
fiinc main
fiinc main
Fiie... Ш 恥哽 Registers Numeric processor User screen Alt~F5
Fiie... Ш 恥哽 Registers Numeric processor User screen Alt~F5
用® 阪歯 Ruirt Brealkpoints Data Hindoo Options
用® 阪歯 Ruirt Brealkpoints Data Hindoo Options
Рис. 58. Диалоговое окно I.
Рис. 58. Диалоговое окно I.
Pick a module1
ЖШШ
Pick a module1
ЖШШ
Breakpoints Stack Log Hatches Variables
диалогового окна, отвечающего данному кош'ексту, выбранный таким образом ответ окажется наверху подобранных ответов.
Перелдещение окон
Перед обсуждением функций информационных и инспекционных окон отладчика необходимо указать их существенную особенность. Каждое окно отладчика может свободно перемещаться по экрану, а его размер - произвольно модифицироваться.
В целях выполнения таких перемещений и изменений необходимо сначала нажать клавишу ScrollLock^ а затем воспользоваться клавишами со стрелками. Как можно убедиться, нажатие клавиш со стрелкой вызывает перемещение края окна, а нажатие этой клавиши одновременно с клавишей Shift - изменение размера окна.
Это изменение происходит таким образом, что левый верхний угол окна остается неподвихеным, а в соответствии с используемыми клавишами перемещаются его правый и нижний края. После выполнения требуемых изменений необходимо снова нажать клавишу ScrollLock. Это вызывает переткхеяае текста б измененное окно.
Внглмание; Аналогичные операции могут быть выполнены на справочных окнах. Окна меню могут только перемещаться.
Рис. 59. Диалоговое окно П.
ИЗ閱 unBreakpoints Ша
Breakpoints
Stack
Log
Hatches
Variables
Module..,A11-F3
File..・
CPU
曲吗
Registers
Numeric processor
User screen A11-F5
I目發ti解》窈昧I
Dwap File...
Hindow
Options
*ick a module-
Fl-Help It-Hove ^-Select Letiers-Match Esc-Abort
Рис. 60. Диалоговое окно Ш.
Рис. 61. Окно перед сдвигом.
1ЙЗ"證二痴t al fO©3 Й-ДЫ w ft-User F6-U«do V?~iwsi г ЙС Rt n ^F^ о Fib -Local
?ile View Kun Brealtpoiw^s &ata Window Options32ЫЗ
Sif?W-^pV dt f^йй Ждп1^
Информационные окна
Информационные окна вызываются на экран из глобального меню View. Каждое из них снабжено одним из следующих названий:
Breakpoints
Stack
Log
Watches
Variables
Module
File
CPU
Dump
Registers
Numeric processor
User Screen
а также порядковым номером, высвечиваемым в правом верхнем углу. В данный момент активировано как минимум одно из информационных окон.
Чтобы убрать информационное окно с экрана, необходимо воспользоваться опцией Window/Close (клавиша F3). Эта акция, называемая в дальнейшем закрытием окна, может быть аннулирована с помощью опции Window/Undo Close (клавиши AU-F6}. Если произойдет закрытие окна, после чего не появится ни одно другое окно, то это означает фон окон.
Существует три вида окон: окно модулей (Module), файлов (File) и процессора (CPU). Они могут появляться многократно. Это позволяет, например, знакомиться с текстом, содержащимся в разных базовых файлах. Эту дополнительную особенность отладчика можно использовать, выбирая опцию View/ Another.
Перемещение между информационными окнами (например, между несколькими модульными окнами) обеспечивает клавиша F6. Кроме того, окна могут выбираться на основе их номеров. В частности, в целях активизации окна с номером i достаточно нажать клавишу Alt~L Если будет нажата клавиша Alt-O, то появится диалоговое окно, содержащее перечень всех открытых окон. После выбора одного из приведенных методов выбранное окно становится активным.
Некоторые окна поделены на рамки. Перемещение между ними в направлении движения часовой стрелки обеспечивает клавиша Tab, а перемещение в противоположном направлении обеспечивает клавиша Shift-Tab. В данный момент активна только одна рамка. Именно та, в которой находится мигающий курсор, или с выделенным заголовком. Во втором случае перемещение между пол5и^и рамки может происходить не только с помощью клавишей со стрелками, PgUp, PgDn и т.д., но также путем выбора заданной последовательности символов записи. Такой способ выбора полей особенно удобен в случаях с документами, подобранными по алфавиту, позволяя быстро перемещаться курсору к слову, начинающемуся рядом введенных букв.
В области каждой рамки с целью высвечивания локального меню, относящегося к данному контексту, можно воспользоваться клавишей Alt-FlO или Ctrl-FlO. Во многих случаях достато^о ограничиться нажатием клавиши Enter, обеспечивающей ускоренный выбор необходимой в данном контексте опции локального меню. Желательно также ознакомиться с реакцией отладчика на начало записи в области каждой из рамок.
Окно модулей
В окне модулей (Module Window) высвечивается основной текст запускаемой программы. Перемещение по этому тексту позволяет выделить выбранные идентификаторы переменных, а также выражений, расставить ловушки и выдать поручения для способа дальнейшего выполнения программы.
Alt; F2-E&pt at F3-lfod F@Anim 將-User F'E-Undo F7-Iwstr 阳-Rt說 F%To ".©-Lo総斜 1
Рис. 65. Фон окон.
—11—11
—11
—11
File Q 设时 Run Br^akpoiiuts Data Mir»dow DptioKS 曲Ade:m紅* Шe:唯爲.e 3-
■Kcluda <stflio.h> inainO
рглпИГ(01Нг11о Рг«мп debugger");
retum 0;Module: МММ M& 帆КС 3・
ttinciu^e《sULio/O
prMf(nHelJ.6 fNjn Mtmgg^r");
return 6;
函砾Й因鎖瞋囑縊MB應L™x4
ftinelude <stdio.Ю
В ffiainO
prin€f<**Hello from Debugg&「);
Feliirn 0;二.
ЖГЖй^ГаГВ-КТЖш^^
Рис. 66. Многократное окно.
Окно обзора (наблюдений)
В окне наблюдений (Watches Window) высвечиваются имена и значения переменных. Самым простым способом размещения имени переменной в окне наблюдений является перемещение курсора к идентификатору переменной, а затем нажатие клавиши CtrbW. В рассматриваемом окне могут высвечиваться также выражения и значения выражений. С целью размещения в окне наблюдений определенного выражения (в частности, имени переменной) необходимо выделить его с помощью клавиши Ins и клавиши со стрелками, а затем нажать клавишу Ctrl~W.
Окно ловушек
В окне ловушек (Breakpoints Window высвечиваются действующие ловушки программы. В левой рамке окна находится список расставленных ловушек, а в правой описание ловушки, выделенной курсором. Перемещение курсора в области р/мкм вызывает высвечивание информации об очередных ловушках. С помощью локального меню можно модифицировать, удалять и добавлять ловушки. Удобным способом установки простой ловушки является перемещение курсора в модульное окно, а затем нажатие клавиши F2.
Окно ВЫЗОВОВ
В окне вызовов (Stack Window высвечиваются имена активных процедур.
В целях получения дополнительной информации об этих процедурах необходимо (после перемещения курсора в области рамки) вызвать локальное меню или инспекционное окно. Этим способом можно, например, познакомиться с локальными переменными вызванной процедуры, а также с аргументами и местом вызова данной процедуры.
Окно сообщений
В окне сообщений {Log Window высвечивается информация, зарегистрированная во время останова программы: значения выражений, выбранных в момент, когда программа попала в ловушку; содержимое произвольно выбранных рамок, а также направленные в него комментарии. Если в окне сообщений выводится более чем 50 строк, то первые строки будут утеряны. В целях сохранения всех строк, посланных в окно сообщений, можно их записать в файл.
Окно переменных
В окне переменных (Variables Window^ высвечиваются идентификаторы переменных, доступные в месте останова программы. В левой рамке окна находится перечень общих переменных (доступных вне модуля), а в правой - список переменных, доступных только в модуле или в области его процедур. С каждым идентификатором переменной связана информация о типе переменной и ее значении. Если переменная является структурной, то можно познакомиться с ее компонентами, вызывая локальное меню или инспекционное окно. Подобным способом можно познакомиться' с переменными указательного типа.
File View Run Brepkp>.inls Data Mindow Options
> maimO
ini Fix = 12; void Inctint *);
Iv№(&Fix); prinl£<"xd". Fix); return 0;
void Inc(int «Рат) {
(1Фаг)++; 卜
rttalches
2-
FZ-Bkpt F3-Close 雨-Here F5-Zoom F&-Mext F7-Trace F8-§tep F9-Run FlC-Мегш
Рис. 67. Окно модулей.
File View Run Breafcpoinls Data Window Options2 寸串 W
rftodule: PAIR File: PAIR.C (modKied) 7—1-.
fiinclude <stdio. Ъ> fnainO
iM Fix = 12,
void 1пс(Ш »);
В Inct&Fix); print£(И>Й", Fix); return 0;
void Inctint 通ar)
(1Фаг)+*;
F2-Bkpl F3-C105® F4-H®r* FS-Zcwm FG-Nexl F7-Trace FS-Sl«p F9-Run FIO-Nenu
File View Run Brealqpoinis Data Window OptionsjK№
rWodule: FAHR File: PAIR.C (modified) 141
■include <stdio, h> mahK)
ini Fix = 12;
Hatches—2
Fix2???
Parimt * ds: FFD6
FZ-Bkpt F3-Close F4-Here F5-2oom F&-Nexl F7-Trace F8-Step F9-Run FlO-Menu
Окно файлов
В окне файлов {File Window высвечиваются данные, содержащиеся в дисковых файлахо Предусмотренн также средства, позволяющие высвечивать данные в виде текстов и шестнадцатеричном виде, а также производить модификаи^ию файлов. Осущеспэляется это с помощью локального меню.
Окно процессора
В окне процессора (CPU Window высвечиваются данные о текущем состоянии процессора. Окно процессора состоит из 5 рамок, в которых находятся: код ассемблера команд программы, данные выбранной области памяти в символьном и шестнадцатерич!юм виде, содержимое регистров процессора, содержимое стека процессора, а также биты регистра флажков» В верхней строке окна указан тип процессора. Знак, имеющий вид стилизованной стрелки, направленной вправо, выделяет команду, которая будет выполнена следующей. В верхней строке рамки, содержащей команды, указываются адрес памяти и значения величины, находящейся по этому адресу.
Окно памяти
В окне оперативной памяти {Dump Window) высвечиваются данные, содержащиеся в выбранной области оперативкой памяти. Эти данные могут быть представлены в шестнадцатеричном виде, в виде символов, слов и двух слов, а также как числа в различных представлениях. Использование локального меню позволяет модифицировать даяиые и перемещать блоки памяти.
Окно регистров
В окне регистров (Registers Winded высвечивается содержимое регистров процессора» Использование локального меню позволяет модифицировать содержимое регистров.
Окно сопроцессора
В окне сопроцессора {Numeric Processor Window) высвечивается содержимое регистров сопроцессора. Окно сопроцессора состоит из трех рамок, в которых находятся: содержимое регистров сопроцессора, содержимое регистра флажков сопроцессора и управляющие данные.
Выходное окно
В выходном окне {User Screen Window высвечивается выходной экран программы» Он точно такой же, как будто активизация программы произошла в системе DOS. В целях ускоренного высвечивания этого окна можно воспользоваться клавишей A*F5. После знакомства с экраном выхода можно высветить экран отладчика, нажав произвольную клавишу клавиатуры.
Инспек1(монны« окна
Инспекционные окна служат для высвечивания информации о переменных и выражениях. Они вызываются на экран нажатием клавиши Ctrl". Эту
File眼®明 Run Sreafepoinls ®ata Window Options
[Module: PAIR Ше: РА1Й.С (modified) 8
^include (stdio<h> maiH()
void ЙStopped al _roain Breattpoint at PMR814 Inc(SSStoppetl at „main 卜 print|Bre&i|M)int at PAIRSS
我£联
void Incfint War)
——*^司
1
(町 ar 〃+;
Ali: Р2-Ш(р1 at 蕊-№d F4^nim F5-User FS-Undo !T?-Iustr F8-Rtn F9-To FlO-Lecal
Рис. 71. Окно сообщений.
File Wiew 段 g Breafepoints Bal® 嘅畑&ж 廳)ti⑪睢
励甌1父 PAIR Ше: PAIR. С (ffiodi£i®d) 8-
寵眦hide <э1й1ОеЮ mainC
:ШИ
ini Fix = 1Z; void ®1№^Ш
I«c(&
В print relui"
(маT跟
Jnc 二8时7 ___ттм 二[<О№ ―I МО Vector ―Int4Veclor —InlSVector
63: 0Ш ???? ???? ???? ???? ????
岷况『?-毀域& al『军飴或開f戒港Z“*er躅-U而◎ F^-Iwstr F8-Rtn F9-To FlO-Local
Рис. 72. Окно переменных.
FZ-Bfept IF3-Ciose 『眾Here F5-Zooro Fg-Next F7-Trace F8-Step F9-Run FIMenuFZ-Bfept IF3-Ciose 『眾Here F5-Zooro Fg-Next F7-Trace F8-Step F9-Run FIMenuРис. 73. Окно файлов.Рис. 73. Окно файлов.
FZ-Bfept IF3-Ciose 『眾Here F5-Zooro Fg-Next F7-Trace F8-Step F9-Run FIMenu
FZ-Bfept IF3-Ciose 『眾Here F5-Zooro Fg-Next F7-Trace F8-Step F9-Run FIMenu
Рис. 73. Окно файлов.
Рис. 73. Окно файлов.
File Uiex Run B^alqwiTjls gla Hindow @jplions
■Module: PAIR File: FAIR.C (modi£ied> 8 打include <stdio,h>
> mainO
File View Run
Breakpoints EJata Mindow Options泄呼
тюате. min глле;
#include <stdio.h> maiwO
гмхло v ktnuuxK леи? /—
0 -f3: ms =询崎——
(^="*3
int Fj
Wl Й
皿HE二「」丿丁二之二—
ах 0000
c-0
void 1
В Inc(& print retur }
void In
cs: 0205》8D46FElea ax」hp-02]
cs:0Z08 50pu#ax
cs:0Z0S E81500callJnc
cs:U20C 59popex
PAIR#8: prKmtf《"笈Г, Fix);
cs:020D F076FEpush[hp-OZJ
cs:0210 B89401movax,8194
c£:0ZI3 50pushax
cs:0Z14 E8CSOScall_prinW
cs:0217 59popex
cs:0218 59popex
PAIK#9: return 0;
bx ОШ ex 0014 dx 9D64 si 0033 di 04Az bp PFD8 sp FFB6 ds 5BBB es 5BBB ss 5BBB cs 5Л83 ip 0Z05
z二0 5=1 o=0 产0 a=0
1二1 d=0
ds:0000 ds:0008
00 00 08 00 54 75 7Z 6Z Тигй
6F 2D 43 20 幼 2S 43 6F о-С - Со
55:FFDC 8001 $s:EFDA 011» ss: FFD8 FFE4 ss:FH)6>080C
F9-Run FIO-Menu
«latches—в asiuuiu /и /з tt ьа ь/ ъи 收 си pyrign^
I ds:0818 Z8 63 29 20 31 39 38 38 (с) 1988
?2~Bkpt F3-Close Ffl-Here F5-Zoom F6-Next F7-Trace FS-Stei
File View Run Sre^points Data Window Option?班
rModule: PAIR File: FAIR.C (raodHied) 7 fiinclude <stdie. b> maimC {
int Fix 二 12;
void Incdnl *);
》Inc<iFix);
priwULZA", Fix);
гс.иг『б1?。—■—‘■ —・…———^—i.Y
》 I ds:0000 00 00 00 00 54 75 72 6Z Turb
Ids.:0088fiFZD4320ZD20436Fo-C - Cd
void InSds:00107D797269E7687420pyrighl
4 Sds:00182863292031393838(c) 2988
《减 ar^»B3'"ekE'*— —I —……,,“”,,,・>■,“f 追
Рис. 75. Окно памяти.
FZ-恥pt F3~Close F^Here JFS-Zoom F6-Me>d 门-Ткасе F8-Slep F9-Run FlO-Menu
File Vies Run Breakpoints
Module: PAIR File: PAIR.C T]爰磐
■iuclude <stdio.h>房通
main():您:茨
int Fix = 12;熒薫
void Iuc(£nt *);気:矮
lnc(&fix);<?:?:<
prinUC'Zd", Fix);差莓
return 0 ;:幾
Rata隗 nd。”Options
2ЩЩ
void Inc<int 冲ar)
»(War)*^;
週 E 4©зл^юовш®34 喻皿:^嚣北嚣関 oo OAOOFF5555O X X X i -1 p pk- s 5 s V 尊 b cdsdb sd e s ci
R-BKpt F3-CloseR-BKpt F3-Close
R-BKpt F3-Close
R-BKpt F3-Close
F5-Zoom ^Nexl П-Тгасё Wstep F9-Riin H®-Menu
#inclu4e <stdic.h>#inclu4e <stdic.h>-ds: 0194 二 0000-ds: 0194 二 0000float, Hfloat, HmainOmainOFLOAT*»: printfC'zr,財imber .FLOAT*»: printfC'zr,財imber .пгпжогппютпгпжогппютiem-0iem-0ds: 0018 28 63 ZS 20 31 39 38 38 (B 1988ds: 0018 28 63 ZS 20 31 39 38 38 (B 1988F2-Bkpt FS-Close F4-Here FS-Zoois 氏昵熊 F7-Irace F8-Step F9-Run FI& MenuF2-Bkpt FS-Close F4-Here FS-Zoois 氏昵熊 F7-Irace F8-Step F9-Run FI& MenuA83202A83202(PU 80286 jDain: nain<)-cs:01FA 55cs:01FB 8BEC(PU 80286 jDain: nain<)-cs:01FA 55cs:01FB 8BECprint returprint returpush movpush movcs:01F» CD35069削 1 cs:0Z0Z>CD35069401cs:0207 CD3AC1cs:01F» CD35069削 1 cs:0Z0Z>CD35069401cs:0207 CD3AC1fid fid faddfid fid faddEmpty ST(l)|Empty ST(2)Empty ST(l)|Empty ST(2)File View Run Breakpoints Data Hindow Options rfiiidule: FLOAT File: FLOAT. C (modified) 8:File View Run Breakpoints Data Hindow Options rfiiidule: FLOAT File: FLOAT. C (modified) 8:Рис. 77. Окно сопроцессора.Рис. 77. Окно сопроцессора.ST(3) Si(4) STC5) ST® ST(7)ST(3) Si(4) STC5) ST® ST(7)
#inclu4e <stdic.h>
#inclu4e <stdic.h>
-ds: 0194 二 0000
-ds: 0194 二 0000
float, H
float, H
mainO
mainO
FLOAT*»: printfC'zr,財imber .
FLOAT*»: printfC'zr,財imber .
пгпжогппют
пгпжогппют
iem-0
iem-0
ds: 0018 28 63 ZS 20 31 39 38 38 (B 1988
ds: 0018 28 63 ZS 20 31 39 38 38 (B 1988
F2-Bkpt FS-Close F4-Here FS-Zoois 氏昵熊 F7-Irace F8-Step F9-Run FI& Menu
F2-Bkpt FS-Close F4-Here FS-Zoois 氏昵熊 F7-Irace F8-Step F9-Run FI& Menu
A83
202
A83
202
(PU 80286 jDain: nain<)
-cs:01FA 55
cs:01FB 8BEC
(PU 80286 jDain: nain<)
-cs:01FA 55
cs:01FB 8BEC
print retur
print retur
push mov
push mov
cs:01F» CD35069削 1 cs:0Z0Z>CD35069401
cs:0207 CD3AC1
cs:01F» CD35069削 1 cs:0Z0Z>CD35069401
cs:0207 CD3AC1
fid fid fadd
fid fid fadd
Empty ST(l)
|Empty ST(2)
Empty ST(l)
|Empty ST(2)
File View Run Breakpoints Data Hindow Options rfiiidule: FLOAT File: FLOAT. C (modified) 8:
File View Run Breakpoints Data Hindow Options rfiiidule: FLOAT File: FLOAT. C (modified) 8:
Рис. 77. Окно сопроцессора.
Рис. 77. Окно сопроцессора.
ST(3) Si(4) STC5) ST® ST(7)
ST(3) Si(4) STC5) ST® ST(7)
bp bp,sp Number); dHord ptrf _Mu dword ptrf _Ku st(l),st
0000 0634 0014 ВБ74 D033 06Z8 FFD6
『时FFEtt m oooi ПЖ 011» ssSFFDSHFEZ
C:\TC20X»UMPS>tc
27.000000
C:\TC20\DUMPSXtd float
Turbo Debugger Version 1.0 Copyright (c) 1988 Borland Inteniational
Z7.0000D0
клавишу необходимо нажимать, когда курсор выделяет идентификатор переменной или когда после нажатия клавиши Ins и клавиши стрелок выделен определенный блок знаков, образующих выражение. Инспекционное окно не делится на рамки, но состоит из полей, содержащих, кроме прочего, имя переменной, ее тип, адрес, значение переменной и т. д. Если переменная является структурной, то в окне высвечиваются ее компоненты, если указательной - то высвечивается информация об указываемой переменной. Подобный способ высвечивания информации откосится и к выражениям.
Перемещение между полями инспекционного окна происходит с помощью клавиши вертикальных стрелок. Если после выбора определенного поля будет снова нажата клавиша Ctrl-I9 то появится инспекционное окно, касающееся выбранного компонента переменной. Очередное иажатие этой клавиши позволяет выполнить проверку компонентов более низкого уровня.
Ниже приведены примеры инспекционных окон для программ на языках Турбо Си и Турбо Паскаль.
Турбо Си
typedef
struct {
unsigned Age;
cha 風 ajng[§];
} Person, * RefPerson;
float Number = 12.4;
1nt Fixed н 13;
unsigned char Arr[2] [2]匸{{1, 2},《3. 4}};
Person Rec = {5, ”Isa'°};
char *Str « "Isabel*;
Person People [ *c₽ - *a* + 1] »
{ {4Q. ”Е4],
{ 60 "Isa"}, {46, "Jan"}};
Person *Ptr;
RefPerson *RefPtr;
Int *Ref irain() {
Ptr »: &Rec;
RefPtr * &Ptr;
Ref н &F1xed;
Турбо Паскаль
type
Person 匸 record
Age : word.
Name : String [5] end;
RefPerson »= Person;
const
Number : real = 12.4;
Fixed : integer = 13;
Arr : array [1 .・ 2, boolean] of byte »
Г(Ъ2), (3,4));
Rec : Person = (Age : 5; Name : *Isa*);
Str : string = 'Isabel';
People : array「a' ... c'] of Person 工
((Age : 40; Mame : *Evae)»
(Age : 6; Name : 'Isa*).
(Age : 46; Name : *Jan,));
war
Ptr : "Person;
RefPtr : ^RefPerson;
Ref : *integer;
begin
Ptr := @ Rec;
RefPtr :工 @ Ptr;
Ref :* @ Fixed;
{…}
end.
Для того чтобы убрать с экрана последнее созданное инспекционное окно, необходимо нажать клавишу ESC. Нажатие клавиши F3 вызывает закрытие всех таких окон.
Как и другие окна, инспекционное окно имеет свое локальное меню.
Оно состоит из следующих полей:
\ Range
.Change
Inspect
Descend
Nfew expression...
Поле Range
Выбор поля Range позволяет опреденить размер высвеченных компонентов структурной переменной. Этот размер состоит из указания первого компонента и числа компонентов. Это особенно удобно в случае таблиц.
Поле Change
Выбор поля Change позволяет изменить значение переменной.
Поле Inspect
Выбор поля Inspect имеет такой же результат, как нажатие клавиши Ctrl-I; кроме того, вызывает открытие очередного инспекционного окна. Это позволяет углубиться в структуру массивов и записей, просматривать цепочку указаний и выявить развитие команд ассемблера.
File View Run BreakpointsOat aWindow Options艰ES
rWodule: INSPECT File: IHSPECT.C 6—1
typedef
struct^
unsigned Age; char Name(5J ; } Person,*RefPerson; float Number 二 1Z.4; int Fix unsigw Person char *S
Person People】'c' - ' a' + 1J 二
(《40, "Eva* }f « 6, "IsaM }, < 46. "Jan"》>; Person *Ptr; RefPerson *RefPtr; int *Ref; mai»C
FZ-Ekpt F3-Clffse F4-Here F5-Zoan F6-№xt F7-Trace Fe-S€ep F^-Run FlO-MenwFZ-Ekpt F3-Clffse F4-Here F5-Zoan F6-№xt F7-Trace Fe-S€ep F^-Run FlO-Menw
FZ-Ekpt F3-Clffse F4-Here F5-Zoan F6-№xt F7-Trace Fe-S€ep F^-Run FlO-Menw
FZ-Ekpt F3-Clffse F4-Here F5-Zoan F6-№xt F7-Trace Fe-S€ep F^-Run FlO-Menw
File View Run Breakpoints* Data Hindow OptionsY 孤就
Module: PROGRAM File: INSPECT. PAS 8—~1
亜
Person - record
Age : word;
Name : string】5】 end; RefPerson 二 APerson; const Number : real - 1Z.4; Fixed : integer 二 13; Arr : array [1. .2,boolean】 of byle 二 ((1,Z), (3,4> >;
Rec : Person 二(Age : 5; Name : 'Isa');
Str : string - 'Isabel';
People : array 【'a'..'c'} of Person 二
((Age : 40; Name : 'Eva'》. (Age : 6; Name : * Isa* >, (Age : 46: Name : * Jan*));
F2-Bkpt F3-Close F4-Here FAZoom F6-Next Г7~Тгасе F8-Step F9-Run F1Q-Me«iu
File Wie* Run Breakpoints Data Hinds』 Options底曲
rflodule: INSPECT File: INSPECT. C 71'
1урейе£ struct^ unsigned Age: char NasieLS];
《6, "Isa'* h
< 46, “Ja/ ),;
Person *Ptr;
Ref Person 疝ef Pt11s
int *Ref;
mainO
Alt: F2-Bl(pt at F3-Mod F4-Anim FE-User F6-Und。F7-Instr F8-Rtn F9-T。FlO-Local
File View Run Breakpoints Mra Hindow Options
<1odule: PROGRAM File: INSPECT. PAS' 9
type
1^—111^—11Person 二 recordPerson 二 recordfill: F2-Bkpt at F3-Wod F4-Amro F&<User FS-Undo "-Instr F8-Rtn F%Ko FIO-Localfill: F2-Bkpt at F3-Wod F4-Amro F&<User FS-Undo "-Instr F8-Rtn F%Ko FIO-LocalAge : Hord;
1^
—11
1^
—11
Person 二 record
Person 二 record
fill: F2-Bkpt at F3-Wod F4-Amro F&<User FS-Undo "-Instr F8-Rtn F%Ko FIO-Local
fill: F2-Bkpt at F3-Wod F4-Amro F&<User FS-Undo "-Instr F8-Rtn F%Ko FIO-Local
Name : stringl 53 end;
RefPerson - APerson; const
Nffifther : real 二 1Z. 4;
Fixed : integer 二 13;
Агг : array П.. 2,boolean] of byte = ((1,2), (3,4) >;
Йес : Person 二(Age : 5; Name : '“*);
$tr : string 二'Isabel' ;•
People : array「a' —' c' J of Person 二
((Age : 40; Mame : * Eva*), (Age : 6; Name : rIsa*), (Age : 46; Name : * Jan*));
6)
File View Run Breakpoints Data Window Options
Hlodule: INSPECT File:工MSPECT.C 8 typedef structt unsigned Aqe; char NawetS];
> Person, i^efPerson!
flcat Number 二 12.4;
int Fixed 二 13;
unsigned char ArHZHQ 二 f 口,办,《3.4} };
Person Rec 二{屮用由也$*Т[У":Н二■1?
char *Str 二"Is
Person Peoplefz ।
5С04: (ЮЗА
{ { 4。EL
{ 8
Person *Ptr;
unsigned char ⑵
>хСЗ\:
F2-Bkpt F3*Close F4-Here F5-Zoom F6~Next F7-Trace F8-Step F3-Run F10-帷nu
RefPerson *RefPtr: i:it *旣f; mainO
File View Run Breakpoints
Module: PRMRAPI File: INSPECT. PAS type
Person 二 record
Age : word;
Name : slring[5]
end;
RefPerson 二 ^Person;
const
Number : real 二 12.4;*
Data Window Options
10
6)
Fixed
Агг :
Rec
Str
:integer 二 13;工~
array tl.. Z,boolean] of byte 二
(<1,Z>, (3,4> >;
Person 二(Age : 5; Name : 'Isa'); string = 'Isabel';
(1,Z)
MRAY [BOOLEAN] OF BYTE
Mam唾Ki庇
₽5B81:0008 tl]
flit: F2-Bkpt at Fl-Mod F4-Anim F5-User F6-Undo "-Instr F8-Rtn F%To F10-Local
Person 二 :'Eva'), :'Isa'》, :'Jan'》>;
People : array fJ a*,, * c* J of ((Age:40;Name
《Age”6;Name
(Age:46;Name
File View\ Run Breakpoints Data Window Options rflodule: INSPECK File: INSPECT. C 8:
lypedef\
slructl '
unsigned Age;
char НадаГ 53;
> Person^ *Re£Person;
float Nwftber = 12.4;
int Fixed 二 23;
unsigmed char ArrtZHZl 二 < U,Z3, <3,4} };
Person Rec 二 < j char «Str 二 BIs I Person People? * I 《《40 { £ < 46
Person *Ptr;
RefPerson *RefPt iut欢或; mainC)
Inspecting Дгг- @5C04: 009A 切
“、xOi、xOZ"
翡蘭p*c,nq»Ai'T 1&】5^2SJ .АЙМ:期耻副童,;Щ丁
[01 【口
‘'刘1‘ 1
'\xO2' 2
unsigned cliar 121
FZ-Bkpt ГЗ-Close М-Here F5-Zootn F6-Next "Face 回-Slep F3-Run FlQ-Menu
Inspecting Arr395B81:0008[1](1,2}咆(3,4)一4P5B81:V00[总1些1fInspecting Arr395B81:0008[1](1,2}咆(3,4)一4P5B81:V00[总1些1ffTrtwlfTrtwlBYTEBYTE
Inspecting Arr3
95B81:0008
[1](1,2}
咆(3,4)
一4
P5B81:V00
[总1些1f
Inspecting Arr3
95B81:0008
[1](1,2}
咆(3,4)
一4
P5B81:V00
[总1些1f
fTrtwl
fTrtwl
BYTE
BYTE
File View Nun Breakpoints Bata Window OptionsU 融必
(*!edule: PROGRAM File: INSPECT. PAS 10—— type
Ferscn 二 record
Age : «ord;
Name : string^5) end;
RefPerson - APerson; const
Munber : real 二 12.4;
Fixed : integer 二 13;
Arr : array £1.. 2/boolean] of byte 二 ((1,2), (3,4));
Rec : Person = (Age : 5: Name : * Isa*
Str : string 二'Isabel';
People Г array E'a'.Jc'」of Person 二
((Age : 40; Name : 'Eva'〉. (Age : 6: Name : Чеа* >, (Age : 46; Name : 'JarO ); var
6>
FZ-Bkpt F3-Close F4-Here F5-Zoom F6-Next F7-Trace F8-Step F3-R«n FIO-Memt
7W-7W-File Uie& Run Breakpoints Data Window Options
7W
-
7W
-
Wofiule: INSPECT File: INSPECT. C 9 typedef struct!
unsigned Age;
char Mamet 51;
> Person, «JtefPerson;
float Number 二 1Z.4;
int Fixed 二 13;
unsigned char ArrtZJ[21 二《《1/}, <3,4> };
Person Rec =《5,"Isa"):
Alt: FZ-Ek;t at ГЗ-Mod F4-Anim F5-User F6-Undo F7-Inslr F8-REn FS-To F10-LocalAlt: FZ-Ek;t at ГЗ-Mod F4-Anim F5-User F6-Undo F7-Inslr F8-REn FS-To F10-Local
Alt: FZ-Ek;t at ГЗ-Mod F4-Anim F5-User F6-Undo F7-Inslr F8-REn FS-To F10-Local
Alt: FZ-Ek;t at ГЗ-Mod F4-Anim F5-User F6-Undo F7-Inslr F8-REn FS-To F10-Local
int *Ref; main《)
2ЖШ2ЖШbyte 二:Ts*);Person 二 :'£va'>, :'H£>, :’Jan'));byte 二:Ts*);Person 二 :'£va'>, :'H£>, :’Jan'));
2ЖШ
2ЖШ
byte 二
:Ts*);
Person 二 :'£va'>, :'H£>, :’Jan'));
byte 二
:Ts*);
Person 二 :'£va'>, :'H£>, :’Jan'));
File View Run Breakpoints Data HitHow Options [Module: PROGRAM File: INSPECT. PAS 12—
type
Person = record 的e : word;
Wane : string】51 end;
RefPerson 二 APerson;
const
Number : real 二 iZ.4;
Fixed : integer 二 13;
Ait : array tl. .2,boolean] of (<LZ),《3,4));
Rec : Person 二(Age : 5; Name Str : string 二'Isabel/;, People : array「*・.'/] of ((Age : 40; Name (Age : 6; Name (如已:46; Name
6)F2-Bkpt FAC1O5© F4-Here F5-Zoom F6~Hext F^-Trace F8-Step F9-»un FlO-Menu
Person РеPerson РеC5C04:UG9EC5C04:UG9EFZ-Ekpt F3-Close M-Неге F5-Zoom F6-Ki*xi» & 二 Yrace F8-Step F9-Run FID-MenuFZ-Ekpt F3-Close M-Неге F5-Zoom F6-Ki*xi» & 二 Yrace F8-Step F9-Run FID-Menu也】$回我tl屮也】$回我tl屮睜ectiig X/)5加加M睜ectiig X/)5加加MPeople : array「八 J с* I of ((Age : 40; Nans? (Age : 6; Name (Age : 46; NamePeople : array「八 J с* I of ((Age : 40; Nans? (Age : 6; Name (Age : 46; NameFixedArr :FixedArr :Oata HiMo» 咖ticms 12Oata HiMo» 咖ticms 12Age NameAge NameRec :Str :Rec :Str :Person «Р RefPerson int «Kef; RRlilOPerson «Р RefPerson int «Kef; RRlilO0] ш ⑵ [31 [410] ш ⑵ [31 [41F2-EI(p& FS-Close F4-Here F5-Zooc? ГБ-Next F7-Trace 陶-Step F5-Run Fl&-MemiF2-EI(p& FS-Close F4-Here F5-Zooc? ГБ-Next F7-Trace 陶-Step F5-Run Fl&-Memi鹿鬭 1:ШЮЕ *Isa*鹿鬭 1:ШЮЕ *Isa*STBINSTBINInspect!^ Rec 05B81:OOOC AGEНШInspect!^ Rec 05B81:OOOC AGEНШ
Person Ре
Person Ре
C5C04:UG9E
C5C04:UG9E
FZ-Ekpt F3-Close M-Неге F5-Zoom F6-Ki*xi» & 二 Yrace F8-Step F9-Run FID-Menu
FZ-Ekpt F3-Close M-Неге F5-Zoom F6-Ki*xi» & 二 Yrace F8-Step F9-Run FID-Menu
也】$回我tl屮
也】$回我tl屮
睜ectiig X/
)5加加M
睜ectiig X/
)5加加M
People : array「八 J с* I of ((Age : 40; Nans? (Age : 6; Name (Age : 46; Name
People : array「八 J с* I of ((Age : 40; Nans? (Age : 6; Name (Age : 46; Name
Fixed
Arr :
Fixed
Arr :
Oata HiMo» 咖ticms 12
Oata HiMo» 咖ticms 12
Age Name
Age Name
Rec :
Str :
Rec :
Str :
Person «Р RefPerson int «Kef; RRlilO
Person «Р RefPerson int «Kef; RRlilO
0] ш ⑵ [31 [41
0] ш ⑵ [31 [41
F2-EI(p& FS-Close F4-Here F5-Zooc? ГБ-Next F7-Trace 陶-Step F5-Run Fl&-Memi
F2-EI(p& FS-Close F4-Here F5-Zooc? ГБ-Next F7-Trace 陶-Step F5-Run Fl&-Memi
鹿鬭 1:ШЮЕ *Isa*
鹿鬭 1:ШЮЕ *Isa*
STBIN
STBIN
Inspect!^ Rec 05B81:OOOC AGE
НШ
Inspect!^ Rec 05B81:OOOC AGE
НШ
-File View Sun Bi'eakpointsrftodule: INSFEQ File: IHSPECT.C 9-
typed或
51rMm《 tmsi•辭就 Age;
char Namel 5J ;
} Pez^on,«lefPerson;- fWat Miunlwr 二 1Z. 4; ini Fixed 二 13;
unsigned char ArrfZHZl 二{ <1Д}, <3,4>》; Person Rec 二 S 5ли15аы }; char 哺t* 脾陋parting Rec-
's' 115
*a* 977' 0
7’ 0
File УЯеи Run Breakpoints [Module: PWWI File: INSPECT. PAS
type
Person 二 record
Age : word;
Name : stringL5J
把啦
Rerpersou = APerson;
const
Number : real 二 12.4;
:integer = 13;
array (1. .2fbocil«aiil of byte =
((1>2>,(3,4) );
Person 二(Age : 5; Name : 'Is£》; string 二 * Isabel*;
Person 二 :f Eva*),
:‘甘3
6>
File View Run Breakpoints Data Hindow Options:I 玉 HN
rffodule: INSPECT File: INSPECT.C W“
typedef strucl-t unsigned Age; char Nane[51; > Person,*RefPerson;
float Number 二 1Z.4;
int Fixed 二 13;
imsNgired char Ar'HZHZl 二{ <l.Z}f《3,4} };
Person Rec - { 5,"Isa" J; char *Str 二"ХзаЛе!";
Person People】'o' - '* 十 口 二
<<40,uEva"}』
<6,MIsaM3,
f%-Jan"> >;
Person #Ptr:w
RefPerson «PefPtr;
int 城ef;
mainO
FZ-Bkpt F3-Close ?4-Here F5~Zoom F6-Next F7-Trace F8-Step FARtm F10-Me>w
File View Run Breakpoints Bata Hindow Options
[{•todule: PROGRAM File: IHSPECT. PAS 13 type
Person = record
Age : word;
Name : stringt5I
end;
RefPerson = APerson; const
Number : real 二 12*4;
Fixed : integer 二 13;
Ait : array [lc.Z?booleaii] of byte - ((1,2), (3,4) >;
Rec : Person 二(Age : 5; Name : 'Isa'〉;
Str : string 二 JIsabel7;
People : array £'& ・■'<;'I of Person 二
((Age : 40; Name : 'Eva'〉, (Age : 6; Name : 'Isa'3 (Age : 46; Name : 'Jan'));
var
FZ-Bkpt F3-Close F4-Here F5-Zoom F6-Next F7-Trace F8-Step F9-Run FiO-Menu
{ { 40,{ { 40,《U,Zh {3,Q К《U,Zh {3,Q Кstruct [31struct [31<40,uEva\0\0n>{6."Isa\0\0"}{46,HJan\0\0M><40,uEva\0\0n>{6."Isa\0\0"}{46,HJan\0\0M>[0] fl] [Zl[0] fl] [Zlitches-itches-F2-Bkp2 F3-Close F4~Here F5-Zoom FB-Next F?-Trace F8-Step F9-Run F10-MenuF2-Bkp2 F3-Close F4~Here F5-Zoom FB-Next F?-Trace F8-Step F9-Run F10-MenuFile rflodule:File rflodule:View Run Breakpoints Data №ndow OptionsView Run Breakpoints Data №ndow OptionsPR0GW1 File: INSPECT. PAS 14((1,2), (ЗЛ));:Person 二《Age : 5; Name :'狂a*);:string = 'Isabel';PR0GW1 File: INSPECT. PAS 14((1,2), (ЗЛ));:Person 二《Age : 5; Name :'狂a*);:string = 'Isabel';Peoyle : array Шс'】 of Person xPeoyle : array Шс'】 of Person xCttspecHijCttspecHij?5B81:0114?5B81:0114vai'vai'PERSONPERSONbegk. — , ■ Ptr :=硼ec; RefHr := @FU; Ref := №xed;begk. — , ■ Ptr :=硼ec; RefHr := @FU; Ref := №xed;
{ { 40,
{ { 40,
《U,Zh {3,Q К
《U,Zh {3,Q К
struct [31
struct [31
<40,uEva\0\0n>
{6."Isa\0\0"}
{46,HJan\0\0M>
<40,uEva\0\0n>
{6."Isa\0\0"}
{46,HJan\0\0M>
[0] fl] [Zl
[0] fl] [Zl
itches-
itches-
F2-Bkp2 F3-Close F4~Here F5-Zoom FB-Next F?-Trace F8-Step F9-Run F10-Menu
F2-Bkp2 F3-Close F4~Here F5-Zoom FB-Next F?-Trace F8-Step F9-Run F10-Menu
File rflodule:
File rflodule:
View Run Breakpoints Data №ndow Options
View Run Breakpoints Data №ndow Options
PR0GW1 File: INSPECT. PAS 14
((1,2), (ЗЛ));
:Person 二《Age : 5; Name :'狂a*);
:string = 'Isabel';
PR0GW1 File: INSPECT. PAS 14
((1,2), (ЗЛ));
:Person 二《Age : 5; Name :'狂a*);
:string = 'Isabel';
Peoyle : array Шс'】 of Person x
Peoyle : array Шс'】 of Person x
CttspecHij
CttspecHij
?5B81:0114
?5B81:0114
vai'
vai'
PERSON
PERSON
begk. — , ■ Ptr :=硼ec; RefHr := @FU; Ref := №xed;
begk. — , ■ Ptr :=硼ec; RefHr := @FU; Ref := №xed;
File tfiew Run breakpoints Oata l€.ndow Options poAule: INSPECT Fiie: INSPECT, C 11
typedef
struct^
unsigned Age; char Hanet 51;
} Person,«RefPerson; float Number 二 12- 4; int Fixed = 13; unsigned char ArrlZJCZl - Person Rec 二{ 5JIsa” }; char *Str 二"Isabel”;
Person Peoplet * с1 - *a* + 13
{ 6, < 46, Person «Ptr;
RefPerscn *RefPtr; int 啾M; mainC
F2-Bkpt F3-Close F4-Here FS-Zoom『G-№xt F?-Trace F8-Step F9-Run FlO-Menu
6)
File View Run Brea^oinls Data Rividaw Options rflodule: IKSPECi File: IKSPECT.C 11
typedM
struct-<
unsigned Age;
char Namef51;
} Person,*KefPerson;
?leat Number = 12.4;
int Fixed ? 23;
unsigned char ArrlZIEZJ 二{ fLZh《3,9 >;
Person Rec = { 5,"Ма"》; char *Str 二 HIsaiel,1;
Person Peopledf c* - *a* ■» 1J =
{《40, MEvaM 》,
{ 6. "Isa" },
《46, “JaM } >;
Person 哪r;
RefPerson *Re£Flr;
int 啾ef;
mai 貳)
Inspecting People-
05C04:00A9
£01
[11
£21
{铀 JEvaMKO"》 《6Jg\0\0f {46,nJan\0\0,*>
悟聽g吋『
•Jan\0\0"
struct
Oli: F2-Bkpt at Fl-Hod №Anim F5~User F6-Undo F?-Instr F8-Rtn F9-To FlO-Local
a)
File View Run Breakpoint Data Mindow Options3^32
iffodule: PRCGRAH File: INSPECT. PAS 14li
< 《1.2), 《3.4));
Rec : Person = (Age : 5; Name : #Isae);
Str : string 工'Isabel*;
People : array Г'а'・・'с'] of Person =
Inspecting People3iEva* )>
@5881:0114Isa#),
ГаЧC40/Eva4|jan,));
end.
AM: FZ-Rkpl at F3-Hod H-Aiaiia F5-Wser F6-«ndo FLmCr Ffi-Rlm F9-To HO-local
6)
Рис. 87, Проверка элемента таблицы структуры People. а> Турбо Си; б) Турбо Паскаль.
File骯®зRun Breahpoinls Data Hinfiow Options
rM»dule: PROGRAM File: INSPECT. PAS Z3
Rec : Person 二《Age : 5; Hams : 'Isa');
Str : string 二 * Isabel*;
People : array £*a*.,*c*J of Person 二
《(Age :削;Name : 'Eva'》.
(Age 3 6; Kami? : 4Isa*),
(Age : 46; tae : •Jan*));
var
Fir : APersoii;
Re^Ptr : ARefPerson;
Ref : Ainteger; begin
Hr := (?Rec;
RefPtr ; ©Ptr;
Ref :=顕i海也;
fill; F2-Bkpt 號 F3-Mod F^Anim Fi-tar F6-«ndo FMnstr 阵RU F9-b. FlO-Localfill; F2-Bkpt 號 F3-Mod F^Anim Fi-tar F6-«ndo FMnstr 阵RU F9-b. FlO-Local! 一.》 end.
fill; F2-Bkpt 號 F3-Mod F^Anim Fi-tar F6-«ndo FMnstr 阵RU F9-b. FlO-Local
fill; F2-Bkpt 號 F3-Mod F^Anim Fi-tar F6-«ndo FMnstr 阵RU F9-b. FlO-Local
File View Run Breakpoints Oala Hindu® Options遅硼
Module; IKSPSCT File; IKSPECT- C 工5ii
typedef strucK
亜si卯匹壮A歌; cbnr tae£51; 》Person, ^efPersoni; float Number 二 12.4; ini Fixed = 13; unsigned char ArrEZMZl 二 < <1»Z}>《3,处 >; Person Rec 二《5,"Isa" }: char 崎館f 二"КаЬв1"; Person Peopled * c* -'裁 + 11 = { {砒-EvaM *, 《6, BIsan < 46, BJanra 卜 X
Person «Ptr;
RefPerson «RefPtr; int 蹴e£; сшп()
僦匕炉Z-励哪 at F3-«od F4-Anim F5-User F6-Undo F7~Instr 眸RU F9-T» MO-local
Inspecting People-Inspecting People-44FZ-Bkpt F3-C»se 暮-昵re F5-Zoob F6-Next F7-Trace F8-Step F%艮un F10-«emiFZ-Bkpt F3-C»se 暮-昵re F5-Zoob F6-Next F7-Trace F8-Step F%艮un F10-«emi(40/*Eva\0\0">{6JIsa\0\0"》 i^/UanXOXO1*}(40/*Eva\0\0">{6JIsa\0\0"》 i^/UanXOXO1*}0SCO4: 00A9 [01[U⑵0SCO4: 00A9 [01[U⑵「Inspecting People[2] 05CO4: Q0B7AgeНаше「Inspecting People[2] 05CO4: Q0B7AgeНаше46■JaiRO'Q"46■JaiRO'Q"
Inspecting People-
Inspecting People-
4
4
FZ-Bkpt F3-C»se 暮-昵re F5-Zoob F6-Next F7-Trace F8-Step F%艮un F10-«emi
FZ-Bkpt F3-C»se 暮-昵re F5-Zoob F6-Next F7-Trace F8-Step F%艮un F10-«emi
(40/*Eva\0\0">
{6JIsa\0\0"》 i^/UanXOXO1*}
(40/*Eva\0\0">
{6JIsa\0\0"》 i^/UanXOXO1*}
0SCO4: 00A9 [01
[U
⑵
0SCO4: 00A9 [01
[U
⑵
「Inspecting People[2] 05CO4: Q0B7
Age
Наше
「Inspecting People[2] 05CO4: Q0B7
Age
Наше
46
■JaiRO'Q"
46
■JaiRO'Q"
File Siew Run Breakpoints Data Window Options rtfodule: INSPECT File: INSPECT. C li-
lypedM struct! unsigned Age; char Nane[53; } Person,»RefPerson; float Number = 12.4; int Fixed = 13; unsigned char ArrIZl[21 二 f 41»Z}, {3,4> };
Person Rec = { 5,uIsan 》; char *Str 二"Isabel";
Person Peoplef'c' - '* t il
{ { 40, "Eva"》,
{ 6, %a“ },
{ 46, "Jan" } };
Person *Hr;
RofPerson *1?efPtr;
int *Ref:
main。
F2-Bkpl F3-Close F飪Here F5-Zogm FS-Mext F7-Trace F8-Step F9-Run FlO-Menu
File View Run Breakpoints Data Window Options
(Module: INSPECT File: INSPECT.C 15
typ^def
struct?
unsigned Age; char Name[51;
F Person, *Ref Pei'son; float Number 二 12.4; ini Fixed 二 13; unsigned char ArHZMZ】二 Person Rec = { 5, "Isa" }; char «Str 二 “Isabel"; Person PeopleE*c" - 'a' + { < 40, ”Eva” 3 { 6, ,,.Isa" >, { 46, ° Jan" > }
Person *Flr:
Jtef Person 疝efPtr:
ini 联e£; nainO
FZ-Bkpt F3-Close 昨Here F5-Zoom F6-Next F7-Trace F8-Step F9-Run ПО-Menu
File View Run Breakpoints Data Hindow Options
FZ-Bkpt F3-Close F4-Here F5-Zoom F6-Next f7-Trace F8-Step F9 Run FlO-Meiw
6}
Рис. 90. Проверка поля записи, указанного Ptr. а> Турбо Си: б) Турбо Паскаль.
25—764
File View Run Breakpoints DataHi ndow Options
Module: INSPECT File: INSPECT.C 16
typedef
struct{
unsigned Age; char Namet 5];
} Person, *RefPersoTB; float Kuwiher 二 12.4; int Fixed - 13; unsigned char ArHZl⑵ Per5g Rec 二{ 5,“Isa"
:lus昵ctitiq Ref映EJ^^S ,盹叫МИ4e :原妊0KЛ
[Q]5C04: 009E E_RecJ
struct far *far «
={ U,»,《3,4}円
char *Str 二"Хзаке!*1;
Person Peoplef*c* - 'a' * 1J 二
{ {如,"Eva" },
{ 6. -Isa" >,
《46, "Jaan * >;
Person, «Ptr;
RefPerson 而efPtr;
int *Ref;
maiiiO
AH: F2-Bkpt at F3-Mod M-Anim F5-User F6-Undo Fl-Instr F8-Rtn F9-To FlO-Local
File View Run Breakpoints Data, Mindcw Options rflodnle: PROGRAM File: INSPECT. PAS 24
Кес : Person = (Age : 5; Hafne : 'Isa');
驾
Str : slriiig = * Isabei* ;
People : array £*a*..*c*] of
((Age :
(Age :
(Age :
40;
6;
46;
Name Name Name
Person 二
:'Eva'),
:Fa'),
:'Jan'));
var
Ptr : APerson:
RefFir : ARefPerson;
Ref : Ainteger;
begin
Ptr :二 PRec;
RefPlr :二曲tr;
Ref :二 PFixed;
鹿81/脈:5B81:飢6g 侬G缈匹国
ED
ARIFPEKSON
5B81:000C [PROGRAM. KECJ
F2-Bkpt F3-Close F4-Here F5~Zoom F6-Next ГУ-Trace F8-§tep F9~Run FlO-Mpnu
布dule: INSPECT File: typedefstract{ unsigned Age; char Name[5】:} Pei'son, *КеГРегзо11; float Number = 1Z.4; int Fixed 二 13:布dule: INSPECT File: typedefstract{ unsigned Age; char Name[5】:} Pei'son, *КеГРегзо11; float Number = 1Z.4; int Fixed 二 13:
布dule: INSPECT File: typedef
stract{ unsigned Age; char Name[5】:
} Pei'son, *КеГРегзо11; float Number = 1Z.4; int Fixed 二 13:
布dule: INSPECT File: typedef
stract{ unsigned Age; char Name[5】:
} Pei'son, *КеГРегзо11; float Number = 1Z.4; int Fixed 二 13:
File View Run Breakpoints Data Window Options 工 C 16-:
I ns peeling Ref Ptr3q
@5C04;QI4£ : 5C04:014A [_Ptr [01 5C04:009E [_RecJ|
unsigned char Arrf Z1[Z]二{
Person Sec 二{ 5JI«a° };
char *Str 二"Isabel*";
Person Pecplet * cJ - /a* * 1]二
{《40, "Eva" },
< 6, uIsaM ),
《46,"屍W* } };
Person *Ptr;
RefPerson 疝efFtr;
ini 却ef;
main(>
6)
蹬-Bkpt F3-Close F4-Here F5-Zoom FG-Next FZ-Trace F8-Step F9-Run FlO-Menu
File
Module:
Rec
*r
View Run Breakpoints Data Hindow Options
PROGRAM File: INSPECT. FAS Z4 :Person 二(Age : 5; Name : 'Isa');
:string 二'Isaheir ;
People : array「a'. J с' 1 of
《(Age :
(Age :
(Age :
var
Ptr : AFersoii;
Kef Hr : лКеГРег5оп;
Ref : integer;
40;
6: 愉
Name
Name
Name
Person 二 :'Eva'), :'Ka'), :'Jan') >;
Inspecling RefPtr 05B81:OL6C : 5B81:0168 [PROGRAM. FIR]
(11
5^1:000C I PROGRAM, REQ
REFFERSOM
KTRINGL5I
FZ-Bkpt ГЭ-Close F4-Here F&-Zoom FS-Hext F?-Trace F8-Step F^-Run FIB-Menu
即峙pecli市
0Kec;
:二 PPtr;
№xed:
begin
Ptr :=
RefPtr
-teBSl:0168 : 5BB1:GOCC [PKOG AGE
File View Run Breakpoints Data Hindcw Options iodide: INSPECT File: INSPECT. C 16-
typedef
struct{
unsigned Age;chat Nawe[51;
} Person,*RefPerson; float Numbei* 二 12.4; int Fixed = 13: unsigned cbar ArrlZ1[23 二《 Person Rec 二{ 5,MIsaM }; char *Str = "Isabel-;
Inspecting RefPtr3・
05CO4: 014E : 5C04: 014A [ _Пг Г 015C04:009E [ZRecJ
•Impacting *RefPtr@5C04:014A : 5C04: 0Q9E [ _Recl
■41
uIsa\0\0w
char 【51
Person Peoplet' c* - * a* + 11 - 《《40; “Eva" >, < 6,飞 a” }, { 46. "Jan*' } %;
Person *Ptr;
RefPersoti 疝efPtr;
int «Ref;
mainO
工叫上国门E常附5
Q5CC4: O0A0
一
F2-Bkpt F3-Close F4-Here F5-Zoom FS-Next F7-Trace F8-Step Fa-Run FlU-Menu
File View Run Breakpoints Data Hindow Options
6)
Rec : Person 二(Age : 5; Name : 'Isa');
Str : string 二 * IsahelJ i
People : array【'a'・
((Age :
(Age :
(Age : var
Ptr : APerson;
RefPtr : ARefPerson;
Ref : Ainleger; begin
Ptr := PRec,
AhApecti!
]of Person 二
Name : 'Eva'),
Name : ' Isa'),
Name : * Jan*));
Inspecting RefFti3
85Ж:016С : 5B81:0168 [PROGFAM.PTRI
Ш5ВВ1:000С I PROGRAM.RED
REFFEKSOK
——6
@5S81:000E 'Is* [01
3
plc CHAR
Inspecting RefPtr*4
35圖1:0168 : 5B81:000C [PROG
AGE5
NAME' Isa'
STRING151
-2】
FZ-BKpt F3~Close f4-Here F5-Zoom FC-Next F7-Trace F8-Step F9-Run FlO-Menu
Поле Descend
Выбор поля Descend имеет такой же результат, как выбор поля Inspect, вновь созданное инспекционное окно занимает место текущего инспекционного окна. Это препятствует ненужному увеличению инспекционных окон, но не позволяет проследить назад цепь указаний или вернуться на высший уровень иерархии компонентов.
Поле New expression
Выбор поля New expression позволяет задать новое значение указанному выражению. Информация о выражении помещается в текущем инспекционном окне.
Составление выражений
Состав выражений, которые можно конструировать пользуясь отладчиком, не отличается существенно от состава выражений используемого языка.
В настоящей версии отладчика можно осуществить выбор состава в соответствии с Турбо Паскалем, Турбо Си или Турбо Ассемблером. По умолчанию принимается такой состав, какой вытекает из текущего базового модуля, то есть того, в котором произошел останов выполнения программы. Однако ничто не мешает выбрать иной состав. С этой целью достаточно высветить меню Options / Language, а затем определить выбор языка. В типичных случаях для обращения к переменной достаточно указать ее идентификатор, а в целях обращения к команде программы - указать ее номер строки, предваренной знаком # (hash)。Это вытекает из того, что, идентифицируя объект базовой программы, отладчик использует те же самые правила определения области действия описания, что и компилятор.
Если локализация объекта в текущем базовом модуле окажется невыполнимой, то принимается, что речь идет о внешнем объекте, находящемся в одном из других модулей программы. Это предположение может быть аннулировано указанием полного имени объекта name; которое имеет вид
[tP module [井 file ]] #Z/ne {#^ame ]
[t^module[ tPfile ] ] [ ^procedure ] ^name
В этой записи, где module является именем модуля, file - именем файла, line - номером строки, a procedure - именем процедуры, фрагменты, взятые в квадратные скобки, могут быть опущены. В частности, выражение
#44 #Count
может быть именем переменной Count, доступной из 44-й строки текущего модуля, а
#Routine #Local
-именем переменной Local, доступной из процедуры Routine.
Турбо Си
390Часть К Турбо отладчик
Сохраняется полный состав выражений, за исключением операции присоединения, выраженной оператором ",“ (запятая). Допускается использование следующих операторов:
01234567890123456789ПриоритетОператоры.
0123456789
0123456789
()[].-> sizeof (.одноаргументный)
♦ & - + ! ^ ++ -
* / %
+ _
« »
< <« > >^
:
&&
: 1
?:
= += у / = %= vv= »« & == 7=:=
Внимание: Дополнительный оператор : : {двойное двоеточие) может использоваться для создания далекого указания (например 2: :3 является указанием номера сегмента 2 и смещения 3).
Пример. Выражениз) в Турбо Си
В области действия описания
int Fixed = 13;
выражение *&Ffxed имеет значение 13.
Турбо Паскаль
Сохраняется полный состав выражений, за исключением операций множеств' м соединения цепочек. Допускается пользование следующих операторов:
Приоритет Операторы
12 3 4 512 3 4 5@ not type( )ч- ^одноаргументный)
12 3 4 5
12 3 4 5
* / div mod and shl shr
in + - or xor
<< = >>==<>
:=
Результатом операции := {присваивание) является присваивание значения
переменной.
/6. Отладчик
Пример. Выражения в Турбо Паскале
В области действия описания
const Fixed : integer » 13
выражение
(@F1xed)*
имеет значение 13.
Турбо Ассемблер
Сохраняется полный состав выражений, в которых ограничиваются использованием следующих операторов:
Приоритет Операторы
123456789123456789ххх PTR (например, BYTE PTR)
123456789
123456789
OR XOR
AND
NOT.;
EQ NE LT LE GT GE + ~ ♦ / MOD SHR SHL
+ - (одноаргументное)
OFFSET SEG
()[]
Вниманием Присваивание значений переменным может происходить с помощью оператора = {присваиваний, например
Count к [BYTE PTR DS : 20]
Пример. Выражения в Турбо Ассемблере
В области действия описания
Fixed DW 13
выражение
[WORD PTR DS: (OFFSET Fixed)] имеет значение 13.
Редактирование
Независимо от выбранного состава после каждого из выражений может присутствовать эталон, определяющий способ высвечивания значения,
представленного выражением. Эталон отделяется от выражения знаком , (запятая) и может иметь один из следующих видов:
Эталон
Интерпретация
с d fn
Вывод символа
Вывод десятичного числа
Вывод действительного числа с w цифрами (отсутствие п вызывает вывод всех цифр)
m md
P
cs
Вывод шестнадцатеричного адреса
Вывод десятичного адреса
Вывод указателя или значения указательной переменной
Вывод строки из с символов (отсутствие с вызывает вывод строки, заканчиваемой знаком nul)
X h
Вывод шестнадцатеричного числа 卻 Вывод шестнадцатеричного числа
166 Опции
меню
Выбор опции начинается с главного меню. Исключением из этого правила является вызов на экран локального меню или использование ускоренного выбора опции с помощью управляющих клавиш.
В этом разделе будут представлены опции отавного меню, опции глобальных меню и опции локальных меню. Многие из них могут быть выбраны с помощью управляющих клавиш. Хотя точное их описание будет указано несколько дальше, специально приводится их полный комплект
Клавиши
Функции
F1 F2
F3 F4
F5
F6 F7
F8 F9
F10
Alt-Fl Alt-F2 AU-F3 AU-F4 AU-F5 AU-F6 AU-F7 Alt-F8 Alt~F9
Alt-FlO
Высвечивание справочной информации
Расстановка ловушек
Закрытие окон
Выполнение до курсора
Увеличение окон до размера экрана
Высвечивание очередного окна
Выполнение одной инструкции / команды
Выполнение покомандное, за исключением процедур
Выполнение до останова
Активизация главного меню
Высвечивание предыдущей справочной информации
Установка адресной ловушки
Выбор базового модуля
Начало выполнения
Высвечивание выходного экрана
Высвечивание закрытого окна
Выполнение одной инструкции
Выполнение до возвращения из процедуры
Выполнение до указанного адреса
Высвечивание локального меню
Alt-0
AU-1・・9
Высвечивание списка открытых окон Активизация окон с указанным номером
FyKBQWOXЛЛЛЛЛЛЛЛFyKBQWOXЛЛЛЛЛЛЛЛВысвечивание глобального меню File Высвечивание глобального меню View Высвечивание глобального меню Run Высвечивание глобального меню Breakpoints Высвечивание глобального меню Data Высвечивание глобального меню Windows Высвечивание глобального меню Options Возврат в систему DOS
FyKBQWOXЛЛЛЛЛЛЛЛ
FyKBQWOXЛЛЛЛЛЛЛЛ
Начало макроопределения Окончание макроопределения
Ctrl-F2 Подготовка к слежению от начала
Ctrl-F4Задание значения выражения
Ctrl-F7Помещение переменной в окне обзора (смотровом)
Ctrl-F8Установка/снятие ловушки
Ctrl-F9Выполнение до останова
Ctrl-F 10Высвечивание локального меню
Ctrl->Ctrl-<-Ctrl->Ctrl-<-EscIns Tab Shift-Tab Scroll-LockEscIns Tab Shift-Tab Scroll-LockУвеличение адреса на 1
Ctrl->
Ctrl-<-
Ctrl->
Ctrl-<-
Esc
Ins Tab Shift-Tab Scroll-Lock
Esc
Ins Tab Shift-Tab Scroll-Lock
Уменьшение адреса на 1
Закрытие инспекционного окна или меню Выделение выражения
Перемещение курсора в следующую рамку Перемещение курсора в предыдущую рамку Изменение конфигурации окна
ГЛАВНОЕ МЕНЮ
File
Меню File состоит из опций» позволяющих, кроме прочего, загружать программу, выбирать каталоги, а также выполнять директивы системы DOS.
Опция Load,
Выбор опции Load вызывает загрузку программы, которая должна быть запущена. Если имя файла, содержащего программу, неоднозначно (содержит знак * или ?), то нажатие клавиши Enter вызывает вывод на экран списка имен файлов, среди которых можно произвести выбор.
Опция Change Dir\
Выбор опции Change Dir вызывает смену текущего каталога.
Опция Get Info
Выбор опции Get Into высвечивает информацию о программе, в частности: ее имя; размер памяти, занятой программой, отладчиком и DOS;
список номеров ловушек, установленных отладчиком, способы обслуживания ловушек (аппаратно или программой) и т. д.
Опция OS Shell
Выбор опции OS Shell вызывает временный вызов системы DOS. После окончания действий в системе DOS можно вернуться к отладчику, выполнив директиву EXIT.
Опция Quit
Выбор опции Quit вызывает возврат в систему DOS.
View
Меню View состоит из опций, позволяющих высвечивать информационные окна. Эти окна делятся на рамкм. Перемещение между рамками происходит в спомощью клавиши Tab и Shift-Tab, а перемещение в рамке - с помощью клавиш с горизонтальными стрелками. В момент, кота активно информационное окно, в него можно заносить символы с клавиатуры. Это вызывает появление диалогового окна, соответствующего данному контексту. Практически исключается такая возможность для отдельных окон и их рамок.
Опция Breakpoints
Выбор опции Breakpoints вызывает высвечивание и активизацию окна ловушек. Это окно состоит из двух рамок. Левая содержит список ловушке, а в правой высвечивается информация о выбранной ловушке. Ловушки могут ставиться в меню Breakpoints или с помощью клавиши F2, а затем модифицируются с помощью локального меню. Локальное меню окна ловушек может касаться только его левой рамки. Как любое локальное меню оно высвечивается нажатием клавиш AM-F10 или Ctrl-FlO.
Локальное меню
Set actionОпределение действий после попадания
программы в ловушку
Breakостанов программы;
Logпомещение значения выражения
в окно сообщений;
Executeобработка указанного
выражения;
ConditionОпределение условия попадания в ловушку
Alwaysвсегда;
Changed memory после внесения изменения
в указанной области памяти (например, если в области действия описания:
6 Турбо Си
long int Fix = 13;
6 Турбо Паскале
const Fix : long1nt 匸 13;
6 Турбо ассемблере '
Pass count...Enable/disable Add...Pass count...Enable/disable Add...GlobalRemoveDelete allInspectGlobalRemoveDelete allInspectFix DD 13 указывается Fix. % это означает определение области в 16 байт, начиная с адреса переменной Fix); Выражение истинно всегда, комда указан ное выражение имеет значение TRUE или отличное от 0.
Pass count...
Enable/disable Add...
Pass count...
Enable/disable Add...
Global
Remove
Delete all
Inspect
Global
Remove
Delete all
Inspect
Определение количества выполнений условия, после которого наступит попадание в ловушку.
Активизация / дезактивизация ловушки.
Добавление ловушки с указанным адресом в перечень ловушек (напрнмер, #44 перед первой инструкцией или командой строки 44). Включение ловушки в глобальный список, (устанавли вается перед каждой инструкцией программы). Снятие рассматриваемой ловушки.
Снятие всех ловушек.
Высвечивание того фрагмента программы, к которому относится данная ловушка.
Опция Stack
Выбор опции Stack вызывает высвечивание и активизацию окна вызовов. Оно состоит из одной? .рамки, в которой находится список активных процедур
в очередности их вызова.
Локальное меню
InspectОткрытие модульного окна, расположенного
в месте вызова выбранной процедуры.
LocalsОткрытие окна переменных и высвечивание
в нем локальных переменных текущего модуля, а также локальных переменных выбранной процедуры (в случае рекуррентных вызовов высвечивание локальных переменных выбранного уровня вызова).
Опцм贡、 Log
Выбор опции Log вызывает высвечивание и активизацию окна сообщений. Это окно состоит из одной рамки, в которой находится перечень последних сообщений (обычно 50 строк), направленных в это окно. Сообщения могут быть помещены в окно в результате попадания программы в ловушку, регистрации комментария, а также копирования содержимого активной рамки выбранного окна.
Локальное меню
Open log file Вывод сообщений не только в окно сообщений, но также в файл с указанным именем (после предвари-
Close log fileLoggingAdd commentErase logClose log fileLoggingAdd commentErase logтельного помещения в этом файле всех сообщений, уже находящихся в указанном окне).
Close log file
Logging
Add comment
Erase log
Close log file
Logging
Add comment
Erase log
Закрытие файла, в который выведены сообщения и дальнейший вывод сообщений только в окно. Включение / выключение регистрации сообщений. Вывод указанного комментария в окно сообщений. Очищение окна сообщений (может оказаться полезным перед выбором опции Open log file).
Опция Watches
Выбор опции Watches вызывает высвечивание и активизацию окна наблюдений. Оно состоит из одной рамки и вместе с модульным окном высвечивается сразу же после активизации отладчика. В окне наблюдений помещаются в峭ажен歌仪, наблюдаемые при выполнении программы. Если выражение является именем структурной переменной, то окне содержит определение типа переменной и значение этой переменной или ее компонент. В остальных случаях окно содержит только определение типа и значение. Если выражение указательное, то приводится информация об указываемой переменной.
Выражения помещаются в окно наблюдений с помощью клавиш Ctrl-F7 (после выделения с помощью клавиши Ins и клавиш с горизонтальными стрелками), а также из локального меню. В случае совпадения идентификаторов предполагается, что речь идет об идентификаторах, находящихся в пункте выполнения программы.
Локальное меню
WatchПомещение указанного имени переменной или
выражения в окно наблюдений.
EditРедактирование наблюдаемого выражения или
имени переменной.
RemoveИзвлечение из окна выделенного наблюдаемого
объекта.
Delete allИзвлечение из окна всех наблюдаемых объектов.
InspectОткрытие инспекционного окна для ознакомления с
компонентами сложного объекта.
ChangeИзменение значения выбранной переменной.
Опция Variables
Выбор опции Variables вызывает высвечивание и активизацию окна переменных. Оно состоит из двух рамок, в которых высвечиваются переменные, доступные в месте останова программы. В левой рамке высвечиваются общие переменные, а в правой - локальные переменные.,
Локальное меню
InspectОткрытие инспекционного окна для ознакомления с
компонентами сложного объекта.
ChangeИзменение значения выбранной переменной.
Опция Module
Выбор опции Module вызывает высвечивание списка имен модулей, из которых можно произвести выбор. После выполнения этой операции прож:ходит высвечивание и активизация модульного окна9 содержащего текст выбранного модуля. Это окно состоит из одной рамки и вместе с окном наблюдений высвечивается непосредственно после активизации отладчика. Поиск модуля с указанным именем происходит в следующей последовательности: 1> в каталоге, в котором компилятор обнаружил запускаемую программу; 2) в каталогах, определенных с помощью опции Options / Path for Source; 3) в текущем каталоге; 4) в каталоге, в котором находится собственно запускаемая программа.
Локальное меню
InspectОткрытие инспекционного окна для ознакомления с
объектом, выделенным курсором или для определения значения выражения, выделенного с помощью клавиши 1ns и клавиш горизонтальных стрелок.
WatchПомещение переменной, выделенной
курсором в окно наблюдений.
ModuleВысвечивание в модульном окне другого модуля,
выбранного из приведенного перечня.
FileВысвечивание в модульном окне той части модуля,
которая находится в другом файле.
Previous Перемещение курсора на позицию, которую он занимал перед последней сменой позиции.
LineПеремещение курсора на первый символ строки с
указанным номером.
SearchПоиск цепочки, состоящей из указанных символов.
Если курсор находится под идентификатором или если с помощью клавиши 1ns выделена группа символов, то как искомый текст принимается идентификатор или группа символов. Если среди указанных символов имеются знаки * {звездочка} или ? {знак вопроса}, то изображаются соответственно: прзнзвольный ряд символов и произвольный символ. Поиск ряда символов начинается с позиции курсора до конца модуля.
NextПоиск идентичного ряда символов, указанного во
время последнего выбора опции Search.
OriginПеремещение курсора на позицию, в которой произо
шел останов выполнения программы. Если необходимо, загрузка в модульное окно другого модуля.
GotoПеремещение курсора на указанную позицию.
Позиция может быть определена с помощью номера строки (например, #44), имени процедуры или адреса, выраженного шестнадцатеричным числом»
EditАктивизация редактора для редактирования текста,
высвеченного в модульном окне (команда системы DOS, вызывающая редактор, должна быть определена во время установки отладчика).
Опция File
Выбор опции File вызывает высвечивание и активизацию окна файлов. Оно состоит из одной рамки, в которой высвечивается содержимое указанного файла в символьном или шестнадцатеричном виде. Переключение между этими двумя видами обеспечивает опция Display As, выбранная из локального меню (ее ускоренной версией является Ctrl-6.
Локальное меню
GotoGotoSeachSeachNextDisplay asFileEditNextDisplay asFileEditПеремещение курсора на позицию с указанным номером. Если содержимое файла высвечивается в виде символов, необходимо указать номер строки, а есля в шестнадцатеричном виде - номер байта. Поиск цепочки, состоящей из указанных символов. Если курсор находится под аденти<|)н.катором или если с помощью клавиши Ins выделен ряд символов, то в качестве искомого текста соответственно принимаются идентификатор или ряд символов. Если в указанном ряду символов находятся знаки * {звездочка} или ? {знак вопроса}, то изображаются соответственно: произвольный ряд символов и произвольный символ. Поиск ряда символов происходит с позиции курсора до конца модуля.
Goto
Goto
Seach
Seach
Next
Display as
File
Edit
Next
Display as
File
Edit
Поиск идентичного ряда символов, указанного во время последнего выбора опции Search. Переключение между высвечиванием файла в символьном и шестнадцатеричном видах. Высвечивание в окне файлов содержимого другого файла- Если указанное имя файла определено неоднозначно, то имеется возможность выбрать нужный файл из приведенного перечня.
Если файл высвечивается в символьном виде - активизация редактора для редактирования текста, высвечиваемого в модульном окне (команда системы DOS, вызывающая редактор, должна быть определена во время установки отладчика). Если файл высвечивается в шестнадцатеричном виде - замена выделенных курсором байтов байтами, введенными с клавиатуры.
Опция CPU
Выбор опции CPU вызывает высвечивание и активизацию окна процессора. Окно состоит из пяти рамок: кода (Code), регистров (Register), флажков (Flags), стека (Stack) и данных (Data).
Рамка Code
Содержит инструкции базовой программы и команды ассемблера. Способ их высвечивания зависит от локальной опции Mixed. Общие символы имеют вид идентификаторов. Остальные символы состоят из имени модуля, после которого следует знак # (hash) или . {точка} и идентификатор. Номера
строк состоят из имени модуля, после которого следует один из упомянутых знаков, и числа, определяющего номер строки в модуле. Адреса команд высвечиваются в виде символов. Если выделяется команда, выполнение которой вызовет скачкообразное изменение счетчика команд, то такая команда дополняется стрелкой, определяющей направление перехода.
GotoOriginFollowCallerPreviousSearchMixedGotoOriginFollowCallerPreviousSearchMixedNew CS: IPAssembleI/ONew CS: IPAssembleI/Oменю рамки Code
Goto
Origin
Follow
Caller
Previous
Search
Mixed
Goto
Origin
Follow
Caller
Previous
Search
Mixed
New CS: IP
Assemble
I/O
New CS: IP
Assemble
I/O
Высвечивание кода в указанном адресе (возврат обеспечивает опция Previos).
Высвечивание кода в адресе останова программы (CS: IP).
Высвечивание кода в адресе команды перехода (JMP, CALL и т.д.)・
Высвечивание кода в адресе, откуда вызвана данная процедура.
Высвечивание кода в месте, в котором использовалась в последний раз опция смены адреса.
Поиск указанной команды или ряда указанных байтов Переключение между высвечиванием инструкций программы и команд ассемблера в рамке кода
No высвечивание только команд;
Yes высвечивание инструкций и их кода на ассемблере (предполагаемый вид в случае, если текущий модуль написан на языке высокого уровня);
Both высвечивание инструкции и только тех команд, которые не являются развитиями инструкции.
Изменение счетчика команд (CS: IP) таким образом, чтобы следующей выполняемой командой была команда с указанным адресом.
Замена текущей команды командой, введенной с клавиатуры.
Выполнение операции в порту входа/выхода In byte ввод данных из байтового порта с указанным адресом;
Out byte вывод данных в байтовый порт; Read word ввод слова данных из порта с указанным адресом;
Write word вывод данных в порт с указанным адресом.
Рамка Register
Рамка содержит перечень регистров процессора и их содержимое.
Локальное меню рамки Register
Increment Decrement Zero ChangeIncrement Decrement Zero ChangeУвеличение содержимого выделенного регистра на L Уменьшение содержимого выделенного регистра на 1. Обнуление выделенного регистра.
Increment Decrement Zero Change
Increment Decrement Zero Change
Изменение содержимого выделенного регистра.
400Часть К Турбо отладчик
Registers 32-b Переключение между высвечиванием как 16-, так и 32-бит регистров (это имеет значение только в случае использования микропроцессора семейства 386).
Рамка Flags
Рамка содержит значения разрядов регистра флажков процессора.
Локальное меню рамки Flags
ToggleИзменение значения выделенного разряда регистра
флажков с 0 на 1 и наоборот.
Рамка Stack
Рамка сод^)жит список данных, находящихся в стеке процессора. Верхушка стека обозначена стрелкой.
Локальное меню рамки Stack
Goto
Origin
Follow
Высвечивание стека по указанному адресу (преобразование предыдущего адреса обеспечивает опция Previous) о
Высвечивание стека и его верхушки.
Высвечивание стека в выделенной позиции.
Previous
Высвечивание той же области стека, которая высвечи валась перед выбором последней опции изменения
адреса.
Change
Изменение значения выделенной позиции стека (значение может быть введено непосредственно без явного выбора опции Change).
Рамка Data
Рамка содержит данные, находящиеся в выбранной области оперативной памяти. Данные высвечиваются в виде, определенном с помощью опции Display As. В правой части рамки высвечиваются символы, находящиеся в выбранной области памяти. Если сегментная часть адреса совпадает с содержимым регистра DS, то в качестве номера сегмента указывается DS.
Локальное меню рамки Data
Goto
Высвечивание данных по указанному адресу. Адрес не может находиться в пределах отлаживаемой
Search
программы.
Поиск адреса, по которому находится указанный ряд байтов.
Next
Высвечивание адреса, в котором находится следующий ряд таких байтов, какие указаны в опции Search.
Change
Изменение значения выделенной данной (значение может быть введено непосредственно без явного
Byteв виде целого числа типа Char илиbyte;Wordв виде целого числа типа int илиword;Longв виде целого шестнадцатеричногочисла (long, longint);Compв виде действительного числа типаcomp;Floatв виде действительного числа типаfloat или single;Realв виде действительного числа типаreal;Doubleв виде действительного числа типаdouble или TBYTE;Extendedв виде действительного числа типаlong double или extended.Выполнение операции на блоке оперативнойпамяти с указанным адресом и размеромClearобнуление блока;Moveкопирование блока;Setоднородное заполнение блока;Readввод данных из файла с указаннымименем;Writeвывод блока в файл с указаннымименем.Byteв виде целого числа типа Char илиbyte;Wordв виде целого числа типа int илиword;Longв виде целого шестнадцатеричногочисла (long, longint);Compв виде действительного числа типаcomp;Floatв виде действительного числа типаfloat или single;Realв виде действительного числа типаreal;Doubleв виде действительного числа типаdouble или TBYTE;Extendedв виде действительного числа типаlong double или extended.Выполнение операции на блоке оперативнойпамяти с указанным адресом и размеромClearобнуление блока;Moveкопирование блока;Setоднородное заполнение блока;Readввод данных из файла с указаннымименем;Writeвывод блока в файл с указаннымименем.
Byte
в виде целого числа типа Char или
byte;
Word
в виде целого числа типа int или
word;
Long
в виде целого шестнадцатеричного
числа (long, longint);
Comp
в виде действительного числа типа
comp;
Float
в виде действительного числа типа
float или single;
Real
в виде действительного числа типа
real;
Double
в виде действительного числа типа
double или TBYTE;
Extended
в виде действительного числа типа
long double или extended.
Выполнение операции на блоке оперативной
памяти с указанным адресом и размером
Clear
обнуление блока;
Move
копирование блока;
Set
однородное заполнение блока;
Read
ввод данных из файла с указанным
именем;
Write
вывод блока в файл с указанным
именем.
Byte
в виде целого числа типа Char или
byte;
Word
в виде целого числа типа int или
word;
Long
в виде целого шестнадцатеричного
числа (long, longint);
Comp
в виде действительного числа типа
comp;
Float
в виде действительного числа типа
float или single;
Real
в виде действительного числа типа
real;
Double
в виде действительного числа типа
double или TBYTE;
Extended
в виде действительного числа типа
long double или extended.
Выполнение операции на блоке оперативной
памяти с указанным адресом и размером
Clear
обнуление блока;
Move
копирование блока;
Set
однородное заполнение блока;
Read
ввод данных из файла с указанным
именем;
Write
вывод блока в файл с указанным
именем.
FollowLong followPreviousDisplay asFollowLong followPreviousDisplay asBlockBlockОпция DumpВыбор опции Оно состоит из относится такоеGotoSearch.NextChangeFollowLong followPreviousDisplay asОпция DumpВыбор опции Оно состоит из относится такоеGotoSearch.NextChangeFollowLong followPreviousDisplay asвыбора опции Change).
Follow
Long follow
Previous
Display as
Follow
Long follow
Previous
Display as
Block
Block
Опция Dump
Выбор опции Оно состоит из относится такое
Goto
Search
.Next
Change
Follow
Long follow
Previous
Display as
Опция Dump
Выбор опции Оно состоит из относится такое
Goto
Search
.Next
Change
Follow
Long follow
Previous
Display as
Высвечивание данных по адресу DS : addr3 в котором addr является содержимым выделенного слова оперативной памяти
Высвечивание данных по адресу seg : Ofs составляет пару последовательных слов, из которых первое выделено.
Высвечивание той же самой области памяти, какая высвечивалась перед выбором последней опции смены адреса.
Определение способа представления данных выбранной области памяти.
Dump вызывает высвечивание и активизацию окна памяти, той же рамки, что и рамка Data окна CPU. К нему же локальное меню, состоящее из следующих полей:.
Byte
Float
Block
Word RealWriteWord RealWriteLongCompDoubleExtendedLongCompDoubleExtendedОпцию Dump удобно использоватьОпцию Dump удобно использоватьизучения рассматриваемого объекта.изучения рассматриваемого объекта.при вызове инспекционного окна дляпри вызове инспекционного окна дляRead
Word Real
Write
Word Real
Write
LongComp
DoubleExtended
LongComp
DoubleExtended
Опцию Dump удобно использовать
Опцию Dump удобно использовать
изучения рассматриваемого объекта.
изучения рассматриваемого объекта.
при вызове инспекционного окна для
при вызове инспекционного окна для
Опция Registers
Выбор опции Registers вызывает высвечивание и активизацию окна регистров и флажков. Оно состоит из двух рамок, идентичных с рамками регистров окна~ CPU. К нему относится то же самое локальное меню, состоящее из следующих полей:
IncrementToggle
Decrement
Zero
Change
Registers-32-bit
Опция Numeric Processor
Выбор опции Numeric Processor вызывает высвечивание и активизацию окна сопроцессора. Оно состоит из трех рамок: рамки регистров (Register), управляющей рамки (Control) и рамки флажков (Flags). Заголовок окна информирует об использовании сопроцессора или эмулятора. Указанный в нем адрес указывается в 20-бит виде (например, адрес ЗАООВ равнозначен нормализованному адресу ЗАОО:ОООВ). IPTR означает адрес инструкции, OPCODE - вид инструкции, a OPTR - адрес памяти, которого касается инструкция.
Рамка Register
Рамка содержит перечень регистров сопроцессора и их содержимое.
Локальное меню рамки Register
ZeroОбнуление выделенного регистра.
ChangeИзменение значения выделенного регистра (значение
может быть введено непосредственно, без явного выбора опции Change).
Рамка содержит значение флажков управляющего слова сопроцессора.
Локальное меню рамкм Control
ToggleToggleИзменение сосгояния выделенного флажка.
Toggle
Toggle
Рамка Flags
Рамка содержит значения флажков слова состояния сопроцессора.
Локальное меню рамки Flags
ToggleИзменение состояния выделенного флажка.
Опция User Screen
Выбор опции User Screen вызывает высвечивание и активизацию выходного окна. Это окно имеет такой же вид, какой имел бы экран монитора, если бы программа была вызвана из системы DOS. С целью ускоренного высвечивания выходного окна необходимо нажать клавиши Alt- F5. Высвечивание выходного окна исчезает после нажатии произвольной клавиши клавиатуры. Выходрос окно не имеег кока/;介юе меню.
Опция Another
Выбор опции Another вызывает высвечивание 恥 активизацию дополнительного окна: модульного (Module), памяти (Dump) илн файла (File). В частности, использование опции Another позволяет одновременно высвечивать содержимое более чем одного файла.
RUN
Меню RUN состоит из опций, позволяющих следить за программой и выполнять ее до останова.
Опция RUN
Выбор опции RUN (клавиша F9) вызывает выполнение программы до останова. Вызов отладчика наступит в одном из следующих ааучаев: 1) после окончания выполнения программы; 2) после попадания программы в ловушку; 3) после нажатия клавиши Ctrl-Break.
Опция Reset
Выбор '岂ции Reset (клавиш。Ctrl-F2) вызывает новую загрузку программы с ;«ска. Поскольку после выполнения этого действия не изменяется содержимс модульного окна, мо^ко. например (после перемещения курсора и нажата- клавиши F4), вызвать выполнение программы до места, пред- шествуюпего тому, в котором выбрана данная опция.
Опция Go to cursor
Выбор опции Go to cursor (клавиша 尸4) вызывает установку ?зрсмерной ловушки в строке, выделенной курсором и начало выпоянения программы до останова.
Опция Trace into
Выбор опции Trace into (клавиша FT) вызывает выполнение одной базовой строки или одной команды. Выполнение команды происходит, если текущим окном является окно процессора (CPU). Если базовая строка содержит вызовы процедур, то слежение охватывает их содержимое.
Опция Step over
Выбор опции Step over (клавиша 戶3) вызывает выполнение одной базовой строки или одной команды. В отличие от опции Trace into слежение не охватывает вызванных процедур. Модификация касается также слежения некоторых команд, в частности команд CALL и INT и команд LOOP, LOOPZ, LOOPNZ (со счетчиком в регистре СХ), а также команд, предваренных префиксами REP, REPZ и REPNZ.
Опция Execute to
Выбор опции Execute to (клавиши AUrF9) вызывает установку временной ловушки по указанному адресу и начало выполнения программы.
Опция Until, return
Выбор опции Until return (клавиши AU-F8) вызывает установку временной ловушки перед инструкцией, которая была бы выполнена по окончании выполнения текущей процедуры, а затем начало выполнения программы до останова.
Опция Animate
Выбор опции Animate (клавиши AU-F4) вызывает возобновление выполнения программы до останова. Выполнение программы можно прервать нажатием произвольной клавиши клавиатуры.
Опция Instruction trace
Выбор опции Instruction trace (клавиши Alt-F7) вызывает выполнение одной команды. Эта опция позволяет следить за подпрограммами обслуживания прерываний и модулей, компилированных без опции, допускающей отладку программы.
BREAKPOINTS
Меню Breakpoints состоит из опций, позволяющих устанавливать и снимать ловушки. Модифицирование предполагаемых сво 访 ств ловушек происходит в окне ловушек.
Опция Toggle
Выбор опции Toggle (клавиша F2) вызывает установку ловушки перед
первой инструкцией базовой строки или перед выделенной командой ассемблера.
Опция At...
Выбор опции At... (клавиша AUrF2) вызывает установку ловушки по указанному адресу.
Опция Changed memory global...
Выбор опции Changed memory global... вызывает установку глобально访 ловушки, в которую попадет программа, когда произойдет изменение значения указанной области памяти. Область памяти определяется указанием имен переменной и размера. Например, если в области действия описания:
G Турбо Си
long int Агг [10];
g Турбо Паскале
var Агг : array [0..9] of longint;
а Турбо Ассемблере
Агг DD 10 DUP (?)
указывается
Агг,3
то это будет определять область в 120 байт, начиная от первсиго байта массива Агг.
Опция Expression true global...
Выбор опции Expression true global... вызывает установку глобально访 ловушки, в которую попадет программа, если указанное выражение будет иметь значение, отличное от 0 или TRUE.
Опция Delete all
Выбор опции Delete all вызывает снятие всех поставленных ловушек.
DATA
Меню Data состоит из опций, позволяющих знакомиться со значениями переменных выражений, а также присваивать переменным новые значения.
406Часть К Турбо отладчик
Опция Inspect
Выбор опции Inspect вызывает высвечивание и нспекционного окна, касающегося переменной с указанным именем. Если в момент выбора этой опции курсор выделяет идентификатор переменно访 или если с помощью клавиши Ins и клавиш со стрелками выделено определенное выражение, то их значение выдается на экран.
Опция Evaluate/modify
Выбор опции Evaluate/modify (клавиши Ctrl-F4) вызывает высвечивание вспомогательного окна, состоящего из трех рамок. Если в первой рамке указано выражение, то во второй высвечено его значение (это значение можно отредактировать, отделяя отредактированный образец от выражения точкой с запятой). Если указанное выражение является именем переменной, то в третьей рамке можно определить новое значение этой переменной. Как и в случае опции Inspect, могут быть выделены идентификатор переменной или выражение, выделенное с помощью клавиши Ins 恥 клавиш горизонтальных стрелок.
Опция Watch
Выбор опции Watch (клавиши С*尸7) вызывает помещение указанного идентификатора или выражения в окно наблюдений.
Опция Function return
Выбор опции Function return выдает результат функции. Опция может быть выбрана только перед окончанием выполнения функции.
WINDOW
Меню Window состоит из опций, позволяющих выполнять операции на окнах без вникания в содержимое окна.
Опция Window pick
Выбор опции Window pick (клавиши Alt-O) вызывает высвечивание перечня всех открытых окон. Выбор одной из позиций этого перечня делает выбранное окно активным.
Опция Next рапе
Выбор опции Next рапе (клавиши Alt-Tab) вызывает выделение следующей рамки активното окошка.
Опция Move/resize
Выбор опции Move/resize (клавиши Alt-Scroll-Lock} вызывает изменение конфигурации активного окна (изменение его размера 恥 положения).
Опция Close
Выбор опции Close (клавиша F3) вызывает закрытие активного окна.
Опция Undo close
Выбор опции Undo close (клавиши AU~F6) вызывает открытие последнего закрытого окошка.
Опция Dump pane to log
Выбор опции Dump pane to log вызывает копирование активной рамки в окно ссюбщений.
Опция Restore standard
Выбор опции Restore standard вызывает преобразование стандартного размещения окна.
Опция Screen repaint
Выбор опции Screen repaint вызывает обновление экрана.
OPTIONS
Меню Options состоит из опций, позволяющих изменить некоторые особенности отладчика.
Опция Language
Выбор опции Language позволяет выбрать язык, на котором будут записаны выражения.
Опция Macros
Выбор опции Macros позволяет вызывать и аннулировать макровызовы, приписанные специально выбранным клавишам»
CreateНачало регистрации макровызова после
предварительного указания специальной клавиши, ©пределяющей ее имя. Регистрация начинается до момента выбора опции Stop Recording. С этого момента нажатие специальной клавиши (например, Ctrl-Del) вызывает такой же результат, что и поочередное нажатие всех клавишей, зарегистрированных между Create (клавиши Л2/-=) и Stop Recording (клавиши Alt--).
Stop RecordingОкончание регистрации макровызова.
RemoveАннулирование макровызова, связанного с указанной
специальной клавишей.
Delete allАннулирование всех макровызовов, связанных со
специальными клавишами.
Опция Environmenf
Выбор опции Environment позволяет определить способ высвечивания данных.
Integer format
Выбор формата записи целых данных
Decimal десятичный;
Display swapping
Нехшестнадцатеричный;
Bothдесятичный и шестнадцатеричный.
Выбор способа переключения между экраном
吊
отладчика и выходным экраном Noneбез переключения;
Screen size
Smartтолько тоща, когда можно ожидать
экранной операции;
Alwaysвсегда.
Выбор максимально допустимого для данной платы
Tab Size *
горизонтального размера экрана (43 - EGA, 50 - VGA).
Выбор размера табуляции.
Опция Path for source
Выбор опции Path for source вызывает указание каталогов, в которых будут разыскиваться базовые модули. Эти модули разыскиваются в следующей последовательности: 1) в каталоге, в котором компилятор нашел базовую программу; 2) в каталогах, определенных с помощью опций; 3) в текущем каталоге; 4) в каталоге, содержащем отлаживаемую программу.
Опция Arguments
Выбор опции Arguments позволяет указывать аргументы программы.
Опция Save options
Выбор опции Save options вызывает запоминание параметров отладчика в файле с указанным именем (в том числе его опции и макровызовы, а также способ размещения окон и рамок).
Опция Restore options
Выбор опции Restore options вызывает установку параметров отладчика, запомненных после выбора опции Save options.
ЧАСТЬ VI. БИБЛИОТЕКИ
17« Принципы описания
В общем случае элементами приведенных здесь описаний являются:
Наименование
Описание
Имя
Заголовок
Имя и краткое описание функции.
Тип результата функции, а также типы и имена ее параметров.
Прототип
Имя файла заголовков, содержащего описание прототипа функции.
Определение
Имя файла заголовков, содержащего макроопределение функции.
Функция
Подробное описание действий, к которым приводит вызов функции
Результат Замечания Пример
Переменная, выдаваемая в точке вызова функции Комментарии и уточнения.
Простая программа, содержащая вызов функции и написанная для IBM PC XT с операционной систе- мо访 DOS 3.30 и оперативной памятью 640 Кбайт.
Замечание: Только немногие функции (например, abs) являются одновременно собственно функциями и макроопределениями. С целью присоединения к программе собственно функции следует воспользоваться директивой, сужающей область макроопределения (например, #undef abs).
17.1. Графическая библиотека
Графическая библиотека состоит из двух частей:
clreol gettext highvideo movetext textattr textmodeclreol gettext highvideo movetext textattr textmodedellinegotoxy lowvideoputtext textcolor whereydellinegotoxy lowvideoputtext textcolor wherey-библиотека для реализации текстовой графики, содержащая функции, прототипы которых находятся в файле conio.h:
clreol gettext highvideo movetext textattr textmode
clreol gettext highvideo movetext textattr textmode
delline
gotoxy lowvideo
puttext textcolor wherey
delline
gotoxy lowvideo
puttext textcolor wherey
clrscr gettexiinfo insline normvideo textbackground wherex window
-графическая библиотека для реализации точечной графики, содержав функции, прототипы которых находятся в файле graphics, h:
arc circle closegraph ellipse floodfill getbkcolor getdrivername getgraphmode getmaxcolor getmaxy getpalette gettextsettings gety graphresult installuserdriver linerel
moveto pieslice rectangle restorecrtmbde setallpalette setcolor setgraphbufsize setpalette settexstyle setvisualpage
bar
cleardevice detectgraph fillellipse getarccoord getcolor getfillpattern getimage getmaxmode getmodename getpalettesize getviewsettings graphdefaults imagesize installuserfont lineto
outtext putimage registerbgidriver sector setaspectratio setfillpattern setgraphmode sergbpalette setusercharsize setwritemode textwidth
bar3d clearviewport drawpoly fillpoly getaspectratio getdefaultpalette getfillsettings getlinesettings getmaxx getmoderange getpixel getx grapherrormsg initgraph line
moverel outtextxy putpixel registerbgifont setactivepage setbkcolor setfillstyle setlinestyle settextjustify setviewport textheight
arc
Имя
Заголовок
arc - вычерчивание дуги окружности, void
arc(int X, 1nt у.
int StAngle, int EndAngle, int Radius)
Прототип Функция
graphics.h
Вычерчивание дуги окружности с центром в точке (х, у) радиусом Radius, начиная с угла St Angle и заканчивая углом EndAngle.
Замечания
Система должна находиться в графическом режиме. Угла StAngle и EndAngle выражаются в градусах. Вычерчивание ведется против иасово访 стрелки. Для StAngle==D и EndAngle==360 вычерчивается полная окружность.
Пример
Вычерчивание дуги окружности с радиусом в 50 точек и центром, размещенным вблизи центра экрана.
/* Аге */
•Include «graph1cs.h>
•include <conio.h>
main()
{
Int Driver, Mode;
Driver ^= DETECT;
1nitgraph(&Driver, &Mode, и. .M)i
1f(graphresult( ) ! = grOk){
cprintf("FAILURE"),
exit(l);
}
arc(getmaxx( ) /2f getmaxy()/2,45r315,50);
whfle(! kbh1t());
close graph();
return 0;
bar
ИмяЗаголовокИмяЗаголовокПрототип ФункцияПрототип ФункцияЗамечанияЗамечанияbar - вычерчивание столбика, void
Имя
Заголовок
Имя
Заголовок
Прототип Функция
Прототип Функция
Замечания
Замечания
bar(Int «1, Int yl.
int x2. int y2) graphtes.h
Вычерчивание столбика (сооавляющего, например, элемент гистограммы) в виде закрашенного прямоугольника, противоположные по диагонали вершины которого имеют координаты (xl, у!) и (х2, у2). Система должна находиться в графическом режиме. Шаблон и цвет закрашивания прямоугольника мотут быть указаны с помощью функций setfillstyle или setflllpattern.
Призер
Вычерчивание столбцка по произвольно выбранному шаблону.
/* Ваг */
•include <graphics.h>
•include <conto.h>
char Pattern[]={"\x07\xdd\x0八x72\x50\x72V82"};
main ()
{
int Driver, Mode;
Driver == DETECT;
1n1tgraph(&Driver, &Mode, ”. .");
If(graphresult( ) 1 = grOk))
exit(l);
setfi11pattern(Patternr getmaxcolor());
bar(50f 50 getmaxx( ) - 50r getmaxy( ) - 50);
whlle(! kbhit());
close graph();
return D;
Имя
Заголовок
Прототип Функция
bar 3d - вычерчивание трехмерного столбика, void bar3d(int xl, Int yl, Int x2. Int y2) Int Depth, int TopFlag) graphIcs.h
Вычерчивание трехмерного столбика (составляющего» например, элемент шстограммы) в виде прямоугольно го параллелепипеда, передняя поверхность которого представляет собой закрашенный прямоугольник. Противоположиые по диагонали вершины прямоуголь ника определены как точки с координатами (xl, у2) и <х2, у2). Глубина параллелепипеда задается с помощью Depth, а необходимость вычерчивания его верхней поверхности указывается с помощью TopFlag. Система должна находиться в графическом режиме. Шаблон и цвет закрашивания прямоугольни ка могут быть указаны с помощью функций setfillstyle или setfillpattern. Оставляя невычерченной верхнюю поверхность, мы получаем возможность вычерчивать столбик, состоящий из нескольких кубиков. Неудачное выполнение функции bar 3d приводит к тому, что результатом функции graphresult является переменная со значением grNoScanMeni - не хватает памяти для закрашивания области методом сканирования.
Пример
Вычерчивание трехмерного столбика глубиной в 20 точек, с видимой верхней поверхностью, закрашенного по одному из стандартных шаблонов.
/* Bar3D */
include <graphics.h>
•include <conio.h>
■deftn® TopOn 1
main()
{
int Driver, Mode;
Driver = DETECT;
1 n1 tgraph(8iDriver, &Moder ”. .**);
if(graphresult( ) 1 = grOk)
exit (1);
setfi1lstyle(XHATCH_FILL, getmaxcolor());
bar3d(50, 50, getmaxx( ) - 50, getmaxy( ) - 50, 20, TopOn);
*hi】e(! kbhit());
closegraph()
return 0;
circle
ИмяЗаголовокИмяЗаголовокcircle - вычерчивание окружности, voidc1rcle(1nt x. Int y.circle - вычерчивание окружности, voidc1rcle(1nt x. Int y.Прототип ФункцияПрототип Функция1nt Radius)1nt Radius)ЗамечанияЗамечанияgraphics.hВычерчивание окружности с центром в точке <х, у) и радиусом Radius.Система должна находиться в графическом режиме.graphics.hВычерчивание окружности с центром в точке <х, у) и радиусом Radius.Система должна находиться в графическом режиме.
Имя
Заголовок
Имя
Заголовок
circle - вычерчивание окружности, void
c1rcle(1nt x. Int y.
circle - вычерчивание окружности, void
c1rcle(1nt x. Int y.
Прототип Функция
Прототип Функция
1nt Radius)
1nt Radius)
Замечания
Замечания
graphics.h
Вычерчивание окружности с центром в точке <х, у) и радиусом Radius.
Система должна находиться в графическом режиме.
graphics.h
Вычерчивание окружности с центром в точке <х, у) и радиусом Radius.
Система должна находиться в графическом режиме.
Пример
Вычерчивание окружности, расположенной вблизи центра экрана.
/* Circle */
^include «graphics.h>
#inc1ude <conio.h>
int Radius = 80;
main()
{
Int Driver. Mode;
Driver = DETECT;
1nitgraph(&Driver, &Modet ". .");
If(graphresult( ) I = grOk)
exit ⑴;
c1rcle(getmaxx( ) »1, getmaxy( ) - »1,RadIns);
*hi1e(! kbhit());
closegraph();
return 0;
cleardevice
Имя ЗаголовокПрототип ФункцияЗамечанияПримерИмя ЗаголовокПрототип ФункцияЗамечанияПримерcleardevice - очистка графического эрана.
Имя Заголовок
Прототип Функция
Замечания
Пример
Имя Заголовок
Прототип Функция
Замечания
Пример
void
cleardevice(void)
graphIcs.h
Очистка графического экрана и установка графического курсора в левом верхнем углу текущего графического окна.
Система должна находиться в графическом режиме.
Вывод в левом верхнем углу зкрана надписи Kaja и в центре экрана надписи Izabefe, а после нажатия любой клавиши - удаление надписи Kaja и замена надписи Izabela надписью Kajusia.
/* ClearDevice */
iinclude «graphics.h>
•include 《conio.h〉
#define ClipOn 1
ma1n()
Int Driver, Mode;
Driver = DETECT;
nftgraph(&Dr 1 verP &Mcde, ". .**);
if(QraphresuH( ) 1 = grOk)
exit (1);
outtext('Xaje#,);
setviewport(getmaxx( )/2„ getmaxy( )/2;
(getmaxx()『getmaxy( ).C1ip0n);
□uttextC'Izabe Ta");
while(! kbhit());
(void)getch();
c1eardevice();
out: text ("Kajusia**);
while(i kbhit());
closegraph();
return 0;
cleamewport
Имя ЗаголовокПрототип ФункцияИмя ЗаголовокПрототип Функциясlearviewport - очистка графического окна, void
Имя Заголовок
Прототип Функция
Имя Заголовок
Прототип Функция
clearviewport
graphics.h
Очистка текущего графического окна, а затем закрашивание его цветом,
соответствующим первой позиции палитры.
ЗамечанияСистема должна находиться в графическом
режиме. Неудачное выполнение функции clearvtewport приводит к тому, что результатом функции graphresult является переменная со значением
grNccanMem - не хватает памяти для закрашивания области методом сканирования.
Пример
Определение графического окна, вычерчивание в нем столбика, а после нажатия произвольной клавиши - очистка тетсущего сжна и вывод в нем надписи Viewport cleared.
/* СlearVlewport */
finclude 〈graphics.h>
finclude <conio.h>
^define CllpOn 1
struct viewporttype ViewPort;
ma1n()
Int Driver, Mode;
Driver н DETECT;
fn1tgraph(&Drtver, &Modec ". .'*);
1f(graphresult( ) £ = grOk)
ex1t(l);
setvieport(50, 50, getmaxx( ) — 50, getmaxy( ) - 50, CllpOn);
getv1ewsettt ngs(&M i ewPort);
bar(ViewPort, left.- VlewPort, top,
VlewPort. right. Viewport, bottom);
whf1e(! kbhit());
(void)getch();
clearviei^ort();
outtext(*'V 1 ewPort cleared");
whllef! kbhit());
closegraph();
return 0;
closegraph
Имя ЗаголовокПрототип ФункцияИмя ЗаголовокПрототип Функцияclosegraph - восстановление текстового режима, void closegraph
Имя Заголовок
Прототип Функция
Имя Заголовок
Прототип Функция
graphics・h
Восстановление текстового режима, очистка памяти, предоставленной автоматически программе графического драйвера и выбранному виду шрифта.
ЗамечанияСистема должна находиться в графическом
режиме. Память, выделенная с помощью функции reglsterbgldriver и reg isterbgi font, не подлежит очистке.
Пример
Вычерчивание огабающей ферана, а после нажатия произвольной клавиши клавиатуры - восстановление графического режима
/* Closegraph */
•include <graphics.h>
#include <conio.h> main () {
int Drived Mode;
1nt Hor, Ver;
extern, void Box(1nt x. int y);
Driver н DETECT;
1n1tgraph(&Driver„ &Mode, w..”);
1f(graphresiilt( ) ! = grOk)
ex1t(l);
Ног н getrwxxC );
Ver * getmaxy( );
Box(Horv Ver);
while(! kbh1t());
closegraph();
return 0;
} void Boxfint xv int y) { line(0, 0, xt 0); 1ine(x. 0, x. y); 1tne(x。 у, X, y); line(0t y. 0, 0);
clreol
ИмяЗаголовокПрототип ФункцияЗамечанияИмяЗаголовокПрототип ФункцияЗамечанияclreo] - удаление символе® в конце строки, void
Имя
Заголовок
Прототип Функция
Замечания
Имя
Заголовок
Прототип Функция
Замечания
clreol(void) coniо.h
Замена пробелами тех знаков в строке, которые расположены между курсором и концом строки. Система должна находиться в графическом режиме. Если цвет фона не является черным, то пробелы окрашиваются цветом, определяемым С помощью функции textbackground.
Замена знаков пробелами заканчивается в момент достижения правого края текущего текстового окна. Положение курсора не изменяется.
Пример
Индикация двух имен и двух фамилий, а после нажатия клавиши Enter удаление фамилии, связанной с именем Е
/* ClrEol */
•include <conio.h>
•Include <stdto.h>
rw1n()
clrscr();
q)rintf("Ewa Bielecka \n“);
cprintf('*Jan Blelecki \n");
wh11e(getchar( )1 工'\n');
gotoxy(5e 1);
clreol();
return 0;
clrscr
ИмяЗаголовокИмяЗаголовокПрототип ФункцияПрототип Функцияclrscr - очистка текстового окна, voiddrscr(void)clrscr - очистка текстового окна, voiddrscr(void)ЗамечанияЗамечанияconio.hОчищает текущее текстовое окно и устанавливает знаковый курсор в левый верхний угол этого окна. Если цвет фона не является черным, то окно заполняется пробелами, цвет которых определяется с помощью функции textbackground.conio.hОчищает текущее текстовое окно и устанавливает знаковый курсор в левый верхний угол этого окна. Если цвет фона не является черным, то окно заполняется пробелами, цвет которых определяется с помощью функции textbackground.
Имя
Заголовок
Имя
Заголовок
Прототип Функция
Прототип Функция
clrscr - очистка текстового окна, void
drscr(void)
clrscr - очистка текстового окна, void
drscr(void)
Замечания
Замечания
conio.h
Очищает текущее текстовое окно и устанавливает знаковый курсор в левый верхний угол этого окна. Если цвет фона не является черным, то окно заполняется пробелами, цвет которых определяется с помощью функции textbackground.
conio.h
Очищает текущее текстовое окно и устанавливает знаковый курсор в левый верхний угол этого окна. Если цвет фона не является черным, то окно заполняется пробелами, цвет которых определяется с помощью функции textbackground.
Пример
Вывод надписи Kajusia, а после нажатия клавиши Enter замена ее надписью Izusia.
/* ClrScr */
『include <graphics.h>
•Include <conio.h>
main()
{
clrscr();
cprlntfC^Kajusla");
whlle(getch&r( )! ^ ‘'n');
c1rscr();
cpr1ntf(**Izusia");
return 0;
delline
Имя
Заголовок
delline - удаление строки, void
de111ne(vo1d)
Прототип Функция
conio.h
Удаление из текстового окна строки, указываемой курсором. Смещение строк, расположенных ниже удаляемой строки, на одну строку вверх. В нижней части окна
Замечаний
добавляется одна пустая строка.
Если цвет фона не является черным, то пустая строка будет заполнена пробелами, цвет которых определяется функцией textbackground.
Пример
Вывод трех строк текста, а после нажатия произвольной клавиши удаление ересей из этих строк.
/* DelLIne */
findude <conio.h>
flnclude <stdto.h>
main()
clrscr();
cprtrrtf("Ewa Bielecka \n“);
cpr1ntf(°Iza Bieleckl \nM);
cprintf(MJan Btelecki \n"j;
gotoxy(5t 2);
wMle(! kbhtt());
(void)getch();
delllnef );
while(! kbhit());
return 0;
detectgraph
ИмяЗаголовокИмяЗаголовокПрототип ФункцияПрототип Функцияdetectgraph - определение графической платы, void
Имя
Заголовок
Имя
Заголовок
Прототип Функция
Прототип Функция
detectgraph(1nt * GraphDriver,
Int * GraphMode)
graphics.h
Определение графического драйвера, а затем присвоение переменной, на которую указывает
ЗамечанияЗамечанияGraphDriver, значения, равного номеру драйвера, а переменной, на которую указывает GraphMode, значения, равного номеру предполагаемого графического режима.
Замечания
Замечания
Значения, приписанные переменным, указываемым аргументами GraphDrlver и GraphMode, могут быть использованы в функции 1 nitgraph для установления графического режима. На самом деле вызов этой функции с первым аргументом DETECT влечет неявный вызов функции detectgraph. Номера адаптеров и режимов определяются следующими константами:
Вид драйвера
DETECT
•• автоматическое определение графического режима
CGA
-адаптер CGA
MCGA
-адаптер MCGA
EGA
-адаптер EGA
EGA64
- адаптер EGA64
EGAMONO
-адаптер EGAMONO
IBM8514
-адаптер IBM8514
HERCMONO
-адаптер Hercules
ATT400
-адаптер АТТ400
VGA
-адаптер VGA
PC3270
■ адаптер РС3270
Вид режима
CGACO
-320x200, палитра 0
CGAC1
-320x200, палитра 1
CGAC2
-320x200, палитра 2
CGAC3
-320x200, палитра 3
CGAHI
-640x200, 1 страница
MCGAC
-320x200, палитра 0
MCGAC1
- 320x200, палитра 1
MCGAC2
-320x200, палитра 2
MCGAC3
-320x200, палитра 3
MCGAME
-640x200, 1 страница
MCGAHI
-640x480, 1 страница
EGALO
-640x200, 16 цветов, 4 страницы
EGAHI
-640x350, 16 цветов, 2 страницы
EGA64LO
-640x350, 16 цвета, 1 страница
EGA64HI
-640x350, 4 цвета, 1 страница
EGAMONOHI
-640x350,
64K на плате, 1 страница
256К на плате, 2 страницы
HERCMONOHI
-720x348, 2 страницы
ATT400C0
-320x200, палитра 0
ATT400C1
-320x200, палитра 1
ATT400C2
-320x200, палитра 2
ATT400C3
-320x200, палитра 3
ATT400MED
-640x200, 1 страница
ATT400HI VGALO VGAMED VGAHI PC3270HI IBM8514LO IBM8514HI
640x400, 1 страниц
640x200, 16 цветов, 4 страницы
640x350, 16 цветов, 2 страницы
640x480, 16 цвета, 1 страница
720x350, 1 страница
640x480, 256 цветов
1024x768, 256 цветов
Неудачное выполнение функции detectgraph приводит к тому, что результатом функции graphresult является переменная со значением grNotDetected - отсутствует графический драйвер.
Пример
Определение графического драйвера и вывод его названия.
/* DetectGraph */
•include <con1o.h>
•include <graphics.h>
char *DrIvers []=
{”GGA\ "MCGA”, "EGA", "EGA64”.
•TGAMono*', IBM8514”,“HercYono".
”AH400, “VGA”. "PC3270”};
mdin()
{
Int Driver, Mode;、
clrscr();
detectgraph(&Dr1ver ₽ &Mode);
cprlntf (**%s"f Drivers [Dr Iver - 1]);
return 0;
drawpoly
Имя
Заголовок
drawpoly - вычерчивание ломаной линии, void
drowpoly(i nt NumPoints, int *PolyPoints)
Прототип Функция
graphics.h
Вычерчивание ломаной линии, состоящей из точек NumPotnts, координаты которых &, у) поочередно перечисляются, а переменная, которой соответ ствует первая из этих точек, указана в артументе
Замечания
PolyPoints.
Система должна находиться в графическом режиме.
Каждая пара координат задается двумя величинами типа (int). Для вычерчивания многоугольника следует задать последнюю пару координат идентичной первой.
Пример
Вычерчивание четырехугольника с произвольным образом выбранными вершинами.
/* DrawPoly */
♦Include «graphics.h>
•Include yonio.h〉
struct pointtype Tetragon[ ] «
{ {10. 10}.
{80, 40},
{30, 70}.
{40. 50},
{10, 10}};
main()
{ int Driver, Mode; Driver = DETECT;
initgraph(&Driver, &Mode. ". .M);
if(graphresult( ) I = grOk)
exit(l);
drawpoly(5. Tetragon);
while(! kbhltf ));
closegraph();
return 0;
ellipse
Имя
Заголовок
ellipse - вычерчивание эллипса, void
ellipse(int х, int у.
int StAngle, int EndAngl%
int xAxis, int yAxis)
Прототип Функция
graphics.h
Вычерчивание эллиптической кривой с центром в точке (х, у) и полуосями xAxis и yAxis, начиная с угла StAngle и заканчивая углом Erd*ngle.
Замечания
Система должна находиться в мафическом режиме. Углы StAngle и EndAngle заданы в градусах. Вычерчивание ведется против часовой стрелки. В случае StAngle==0 и EndAngle~360 вычерчивается полный эллипс.
Пример
Вычерчивание эллипса, расположенного в центре экрана.
/* Ellipse */
•Include «graphics.h*
finclude <conto.h>
main()
{
int Driver. Mode;
int xCen, yCen,
xRadt yRad;
Driver н DETECT;
ir1tgraph(&Driver, &Mode, ". .*);
if(graphresult( ) I = grOk)
ex1t(l);
xCen 工 getmaxx( )/2;
yCen = getmaxy( )/2;
xRad = 150;
yRad н 100;
el 11 pse(xCeiri,yCen, 0,360,xRad, yRad);
while(! kbh1t( )};
closegraph();
return 0;
fillellipse *
Имя
Заголовок
fillellipse - вычерчивание закрашенного эллипса, void far
fillellipse(int x, int y.
int xAxis,
int yAxis)
Прототип Функция
graphics.h
Вычерчивание закрашенного эллипса с
центром в точке (х, у) и полуосями xAxis и yAxis.
Замечания
Система должна находиться в мафическом режиме. Закрашивание производится текущим цветом.
Призер
Вычерчивание эллипса с полуосями по 100 точек, расположенного в центре экрана.
"FillEllipse */
•include «graphics.h*
#iDelude <cor»io.h>
main()
{
int Driver, Mode;
Driver = DETECT;
initgraph(&Driver, &Moder M..”);
if(graphresult( ) I 工 grOk)
exit(l);
fi 1 lei 11pse(getmaxx( ) »1, getmaxy( ) - »1, 100f 100);
17. Принципы описания423
whi1e(! kbhit());
(void)getch();
closegraphf );
return 0;
}
fillpoly
Имя
Заголовок
fillpoly - закрашивание многоугольника, void
fillpolyfint Num Points, fnt * PolyPoints)
Прототип Функция
graphics.h
Закрашивание по заданному шаблону многоугольника c Num Points вершинами, координаты которых поочеред но перечисляются, а первая из них приписывается переменной, указываемой аргументом PolyPoints.
Замечания
Система должна находиться в графическом режиме. Каждая пара координат задается двумя величинами типа (fnt). Шаблон и цвет закрашивания прямоугольника могут быть заданы с помощью функции setfillstyle и setfHlpattern. Неудачное выполнение функции fillpoly приводит к тому, что результатом функции graphresult является переменная со значением grNoScanMan - не хватает памяти для закрашивания области методом сканирования.
Пример
Вычерчивание четырехугольника и его закрашивание по одному из стандартных шаблонов.
/* 臼ГРоТу */
ftnclude<graphics.h>
#include<conio.h>
struct pointtype Tetragon[]= { {10, 10}, {80, 40}. {30, 70}. {40, 50};
Tnain()
{
int Driver, Mode;
Driver = DETECT;
initgraph(&Driverf &Mode. M..");
if(graphresult( ) t
=grOk)
exit(l);
setfi1lstyle(XHATCH_FILL, getmaxcolor());
fillpoly(4f Tetragon);
.while( I kbnit());
floodfill
Имя
floodfill - закрашивание области по заданному шаблону.
Заголовок
void
floodfill(int х. int у. int Border)
Прототип Функция
graphics.h
Закрашивание по заданному шаблону внутренней области, охватывающей точку с координатами (х, у) и ограниченной линией, номер которой задается
哥
Замечания
аргументом Border.
Система должна находиться в графическом режиме. Если точка с координатами (х. у) находится за пределами области, то закрашиванию подлежит внешняя часть этой области, ограниченная краями графического окна. Выполнение функции заканчива ется преждев ременно после ввода двух пустых линий.
Шаблон и цвет закрашивания могут быть заданы С помощью Функции setfillstyle или setfillpattern. Неудачное выполнение функции floodfill и приводит к тому, что результатом функции graphresult является переменная со значением
grNoFloodMem - не хватает памяти для закрашивания области лавинным методом.
Пример
}}closegraph();return 0;closegraph();return 0;
}
}
closegraph();
return 0;
closegraph();
return 0;
Закрашивание внешней области треугольника с произвольным образом выбранными вершинами.
/* FloodFill */ find ude<g raph ics.h> findude<con1o.h> struct pointtype Triangle[〕=
{ {50, 100}.
{100f 100}.
{150, 150}, {50, 100};
main()
{
int Driver, Mode;
Driver = DETECT;
initgraph(&Driver, &Modet ". .**);
if(graphresu1t( ) I = grOk) exit(l);
drawpoly(4. Triangle);
floodfill(0, 0. getmaxcolor());
while( I kbhit());
closegraph();
return 0;
}
getarccoords
Имя
Заголовок
getarccoords - определение координат дуги, void
getarccoords (struct arccoordstype *Arcl;oords)
Прототип Функция
graphics.h
Присвоение структуре, указанной в аргументе ArcCoords, значения типа (struct arccoordstype), определяющего параметры дуги окружности, вычерчиваемой с помощью функции аге.
Замечания
Система должна находиться в графическом режиме. Тип
(struct arccoordstype) определен следующим образом:
struct arccoordstype { int xt у;
int xstart. ystart;
int xend. yend;
Поля x и у определяют координаты центра окружности, поля xstart и ystart указывают координаты начала дуги, а поля xerd и yend - координаты конца дуги.
Пример
Вычерчивание дуги окружности, соединение концов дуги отрезком прямой линии, а затем закрашивание внешней области полукруга по одному из стандартных шаблонов.
/* GetArcCoords */
#include<graphics.h>
#inc1ude<conio.h>
struct arccoordstype ArcCoords;
matn()
int Driver, Mode;
Driver = DETECT;
initgraph(&Driver, &Mode, *'..“);
if(graphresult( ) 1 = grOk)
exit(l);
arc(getmaxx( )/2, getmaxy( )/2,0,180,100);
getarccoords(&ArcCoords);
11ne(ArcCoords.xstart,ArcCoords.ystart, ArcCoords.xend,ArcCoords♦yend);
setfi1lstyle(XHATCH_fILLr getmaxcolor());
floodfill(0,0fgetmaxcolor());
whtle( I kbhit());
closegraph();
return 0;
getaspectratio
Имя
getaspectratio - Определение коэффициента сжатия экрана.
Заголовок
void
getaspectratioCint * xAsp,
Прототип Функция
int * yAsp)
graphics.h
Присвоение переменным, указанным в аргументах xAsp и yAsp, значений типа (int), на основе которых можно вычислить коэффициент сжатия экрана.
Замечания
Система должна находиться в графическом режиме. Применение коэффициента сжатия, выражаемого в
•
виде отношения хАзр/yAsp, позволяет вычерчивать прямоугольники, имеющие вид квадрата, и эллипсы в виде окружн(юти.
Пример
Вычерчивание
прямоугольника, по виду близкого к квадрату.
/* GetAspectRatio */
#1nc1ude<graphics.2
#1nclude<conio.h>
#include<math.h>
main()
{
tnt Driver, Mode;
Int xAsp. yAsp
int xSide, ySIde;
Driver = DETECT;
initgraph(&Driver, &Mod% ". ."*);
if(graphresult( ) I = grOk)
exit(l);
getaspectratiо(&xAsp. &yAsp);
xS1de * 100;
ySlde » floor((float)xAsp/yAsp * xSide + 0.5);:
rectangle(0t 0(xSideryS1de);
while( I kbh1t());
closegraph();
return 0;
getbkcollor
Имя
getbkcoior - задание цвета фона.
Заголовок
int
Прототип
getbkcoior(void) graphics.h
Функция
Формирование величины типа (int) со значением,
Замечания
равным номеру той позиции палитры, которая указывает цвет фона.
Система должна находиться в графическом режиме.
Пример
Если результатом функции является значение, равное п, то цвет фона задается п-й позицией палитры. В случае применения драйвера Hercules фон может быть только черным, а результатом функции getbkcoior является зкз\С1‘нс 0.
Вычерчивание диагонали экрана, а после нажатия произвольной клавиши удаление с экрана половины этой диагонали.
/* GetBkColor */
#include<graphics.h>
#inc1ude<conio.h>
main()
Int Driver, Mode;
Driver 工 DETECT;
initgraph(&Driver, KMode. ". .");
if(graphresu1t( ) I * grOk)
exH(l);
1ine(0°0, getmaxx( )/2 *2,
getmaxy( )/2, *2);
while( I kbh1t());
(void)(getch();
setcolor(getbkcolor());
line(0.0, getmaxx( )/2, getmaxy( )/2);
while( I kbnit());
closegraph();
return 0;
getcolor
Имя
getcolor - получение номера цвета. '
Заголовок
int
getcolor(vold)
Прототип
graphics.h
Функция
Формирование значения типа (1nt>, равного номеру
ЗамечанияЗамечаниятекущего цвета, используемого для вычерчивания линии.
Замечания
Замечания
Система должна находиться в графическом режиме. Если результатом функции getcolor является значение, равное п, то текущий цвет задается n-й позицией палитры. В случае применения драйвера Hercules результат, равный 0, означает черный цвет, а результат, равный 1, - белый цвет.
Пример
Попеременное вычерчивание и стирание горизонтальной линии, расположенной вдоль верхнего края экрана, на мониторе, управляемом драйвером Hercules. 俊
/* GetColor */
find ude<graph i cs. h>
#include<conio.h> main() { tnt Driver, Mode; tnt i; * Driver 二 DETECT; 1 nitgraph(&Dr 1 ver, &Modef M. ."*); И((graphresult( ) t = grOk)|(Driver I = HERCMONO)) exit(l);
for(1 я 1; i < = 15; i ++){
Hne(0,0・ getmaxx( ), 0);
setco1or(1-getcolor());
sleep();
}
wMle( I kbh1t());
closegraph();
return 0;
getdefaultpalette
ИмяЗаголовокИмяЗаголовокПрототип ФункцияПрототип Функцияgetdefaultpalette - получение ИСХОДНОЙ палитры, void far * fargetdefaultpalette(void)getdefaultpalette - получение ИСХОДНОЙ палитры, void far * fargetdefaultpalette(void)graphics.hgraphics.hЗамечанияЗамечанияФормирование значения типа (void far *), указывающего ту палитру, которая была выбрана непосредственно после инициирования драйвера. Система должна находиться в графическом режиме. Инициирование драйвера производится с помощью функции 1 nitgraph.Формирование значения типа (void far *), указывающего ту палитру, которая была выбрана непосредственно после инициирования драйвера. Система должна находиться в графическом режиме. Инициирование драйвера производится с помощью функции 1 nitgraph.
Имя
Заголовок
Имя
Заголовок
Прототип Функция
Прототип Функция
getdefaultpalette - получение ИСХОДНОЙ палитры, void far * far
getdefaultpalette(void)
getdefaultpalette - получение ИСХОДНОЙ палитры, void far * far
getdefaultpalette(void)
graphics.h
graphics.h
Замечания
Замечания
Формирование значения типа (void far *), указывающего ту палитру, которая была выбрана непосредственно после инициирования драйвера. Система должна находиться в графическом режиме. Инициирование драйвера производится с помощью функции 1 nitgraph.
Формирование значения типа (void far *), указывающего ту палитру, которая была выбрана непосредственно после инициирования драйвера. Система должна находиться в графическом режиме. Инициирование драйвера производится с помощью функции 1 nitgraph.
Пример
Иллюстрация воспроизведения палитры, которая была выбрана по умолчанию при инициировании драйвера.
/* GetDefau 1 tPalette */
finclude<graphics.h>
#1nclude<conio.h>
#1nc1ude<dos.h>
#include<std11b•h>
main()
{
Int Driver, Mode;
struct palettetype far *OldPalf NewPa1;
Driver - DETECT;
initgraph(&Driver, —% ", .");
if(graphresult( ) I = grOk)
exit(l);
setcolor(l);
outtext(°Hello");
delay(2000);
wMle( t kbhitf )){
NewPal.colors[l] = rand( ) % NewPal. size;
setalIpa1ette(&NewPa1);
(void)getch();
01dPa1 - getdefaultpalette(); setalIpalette(OldPal};
delay(2000);
closegraphf );
return 0;
getdrivername
ИмяЗаголовокИмяЗаголовокПрототип ФункцияПрототип Функцияgetdrivername - получение имени драйвера, char * fargetdrivername(void)getdrivername - получение имени драйвера, char * fargetdrivername(void)graphics.hgraphics.hЗамечанияЗамечанияФормирование значения типа (char*), описывающего последовательность символов, представляющих имя графического драйвера.Система должна находиться в графическом режиме.Формирование значения типа (char*), описывающего последовательность символов, представляющих имя графического драйвера.Система должна находиться в графическом режиме.
Имя
Заголовок
Имя
Заголовок
Прототип Функция
Прототип Функция
getdrivername - получение имени драйвера, char * far
getdrivername(void)
getdrivername - получение имени драйвера, char * far
getdrivername(void)
graphics.h
graphics.h
Замечания
Замечания
Формирование значения типа (char*), описывающего последовательность символов, представляющих имя графического драйвера.
Система должна находиться в графическом режиме.
Формирование значения типа (char*), описывающего последовательность символов, представляющих имя графического драйвера.
Система должна находиться в графическом режиме.
Пример
Вывод надписи HERC на экран монитора, управляемого драйвером Hercules.
/* GetDriverName */
findude<graphics.h>
#ir»clude<conio.h>
mair»()
{
int Driver, Mode;
char *Name;
Driver ° DETECT;
1nitgraph(&Driverr &Mode, ”. .");
if(graphresult( } I * grOk) exit(l);
Name 工 getdrIvername();
closegraph();
cprintf(w%s*. Name);
return 0;
getfillpahern
Имя
getfillpattem - сообщение о шаблоне закрашивания областей.
Заголовок
Прототип Функция
void
getf1llpattern(char * Pattern)
graphics.h
Размещение в области памяти, на начальный адрес которой указывает аргумент Pattern, восьми значений типа (unsigned char), описывающих намеченный пользователем шаблон для закрашивания областей.
Замечания
Система должна находиться в графическом режиме. Если перед вызовом функции getfillpattem функция setfillpattern не вызывалась, то в указанную область памяти будут помещены значения Oxff.
Пример
Заполнение экрана редко расположенными горизонтальными линиями.
/* GetFillPattern */
#1nc1ude<graph i cs.h>
#include<conio.n>
char Patternt&];
main()
int Driver, Mode;
int t;
Driver = DETECT;
initgraph(&Driver, &Mode, ". .");
1f(graphresult( ) I = grDK)
exit(l);
getfillpattern(Pattern);
for(1*0; i<8; i++)/
if(! (i & D)
Pattern[i] = 0;
setfillpat tern (Pattern, gt'tmaxcolor());
f1oodfi11(0p0,getmaxcolor());
closegraph();
return 0;
getfillsettings;
ИмяЗаголовокПрототип ФункцияЗамечанииИмяЗаголовокПрототип ФункцияЗамечанииgetfillsettings - сообщение о шаблоне закрашивания областей.
Имя
Заголовок
Прототип Функция
Замечании
Имя
Заголовок
Прототип Функция
Замечании
void
getfillsettings(struct filIsett1ngstype
*Info)
graphics.h
Присвоение структуре, указываемой аргументом info, значения типа (struct filIse."tingstype):, указывающего шаблон для закрашивания областей и номер цвета для вычерчивания линий.
Система должна находиться е: 1рафическом режиме. Тип
(struct fillsettingstype)определен следующим образом:struct f illseti.ingstype{int patten;
int color; }
Поле pattern указывает номер шаблона, выбранного с помощью функции setfillstyle или определенного с помощью функции setfillpattern, а поле color указывает номер инета, которь й будет использован для закрашивания областей. В1оды шаблонов, характеризуюсдих способ закрашивания областей, задаются следующим образом:
EMPY_FILL
-цветом фона
S0Ll6_FIU
-одним и тем же цветом
LIWE_FIl.l.
-утолщенными горизонтальными линиями
LTSLASH_F;Ll.
-наклонными линиями
SLASH_FILL
-утолщенными наклонными линиями
BKSLASH一FILL
-утолщенными линиями
LTBKSl 応 H_FI
-диагональными линиями
HATCH_FILL
-вертикальной сеткой
XHATCH_FILL
-диагональной сеткой
INTERLEAVE_FILL
-переплетенными линиями
WIDEDOT_FILL
-точками
CLOSEDOT_FILL
-сгущенными точками.
Пример
Сообщение о текущем шаблоне закрашивания областей.
/* 6etFillSettings */
#include<graphics.h»
#1псlude<conio.h>
struct fillsettingstype FillSettings;
ma1n()
{
Int Driver, Mode;
Driver “DETECT;
1n1tgraph(&Driver, &Modet ". •");
if(graphresult( ) 1 * grOk)
exit(i)j
setf11lstyle(XHATCH_rILl.„ getmaxcolor());
c1rcle(getmaxx( )/2, geimixy( )/2, 50));
floodfill(getmaxx( )/2. g«taxy( j/2);
getriaxcolor());
getfillsettings(&FillSettings);
if(FillSettings.pttern »* XHATChLFILL]
outtext^y(0,0、HatchF111”);
closegraph();
return 0;
getgraphmode
Имя
getgraphmode - сообщение о текущем графическом режиме^.
Заголовок
int
getgraphmode(void)
Прототип Функция
graphics«h
Формирование значения типа (int), определяющего номер текущего графического режима.
Замечания
Система должна находиться в графическом режиме. Результатом является значение типа (Int), находящееся в диапазоне 0 .. 5 и указывающее номер режима, установленного с помощью функции initgraph или setgraphmode. Номера режимов выражаются следующими константами:
CGACO
-320x200, палитра 0
CGAC1
-320x200, палитра 1
CGAC2
-320x200, палитра 2
CGAC3
-320x200, палитра 3
CGAHI
-640x200, 1 страница
MCGACO
-320x200, палитра 0
MCGAC1
-320x200, палитра 1
MCGAC2
-320x200, палитра 2.
/7. Принципы описания
MCGAC3
-320x200, палитра 3
MCGAMED
-640x200, 1 страница
MCGAHI
-640x480, 1 страница
EGALO
-640x200, 16 цветов,
4 страницы
EGAHI
-640x350, 16 цветов.
2 страницы
EGA64L0
-640x350, 16 цветов.
1 страница
EGA64HI
-640x350, 4 цвета.
1 страница
EGAMONOHI
-640x350,
64K на плате, 1 страница
256K на плате, 2 страницы
HERCMONOHI
-720x348, 2 страницы
АП400С0
-320x200, палитра 0
ATT400C1
-320x200, палитра 1
ATT400C2
-320x200, палитра 2
ATT400C3
-320x200, палитра 3
ATT400MED
-640x200, 1 страница
ATT400HI
-640x400, 1 страница
VGA1.0
-640x200, 16 цветов,
4 страницы
VGAMED
-640x350, 16 цветов.
2 страницы
VGAHI
-640x480, 16 цветов.
1 страница
PC327OHI
-720x350, 1 страница
IBM8514L0
-640x480, 256 цветов
1ВМ8514НГ
-1024x768, 256 цветов
Пример
Вывод числа 1 на экран монитора, управляемого драйвером Hercules.
/* GetGraphMode */ find ude<graphi cs. h> #1nclude<conio.h>
#include<stadio.h>
ma1n()
int Driver, Mode;
Driver = DETECT;
n 1 tgraph(&Driver, &Mode, и. .'*);
1f(graphresult( ) I 工 grOk) exit(l);
1f(Driver == HERCMONO){ restorecrtmode();
cprintf('W. getgraphmode( ) = HERCMONOHI); /* 1 */,
while(getchar( ) I = 'W);
setgraphnwde(Mode);
}
while(!kbhit()J; closegraph();
return 0;
getimage
ИмяЗаголовокИмяЗаголовокПрототип ФункцияПрототип ФункцияЗамечанияЗамечанияgetimage - запоминание изображения.
Имя
Заголовок
Имя
Заголовок
Прототип Функция
Прототип Функция
Замечания
Замечания
void
getimage (int xlr int ylf Int x2. int y2. void * BitMap) graphics.h
Выделение в текущем графическом окне прямоугольной области, противоположные по диагонали вершины, которой имеют координаты (xl, yl) и (х2. у2), а затем запоминание заключенного в этом прямоугольнике изображения в области памяти, указанной аргументом BitMap.
Система должна находиться в графическом режиме» Размер области рекомендуется указывать с помощью функции imagesize.
Пример
Запоминание и воспроизведение изображения
/* Getimage */ finclude <graphics.h> ¥oid*Ref main() {
int Driver, Mode;
Driver = DETECT;
1nitgraph(&Driver. &Mode. ". •”);
1f(graphresu1t()l = grOk) exit(l)
11ne(0.0, getmaxx()r getmaxyO);
Ref h ma Hoc(i mages1ze(0,0 getmaxx(), getmaxy())); getImage(0,0, getmaxx(). getmaxy(). Ref);
while(!kbhit());
(¥oid)getch();
clearv1ewport();
putimage(0,0 Ref^COPY PUT);
while(!kbhit());
closegraph();
return 0;
getlinesettings
ИмяИмяgetlinesettings - сообщение о параметрах линии.
Имя
Имя
Заголовок
void
getlinesettings
(struct linesettingstype * Info)
Прототип Функция
graphics.h
Присвоение структуре info значения типа
(struct linesettingstype).
характеризующего вид, шаблон и толщину линии.
Замечания
Система должна находиться в графическом режиме. Тип
(struct linesettingstype) определен следующим образом:
struct linesettingtype {
Int linestype; unsigned upattern; Int thickness;
Поле lines type указывает номер вида линии. Если ЭТОТ номер равен USERBIT_LINE,. ТО поле ^pattern указывает шаблон линии. Поле thickness толщину линии. Приписываемые полями linestyle и chickness значения выражаются следующими константами:
Поле Unestyle
SOLID_LINE-непрерывная линия
DOTTED LINE-точечная линия
CENTER LINE-точечнопунктирная линия
DASHED一LINE-пунктирная линия
USERBIT_LINE - линия, определяемая пользователем,
Поле thickness
NORMJWIDTH— тонкая линия
THICKJIDTH- утолщенная линия
В поле upattem может быть указано произвольное 16-бит обозначение шаблона.
Пример
Вычерчивание линии и сообщение о ее шаблоне.
/* GetLineSettings */
findude<graph ics.h>
#include<conio.h>
struct linesettingstype LineSetting;
main()
{
int Driver, Mode;
unsigned Mask;
Driver = DETECT;
1n1graph(&Driver, BiMode, *'..");
if(graphresult()! « grOk)
exit(i);
se11inestуle(USERBIT_LINE, 0x8f. NORM_WIDTH);
line(Or getmaxy()/2. getmaxx()f getmaxy()/2);
get11nesettings(&L1neSetting);
Mask ■ 1 « 15;
for(1 * 0; t<16; 1 ++){
if(LineSetting.upattern & Mask) outtext(w*w);
else
outtext(">")
Mask » = 1;
}瞪
while(!kbhit());
closegraph();
return 0;
}
getmaxcolor.
Имя
getmaxcolor ~ сообщение о максимальном номере цвета.
Заголовок
int
getmaxcolor(void)
Прототип Функция
graphics.h
формирование значения типа (int), определяющего максимальный номер цвета.
Замечания
Система должна находиться в графическом режиме.
Пример
Вычерчивание отрезка прямой линии цветом, равным максимальному номеру цвета.
/* GetMaxColor */
#include<graphics.h>
#1nclude<con1o.h>
niain()
{
Int Driver, Mode;
Driver в DETECT;
initgraph(&DrIver, &Moder ". .”);
1f(0raphresult() I ■ grOk)
exit⑴
setcolor(getinaxcolor());
lineto(getinaxx()t 0);'
wM、(J kbhit());
/7. Принципы описания437
closegraph(); return 0;
}
getmaxmode
Имя
getmaxmode - сообщение о максимальном номере графического режима.
Заголовок
Int far
getmaxmode(void)
Прототип
Функция
graphics.h
Формирование значения типа (int), определяющего максимальный номер графического режима.
Замечания
Система должна находиться г графическом режиме.
Пример
Выдача максимального номера графического режима.
/* GetMaxMode */
#include<graphics.h>
findude<con1o.h>
main()
{
int Driver, Mode, Max;
Driver ^ DETECT;
1n1tgraph(&Dr1ver, &Mode, ". .");
if(graphresult() I = grOk)
exit(i)
Max = getmaxmode();
setcolor(getmaxcolor());
closegraph();
cprintfC'%dM. Max);
return 0;
}
getmaxx
Имя
getmaxx - сообщение о максимальном значении горизонтальной координаты графического экрана.
Заголовок
1nt
getmaxx(voicl)
Прототип Функция
graphics.h
Формирование значения типа (int), определяющего максимальную горизонтальную кординату графического
Замечания
экрана.
Система должна находиться в графическом режиме. Значения горизонтальной координзты принадлежат диапазону 0.. getmaxx().
Пример
Вычерчивание отрезка прямой линии вдоль верхнего края экрана.
/* GetMaxX */
#include<graphics.h>
#include<conio.h>
main()
{
int Driver, Mode;
Driver 匸 DETECT;
1n1tgraph(&Driver, 8tMode, и..");
1f(graphresult() I = grOk)
exit。)*
7ine(0.0, getmaxx(), 0);
while( I kbhitO);
closegraph();
return 0;
}
getmaxy
Имя
getmaxy - сообщение о максимальном значении вертикальной координаты графического экрана.
Заголовок Прототип Функция
Int
graphics.h
Формирование значения типа (Int), определяющего максимальную вертикальную координату графического экрана.
Замечания
Система должна находиться в графическом режиме. Значения вертикальной координаты принадлежат диапазону 0. .getmaxy().
Пример
Вычерчивание отрезка прямой линии вдоль левого края экрана
/* GetMaxY */
#include<graphics.h>
#include<conio.h>
main()
{
int Driver, Mode;
Driver * DETECT;
initgraph(&Driver, &Modet M..");
if(graphresult() I 匸 grOk)
ex1t(l)
line(0r0,^r getmaxy());
wh1le(! kbhitO);
closegraph()i; return 0;
getmodename
ИмяЗаголовокПрототип ФункцияЗамечанияИмяЗаголовокПрототип ФункцияЗамечанияgetmodename - сообщение о наименовании графического режима.
Имя
Заголовок
Прототип Функция
Замечания
Имя
Заголовок
Прототип Функция
Замечания
chay * far
getmodename (,nt 丛圈)
graph!cs.h
Формирование значения типа (char *), задающего последовательность символов, определиющих графический режим с номером Num.
Система должна находиться в графическом режиме.
Пример
Выдача имени режима с номером 0. Вывод надписи 720 х 348 HERCULES на экран монитора, уирзвляемого драйвером Hercules.
/* GetModeName */
#include<graphics.h>
f1nclude<conio.h>
main()
{
int Driver, Mode;
char "Name;
Driver * DETECT;
initgraphf&Driver. &Mode. ". .”);
if(graphresult() I 匸 grOk)
exit(l)
Name * getmodename(0);
closegraphf);
cpr1ntf(',%S", Name);
return 0;
getmoderange
ИмяЗаголовокИмяЗаголовокПрототип ФункцияПрототип Функцияgetmoderange - сообщение о диапазоне графических режимов.
Имя
Заголовок
Имя
Заголовок
Прототип Функция
Прототип Функция
void
getmoderange(int GraphDriver.
int * LoMode,
Int * HiMode
graph1cs.h
Присвоение переменной, указанной в аргументе
LoMode, наименьшего, а переменной, указанной
в аргументе Hl Mode, наибольшего номера режима для графического драйвера С номере^ GraphDriver.
ЗамечанияЗамечанияСистема должна находиться в графическом режиме. Если номер драйвера не принадлежит диапазону 1..5 или 7..10, то переменным, указанным в аргументах LoMode и HiMode, будут присвоены значения -1. Номера графических драйверов описываются следующими константами:
Замечания
Замечания
CGA
-драйвер GCA
MCGA
-драйвер MCGA
EGA
-драйвер EGA
EGAMONO
-драйвер EGAMono
IBM8514
-драйвер IBM8514
HERCMONO
-драйвер Hercules
ATT400
-драйвер АТТ400
VGA
-драйвер VGA
PC3270
-драйвер РС3270.
Пример
Определение диапазона допустимых режимов монитора, управляемого драйвером Hercules.
/* GetModeRange */
#1nclude<graph1cs.h>
#include<conio.h>
main()
{
■ 1nt LoMode, HiMode;
getmoderange(HERCMONOr &Mode, &H1Mode);
cpr1ntf(nLoMode = X dwr LoMade); /* 0 */
cprintf(°HiMode 工 X cT. HiMode); /* 0 */
while(!kbhit());
closegraph();
return 0;
getpalette
Имя
Заголовок
getpalette - сообщение о текущей палитре цветов, void
getpalette(struct palettetype * Palette)
Прототип Функция
graphics.h.
Присвоение структуре типа (struct palettetype), указанной в аргументет Palette, значений, определяющих размер палитры цветов и идентификаторы цветов, соответствующих отдельным позициям палитры.
Замечания
Система должна находиться в графическом режиме.
Тип
(struct palettetype} определен следующим образом: struct_palettetype { unsigned char size;
signed char colors[16];
}
Поле size указывает размер палитры, а поле colors - идентификаторы цветов, соответствющих очередным позициям палитры。Идентификаторы цветов задаются следующими константами:
BLACK-черный
BLUE-голубой
GREEN-зеленый
CYAN-бирюзовый
RED-красный
MAGENTA-ярко-красный
BROWN-коричневый
LIGHTGRAY-светло-серый
DARKGRAY-темно-серый
LIGHTBLUE-светло-голубой
LIGHTGREEN-светло-зеленый、
LIGHTCYAN-светло-бирюзовый
LIGHTRED-светло-красный
LIGHTMAGENTA-светло-ярко-красный
YELLOW-желтый
WHITE-белый.
Пример
Вывод названий цветов на экран в принятой палитре монитора, управляемого драйвером EGA.
/* GetPalette */
findude<graphics.h>
#include<conio.h>
srtuct palettetype Palette;
char *Names[]
{•'Black'\ "Blue0. •'Green*', "Cyan", "Red", "Magenta'*t "Brown", •tightGray".
"DarkGray4, MLightBlue", ,tLightGreen,\ ^LightCyan**, •,LightRed",
•TightMagenta", MYellowM. •'White"};
main()
int Driver, Mode:
int 1;
detectgraph(& Driver, &Mode);
if((graphresult()! = grOk)|| (Driver! = EGA)){
cprintf(wFailureM)
exit(l);
}
getpa1ette(&Palette);
restorecrtmode();
for(i=0, i<=Paletter size-1; i ++) {
if(Palette.colors[i]<16)
cprintfC^ZO", Names[Palette.colors[i]]);
else
cprintf("???:( %d", Palette.colors[i]);
}
return 0;
getpalettesize
Имя Заголовок
getpalettesize - сообщение о размере палитры. Int far
getpalettesize(void)
Прототип Функция
graphics.h
Формирование значения типа (int), равного размеру палитры.
Замечания
Система должна находиться в графическом режиме. В
•
случае монитора, управляемого драйвером EGA, рассматриваемое значение равно 16.
Пример
Определение размера палитры. Вывод числа 1 на экран монитора, управляемого драйвером Hercules.
/* GetPaletteSize */
#include<graphics.h>
firclude<conio.h>
main()
{
int Driver, Mode, Size;
Driver = DETECT;
initgraph(& Driver, &Mode, w..");
if(graphresult()! = grOk)
exit(l);
Size = getpaletts1ze();
closegraph();
cprintf(%d*\ Size);
return 0;
getpixel
Имя ЗаголовокПрототипИмя ЗаголовокПрототипgetpixel - сообщение о номере цвета точки.
Имя Заголовок
Прототип
Имя Заголовок
Прототип
unsigned
getpixel(int х, Int у)
graphics.h
ФункцияФормирование значения типа (unsigned), равного
ру цвета точки с координатами (х, у).
ЗамечанияСистема должна находиться в графическом режиме.
Пример
Вычерчивание точки цветом, соответствующим последней позиции палитры, а затем вывод номера этого цвета.
/* GetPixel */ #1nclude<graph1cs.h> #irclude<conio.h> main() {,
Int Driver. Mode;7,
int ColNun; Driver = DETECT 1n1tgraph(& Driver, &Mode. ". .**);
1f(graphresult()! = grOk) exit(l);
putpixel(OtOv getmaxcolorO);
ColNum = getpixel(OtO); restorecrtniode ();
cprintf(MColor number = %d°. Co1Nun); return 0;
gettext
Имя
Заголовок
gettext - перенесение текста с экрана в память. Int
gettext(int xl( int yl, Int x2, int y2.
void * TextArea)
Прототип Функция
conIo.h
Перенесение текста, находящегося в прямоугольнике с координатами противоположных по диагонали вершин (х1. yl) и (х2. у2), в область памяти, указанную в
Замечания
аргументе TextArea.
Результатом функции является величина типа (int), которая в случае удачного выполнения операции принимает значение, отличное от 0.
Пример
Перенесение символов из произвольным образом выбранного прямоугольника в другое место экрана.
/* GetText */
#t nclude<con1o.h>
char Family[100];
nain()
{
clrscr();
cpr i ntf(**Ewa\r\nw);
cprintf(Iza\r\nw);
cprt ntfi"Jan\r\rT);
gettext(lf 1. 4. 3, Family);
clrscr();
puttext(20. 13. 23・ 15. Family);
gettextinfoГИмяЗаголовокПрототип ФункцияЗамечанияgettextinfoГИмяЗаголовокПрототип ФункцияЗамечанияreturn 0;
gettextinfo
Г
Имя
Заголовок
Прототип Функция
Замечания
gettextinfo
Г
Имя
Заголовок
Прототип Функция
Замечания
gettextinfo - сообщение об условиях отображения текста на экране.
void
gettextinfо(struct tett_info * Info)
conio.h
Присвоение структуре типа (struct text-inf о), указанной в аргументе info, значений, характеризующих текущие условия отображения текстов.
Тип (struct text_1nfo) определен следующим образом:
struct text_Info { unsigned char winleft, wintop, winright, winbottom, attribute, normattr, currmode, screenheight, screenwidth, curx, cury;
}
Поля winleft, wIntop, winright, wtnbottom определяют координаты углов текстового окна, а поле attribute ~ признак, присвоенный переменной TextAttr; поле normattr указывает принятый по умолчанию признак этой переменной; поле currmode определяет текущий режим вывода Символов» поля screenheight и screenwidth указывают соответственно вертикальный и горизонтальный размеры экрана, выраженные количеством символов, а поля curx и сигу задают гехущ2£2 координаты графического курсора.
Пример
Определение размеров окна в текстовом режиме, принятом по умолчанию»
/* GetTextlnfo */
fInclude <conio.h>
struct text_info Textinfo;
Ma1n()
{
clrscr();
gettextt nfo(&TextInfo);
cprintf(*'Screen size Is %d x %d'\
Textinfo, screenwidth, Textinfo, screenheight);
return 0;
}
gettextsettings
ИмяЗаголовокПрототип ФункцияЗамечанияИмяЗаголовокПрототип ФункцияЗамечанияgettextsettings - сообщение о параметрах вычерчивания текстов.
Имя
Заголовок
Прототип Функция
Замечания
Имя
Заголовок
Прототип Функция
Замечания
void
gettextsettings(struct textsettingstype *Info)
graphIcs.h
Присвоение структуре, указанной в аргументе Info, значений записи типа
(struct textsett i ngstypy), указывающей формат шрифта, направление вычерчивания текста и способ его выравнивания. Система должна находиться в графическом режиме. Тип
(struct textsettingstype) определен следующим образом:
struct text settingstype {
int font;
int charsize;int charsize;int horiz;int vert;int horiz;int vert;}Поле font указывает DEFAULT_FONTTRIPLEX.FONT SMALL_FONT SANS_SERIF_FONT G0THIC_F0NT}Поле font указывает DEFAULT_FONTTRIPLEX.FONT SMALL_FONT SANS_SERIF_FONT G0THIC_F0NTint direction;
int charsize;
int charsize;
int horiz;
int vert;
int horiz;
int vert;
}
Поле font указывает DEFAULT_FONT
TRIPLEX.FONT SMALL_FONT SANS_SERIF_FONT G0THIC_F0NT
}
Поле font указывает DEFAULT_FONT
TRIPLEX.FONT SMALL_FONT SANS_SERIF_FONT G0THIC_F0NT
номер шрифта:
шрифт, принятый по умолчанию,
тройной шрифт,
индексный шрифт,
шрифт сансериф
готический шрифт.
Поле direction указывает направление вычерчивания
текстов:
HORIZ_DIRVERT_6lRHORIZ_DIRVERT_6lRгоризонтально,
HORIZ_DIR
VERT_6lR
HORIZ_DIR
VERT_6lR
вертикально.
Поле chars ^ze указывает множитель для определения размера шрифта (если charsize — USER_CHAR一SIZE, то вертикальный и горизонтальный множители размера шрифта определяются функцией setusercharsize); поле horiz указывает способ выравнивания текста в горизонтальном направлении:
LEFTJEXT CENTERJEXT RIGHT_TEXTLEFTJEXT CENTERJEXT RIGHT_TEXT-выравнивание влево,
LEFTJEXT CENTERJEXT RIGHT_TEXT
LEFTJEXT CENTERJEXT RIGHT_TEXT
-выравнивание по центру,
-выравнивание вправо;
в вертикальном направлении: BOTTOMJEXT - выравнивание вниз, CENTERJEXT - выравнивание по центру, ТОР_ТЕХТ - выравнивание вверх.
Значения, приписанные полям font, direction, horiz и
vert, выражаются перечисленными выше константами.
Пример
Вывод на экран надписи Janek, а затем вывод символа, указывающего выбранное направление вывода этой надписи.
/* GetTextSettings */
#incl ude<gra|5h ics.h>
^include<conio.h>
struct textsettingstype TextSettingS;
char *Names[]=
{ ”Left Text". ''Center Text”. "Right Text*'};
main()
int Driver, Mode;
Driver = DETECT;
in1tgraph(& Driver, & Mode, ". .”);
if(graphresult()! = grOk)
—);
settextstyle(DEFAULT_FONT, HORIZ_DIR. 5);
settextjust ifу(LEFT_TEXT, TOPJEXT);
outtextxy(getmaxx()/2, getmaxy()〃・ "Janek”);
while(*kbhit());
(void)getch();
gettextsettt ngs(&TextSettt ngs);
restorecrtnodeO;
cprintf("Horiz = Xs". Names[Text Settings.horiz]);
return 0;
gerviewsettings
ИмяЗаголовокИмяЗаголовокgetviewsettings - сообщение о параметрах графического окна.
Имя
Заголовок
Имя
Заголовок
void
Прототип ФункцияПрототип ФункцияЗамечанияЗамечанияgetviewsettings(struct viewporttype * Viewport) graphIcs.h
Прототип Функция
Прототип Функция
Замечания
Замечания
Присвоение структуре типа
(struct viewporttype), указанной в аргументе View Port, значений, определяющих координаты противоположных по диагонали вершин графического окна, а также способ отображения графических фрагментов, выходящих за пределы окна. Система должна находиться в графическом режиме. Тип (struct viewport type) определен следующим образом:
struct viewporttype { int left, top; int right, bottom; int clip;
}
Поля left, top и right определяют координаты противоположных вершин графического окна, а поле clip указывает, должны ли упомянутые фрагменты быть оборваны на краях окна.
Пример
Вывод на экран информации о параметрах окна, установленного по умолчанию.
/* GetViewSettings */
findude<graphics.h»
#include<conio.h>
struct viewporttype DefaultViewPort;'
ma1n()
{
int Driver, Mode;
Driver = DETECT;
1nttgraph(& Driver, & Mode. ". J);
1f(graphresult()I = grOk)
exit ⑴;
getvt ewsettings(&Defau1tVIewPort);
restorecrtmodeO;
cprtntf("xl = %d, yl ^ %d\r\n0B. DefaultViewPort. left.
DefauItViewPort.top);
cprintf("x2 н %d, y2 = %d\r\nM, DefaultViewPort.right,
DefaultViewPort.bottom);
If(DefaultViewPort.clip)
cprintf(,sClip = %d°, DefaultViewPort.clip);
return 0;
ИмяИмяgetx - сообщение о горизонтальной координате
Имя
Имя
ЗаголовокПрототип ФункцияЗамечанияПримерЗаголовокПрототип ФункцияЗамечанияПримерграфического курсора, int getx(vold) graphics,h
Заголовок
Прототип Функция
Замечания
Пример
Заголовок
Прототип Функция
Замечания
Пример
Формирование значения типа (int), равного горизонтальной координате графического курсора. Система должна находиться в графическом режиме. Координата определяется относительно текущего графического окна.
Вывод координат центра экрана
/* GetX */
#include<graphics.h>
finclude<conio.h>
main()
{
int Driver, Mode;
int xCor, yCor;
Driver = DETECT;
initgraph(&Driver, &Mode, M..");
if(graphresult() ! = grOk)
exit ⑴;
woveto(getmaxx()/2, getmaxy()/2;
xCor = getx();
уСог н gety();
restorecrtmode();
cprintf("(xCor. yCor) = (%d, %d)", xCor, yCor);
return 0;
gety
Имя
gety - сообщение о вертикальйой координате графического курсора.
Заголовок
int gety(vDid)
Прототип Функция
graphIcs.h
Формирование значения типа (int), равного вертикальной координате графического курсора.
Замечания
Система должна находиться в графическом режиме. Координата определяется относительно текущего графических) окна.
Пример
Вывод максимальных координат экрана.
/* GetY */
#1nclude<graphics.h*
findude<conio.h>
matn()
{
int Driver, Mode;
Int xCor. yCor;
Driver « DETECT;
initgraph(&DrIver. &Mode, 8\ .");
1f(graphresult()! = grOk)
exit(l);
moveto(getmaxx(). getmaxyO);
xCor м getx();
yCor = gety();
restorecrtniode();
cprintfC^or. yCor) = (%d( Xd)M, xCor, yCor);
return 0;
gotoxy
Имяgotoxy - перемещение текстового курсора.ЗаголовокvoidИмяgotoxy - перемещение текстового курсора.Заголовокvoid
Имяgotoxy - перемещение текстового курсора.
Заголовокvoid
Имяgotoxy - перемещение текстового курсора.
Заголовокvoid
Прототип ФункцияПрототип ФункцияЗамечанияЗамечанияgotoxy(Int xf int y) conio.h
Прототип Функция
Прототип Функция
Замечания
Замечания
Перемещение текстового курсора на позицию с координатами (х, у).
Координаты определяются относительно текущего текстового окна. Левый верхний угол этого окна имеет координаты (1, 1). Если новые координаты указывают позицию за пределами окна, то выполнение функции ни к каким действиям не приведет.
Пример
Вывод буквы J в левом верхнем углу экрана и буквы Ь на позиции с координатами (10, 10).
/* GotoXY */
#include<conio.h>
#1nclude<std1o.h>
main()
{
clrscr();
cprintfip”);
w1ndow(l0, ID. 20. 20);
gotoxy(lr 1);
cprintfCV);
return 0;
graphdefaults
Имя
graphdefaults - восстановление графических параметров, принятых по умолчанию.
Заголовок
void
graphdefaults(void)
Прототип Функция
graphIcs.h
Установление графического окна, охватывающего весь экран, перемещение графического курсора в его левый верхний угол, задание всех принятых по умолчанию графических параметров (палитра, шрифт, вид линий, способы закрашивания областей и выравнивания текста, размер шрифта, а также цвет фона и цвет символов).
Замечания 芋
Система должна находиться в графическом режиме.
Пример
Вычерчивание пунктирной линии, а затем линии с параметрами,которые были установлены по умолчанию.
/* GraphDefauHs */
#include<graphics.h>
#include.conio.h>
main()
{
int Driver. Mode;
Driver = DETECT;
1n1tgraph(&Drivert &Modet ". .");
if(graphresult() !
м grOk)
exit ⑴;
moveto(getmaxx()/2, getmaxy()/2);
set1inestyle(DASHED„LINE, 0, NORM_WIDTH); linerel(20, 0); /* Dashed */ graphdefaults();
linerel(20f 0); /* Solid */
while(» kbhitf));
c1osegraph();
return 0;
grapherrormsg
Имя
grapherrormsg - сообщение о ходе выполнения графической функции.
Заголовок
char *、
grapherrormsg(int ErrorCode)
Прототип Функция
graphIcs.h
Присвоение внутренней переменной системы значения
ЗамечанияЗамечаниястроковой константы, состоящей из символов, образующих сообщение о номере ошибки ErrorCode, и сообщение о первом символе этой переменной» Система должна находиться в графическом режиме. Номера сообщений могут быть выражены следующими константами:
Замечания
Замечания
grOkgrNoInitGraphgrNotDetected grFileNotFound grlnvalidDrivergrNoLoadMemgrNoScanMemgrNoFloorflemgrNoFontFoundgrNoFontMem grlnvalidModegrErrorgrIOErrorgrlnvalidFont grlnvalidFontNumgrl nva UdDev 1 ceNumgrOkgrNoInitGraphgrNotDetected grFileNotFound grlnvalidDrivergrNoLoadMemgrNoScanMemgrNoFloorflemgrNoFontFoundgrNoFontMem grlnvalidModegrErrorgrIOErrorgrlnvalidFont grlnvalidFontNumgrl nva UdDev 1 ceNumудачное выполнение графической операции,
grOk
grNoInitGraph
grNotDetected grFileNotFound grlnvalidDriver
grNoLoadMem
grNoScanMem
grNoFloorflem
grNoFontFound
grNoFontMem grlnvalidMode
grError
grIOError
grlnvalidFont grlnvalidFontNum
grl nva UdDev 1 ceNum
grOk
grNoInitGraph
grNotDetected grFileNotFound grlnvalidDriver
grNoLoadMem
grNoScanMem
grNoFloorflem
grNoFontFound
grNoFontMem grlnvalidMode
grError
grIOError
grlnvalidFont grlnvalidFontNum
grl nva UdDev 1 ceNum
не установлен графический режим,
не обнаружен графический адаптер,
не найден файл, содержащий графический драйвер,
неподходящий графический драйвер,
не хватает памяти для загрузки драйвера,
не хватает памяти для закрашивания области методом сканирования,
не хватает памяти для лавинного закрашивания области,
не найден файл с определением шрифта,
не хватает памяти для загрузки штрихового шрифта,
неправильно выбран графический режим,
другие ошибки (например, слишком большое число заданных штриховых шрифтов),
ошибка операции ввода -вывода,
неправильный шрифт,
неправильный номер шрифта,
неправильным номер устройства.
Пример
Вычерчивание отрезка- прямой линии или вывод сообщения о причине неудачного инициирования графического адаптера.
/* GraphErrorHsg */ finclude<graphics.h> #include<conio.h> main()
29*
{{int Driver, Mode;
{
{
Int Result;
Driver - DETECT;
1nitgraph(&Drivert &Mode. "DRIVERS");
Result * graphresult();
if(Result I = grOk){ clrscr();
cprintf(M%sw, grapherronnsg(ResuIt)); exit(l);
}
line(0( 0. getmaxx()t getmaxyO);
while(! kbhit());
closegraph();
return 0;礫
graphresult
ИмяЗаголовокПрототип ФункцияЗамечанияИмяЗаголовокПрототип ФункцияЗамечанияgraphresult - выдача кода ошибки для последней 乂安 удачно выполненной графической операции, Int
Имя
Заголовок
Прототип Функция
Замечания
Имя
Заголовок
Прототип Функция
Замечания
graphresult(void)
graphics.h
Формирование значения типа (int), равного коду ошибки последней неудачно выполненной графической операции.
Система должна находиться в графическом режиме.
Результат, равный 0, означает удачное, а отрицательный результат - неудачное выполнение операции. Коды ошибки выражаются следующими константами:
-удачное выполнение графической
операции.
grNoInitGraph
-не
установлен графический режим.
grNotDetected
-не
обнаружен графический адаптер,
grFileNotFound
-не
найден файл, содержащий графический драйвер,
grlnvalidDriver
-неподходящий графический драйвер,
grNoLoadMem
-не
хватает памяти для загрузки драйвера,
grNoScanMem
一 hе
хватает памяти для закрашивания области методом сканирования,
grFloodMem
-не
хватает памяти для лавинного
закрашивания области,
grNoFontFound
~ не
найден файл с определением шрифта
grNoFontMem
-не
хватает памяти для загрузки шрифтов
grlnvalidModegrErrorgrlnvalidModegrErrorgrIOError grlnvalidFont grlnvalidFontNum grlnva11dDev1ceN umgrIOError grlnvalidFont grlnvalidFontNum grlnva11dDev1ceN um-неправильно выбран графический режим,
grlnvalidMode
grError
grlnvalidMode
grError
grIOError grlnvalidFont grlnvalidFontNum grlnva11dDev1ceN um
grIOError grlnvalidFont grlnvalidFontNum grlnva11dDev1ceN um
-другие ошибки (например, слишком большое число заданных штриховых шрифтов),
-ошибка операции ввода-вывода,
-неправильный шрифт,
-неправильный номер шрифта
-неправильный номер устройства.
Поскольку при повторном вызове функции graphresult <без вьшолнения графической операции между очередными вызовами) выдается значение О, рекомендуется присваивать значение результата некоторой вспомогательной переменной.
Пример
Иллюстрация рекомендуемого способа использования кода ошибки графической операции.
/* GraphResult */
#1nclude<graphi cs.h>
#1nclude<conio.h>
main()
int Driver, Mode;
int Result;
Driver = DETECT;
in 1 tgrapfi (&Dr 1 ver, &Mode, M..”);
if((Result = graphresult())I = grOk){
cprlntff'GraphResult = d”, Result);
exit(l);
}
line(0, 0, getmaxxf), getmaxyf));
while(! kbhit());
closegrapfif);
return 0;
highvideo
Имя ЗаголовокПрототип ФункцияЗамечанияИмя ЗаголовокПрототип ФункцияЗамечанияhighvideo - увеличение яркости символов.
Имя Заголовок
Прототип Функция
Замечания
Имя Заголовок
Прототип Функция
Замечания
void
highvideo(void)
graph!cs.h
Установка бита яркости в переменной TextAttr, в результате чего очередные выводимые на экран символы будут иметь большую яркость.
Установка бита яркости приводит к тому, что темные
цвета первого плана превращаются в светлые:
Темный цвет
Светлый цвет
BLACK BLUE GREEN CYAN RED MAGENTA BROUN LIGHTGRAY
darkgraY(черный / темно-серый}
LIGHTBLUE (голубой)
LIGHTGREEN (зеленый)
LIGHTCYAN(бирюзовый}
LIGHTRED(красный)
LIGHTMAGENTA (ярко-красный)
LIGHTBROWN {коричневый)
WHITE{светло-серый / белый}
Пример
Вывод на экран затемненной надписи Jan и более яркой буквы в.
/* HighVideo */
#include<conio.h>
#inc1ude<stdio.h>
main()
clrscr();
cprintfC^an");
highvideo();
cpr1ntf(MB");
return 0;
}
imagesize
Имя
imagesize - определение размера памяти для хранения графического изображения.
Заголовок
unsigned imagesize (int xl. int yl, int x2, int yZ)
Прототип Функция
graphics.h
Формирование значения типа (unsigned), равного числу байтов памяти, необходимых для запоминания графи ческого изображения, находящегося в прямоугольнике, противоположные по диагонали вершины которого имеют координаты (xl. yl) и (х2г у2).
Замечания
Система должна находиться в графическом режиме.
Пример
Вычерчивание
надписи JanB, запоминание в “куие"。изображения, состо-
D “Куча" (ансп. heap) - динамически распределяемая область - область памяти, используемая для размещения структур данных в режиме слу<гайного формирования этих структур. - Прим. ред.
ящего из этой надписи, а затем дсжюлнительный вывод ее вблизи центра экрана.
/* InageSize */
#1nclude<graphics.h>
finclude<conio.h>
char *MyName 工 QanB”;
ma1n()
{
int Driver, Mode; void * Ref;
int xSizet ySize;
Driver * DETECT;
Initgraph(Driver. &Modev ". .");
if(graphresult() I = grOk) t exit(l);
xSize н textwidth(HyNaine);
ySize = texthe1ght(MyName);
8ettextjustify(LEFT_TEXT. TOP_TEXT);
outtextxy(0F 0, HyName);
Ref = malloc(1iMgesize(0. 0, xSize-1, ySize-1));
getinage((0. 0, xSize-lf ySize-1, Ref);
put 1 mage(getinaxx()/2f getnaxy()/2. Ref, COPY^PUT);
while(! kbhit(J);
closegraphf);
return 0;
initgraph
Имя
initgraph - установка графического режима.
Заголовок
void
initgraph(int * GraphDriver,
int * GraphMode, char * PathToDriver)
Прототип Функция
graphics.h
Поиск в каталоге, имя которого указано в аргументе PathToDriver, файла, содержащего программу графического драйвера для адаптера с номером, указанным в аргументе GraphDriver, перемещение программы в оперативную память и установка 1рафического режима, номер которого присвоен переменной, указанной в аргументе GraphHode.
Замечания
Если имя каталога является пустым, то файл ищется в текущем каталоге. Если GraphDriver — 0, то производится автоматическое распознавание графической среды, а переменным, указанным в аргументах GraphDriver и GraphMode, присваиваются
значения, определяющие номер драйвера и номер режима. Если *GraphDr1ver!*O, то *GraphDriver и ♦GraphMode должны правильно задавать номер адаптера и номер режима» Необходимая для драйвера оперативная память предоставляется в “куче" и освобождается при выполнении функции closegraph. Номера адаптеров и режимов могут быть определены с помощью следующих констант:
Адаптеры:
DETECT
CGA MCGA EGA EGA64 1ВИ8514 EGAMONO HERCMONO ATT400 VGA PC3270
автоматическое распознавание графического адаптера
-адаптер CGA
-адаптер MCGA
адаптер EGA
адаптер EGA64
адаптер IBM8514
- адаптер EGAMono
адаптер Hercules
адаптер АТТ400
адаптер VGA
-адаптер РС3270
Режимы:
CGACO
-320x200, палитра 0
CGAC1
-320x200, палитра 1
CGAC2
-320x200, палитра 2
CGAC3
-320x200, палитра 3
CGAHI
-640x200, 1 страница
MCGACO
-320x200, палитра 0
HCGAC1
-320x200, палитра 1
MCGAC2
-320x200, палитра 2
MCGAC3
-320x200, палитра 3
MCGAMED
-640x200, 1 страница
HCGAHI
-640x480, 1 страница
EGALD
-640x200, 16 цветов.
4 страницы
EGAHI
- 640x350, 16 цветов,
2 страницы
EGA64LD
-640x200, 16 цвете®,
1 страница
EGAMONOHI
-640x350,
64K на плате, 1 страница
256K на плате, 2 страницы
HERCMONOHI
-720x348, 2 страницы
ATT400C0
-320x200, палитра 0
ATT400C1
-320x200, палитра 1
ATT400C2
-320x200, палитра 2
АП400СЗ
-320x200, палитра 3
ATT400MED
-640x200, 1 страница
/7. Приняты описания457
ATT400HI-640x400,1 страница
VGALO-640x200,16цветов,
Q4 страницы
VGAMED-640x350,16цветов,
2 страницы
VGAHI-640x480,16 цветов,
1 страница
РС3270Н1-720x350,1 страница
IBM8514L0-640x480,256 цветов
IBM8514HI-1024x768, 256 цветов.
Неудачное выполнение функции 1 nitgraph приводит к тому, что результат функции graphresult приобретает одно из следующих значений:
grNotDetected-не обнаружен графический
адаптер,
grFileNotFound-не найден файл содержащий
графический драйвер, grlnvalidDriver-неподходящий графический
драйвер,
grNoLoadMem- не хватает памяти для
загрузки драйвера, grlnvalidMode- неправильно выбран
графический режим, grlnvalidDevIceNum - неправильный номер
устройства.
Пример
Вывод на экран одной точки вблизи центра экрана
/* InitGraph */
#1nclude<graphics.h>
#include<conio.h>
ma1n()
{
int Driver. Mode;
Driver = DETECT;
1r)itgraph(&Driver, SMode. ". .");
if(graphresult()!= grOk()
exit(l);
putpixelCgetrnaxxO/S, getmaxy()/2f getmaxcolorO);
while(! kbhit());
closegraph();
return 0;
}
insline
ИмяИмяinsline - вставка строки.
Имя
Имя
458
Часть VI. Библиотеки
Заголовок
void
insline(void)
Прототип Функция
conio.h
Вставка одной пустой строки в текстовом окне непосредственно под строкой, указываемой курсором. Перемещение строк, расположенных ниже указываемой курсором строки, на одну вниз. Удаление из окна самой нижней строки.
Замечания
Если цвет фона не является черным, то пустая строка будет заполнена пробелами, имеющими цвет, определяемый с помощью функции textbackground.
Пример
Вывод на экран двух строк текста, разделенных одной пустой строкой.
/* InsLine */ include<conio.h> include<stdio.h> main()
{
clrscr();
cprintfCTwArXn0); cprintf(”Jan\r\rT);
gotoxy(lr 2);
inslineO;
return 0;
}
installuserdriver
Имя
installuserdriver - установка нестандартного драйвера.
Заголовок
Int far
instai 1userdrIver(char far * Name, int huge(*Detect)(vold))
Прототип Функция
graphics.h
Установка нестандартного драйвера с названием, указанным в аргументе Name, распознавание его с помощью функции Detect и формирование значения типа (int), идентифицирующего драйвер при его инициировании.
Замечания
После установки драйвера сформированное значение можно передать непосредственно функции initgraph. Если вместо этого задать автоматическое распознава нме, то произойдет неявный вызов функции Detect. Функция Detect должна быть иаписана так, чтобы в случае опознания драйвера ее результатом было зна чение, определяющее номер режима, а в противном случае значение дгЕггог - графический адаптер не опознан.
Пример
Способ действий при установке нестандартного адаптера.
/* InstallUserDriver */
#1nclude<graphics.h>
#include<conio.h>
Int Driver, Mods, Result;
int huge
DetectHerc(vold)
{
detec tgraph(&Dr1ver, RMode);
if(graphresult() == grNotDctected)
return grError;
else
return 0;
}
ma1n()
{
Result = installuserdriverC^HERCULES.BGI*15 DetectHere);
Driver = DETECT;
1n1tgraph(&Dr1verf &Mode( n..");
if(graphresult()I = grOk)
exit(l);
outtext("Hello,();
closegraphf);
return 0;
installuserfont
Имя
Заголовок
installuserfont 一 установка нестандартного шрифта, int far
instal luserfontfchar far *Nauie)
Прототип Функция
graphics.h
Задание нестандартного шрифта с названием, указанным в аргументе Name, и формирование значения типа (int), равного номеру этого шрифта.
Замечания
Сформированное значение может быть передано непосредственно в процедуру settextstyle.
Пример
Способ действий при задании нестандартного шрифта.
/* InstalWserFont */ #include<grap hlcs.h» linelude<conio.h> int Driver, Mode. Font; main()
{
Font н installuserfont(••CUSTOM.CHR");
Driver « DETECT;
in1tgraph(&Driverr &Mode, ". .*);
1f(graphresult()I 工 grOk)
exlt(l);
settextstyle(Font, HORIZ_DIR* 5);
outtext(MHellOM); closegraph();
return 0;
kbhit
ИмяЗаголовок 衬Прототип ФункцияЗамечанияПримерИмяЗаголовок 衬Прототип ФункцияЗамечанияПримерkbhit - анализ буфера клавиатуры.
Имя
Заголовок 衬
Прототип Функция
Замечания
Пример
Имя
Заголовок 衬
Прототип Функция
Замечания
Пример
int
kbhit(void)
conio.h
Формирование значения типа (int), если в буфере клавиатуры находится еще не прочитанный символ. Функция kbhit не распознает такие символы,как Shift. Alt, NumLock и т.д»
Анализ времени реакции на ввод с клавиатуры с пересчетом его в условные единицы.
/* khbit */
#1nclude<conio.h>
#include<stdio.h>
main()
{
long Num = 0;
clrscr();
while(l kbhit());
Num ++;
cprintf("Count н %d". Num); while(getchar()! = '\n'); return 0;
Имя
Заголовок
line - вычерчивание отрезка прямой линии, void
line(int xlt int yl(
int x2, int y2)
Прототип Функция
graphics.h
Вычерчивание отрезка прямой линии, соединяющего
точку с координатами (xl, yl) с точкой с координатами &2. у2).
ЗамечанияСистема должна находиться в графическом режиме.
Координаты графического курсора не изменяются.
Пример
Вычерчивание отрезка прямой линии вдоль правого края экрана.
/* Line */
findude<graphics.h>
#inc1ude<conio.h>
main()
{
int Driver, Mode;
Driver «= DETECT;
initgraph(&Driver, &Mode. M..");
if(graphresu1t()! = grOk)
exit(l);
line(getmaxx(), 0, getmaxx(), getmaxxy());
while(! kbhit());
closegraph();
return 0;
linerel
Имя
Заголовок
linerel - вычерчивание отрезка прямой линии, void
linerel(int dxr int dy)
Прототип Функция
graphics.h
Вычерчивание отрезка прямой линии, соединяющего точку, указываемую курсором, с точкой, удаленной от нее на расстояние dx по горизонтали и расстояние dy по вертикали. Изменение координат графического курсора на величину dx по горизонтали и величину dy по вертикали.
Замечания
Система должна находиться в графическом режиме.
Пример
Вычерчивание линии, соединяющей центральную точку экрана с точкой с координатами (0, 0).
/* LineRel */ #1nclude<ics.h> #inc1ude<conio.h> main()
int Driver, Mode;
driver к DETECT;
initgraph(&Driver, &Modev ".「);
if(graphresu1t()! * grOk)
exit⑴;
noveto(getmaxxO » 1. getmaxy() » 1);
1inerel(-getmaxx()/2, -getmaxy()/2);
while(! kbh1t());
closegraphO;
return 0;
lineto
ИмяЗаголовок,ИмяЗаголовок,Прототип ФункцияПрототип Функцияlineto - вычерчивание отрезка прямой линии, voidlineto(int х. int у)lineto - вычерчивание отрезка прямой линии, voidlineto(int х. int у)graphics.hgraphics.hЗамечанияЗамечанияВычерчивание отрезка прямой линии, соедин^пощего точку, указываемую графическим курсором, с точкой с координатами (х, у). Перемещение графического курсора в точку с координатами (х. у).Система должна находиться в графическом режиме.Вычерчивание отрезка прямой линии, соедин^пощего точку, указываемую графическим курсором, с точкой с координатами (х, у). Перемещение графического курсора в точку с координатами (х. у).Система должна находиться в графическом режиме.
Имя
Заголовок,
Имя
Заголовок,
Прототип Функция
Прототип Функция
lineto - вычерчивание отрезка прямой линии, void
lineto(int х. int у)
lineto - вычерчивание отрезка прямой линии, void
lineto(int х. int у)
graphics.h
graphics.h
Замечания
Замечания
Вычерчивание отрезка прямой линии, соедин^пощего точку, указываемую графическим курсором, с точкой с координатами (х, у). Перемещение графического курсора в точку с координатами (х. у).
Система должна находиться в графическом режиме.
Вычерчивание отрезка прямой линии, соедин^пощего точку, указываемую графическим курсором, с точкой с координатами (х, у). Перемещение графического курсора в точку с координатами (х. у).
Система должна находиться в графическом режиме.
Пример
Вычерчивание отрезка прямой линии, соединяющего центральную точку экрана с точкой с координатами (0, 0).
/* LineTo */
#1nclude<graph1cs.h>
#inc1ude<conio.h>
main()
{
int Driver, Mode;
Driver ■ DETECT;
1nitgraph(&Driverf &Mode, ”. /');
if(graphresu1t() !=grOk)
exit(l);
noveto(getmaxx() » 1, getmaxy() » 1);
1ineto(0, 0);,
while(! kbhit(J);
c1osegraph();
return 0;
ИмяЗаголовокИмяЗаголовокlowvideo
Имя
Заголовок
Имя
Заголовок
lowvldeo - уменьшение яркости символов, void
lowvideo(void)
Прототип Функция
conio.h
Обнуление бита яркости в переменной TextAttr, в результате чего очередные выводимые на экран знаки
Замечания
будут иметь меньшую яркость.
Обнуление бита яркости приводит к тому, что светлые цвета первого плана превращаются в темные.
Светлый цвет Темный цвет
DARKGRAYBLACK{темно-серый / черный)
LIGHTBLUEBLUE(голубой)
LIGHTGREENGREEN(зеленый)
LIGHTCYANCYAN(.бирюзовый)
LIGHTREDRED(красный)
LIGHTMAGENTAMAGENTA(ярко- красн ыи)
YELLOWBROWN(коричневый)
WHITELI GHTGRAY(белый / светло-серый)
Пример
Вывод на экран затемненной надписи Jan и более яркой буквы В.
/* LowVideo */•
•Inc1ude<conio.h>
f1nc1ude<stdio.h>
砲 1n()
{
clrscr();
lowvideof);
cprintf(MJanw);
highvideo();
cprintf(ИВ');
return D;
}
moverel
Имя
Заголовок
moverel - перемещение графического курсора, void
moverel(int dx, Int dy)
Прототип Функция
graphicseh
Изменение горизонтальной координаты графического курсора на величину dx и вертикальной координаты на величину dy.
Замечания
Система должна находиться в графическом режиме.
Пример
Вывод на экран двух точек - одной в центральной точке экрана, а другой в его левом верхнем углу.
/* MoveRel */
#1nclude<graphics.h>
#include<conio.h>
main()
{
int Driver, Mode;
Driver * DETECT;
1nitgraph(&Driver, &Mode, ". •”);
1f(graphresult()! * grOk) exit(l);
noveto(getmaxx()/2, getmaxy()/2);
putpixe1(getx(), gety(), getmaxcolorO); movere1(-(getmaxx()/2, -(getmaxy()/2i);
putpixe1(getx(), gety(). getmaxcolorO); while(! kbhitO);
closegraph(斗
return 0;
movetext
Имя
Заголовок
novetext - перемещение текста, int
novetext(Int xl. 1nt yl.
int x2t Int y2.
int xt int y)
Прототип Функция
coniOoh
Перемещение текста, находящегося в прямоугольнике, противоположные (по диагонали) вершины которого имеют координаты (xl. у1) и (х2, у2), в такое место экрана, чтобы левый верхний символ перемещаемого текста имел координаты (х. у).
Замечания
Результатом функции является значение, которое б случае ее удачного выполнения отлично от 0.
Пример
Копирование символов, находящихся в произвольным образом выбранном прямоугольнике экрана.
/* MoveText */ fInclude <conio.h> char Fariily[10D]; niain() {
clrscr();
cprintf(B,Ewa\r\ne>); cprintfC^IzaW); cprintf("JanM);
novetext(l,lf4.3r5,5);
moveto
Имя
Заголовок
moveto - перемещение графического курсора, void
noveto(int X。 int у)
Прототип Функция
graphics.h
Перемещение графического курсора в точку с координатами (х. у).
Замечания
Система должна находиться в графическом режиме.
Пример
}}return 0;return 0;
}
}
return 0;
return 0;
Вывод надписи (719, 347) на экран монитора, управляемого адаптером Hercules。
/* MoveTo */
•t nc1ude<graphics.h>
•t nc1ude<conio»h>
mainf)
int Driver, Mode;
1nt xCor, yCor;
Driver = DETECT;
1nitgraph(&Driverp &Modet ". .°);
1f(graphresult()! «
grOk)
exit(l);
moveto(getmaxx(), getmaxy(J);
xCor - getx();
уСог к gety();
putp1xel(x, Cort yCor, getmaxco1or());
wh11e(! kbhit(J);
(vo1d)getch();
restorecrtrnode();
cprintf("(%df %d)”・ xCor, yCor);
return 0;
}
norm video
Имя
normvideo - восстановление признака индикации символов.
Заголовок
void
normvideo(void)
Прототип Функция
conlo.h
Присвоение переменной TextAttr признака, указывающего способ индикации символов, который ;
действовал в момент начала выполнения программы.
Пример
Вывод на экран надписи Ewa буквами повышенной яркости и надписи Iza буквами повышенной яркости таким же способом, какой был принят перед выполнением программы.
/* NormVIdeo */
#1nc1ude<conio.h>
#inc1ude<stdio.h>
ma1n()
clrscr();
highvideo();
cprintfC'Ev^");
normvideoO;
cprintf(*'IzaM);
return 0;
outtext
ИмяЗаголовокИмяЗаголовокПрототип ФункцияПрототип ФункцияЗамечанияЗамечанияouttext - вычерчивание текста.
Имя
Заголовок
Имя
Заголовок
Прототип Функция
Прототип Функция
Замечания
Замечания
void
graphics.hgraphics.houttext(char * Textstring)
graphics.h
graphics.h
Вычерчивание текста, указанного в аргументе Textstring, вблизи текущего положения графического курсора.
Система должна находиться в графическом режиме. Шрифт вычерчиваемого текста определяется с помощью функции settextstyle, а его цвет - с помощью функции setcolor. Расположение текста относительно позиции курсора может быть указано с помощью функции set text just if у. Если первый аргу мент функции имеет значение LEFTJEXT, а текст выво
дится по горизонтали, то горизонтальная координата графического курсора смещается на ширину этого
текста. В остальных случаях положение курсора не изменяется. Если текст не уменьшается в текущем графическом окне, то он обрезается на краях окна.
Пример
Вычерчивание текста Inside ViewPort в левом верхнем углу текущего графического окна.
/* OutText */
#include<graphics.h>
finclude<conio.h>
fdefine ClipOn 1
main()
{
Int Driver, Mode;
int xMar. yMar;
Driver * DETECT;
Initgraphf&Driver, &Mode( ". .");
If (graphresultO! »grOk)
exit(l);
xMar x getmaxx()/3;
yMar ■ getmaxy()/3;
setv1ewport(xMar. yMar, 2 * xMar, 2 * yMar, CUpOn): outtextf*Inside VlewPort");
whl1e(! kbhlt(J);
c1osegraph();
return 0;
outtextxy
Имя
Заголовок
outtextxy - вычерчивание текста, void
outtextxy(1nt х, int у.
char * Textstring)
Прототип Функция
graphics.h
Вычерчивание текста, указанного в аргументе Textstring, вблизи точки с координатами (х. у).
Замечания
Система должна находиться в графическом режиме. Положение графического курсора не изменяется. Шрифт вычерчиваемого текста определяется с помощью функции set textstyle, а его цвет - с помощью функции setcolor. Расположение текста относительно точки с координатами (х, у) может быть указано с помощью функции settext just if у. Если текст ие умещается в текущем графическом окне, то он обрезается на краях окна.
Пример
Вычерчивание текста Jan Bielecki, усеченного до Jan B1. /* OutTextXY */ finclude<graphics.h> #include<conio.h>
char *MyName * wJan B1e1eck1M;
main()
{
int Driver, Mode;
unsigned xS1ze;
Driver * DETECT;
initgraph(&Driver, &Made₽ "» .");
If(graphresultf)! * grOk) exlt(l);
xSIze n textwidth(MyNane);
settextjus11fу(LEFTJTEXTt TOP_TEXT);
outtextxy(getn)axx() - xSize/2, 0f MyName); /* Jan B1 */
while(! kbhltO);
c1osegraph();
return 0;
pieslice
Имя
Заголовок
Прототип Функция
Замечания
pieslice - вычерчивание и закрашивание сектора круга.
void
piesl1ce(1nt х№ int у, int StAngle Int EndAngle. Int Radius) graphics.h
Вычерчивание сектора круга с центром в точке (х, у) к радиусом Radius, начиная с ума StAngle и заканчивая углом EndAngle. Закрашивание сектора по шаблону, задаваемому с помощью функции setfillstyle или setfillpattern.
Система должна находиться в графическом режиме. Если задать StAng1e=O и EndAngle=36O, то будет вычерчен полный круг. В случае неудачного выполнения функции pieslice результатом функции graphresult является значение grNcScanMen - не хватает памяти для закрашивания области методом сканирования.
Пример
ВычерчиБание шаблону.
четверти круга и ее закрашивание по стандартному
/* PieSlice */
#1псlude<graphics.h>
#lnclude<con1o.h>
Пй1п()
{
Int Driver, Mode;
Driver = DETECT;
InltgrapM&DrWer. &Mode. w. .**);
if(srapbresu1t()! = grOk)
exit(l);
piesHce(0.0p270B360f100);
}
whlle(! kbhit(J); closegraph();
return 0;
putimage
Имя
Заголовок
Прототип Функция
put linage - размещение изображения на экране, void putiraage(int xt Int у, void * Bitmap.
int Op) graphics.h
Размещение на экране прямоугольного графического изображения, предварительно записанного в области памяти, указанной в аргументе ВНМар. Изображение размещаегся таким образом, что левый верхний угол
Замечания
прямоугольника попадает в точку с координатами (х, у), а наложение изображения на экран происходит в соответствии со значением Ор.
Система должна находиться в графическом режиме. Выполнение функции put Image не вызывает усечения изображения по краям графического окна. Если потребуется усечение, то выполнение функции не будет иметь никаких результатов. Исключение: если нижним краем окна является нижний край экрана, то изображение, выходящее за этот край (и только за него) размещаегся на экране и усекается» Способ наложения на экран (параметр Ор) может быть задан
Пример
следующими констгантами: copy_put-операцияnov,
XOR_PUT-операцияхог,
OR PUT-операцияог,
AND PUT-операцияand,
NOT_ PUT-операцияnot.
Вычерчивание на мониторе, управляемом адаптером Hercules, двух кругов таким образом, чтобы их общая часть имела цвет 4юна.
/* PutImage */
•1nc1ude<graphics.h>
#1nc1ude<conio.h>
main()
{
int Driver, Mode;
Int xCor, yCor;
Int xCen, yCen;
void * Ref;
Driver = DETECT;
initgraph(&Drivert &Moder ". .w);
If(graphresu1t()! * grOk)
exit(l);
xCen « getmaxx()/2;
yCen * getmaxy()/2;
circ1e(xCen, yCen, 50);
floodfi11(xCen, yCen, getmaxcolorO);
xCor « xCen - 100;
yCor « yCen - 100;
Ref * Rialloc( imageS 1ze(xCor( yCor.
xCor + 200f yCor + 2D0));
get1mage(xCor, yCor,
xCor + 200, yCor + 200t Ref);
putimage(xCor + 20, yCor + 20, Ref.XOR_PUT).
while(! kbhit(J);
closegraphQ;
return 0;
putpixel
ИмяЗаголовокИмяЗаголовокПрототип ФункцияЗамечанияПрототип ФункцияЗамечанияputplxel - вывод точки.
Имя
Заголовок
Имя
Заголовок
Прототип Функция
Замечания
Прототип Функция
Замечания
void
putpfxe!(1nt х, int у,
Int Color)
graphics.h
Вывод на экран точки с координатами (х, у) с цветом, имеющим номер Color.
Система должна находиться в графическом режиме.
Пример
Вычерчивание отрезка прямой линии вдоль верхнего края экрана.
7* PutPixel */
#1nc1ude<graph ics.h»
#inc1ude<conio.h>
iMin()
{
Int Driver, Mode;
unsigned 1;
Driver 船 DETECT;
1n1tgraph(&Dr1ver( &Mode, ". .**);
If(graphresult()! = grOk) exit(l);
for(i » D; i<= getmaxx(); i++) putp1xe1(1( 0, getmaxcolorO);
whi1e(! kbhit()); closegrapM);
return 0;
puttext
ИмяИмяЗаголовокЗаголовокputtext - размещение текста в выбранном прямоугольнике.
Имя
Имя
Заголовок
Заголовок
int puttext(int xl, int yl.
Прототип ФункцияПрототип Функцияint x2. int y2, void *TextString) conio.h
Прототип Функция
Прототип Функция
ЗамечанияЗамечанияРазмещение текста, указанного в ар!умен@е Textstring, в прямоугольнике, противоположные по диагонали ве ршины которого имеют координаты (xl„ yl) и (х2, у2). Результатом функции является величина типа (int), которая в случае удачного выполнения операции принимает значение, отличное от 0.
Замечания
Замечания
Пример
Запоминание,Запоминание,а затем вывод наа затем вывод нанаходящихся в произвольно выбранномнаходящихся в произвольно выбранномI экран последовательности знаков, прямоугольнике.I экран последовательности знаков, прямоугольнике.
Запоминание,
Запоминание,
а затем вывод на
а затем вывод на
находящихся в произвольно выбранном
находящихся в произвольно выбранном
I экран последовательности знаков, прямоугольнике.
I экран последовательности знаков, прямоугольнике.
/* PutText */ #include<conio.h> char Family[100]; main()
clrscr();
cprintf(*'Ewa \r\n");
cprintf("Iza \r\n");
cprintfC'Jan*');
gettext(lr 1. 4. 3t Family);
clrscr();
puttext(5v 5. 8, 7, Family);
return 0;
}
rectangle
Имя
Заголовок
Прототип Функция
Замечания
rectangle - вычерчивание прямоугольника, void
rectangle(int xl. 1nt yl, fnt x2, int y2)
graphics.h
Вычерчивание прямоугольника, противоположные по диагонали вершины которого имеют координаты 《xl, yl) и (х2. у2).
Система должна находиться в графическом режиме.
ВычерчиваниеВычерчивание
Вычерчивание
Вычерчивание
Пример
прямоугольника, сторонами которого являются края экрана.
/* Rectangle */
•tnc1udevgraph ics.h>
#include<conio.h>
main()
{ int Driver, Mode;
Driver = DETECT;
1nitgraph(&Dr1vert &Modev ”. .");
if(graphresult()! * grOk)
exit(l);
rectangle(O, 0₽ getmaxx(), getmaxyO);
while" kbhitU); closegraph();.
return 0;
registerbgidriver
Имя
Заголовок *
Прототип Функция
registerbgidriver - подтверждение графического драйвера.
int
reg1sterbgidriver(vo1d(*Driver)(vo1d))
Замечания
graphIcs.h
Подтверждение того, что в области оперативной памяти, указанной в аргументе Driver, находится программа графического драйвера.
В случае неудачного выполнения функции registerbgidriver результатом функции graphresult буде: значение
grlnvalidDriver - неподходящий графический
драйвер.
Пример
Неавтоматическое подтверждение графического драйвера.
/* Reg1sterBGIDriver */
•1nc1ude<graph1cs.h>
•include<coniо.h>
#include<stdio.h>
ma1n()
{
int Driver, Mode;
y**iWttfr *************
/* BINOBJ HERC
/* Project:
l.source.C
*/
*/
*/
*/
2.GRAPHICS.LIB*/
3. HERC.OBJ */
Driver х registerbgidriver((void(*)(void))Hercjdriver)
if(Driver < 0){
cprintf('*Error: %s”.
grapherrormsg(graphresult()))
exlt(13);
}
Driver м HERCMONO;
Mode - HERCMONOHI;
initgraph(8J)river, &Mode, ”. •");
if(graphresult()! ■ grOk)
ex1t(l);
settextstyle(GOTHIC_FONT, HORIZ_DIR. 4);
settextjustify(LEFT_TEXT. TOPJEXT);
outtext("Driver reg1stered");
wh11e(! kbhitU);
closegrapM);
return 0;
re^sterbgifont
Имя
Заголовок
reg isterbgifont - подтверждение шрифта.
1nt
registerbgifont(void (* Font)(void))
Прототип Функция
graphIcs.h
Подтверждение того, что в области оперативной памяти, указанной в аргументе Font, находится определение шрифта. Формирование значения типа (int), равного внутреннему номеру этого шрифта.
Замечания
В случае неудачного выполнения функции registerbgifont результат функции graphresult примет одно из следующих значений:
дгЕггог~слишком большое число
заданных шрифтов,
grlnvalidFont-неправильный шрифт,
grlnvalidFontNum-неправильный номер шрифта.
Пример
Неавтоматическое подтверждение шрифта.
/* RegisterBGIFont */
•i nc1udevgraph ics.h>
#include<conio.h>
#1nclude<std1o.h>
ma1n()
int Driver. Mode;
int 1 *0;
/* BIN08J GOTH*/
/* BINOBJ TRIP*/
/* Project:*/
/*1.source.C*/
/* 2. GRAPHICS.LIB*/
/* 3. GOTH.OBJ*/
/* 4. TRIP.OBJ
registerbgifont(gothicefoot);
registerbgifont(tr1plex_font);
Driver » DETECT;.
initgraph(&Driver, &Hode. ". .");
If(graphresylt()!匸 grOk)
exit(l);
do {
i++;
<jlearviewport();
If(I & 1){
settextsty1e(GCTHIC_F0NT.H0RIZ_DIR 5);
outtext("Gothic");
} else {
settextstylefTRIPLEX^FONT, HORIZ^DIR, 5);
outtext("Trtp】ex");
}
sleep(l);
} while(! kbh1t());
closegraph();
return 0;
restorecrtmode
Имя
Заголовок
restorecrtmode - восстановление текстового режима, void
restorecrtmode(void)
Прототип Функция
graphics.h
Восстановление текстового режима, действовавшего перед установлением графического режима.
Замечание
Система должна находиться в графическом режиме. Применение функции restorecrtmode поочередно с функцией setgraphmode создает возможность удобного переключения системы между текстовым и графическим режимами.
Пример
Вычерчивание, а затем вывод надписи Jan Bielecki.
/* RestoreCrtMode */
•1ncludecgraphlcs.h>
finclude<conio.h>
main()
}
int Driver, Mode;
Driver » DETECT;
1n1tgraph(&Driver, &Mode. ". .**);
if(graphresult()! * grOk)
exit(l)r
outtext(*'Graphics mode: Jan Bielecki**);
whi】e(l kbhit());
(void)getch();
restorecrtmodef);
cprintf("Text mode: Jan Bielecki");
return 0;
sector
Имя
Заголовок
sector - вычерчивание сектора эллипса, void far
sector(int xv int у, int StAngle, int EndAngle, Int xAxis, Int yAxis)
Прототип Функция
graphIcs.h
Вычерчивание закрашенного сектора эллипса с центром в точке (х. у), начальным и конечным углами дуги StAngle и EndAngle и полуосями xAxis и yAxis соответственно.
Замечания
Система должна находиться в графическом режиме. Сектор закрашивается по шаблону, заданному с помощью процедур setfillstyle и setfillpattern-
Пример
Вычерчивание окружности.
сектора, описанного дугой эллипса, по форме, близкой к
/* Sector */
#1nc1ude<graphics.h>
#include<conio.h>
main()
{
1nt Driver, Mode:
Driver н DETECT;
initgraph(&Driver. &Mode. ". .");
if(graphresult(){ ■ grOk)
exit(l);
sector(getmaxx()» 1, getmaxy()>> 1(
0,270.
150, 100); wh1】e(l kbhit()j; (void)getch(); closegraph();
return 0;
setactivepage
Имя
Заголовок
setactivepage - выбор активной страницы, void
setactivepage(int Page)
Прототип 修 Функция
graphics.h
Выбор страницы с номером Page в качестве активной страницы.
Замечания
Система должна паходиться в графическом режиме. После выполнения фун!сции setactivepage все графические операк«ии будут относиться к странице с указанным номером. Возможность выбора активной
*
страницы существует только в адаптерах EGA, VGA и Hercules.
Пример
Вычерчивание диагонали экрана на неактивной странице, а после нажатия произвольной клавиши ее вывод на экран.
/* SetActivePage */
#include<graphics.h>
#include<conio.h>
main()
int Driver, Mode;
Driver = HERCMONO;
Mode « HERMONOHI;
initgraph(&Driver, &Hode. ". .");
if(graphresult()i =
grOk)
exit(l);
setvisualpage(0};
setactivepage(O);
outtext("Press any key");
setactivepage(l);
line(0p 0, getmaxx()e getmaxyO);
while" kbhlt());
(void)getch();
setvi suaIpage(1);
wh1le(! kbhit());
closegraph();
return 0;
}
setallpalette
Имя
setallpalette - изменение цветов, соответствующих позициям палитры.
Заголовок
void
setal1palette(struct palettetype *Palette)
Прототип Функция
graphics.h
Присвоение позициям палитры идентификаторов цветов, определяемых полями структуры типа (struct palettetype), указанной в аргументе Palette.
Замечания
Система должна находиться в графическом режиме.
Тип
(struct palettetype)
определен следующим образом:
struct palettetype {
unsigned char size; signed char colors[16];
}
Поле size задает размер палитры, а поле colors - идентификаторы цветов. Если элемент массива colors имеет значение ~1, то присвоенный соответствующей позиции палитры цвет не изменяется.
Идентификаторы цветов ммут быть следующими:
BLACK-черный
BLUE-голубой
GREEN-зеленый
CYAN-бирюзовый
RED-красный
MAGENTA-ярко-красный
BROWN-коричневый
LIGHTGRAY-светло-серый
DARKGRAY-темно-серый
LIGHTBLUE - светло-голубой
LIGHTGREEN - светло-зеленый
LIGHTCYAN - - светло-бирюзовый
LIGHTRED - светло-красный
LIGHTMAGENTA - светло-ярко-красный
YELLOW- желтый
WHITE- белый
Пример
Вычерчивание емого адаптером смены палитры.
голубой главной диагонали на экране монитора, управля- EGA, а затем изменение цвета диагонали на красный за счет
/* SetAllPalette */
#1nclude<graphics.h> finclude<conio.h>
struct palettetype Palette;
ma1n()
{
int Driver, Mode;
detectgraph(&Dr i ver r &Mode);
1f((graphresult()! ■ grOk) || (Driver t ■ EGA)){ cprlntf (*'Fai lure");
exit(l);
}
setpalette(l. BLUE);
setcolor(l);
Iine(0, 0. getmaxx()r getmaxy());
whi1e(l kbhit());
(vcid)getch();
Palette.colors[0] = -1;
Palette.colors[l] = RED;
setallpalette(&Palette);
wh11e(l kbhit());
closegraph();
return 0;
setaspectratio
Имяsetaspectratio - задание коэффициента сжатия экрана.
Заголовокvoid far
Прототип Функция ЗамечанияПрототип Функция Замечанияsetaspectratio(int xAsp, 1nt yAsp)
Прототип Функция Замечания
Прототип Функция Замечания
graphics.h
Задание коэффициента сжатия графического экрана.
Система должна находиться в графическом режиме. Текущую величину коэффициента сжатия можно определить с помощью функции getaspectratio.
Пример
Вычерчивание неискаженной окружности на мониторе экрана, управляемого адаптером Hercules.
/* SetAspectRatlo */
#inc1udevgraphics.h>
#inc1ude<conio.h>
main()
{
int Driver, Mode;
Driver = DETECT;
InitgrapM&DrWer. &Mode. ”. .");
if(graphresult()! » grOk)
exit ⑴;
setaspectratio(2t 3);
circle(getmaxx()» 1. getmaxyf) » 1. 100);
whfle(! kbhit()); (void)getch(); closegraph();
return 0;
setbkcolor
Имя ЗаголовокИмя ЗаголовокПрототип ФункцияПрототип Функцияsetbkcolor - изменение цвета фона, voidsetbkcolor(int Color)setbkcolor - изменение цвета фона, voidsetbkcolor(int Color)ЗамечанияЗамечанияgraphics.hИзменение цвета фона на тот цвет, который соответствует позиции с номером Color в текущей палитре. Исключение: если Color —0, то цвет фона изменится на черный.Система должна находиться в графическом режиме.graphics.hИзменение цвета фона на тот цвет, который соответствует позиции с номером Color в текущей палитре. Исключение: если Color —0, то цвет фона изменится на черный.Система должна находиться в графическом режиме.
Имя Заголовок
Имя Заголовок
Прототип Функция
Прототип Функция
setbkcolor - изменение цвета фона, void
setbkcolor(int Color)
setbkcolor - изменение цвета фона, void
setbkcolor(int Color)
Замечания
Замечания
graphics.h
Изменение цвета фона на тот цвет, который соответствует позиции с номером Color в текущей палитре. Исключение: если Color —0, то цвет фона изменится на черный.
Система должна находиться в графическом режиме.
graphics.h
Изменение цвета фона на тот цвет, который соответствует позиции с номером Color в текущей палитре. Исключение: если Color —0, то цвет фона изменится на черный.
Система должна находиться в графическом режиме.
Пример
Выбор красного, а затем черного цвета фона на экране монитора,
управляемого адаптером EGA.
/* SeBkColor */
#inc}ude<graphics.h>
#1nclude<conio.h>
main()
{
int Driver, Mode;
detectgraph(&Driver, &Mode);
if((graphresult()!匸 grOk);; (Driver!工 EGA)){ cprintf C'Fai lure**);
exit ⑴;
}
setpa'iette(l. RED);
setbkcolor(l);
while(! kbhit());
(vo1d)getch();
setbkcolor(O);
wh1 le(! kbhitO);
c]osegraph();
return 0;
setcolor
ИмяИмяЗаголовокЗаголовокsetcolor - выбор номера цвета для вычерчивания линии.
Имя
Имя
Заголовок
Заголовок
void
Прототип ФункцияЗамечанияПримерПрототип ФункцияЗамечанияПримерsetcolor(Int Color)
Прототип Функция
Замечания
Пример
Прототип Функция
Замечания
Пример
graphics.h
Выбор для вычерчивания линии цвета с номером Color.
Система должна находиться в графическом режиме.
Вычерчивание отрезка прямой линии вдоль левого края экрана.
/* SetColor */
#inc]ude<graphics.h>
#include<conio.h>
main()
int Driver,串ode;
Driver = HERCMONO;
Mode - HERCMONOHI;
inftgraph(&Driver( &Modet ”. .”);
1f(graphresult()l ■ grOk)
clrscr();
cprintf(wFailurew);
exit(l); *
}
setcolor(getmaxcolor());
1ine(0. 0. 0. getmaxyO);
while(! kbhit());
closegraphO;
return 0;
setfillpattern
Имя
setfillpattern - задание шаблона для закрашивания областей.
Заголовок
void.
setf11lpattern(char * Pattern, int Color)
Прототип Функция
graphics.h
Задание указанного в аргументе Pattern шаблона для закрашивания областей (fillpaly, bar, floodfill, bar3D. pieslice) и номера цвета Color этого шаблона.
Замечания
Система должна находиться в графическом режиме. Шаблон закрашивания является битовым прямоуголь ником 8x8 точек, представленным в 8-байт таблице, первый символ которой указан в аргументе Pattern.
Пример
Закрашивание экрана по произвольно выбранному шаблону.
* SetFillPattern */
#include<graphics.h>
#include<conio.h> unsigned char Pattern[]=
{ ,,\xl2\x6c\x44\x92"
-\x44\x6c\x90\x00"}s
main()
{
int Driver. Mode;
Driver = DETECT;
initgraph(8iDriver, &Mode, M. .w);
if(graphresult()! = grOk)
exit(l);
setfl1lpattern(Pattern, getmaxcolor());
floodfill(Of 0, getmaxcolor());
while(! kbhit()); closegraph();
return 0;
Имя
setfillstyle - задание стандартного шаблона закрашивания областей.
Заголовок
void
setfillstyle(int Pattern, Int Color)
Прототип
graphics.h
Функция
Задание номера Pattern шаблона для закрашивания областей (fillpoly, floodfill, bar, bar3d, pieslice) и номера цвета закрашивания.
Замечания.
Система должна находиться в графическом режиме. Номера шаблонов соответствуют следующим возможным способам закрашивания:
EMPTY_FILL-цветом фона,
SOLID—FILL-непрерывно,
LINE了ILL-утолщенными
горизонтальными линиями, LTSLASH_FILL-наклонными линиями,
SLASH_fIll-утолщенныминаклонными
-линиями, BKSLASH_FILL- утолщенными диагональными
линиями, LTBKSLASH_FILL-диагональными линиями,
HATCLFIlI-вертикальной сеткой,
ХНАТСЙ_ПИ-диагональной сеткой,
INTERLEAVE_FILL-переплетенными линиями,
WIDEDOT_FILL-точками,
CLOSEDOT_FILL-точками С повышенной
setfillstyle
плотностью.
Пример
Демонстрация стандартных шаблонов закрашивания областей.
/* SetFillStyle */
#include<graphics.h>
#1nclude<conio.h>
жа1п()
{
int Driver, Mode;
int Num = XHATCH_FILL;
Driver = DETECT;"
initgraph(&Driverr &Mode. ". .");
if(graphresult() != grOk)
exit(l);
加(»
setfillstyle(Num. getmaxcolor());
floodf111(0, 0. getmaxcolor());
while(! kbhit());
(void)getch();
restorecrtmode();
cscanf("%dM, &Nim);
setgraphmode(Mode);
} while(Numf;
closegraph();
return 0;
setgraphbufsize
Имя
setgraphbufsize - задание размера буфера, используемого для закрашивания ойласте血.
Заголовок
void
setgraphbufs i ze(uns igned BufSize)
Проток ^ ип Функция
graphics.h
Задание размера буфера, используемого для закрашивания областей, равным BufSize байт.
Замечания
Система должна находиться в графическом режиме. Размер буфера должен быть задан перед вызовом функции initgraph. Место для буфера выделяется в **куче**. Принимаемый по умолчанию размер буфера составляет 4 Кбайт.
Пример
Выделение графического буфера для правильного закрашивания многоугольника с большим числом вершин.
/* SetGraphBufSize */ fine1ude<graphics.h>
#include<conio.h>
#1nclude<math.h>
^define dx 4
•define dy 5
•define step 20 n)ain()
int Driver, Mode;
int i,J;
setgraphbufs i ze(20000);
Driver * HERCMONO;
Node = HERCMONOHI;
1n1tgraph(&Driverv &Mode, M..");
1f(graphresult()! = grOk) exit(l);
for(J * 1;
J <= floor((float)getmaxy()/step); j++){ inoveto(0vj * step); for(i=l;
<= floor(2.0/3 * getmaxx()/dx); i++){ if(i & 1)
linerel(dxv +dy);
else
11nerel(dx, -dy);
}
floodf111(getmaxx()f D. getmaxcolor()); sleep(l);
closegraph();
return 0;
setgraphmode
Имя
Заголовок
Прототип Функция
setgraphmcxJe - переключение системы в графический режим.
void
setgraphmode(int Mode) graphics.h
Переключение системы в графический: режим с номером Mode» а затем неявное выполнение функции graphdefaults.
CGACO
-320x200,
палитра 0
CGAC1
-320x200,
палитра 1
CGAC2
-320x200,
палитра 2
CGAC3
-320x200,
палитра 3
CGAHI
-320x200,
1 страница
MCGAC0
-320x200,
палитра 0
MCGAC1
-320x200,
палитра 1
MCGAC2
-320x200, палитра 2
MCGAC3
-320x200, палитра 3
MCGAHED
-640x200, 1 страница
MCGAHI
-640x480, 1 страница
EGALO
-640x200, 16 цветов,
4 страницы
EGAHI
-640x350, 16 цветов,
2 страницы
EGA64L0
-640x200, 16 цветов.
1 страница
EGA64HI
-640x350, 4 цвета,
1 страница
EGAMONOHI
-640x350,
64К на плате адаптера,
1 страница
Я
256К на плате адаптера.
2 страницы
HERCMONOHI
-720x348, 2 страницы
ATT400C0
-320x200, палитра 0
ATT400C1
-320x200, палитра 1
ATT400C2
-320x200, палитра 2
ATT400C3
-320x200, палитра 3
•
ATT400HED
-640x200, 1 страница
АП400Н1
-640x400, 1 страница
VGALO
- 640x200, 16 цветов,
4 страницы
VGAMED
-640x350, 16 цветов.
2 страницы
VGAHI
-640x480, 16 цветов.
1 страница
PC3270HI
-720x350, 1 страница
IBM8514LO
-640x480, 256 цветов
IBH8514HI
-1024x768, 256 цветов
Пример
Вывод и вычерчивание цифры.
/* SetGraphMode */
#include<graphics.h>
#include<conio.h>
main()
{
int Driver, Mode;
int Num;
char Gothic[5];
char Value[15];
Driver 工 DETECT;
initgraph(&Driver, &Mode, ". .**);
if(graphresultf) != grOk)
rxit(l);
restorecrtmodeO ;
cscanf(wXde,, &Num);
setgraphmode(Mode);
settextstyle(DEFAULT_FONT. H0RIZ_DIRt 3); settextjustify(LEFT_TEXT, TOP_TEXT);
1toa(Numr Gothic, 10);
strcpy(Value, **Value « **);
strcat(Value, Gotic);
outtext(Value);
while(! kbhit());
closegrapM);
return 0;
setlinestyle
Имя
Заголовок
set linestyle - выбор вида линии, void setlinestyle(int LineStyle, unsigned Pattern, int Thickness)
Прототип Функция
graphics.h
Выбор вида линии с помощью ар1умента LlneStyle и толщины линии с помощью аргумента Thickness. В случае если LineStyle~USERBIT_LINE, ТО вид линии определяется в соответствии со значениями битов в аргументе Pattern.
Замечания
Система должна находиться в графическом режиме. Номера видов и толщин линий соответствуют следующим возможным вариантам:
Вид линии
SOLIDJLINE - сплошная линия
DOTTED_LINE - точечная линия
CENTERJ.INE - штрихпунктирная линия
DASHED一LINE - пунктирная линия
USERBIT_LINE - линия, задаваемая пользователем.
Толщина линии
NORM_WIDTH - тонкая линия, THICKJ/IDTH - утолщенная линия.
Пример
Вычерчивание окружности и прямой утолщенными точечными линиями.
/* SetLineStyle */
#include<graphics.h>
#include<conio.h>
main()
int Driver, Mode;
Driver н DETECT;
initgraph(&Driverr SMode, M. .**);
if(graphresult()l = grOk)
exit(l);
setlinestyle(DOTTED_LINE. 0, THICK_WIOTH);
circle(getmaxx()/2» getmaxy()/2, 100);
line(0, 0, getmaxxO,0);
while(l kbhit());
closegraph();
return 0;
}
setpalette
Имя
setpalette - изменение цвета, соответствующего одной
Заголовок
Прототип Функция •
из позиций палитры»
void
setpslette(int ColorNum, int Color)
graphics.h
Присвоение идентификатора цвета Color позиции
Замечания
ColorNum палитры.
Система должна находиться в графическом режиме.
Пример
Изменение цвета отображается на экране сразу же после выполнения функции setpalette. Идентификаторы цветов могут иметь следующие значения:
BLACK-черный
BLUE-голубой
GREEN-зеленый
CYAN-бирюзовый
RED-красный
MAGENTA-ярко-красный
BROWN-коричневый
LIGHTGRAY-светло-серый
DARKGRAY-темно-серый
LIGHTBLUE-светло-голубой
LIGHTGREEN-светло-зеленый
LIGHTCYAN-светло'бирюзовый
LIGHTRED-светло-красный
LIGHTMAGENTA-светло-ярко-красный
YELLOW-желтый
WHITE-белый.
Вычерчивание отрезка прямой линии красного цвета на экране монитора, управляемого адаптером EGA, а затем изменение этого цвета на зеленый при нажатии произвольной клавиши.
/* SetPalette */
#1nclude<graphicSoh>
finclude<conio.h>
main()
{
int Driver, Mode;
detectgraph(&Dri verf &Mode);
if((graphresult()! * grOk)||(Driver! = EGA)){ cprintf(MFai]ure");
exlt(l);
setpalette(lt RED);
setcolor(l);
Л.Л1пе(0, 0, getmaxK()f 0);
,、hile(I kbhit());
(void)getch();
setpalette(l» GREEN);
while(! kbhit());
closegraph();
return 0;
setrgbpalette
Имя
setrgbpalette - определение палитры для адаптера IBM 8514.
Заголовок
void setrgbpalette(1nt Color, int Red. int Green, int Blue)
Прототип Функция
graphics.h
Определение компонентов цвета Color с помощью шести старших битов данных (char)Red, char (Green) и (char)Blue.
Замечания
Необходимо, чтобы 0。Color <= 255.
Пример
Вычерчивание диагонали экрана произвольного цвета на мониторе,
управляемом адаптером IBM 8514.
/* SetRGBPalette */
#include<graphics.h>
#include<conio.h>
•define Red 12
•define Green 13
fdefine Blue 12
main()
{
int Driver, Mode;
detectgraph(&Driver, &Mode);
if((graphresullt()! = grOk): g\
(Driver! = IRM8514)){
cprintf(MIcorrect grahplcs environroent**); exit(13);
}
Mode * IBM8514HI;
initgraph(&Driver, &Modet ". .*);
if(graphresult() 1= grOk)
exit ⑴;
setrgbpalette(l( Red «2, Green « 2, Blue «
line(0. 0, getmaXK()r getmaxy());
sleep ⑴;
closegraph();
return 0;
}
settextjustify
Имя
set text justify - задание способа выравнивания графических текстов.
Заголовок
void
settextjustifу(int Horiz, int Vert)
Прототип ・ Функция
graphics.h
Задание способа выравнивания графических тексте® по горизонтали с помощью аргумента Horiz и задание способа их выравнивания по вертикали с помсяцью аргумента Vert.
Замечания
Система должна находиться в графическом режиме. Выравнивание производится относительно точки, отмеченной графическим курсором (функция outtext) или относительно точки с заданными координатами (функция outtextxy). Выравнивание по горизонтали и вертикали может быть выполнено следующими способами:
Выравнивание по горизонтали:
LEFT_TEXT- выравнивание по левому краю,
CENTER_TEXT-выравниваниепо центру,
RIGHT_TEXT-выравниваниепо правому краю,
Выравнивание по вертикали,
ВОТТОМ_ТЕХТ-выравниваниеснизу,
CENTER_TEXT-выравниваниепо центру,
ТОР_ТЕХТ-выравниваниесверху.
Пример
Вывод на экран экрана.
надписи Izabela с выравниванием в правый нижний угол
/* SetTextJustify */
#1nclude<graphics.h>
finclude<conio.h>
main()
{
int Driver, Mode;
Driver = DETECT;
initgraph(&Driverf AMode,"..");
if(graphresult()! = grOk)
exit(l); ^
settextjustify(RIGHT3EXT, BOTTOM_TEXT);
settextstyle(TRIPLEX_FONT, HORIZ_DIRf 5);
outtextxy(getmaxx()r getmaxy(), •'Izabela1'); while(l kbhit());
closegraph();
return 0;
settextstyle
ИмяЗаголовокПрототип ФункцияЗамечанияИмяЗаголовокПрототип ФункцияЗамечанияsettextstyle - выбор шрифта, направления вычерчивания символов текста и их размера, void
Имя
Заголовок
Прототип Функция
Замечания
Имя
Заголовок
Прототип Функция
Замечания
settexStyle(int Font.
int Direction,
int CharSlze)
graphics.h
Выбор шрифта Font, направления вывода символов Direction и размера СИМВОЛОВ CharSize.
Система должна находиться в графическом режиме. Могут быть выбраны следующие виды шрифтов:
DEFAULT_FONT
-шриф1, принимаемый по умолча
TRIPLEX_FONT
нию и определяемый шаблоном 8x8 бит, -тройной штриховой шрифт,
small_f6nt
-ицдексный штриховой шриф1,
SANSSERIF_FONT
-штриховой шрифт сансериф,
GOThIC_FONT
-готический штриховой шрифт.
Штриховые шрифты характеризуются тем, что увели чение их размера не ухудшает вида литер. Можно выбрать следующие направления вывода символов:
HORIZJHR- по горизонтали (слева направо),
VERT_DIR- по вертикали (снизу вверх).
Литеры штриховых шрифтов можно растягивать по вертикали и по горизонтали (см. функцию setusercharsize). Это требует применения параметра Size со значением
USER_CHAR_SIZE - программируемый размер.
Поскольку виды шрифтов обычно загружаются с магнитного диска, то в случае неудачного выполнения функции settextstyle результатом функции будет одно из следующих значений:
grFileFound- отсутствие файла, определяю
щего шриф1,
grNoFontMem- не хватает оперативной памяти
для запоминания шриф1а.
Призер
Вывод вертикальной надписи Kajusla с выравниванием в правый верхний угол экрана.
/* SetTextStyle */
finclude<graph1cs.h>
#include<conio.h>
ma1n()
{*
int Driver. Mode;
Driver н DETECT;
in1tgraph(&Driver, &Moder ". .*);
if(graphresult()! = grOk)
exit(l);
settextjustify(RlGHT_TEXT, TOP_TEXT);
settextstyle(TRIPLEX_FONT. VERT_DIR, 5);
outtextxy(getmaxx(), "Kajusia**);
whHe(! kbhit());
closegraph();
return 0;
setusercharsize
Имя
setusercharsize - задание коэффициентов растяжения литер в штриховых шрифтах.
Заголовок
void
setuserchars 1 ze(int xMul, int xDW. int yMulr Int yDiv)
Прототип Функция
graphics.h
Задание коэффициента растяжения по горизонтали в виде xMul/xDiv и коэффициента растяжения по вертикали в виде yMul/yDiv.
Замечания
Система должна находиться в графическом режиме. После выполнения функции setusercharsize следует вызвать функцию set textstyle с третьим аргументом, имеющим значение USER CHAR SIZE.
Пример
Вычерчивание дважды (растянутой по горизонтали и по вертикали) надписи Jan Bielecki.
/* SetUserCharSize */
#1nclude<graph1cs.h>
finclude<con1o.h>
nia1n()
{/
1nt Driver. Mode;
Driver n DETECT;
initgraph(&Driver, &Mode. ". /');
if(graphresjjlt()f = grOk)
exit(l);
settextjustify(LEFT_TEXT, TOPJTEXT);
setusercharsize(31 1, lr 1);
settextstyle(GOTHIC_FONT, HORIZ_DIR, USER_CHAR_SIZE);
outtext(MJan Bie№ckt“);
settextjustify(LEFTJEXTr BOTTOHJEXT);
setusercharsize(lr 1. 3, 1);
settextsty 1e(GOTHIC_FONT. HORIZ_D% USER_CHAR_SIZE);
outtextxy(0, getmaxy(), "Jan Bielecki");
wh11e(! kbhitC);
closegraph();
return 0;
setviewport
Имя
Заголовок
setviewport - задание графического окна, void
setviewport(int xl₽ int yl₽
int х2. int у2.
int Clip)
Прототип Функция
graphics.h
Задание графического окна в виде прямоугольника с координатами противоположных по диагонали вершин (xle yl) и (х2, у2). Аргумент clip показывает, следует ли усекать фрагменты, выходящие за пределы окна.
Замечания
После создания графического окна все графические операции (за исключением setviewport) выполняются в этом окне» По умолчанию принимается, что таким окном является весь экран.
Пример
Вычерчивание
вертикального отрезка прямой линии в окне, составляющем
правую половину экрана»
/* SetViewPort */ finclude<graphics.h» #include<conio.h>
•define ClipOn 1
nain()
{
int Driver, Mode;
Driver « HERCMONO;
Mode n HERCMONOHI;
initgraph(&Driver, &Mode. ". .*'); if(graphresult()! ■ grOk)
®xit(l);
setv1ewport(getmaxx()/2, 0,
getnaxxO, getiwcy(). ClipOn); line(0, 0, 0^getnaxy()/3);
while(! kbh1t());
c】osegraph();
return 0;
setvisualpage
Имя ЗаголовокПрототип ФункцияЗамечанияИмя ЗаголовокПрототип ФункцияЗамечанияsetvisualpage ~ выбор страницы, выводимой на экран, void
Имя Заголовок
Прототип Функция
Замечания
Имя Заголовок
Прототип Функция
Замечания
setvisualpage(int Page)
graph!cs.h
Выбор для индикации на экране страницы с номером Раде.
Система должна находиться в графическом режиме. Возможность выбора выводимой на экран страницы относится только к адаптерам EGA, VGA и HERCULES.
Пример
Попеременная индикация надписей izunla и KajurHa.
/* SetVisual Page */
#include<graphics.h»
#include<conio.h>
n»in()
{
int Driver. Mode;
int Nun n 0;
int i;
Driver « DETECT;
in1tgraph(&Dr1ver( &Mode, ". .");
if(graphresu1t()! = grOk) exit(l);
settextjustify(LEFT_TEXT, TOP_TEXT);
settextsty1e(G0THIC_F0NT. HORIZ_DIR, 6);
outtextxy(Or 0. "Kajuniaw);
setactivepage(l);
settextjustify(RIGHT_TEXTt TOPJTEXT);
outtextxy(getmaxx()f 0r MIzunia");
for(i«l; i<=20; i++){
Num « 1 - Num;
setvisualpage(Num);
sleep(l);
}
closegraph();
return 0;
setwritemode
Имя
Заголовок
setwr Itemode - задание режима вычерчивания линий, void
setwr1temode(1nt Mede)
Прототип Функция
graphics.h
Задание с помощь^ аргумента Mode одного из двух режимов вычерчивания линий.
Замечания
Система должна находиться в графическом режиме. Могут быть заданы следующие режимы вычерчивания линий:
COPY_PUT- с необратимым наложением,
XOR_PUT- с обратимым наложением.
Пример
Вычерчивание отрезка прямой линии, перемещающегося на фойе сектора эллипса.
/* SetWriteMode */
findude<graphics.h»
#include<conio.h>
main()
{
int Driver, Mode;
Driver w DETECT;
initgraph(&DrIver. 8iMode, ". .”);
if(graphresult() 1= grOk)
exit(l);
sector(getmaxy( )»1« getiwcy()»l;
0. 270.
150. 100);
setwri temode(XOR_PUT);
for(i=0; 1 < =144; i++){
Hne(0f getn»xy()( 5, * t. 0);
494
Часть VI. Библиотеки
line(O, getmaxy()t 5 * 1.0) }
while(l kbhit(J);
(votd)getcM):
closegraph();
return 0;
}
textattr
Имя
textattr - изменение признаков символа, фона и мерцания.
Заголовок
void
Прототип.辞 Функция
textattr(int NewAttr)
conio.h
Присвоение переменной TextAttr признаков цвета символа, цвета фона и мерцания, определяемых аргументом NewAttr.
Замечания
Переменная TextAttr является 8-бит переменной
! В 1 ь 1 Ь 1 Ь 1 f 1 f 1 f 1 f !
Бит В связан с мерцанием, биты b указывают цвет фона, а биты f - цвет символа.
Пример
Вывод мерцающего негативного (inverse,video) изображения надписи Hello в левом верхнем углу экрана монитора, управляемого адаптером HERCULES.
/* TextAttr */
#include<conio.h>
n«in()
{
int Driver Mode;
clrscrf);
textattr(OxFO);
cprintfC,Hello,');
retum 0;
}
textbackground
Имя
Заголовок
textbackground - задание цвета фона, void
textbackground(1nt Color)
Прототип Функция
conio.h
Присвоение переменной TextAttr признака цвета фона Color
Замечания
Признак цвета фона является трехбитовым, с его помощью могут быть заданы следующие цвета:
BLACK BLUE GREEN CYAN
RED MAGENTA BROWN LIGHTGRAY
-черный
-.голубой
-зеленый
-бирюзовый
-красный
-ярко-красный
-коричневый
-светло-серый
После задания цвета фона все выводимые на экран символы (в том числе и пробелы) будут демонстрироваться на этом фоне.
Пример
Вывод красной надписи Jan на зеленом фоне на экран монитора, управляемого адаптером EGA.
/* TextBackground */ findude<graphics,h> #include<conio.h> main()
{
int Driver. Mode;
clrscr();
detectgraph(&Dr i ver, &Mode); if((graphresult()! = grOk):
(Driver! = EGA)){ cprirrtf(wFailure"); exit(l);
}
textbackground(GREEN);
textcolor(RED);
cprintfC^Jan1');
return 0;
textcolor
Имя Заголовок
Прототип Функция
Замечания
text со lor - задание цвета символа.
void
textcolor(int Color)
conio.h
Присвоение переменной TextAttr признака цвета символа и признака мерцания, определяемых в аргументе Color.
Признак цвета символа является трехбитовым, а
признак мерцания - однобитовым. С помощью этих признаков можно задать следующие значения:
BLACK BLUE GREEN CYAN RED MAGENTA BROWN UGHTGRAY DARKGRAY UGHTBLUE UGHTGREEN UGHTCYAN LIGHTRED UGHTMAGENTA YELLOWWHITEBLACK BLUE GREEN CYAN RED MAGENTA BROWN UGHTGRAY DARKGRAY UGHTBLUE UGHTGREEN UGHTCYAN LIGHTRED UGHTMAGENTA YELLOWWHITEчерный
BLACK BLUE GREEN CYAN RED MAGENTA BROWN UGHTGRAY DARKGRAY UGHTBLUE UGHTGREEN UGHTCYAN LIGHTRED UGHTMAGENTA YELLOW
WHITE
BLACK BLUE GREEN CYAN RED MAGENTA BROWN UGHTGRAY DARKGRAY UGHTBLUE UGHTGREEN UGHTCYAN LIGHTRED UGHTMAGENTA YELLOW
WHITE
голубой
зеленый
бирюзовый
красный
ярко-красный
коричневый
-светло-серый
темно-серый
св етл о-гол у бой
светло-зеленый
- светло-бирюзовый
светло-красный
- светло-ярко-красный
желтый
белый
Признак мерцания
BUNKBUNK-мерцание
BUNK
BUNK
После задания цвета символа все выводимые на экран символы будут иметь этот цвет.
Пример
Вывод красной мерцающей надписи Jan на зеленом фоне на экран монитора, управляемого адаптером EGA.
/* 3extColor */
#tnc1ude<graphics.h>
#include<coriio»h>
main()
{
tvrt Driver, Mode;
c1rscr();
dBtectgraphC&Driver, &Mode);
if((graphresult()l « grOk)[J (Driver! * EGA)){
cprintf("FAILURE-);
exit(l);
}
textbackground(GREEN);
textcolor(RED + BLINK);
cprintf(wJanw);
return 0;
textheight
Имя
Заголовок
textheight - задание высоты текста, int
textheight(char * Textstring)
Прототип Функция
graphics.h
Формирование значениия типа (int), равного вертикальному размеру (измеряемому числом точек) текста, указанного в аргументе Textstring.
Замечания
Система должна находиться в графическом режиме» Результат учитывает коэффициент растяжения символов по вертикали.
Пример
Задание высоты текста, вычерчиваемого готическим шрифтом
/* TextHeight */
#include<graphics.h»
finclude<con1o.h>
nain()
{
int Driver, Mode;
int Height;
Driver = DETECT;
initgraph(&Driver, &Mode, *..");
if(graphresu]t()! « grOk)
exit(l);
settextstyle(GOTHIC_FONTf HORIZ_DIR, 1);
Height « textheight (” * w);
restorecrtrodeO;
cprlntf("Height - %d”. Height); /* If HERC » 16 */
return 0;
}
BW40C40BW80BW40C40BW80-40x80, черно-белый-40x25, цветной-80x25, черно-белый-40x80, черно-белый-40x25, цветной-80x25, черно-белый
BW40
C40
BW80
BW40
C40
BW80
-40x80, черно-белый
-40x25, цветной
-80x25, черно-белый
-40x80, черно-белый
-40x25, цветной
-80x25, черно-белый
textmode
Имя
Заголовок
textmode - установка текстового режима, void
textmode(int Mode)
Прототип Функция
conio.h
Переход от текущего текстового режима к текстовому
Замечания
режиму Mode.
Новый текстовой режим может быть указан с помощью следующих констант:
С80MONOС80MONO-80x25, цветной-80x25, черно-белый (на-80x25, цветной-80x25, черно-белый (намонохроматическом мониторе)монохроматическом мониторе)
С80
MONO
С80
MONO
-80x25, цветной
-80x25, черно-белый (на
-80x25, цветной
-80x25, черно-белый (на
монохроматическом мониторе)
монохроматическом мониторе)
Дополнительную возможность указания режима дает применение константы LASTMODE. В случае указания
ее в качестве аргумента функции textmode происходит переключение в режим, действовавший до начала
выполнения программы. Следует отметить, что сразу же после вызша функции textmode текущее текстовое окно распространяется на весь экран и очищается, а переменной TextAttr присваиваются значения
признаков как после вызова функции nonnvideo.
Пример 品
Вывод на экран надписи Jan повышенной яркости, а после нажатия клавиши Enter - надписи Ewa в том режиме, который действовал до начала выполнения программы.
/* TextMode */
#include<conjo.h>
#include<stdio»h>
natn()
{
clrscrf);
hightvideo();
cprintfC,Jan,,);
while(getchar() I = f\n*);
textmode(LASTMODE);
cprintf(MEWAM);
return 0;
textwidth
ИмяЗаголовокИмяЗаголовокПрототип Функция.Прототип Функция.ЗамечанияЗамечанияtextwidth - задание ширины текста.inttextwidth(char * Textstring)graphics.hФормирование значения тапа (int), равного горизонтальному размеру (измеряемому числом точек) текста, указанного в аргументе Textstring.Система должна находиться в графическом режиме. Результат учитывает коэффициент растяжения символов по горизонтали.textwidth - задание ширины текста.inttextwidth(char * Textstring)graphics.hФормирование значения тапа (int), равного горизонтальному размеру (измеряемому числом точек) текста, указанного в аргументе Textstring.Система должна находиться в графическом режиме. Результат учитывает коэффициент растяжения символов по горизонтали.
Имя
Заголовок
Имя
Заголовок
Прототип Функция.
Прототип Функция.
Замечания
Замечания
textwidth - задание ширины текста.
int
textwidth(char * Textstring)
graphics.h
Формирование значения тапа (int), равного горизонтальному размеру (измеряемому числом точек) текста, указанного в аргументе Textstring.
Система должна находиться в графическом режиме. Результат учитывает коэффициент растяжения символов по горизонтали.
textwidth - задание ширины текста.
int
textwidth(char * Textstring)
graphics.h
Формирование значения тапа (int), равного горизонтальному размеру (измеряемому числом точек) текста, указанного в аргументе Textstring.
Система должна находиться в графическом режиме. Результат учитывает коэффициент растяжения символов по горизонтали.
Пример
/* TextWidth */
#1nclude<graphics.h»
#include<con1oeh>
irain()
{
int Driver. Mode;
int Width;
Driver « DETECT;
1n1tgraph(&Dr1ver, feMode. ". J);
1f(graphresult()! = grOk) exit(l);
settextstyle(GOTHICJONT. VERT_DIR. 1);
settextjustifyfRXGHT.TEXT, ВОТТОМДЕХТ); outtextxy(getmaxx()₽ getmaxyf), 咏B; while(! "hit。); (void)getch();
Width 工 textw1dth(Mjb,s); restorecrtmode();
cprintf「Width = %d\ Width); /* if HERC » 13 */ return 0;
}
wherex
Имя
wherex - сообщение о горизонтальной координате текстового курсора.
Заголовок
int
wherex(woid)
Прототип Функция
conio.h
Формирование значения типа (int), равного горизонтальной координате текстового курсора.
Замечания
Координата относится к текущему графическому окну. Левый верхний символ в окне имеет горизонтальную координату, равную L
Пример
.Вывод на экран надписи Jan 映 цифры 4.
/* WhereX */
finclude<conio.h>
finclude<stdio.h>
main()
{
clrscr();
cprintf(MJanw);
cprintf(M%dM, wherex()); /* 4 */
return 0;
}
wherey
Имя
wherey - сообщение о вертикальной координате текстового курсора.
Заголовок
int wherey(void)
Прототип Функция
conlo.h
Формирование значения типа (int), равного вертикальной координате текстового курсора.
Замечания
Координата относится к текущему графическому окну. Левый верхний символ в окне имеет вертикальную координату, равную 1.
Пример
Вывод на экран
надписи Jan и цифры 1.
/* WhereY */
f1nclude<conio.h>
#include<stdio«h>
п»1п()
{*
clrscr();
cprintf("Jan");
cprintf(M%d\nM, whereyO); /* 1 */ return 0;
window
Имя
Заголовок
window,- создание текстового окна, void
window(int xlf int yl,
1nt x2. int y2)
Прототип Функция
conio.h
Формирование текстового окна в виде прямоугольника, противоположные по диагонали вершины которого имеют координаты &1. yl) и G2. у2)
Замечания
Координаты отсчитывакися относительно экрана. Левый верхний угол экрана имеет координаты (1, 1). Самое малое окно состоит из одного столбца и одной строки. Окно, принимаемое по умолчанию, имеет координаты (1, 1, 80, 25) в режимах с шириной экрана 80 столбцов и координаты (1, 1, 40, 25) в режимах с шириной экрана 40 столбцов. В случае ошибочного указания координат окна выполнение функции window заканчивается безрезультатно. После создания текстового окна все текстовые координаты (за исключением упомянутых в функции window)
отсчитываются относительно этого окна.
Пример
Создание текстового окна и размещение в нем случайно подобранных малых букв.
/* Window */
#1nclude<con1o.h>
#include<stdio.h>
ma1n()
{
Int 1;
clrscrf);
srand(O);
wlndowflO, 10. 30. 20);
for(1 m1; i < = 200; i++){
gotoxy(rand()%81, rand() % 26);
cpr1ntf(MXcM, ra* + rand() % 26);
}
return 0;
17.2. Системная библиотека
Сисгемная библиотека состоит из функций стандарта ANSI (курсивом выделены функции, не реализованные в Турбо С), а также из избранных функций системы Турбо С.
функции ANSI
abort
abs
acos
asctime
asin
assert
atan
atan2
atexit
atof
atoi
atol
brearch
calloc
ceil
clearerr
clock
cos
cosh
ctime
difftime
div
exit
exp
fabs
fclose
feof
ferror
fflush
fgetc
fgetpos
fgets
floor
taod
fopen
fprintf
fputc
fputs
fread
free
freopen
frexp
fscanf
fseek
fsetpos
ftell
fwrite
getc
getchar
getenv
gets
gmtime
isalnum
isalpha
iscntrl
isdigit
isgraph
islower
isprint
ispunct
isspace
isupper
isxdigit
labs
Idexp
Idiv
localeconv
locallime
log
502
Часть VI. Библиотеки
loglO
longjmp
malloc
тЫеп
mbstowcs
mbtowc
memchr
memcmp
memcpy
memmove
memset
mktitne
modf
onexit
offsetof
perror
pow
printf
putc
putchar
puts
qsort
raise
rand
realloc
remove
rename
rewind
scanf
setbuf
setjmp
setlocale
settime
setvbuf
signal
sin
sinh
sprintf
sqrt
srand
sscanf
strcat
strchr
strcmp
strcoil
strcpy 承
strcspn
strerror
strftime
stiien
strncat
strncmp
strncpy
strpbrk
strrchr
strspn
strstr
strtod
strtok
strtol
system
tan
tanh
time
tmpfile
tmpnam
tolower *
toupper
ungetc
va-arg
va-end
va—start
vfprintf
vprintf
vsprintf
Функции Турбо
bdos
bdosptr
cgets
chdir
coreleft
cprintf
cputs
cscanf
delay
-EMIT
farcalloc
farcoreleft
farfree
farmalloc
farrealloc
findfirst
findnext
fnmerge
fnsplit
FP-OFF
FP-SEG
getch
getdate
gettime
getvect
inport
inportd
int86
in[86x
intdos
intdosx
intr
itoa
kbhit
Itoa
mkdir
MK-FP
movedata
nosound
outport
outportb
peek
peekb
poke
poked
putch
putenv
rmdir
setdate
settime
setdisk
setvect
sleep
sound
ultoa
ungetch
unlink
vfscanf
vscanf
vsscanf
Использование системной библиотеки во многих случаях требует обращения к предварительно объявленным типам и переменным. Вот наиболее важные из них.
Предварительно объявленные типы
stdlo.h
typeredef long fpos_t;
sdlib.h
typedef unsigned size_t;
typedef struct{
Int quot. rem
} d1v_t;
typedef struct{
long quot, rem;
} ldiv_t;
typedef void.(*atextt_t)(votd);
time.h
typedef long time_t;
typedef long docket;
stdarg.h
typedef void *va_ltstj
setjmp.h
typedef struct{
unsigned j_sp, j_ss. Lflag.
J_CS. j_ip. Lbp・
Ldt. J_es. J_st. j_ds;
} jmp_buf[l];
Предварительно объявленные переменные
ermo
Если выполнение функции, в описании которой упомянута переменная errno, завершится неудачно, то этой переменной будет присвоено значение, отличное от нуля и равное, например
EDOM- ошибка области определения (domain error),
ERANGE - ошибка диапазона (range error).
-8087
Если в системе имеется арифметический сопроцессор, то этой переменной присваивается значение, отличное от нуля, а именно:
1-длясопроцессора8087,
2-длясопроцессора80287,
3-длясопроцессора80387.
В противном случае —8087 == 0.
-fmode Если при вызове функции fopen не указан явно режим обра ботки 融йла (текстовый или бинарный), то режим определяет ся значением этой переменной (по умолчанию О-ТЕХТ).
-pspЗначение переменной указывает номер сегмента, в котором
находится PSP программы.
-heaplen Значение переменной определяет размер ближней кучи.
Ближняя "куна" существует только в моделях Tiny, Small и Medium. В моделях Small и Medium размер сегмента данных определяется по формуле
segment = global + heap + stack
(глобальные данные, “куча", стек). В модели Tiny как код, так и данные находятся в одном и том же сегменте, поэтому применяется формула
* segment = 256+code+global+heap+stack
(256 байт занимает PSP).
-stklen ' Значение переменной определяет размер стека (в байтах). По умолчанию принимается 4 Кбайт.
-version Значение переменной определяет номер версии операционной системы DOS.
Замечание. В стандартной версии Си ANSI интерпретацию имеет только переменная еггпо.
abortANSI
Имя
abort - преждевременное, аварийное завершение выполнения программы.
Заголовок
void abort(void)
Прототип Функция
stdMb.h, process.h »
Вывод сообщения в файл с идентификатором stderr и немедленное прекращение исполнения программы (без очистки буферов и закрытия файлов).
Результат
void
Пример
D Прототипы некоторых системных функций находятся в нескольких файлах заголовка. При написании программы в директиве процессора include можно использовать наиболее предпочтительную, исходя, например, из соображений меньшего объема оперативной памяти. - Прим. ре°・
Помещение последовательности символов Jan в файл DISK.
/* abort */
•Include <stdio.h>
『Include <stdlib.h>
ma1n(}
FILE *Out n fopenC^ISK". ”『);
fprintf(Out, "Jan");
fflush(Out);
fprintffOut, -EWA");
abort();
return 0;
}
abs
ANSI
Имяabs - определениеабсолютногозначения.
Заголовокint
abs(1nt 1)
Прототипstdllb.h, math.h
ОпределениеstdMb.h
ФункцияФормированиезначения,равного№.
РезультатВеличина типа (fnt), равная абсолютному
аргумента.
Исключение: abs (-32768) «« -32768.
значению
Пример
Использование макроопределения для вывода числа 13.
/* abs */
•include <stdio.h>
•include <std11b.h>
undef abs
main()
{
pr1ntf(-*Xd,,t abs (-13));
retutn 0;
}
acos
ANSI
Имя.acos - вычисление арккосинуса.
Заголовокdouble
acos(double x)
Прототипmath.h
ФункцияФормирование значения, равного arc cos x.
506
Часть УЛ Библиотеки
Результат
Величина типа (double) со значением, равным арккосинусу аргумента. Это значение принадлежит диапазону 0・.р厶
Замечания
Если аргумент не принадлежит диапазону “..1, то результат имеет значение 0, a errno=ED0M.
Пример
Вывод числа 3.14.
/* acos */
♦Include <std1o.h> include <math.h> main() {
prlntf(и% ^Г\ 3 * acos(0r5)); return 0;
}
asctime
ANSI
Имя•
asctime - преобразование даты и времени в символьную форму.
Заголовок
char *
asct1me(struct tm *tm)
Прототип Функция
tlme.h
Преобразование даты и времени, выраженных с помощью полей структуры, указанной в аргументе tm, в последовательность символов вида, например,
Sun Dec 13 06: 00: 00 1981 /п/
(название дня недели, название месяца, номер дня в месяце, время дня, год) с учетом того, что структура типа (struct tm) содержит следующие компоненты времени и даты: количество секунд с начала часа (min), количество часов после полуночи (hour), количество месяцев, начиная в января (mon), количество лет с начала века (year), количество дней после воскресенья (wday), количество дней с 1 января (yday), признак, указывающий, действует ли летнее время (isdst).
Результат
Значение типа (char *), указывающее на первый символ сформированной последовательности.
Замечания
Тип (struct tm) объявлен следующим образом:
struct tn { Int tm_sec.
tm_^n, tm_hour, tw_raday.
tm_mon, tm」ear, tm_mdayr tm_1sdst;
Пример
Вывод на экран надписи Sun 13 06 :00:00 1981
/* asctime */
ffnclude <t1me.h>
•include <stdio.h>
struct tm TheDay = {0, 0, 6, 13, 12, 81};
main()
{
printf(”% s". ascthie(&TheDay));
return 0;
}
asin
ANSI
Имя
Заголовок
asin - вычисление арксинуса, double
asin(double х)
Прототип Функция Результат
mathoh
Формирование значения, равного arc sin х.
Величина типа (double), равна арксинусу аргумента. Это значение принадлежит диапазону -pi/2^pl/2.
Значения
Если аргумент не принадлежит диапазону ~1..1, то результат имеет значение 0, a errno=ED0M.
Пример
Вывод на экран числа 3.14.
/* asin */
•include <stdio.h>
finclude <math.h>
matn() {
prlntff'% 2f"t Z * asin(l.O));
return 0;
}
assert
ANSI
Имя
Включение
assert - проверка правильности сравнения, assert.h
508
Часть VI. Библиотеки
Заголовок
/* void */
assert(/* int */ test)
Определение Функция
assert.h
Проверка правильности сравнения
(test) ■■ 1.
в противном случае аварийное завершение выполнения программы, которому предшествует выдача сообщения
Assertion failed: test file name, line number
в котором name - имя исходного файла, a number - номер строки в этом файле.
Замечания
Функция assert является макроопределением. Если ее включение произойдет в пределах макроопределе ния NDEBUG, то оно будет считаться не имевшим места.
Пример
Вывод надписи
Assertion failed: Vai »* O.flle ASSERT.С, Mne 9
(предполагается, что
программа находится в файле ASSERT.С)
/* assert */
♦Include <assert.h>
•Include <std1o.h>
main()
{
int val n 13;
fdeflne NDEBUG
assert(Val »«0);
pr1ntf(MAfter first assert");
ftndef NDEBUG
assertrt(Val »« 0);
pr1ntf(MAfter second assert**);
return 0;
}
atan
ANSI
Имя
Заголовок
atan - вычисление арктангенса, double atan(double х)
Прототип Функция Результат
math.h
Формирование значения, равного arc tg х.
Величина типа (double) со значением, равным арктан генсу аргумента. Это значение принадлежит диапазону
-pi/2..pl/2.
Пример
Вывод числа 3』4。
/* aten */
^include <stdio.h>
ffnclude *math.h>
main()
{
prlntff*% 2Г, 4 * atan(l.O));
return 0;
}
atan2
ANSI
Имя
atan2 - вычисление арктангенса..
Заголовок
double
atan2(double y.
double x)
Прототип
math.h
Функция
Формирование значения, равного ars tg y/x.
Результат
Величина типа (double) co значением, равным
арктангенсу частного от деления первого аргумента
на второй. Это значение принадлежит диапазону
-pZ/2..pZ/2.
Замечания
Если оба apiyмента имеют значение 0, то
errno=ED0M.
Пример
Вывод числа 3.14.
/* atan2 */
•Include <stdio.h>
#tnc1ude <math.h>
ma1n()
{
printf(“X 2f”. 4
* atanZ(l.l));
return 0;
}
atexit
ANSI
Имя
atexft - определение действия, завершающего
выполнение программы.
Заголовок
int
atex1t(atexit_t fun)
Прототип
stdllb.h
510
Функция
Часть УЛ Библиотеки
Регистрация функции, определяющей действие, которое будет выполнено после завершения исполнения программы.
Результат
Величина типа (int) со значение 0 в случае успешной регистрации действия и со значением, отличным от нуля, в противном случае.
Замечания
В случае регистрации более чем одного действия последовательность их выполнения будет обратной очередности их регистрации.
Пример
Вывод надписи Зуе, bye!, а затем надписи Second и надписи First.
/* atexlt •/ /* atan */*
•Include <std!1o.h> findude <stdio.h> void Ftrst(vold) {
printf(wnF1rstw);
}
void Second(vofld)
{
prtntf^nSecond")
}
main() {
atexft(Ffrst);
atexlt(Second);
pr1ntf(e,\nByef bye!");
return 0;
}
atof
ANSS
Имя
atof - преобразование последовательности символов в число с плавающей точкой.
Заголовок
double
atof(char *nptr)
Прототип Функция
stdllb.h, math.h
Преобразование строковой переменной, указанной в аргументе nptr, в число типа (double).
Результат
Число типа (double), соответствующее данной строковой переменной.
Замечания
Преобразуемая последовательность символов может содержать следующие элементы: пробел, табуляция, знак числа, последовательность цифр, точка, последовательность цифр, малая или большая буква Е и показатель степени. Показатель степени может содер-
ИмяИмяЗаголовокЗаголовокПрототип. ФункцияПрототип. ФункцияРезультатРезультатatoi - преобразование строки символов в число типа (int)intatoi(const char *nptr)stdllb.hПреобразование строковой переменной, указанной в аргументе nptr, в число типа (int).atoi - преобразование строки символов в число типа (int)intatoi(const char *nptr)stdllb.hПреобразование строковой переменной, указанной в аргументе nptr, в число типа (int).ЗамечанияЗамечанияЧисло типа (int), соответствующее данной строковой переменногоПреобразуемая строка может содержать следующие элементы: пробел и табуляция, знак числа, последовательность цифр. Преобразование заканчивается в тот момент, когда встречается символ, не входящий в число.Число типа (int), соответствующее данной строковой переменногоПреобразуемая строка может содержать следующие элементы: пробел и табуляция, знак числа, последовательность цифр. Преобразование заканчивается в тот момент, когда встречается символ, не входящий в число.
Имя
Имя
Заголовок
Заголовок
Прототип. Функция
Прототип. Функция
Результат
Результат
atoi - преобразование строки символов в число типа (int)
int
atoi(const char *nptr)
stdllb.h
Преобразование строковой переменной, указанной в аргументе nptr, в число типа (int).
atoi - преобразование строки символов в число типа (int)
int
atoi(const char *nptr)
stdllb.h
Преобразование строковой переменной, указанной в аргументе nptr, в число типа (int).
Замечания
Замечания
Число типа (int), соответствующее данной строковой переменного
Преобразуемая строка может содержать следующие элементы: пробел и табуляция, знак числа, последовательность цифр. Преобразование заканчивается в тот момент, когда встречается символ, не входящий в число.
Число типа (int), соответствующее данной строковой переменного
Преобразуемая строка может содержать следующие элементы: пробел и табуляция, знак числа, последовательность цифр. Преобразование заканчивается в тот момент, когда встречается символ, не входящий в число.
/7. Приняты описания
жать знак + (плюс) или - (.минус) и последователь^ ность цифр» Преобразование заканчивается в тот момент, когда встречается символ» не входящий в число.
Пример
Вывод числа -456.78
/* atof */
finclude <stdio.h> finclude <math.h> main(}
{
printf(”% 2f\ а4оГ(и-45.678е+01и)); return 0;
atoiatoiANSI
atoi
atoi
Пример
Вывод числа 45.
/* atoi */
•include <stdio.h>
^include <stlib.h>
main()
{
printf('%d"₽ atoi(° 45JB));
return 0;
512
Часть VI. Библиотеки
atol
ANSI
Имя
atol - преобразование строки символов в число типа (long).
Заголовок
long
atol(const char * nptr)
Функция
Преобразование строковсж переменной, указанной в ар!ументе nptr, в число типа (long).
Результат
Число типа (int), соответствующей данной строковой переменной.
Замечания
Преобразуемая строка мохсет содержать следующие элементы: пробел и табуляция, знак имела, последовательность цифр. Преобразование заканчиватеся в тот момент, когда встречается
司
символ, не входящий в число.
Пример
Вывод числа -3.
/* atol */
finclude <stdio.h>
finclude <stdlib.h>
nain()
{
printfC^ld", ato](” ・““3х“)); return 0;
}
bdos
TURBO
Имя
Заголовок
bdos - вызов функции системы DOS. int
bdosfint dosfun,
unsigned dosdx, unsigned dosal)
Прототип Функция
dos.h
Исполнение функции системы DOS с номером dosfun, связанной с прерыванием 0x21. Передача функции ар гументов, ожидаемых в регистрах DX(dosdx) и AL(dosal).
Результат
Число типа (int), оставляемое функцией в регистре АХ。
Пример,
Вывод надписи
Current drive: d
в которой d обозначает текущий дисковод (нап|жмер, В).
"bdos */
finclude <stdio.h>
finclude <dos.h>
HiainO
{
printf(HCurrent drive: Xcw, *A* + bdos(0x19. 0, 0)); return 0;
}
bdosptr
TURBO
Имя
Заголовок
bdosptr - вызов системной функции, int
bdosptr(int dosfun.
void *arg, unsigned dosal)
Прототип Функция
dos.h
Вызов системной функции с номером dosfun, связанной с прерыванием 0x21. Передача функции оходаемых параметров: адреса arg и содержимого регистра Al - dosal.
Результат
Переменная типа (int), оставляемая функцией в регистре ах.
Пример
Вывод надписи Izabela.
/* bdosptr */ finclude <stdio.h> •include <dos.h> mainO {
(void)bdosptr(0x9, "Izabela$w,, 0); return 0;
}
bsearch
ANSI
Имя
Заголовок
bsearch - бинарный поиск.
void *
bsearch(const void *key. const void *base, size_t nelera, size」width,
int (*fcmp)(const void *₽ const void *));
' Прототип Функция
stdlib.h
Просмотр таблицы с целью обнаружения элемента, идентифицируемого заданным ключом. При этом
514Часть W. Библиотеки
понимается, что base указывает первый элемент таблицы, nele・-число элементов в таблице, key - ключ, a width определяет размер ключа. Сравнение ключей производится с помощью функции, указываемой в fcmp. Эта функция должна быть подобрана таким образом, итойл в случае ее вызова с двумя аргументами: Key (указание адреса искомого элемента) и Elm (указание адреса элемента таблицы) она выдавала результат, имеющий отрицательное, нулевое или положительное значение в зависимости от того, находится ли объект в области, указываемой Key, и является ли ои соответственно меиьшим, равным или болыпим объекта, находящегося в области, указываемой Elm.
РезультатПеременная типа (void *), указывающая найденный
элемент таблицы или имеющая пустое значение ~ если такой элемент в таблице отсутствует.
Пример
Вывод буквы С.
/* brearch */
•include <stdio.h>
•include <stdlib.h>
char Arr[3][2] = { S・ »'}{1, 'B'}・{2. У'}};
char Key[2] = {2};
main()
int CompO;
printf("%c"・ *(1 + (char *)
bsearchfKey(Arrt3r2rComp)));
return 0;
} int Comp(void *Key,vo^d *Elm) {
return *(char *)Key - *(char *)Elm;
}
callocANSI
Имя
Заголовок
calloc - выделение памяти, void *
calloc(size_t nelem.
size_t elsize)
Прототип Функция
stdltb.h. alloc.h
Выделение обнуленной области памяти, в которой мох^но разместить nelem объектов размером el size каждый.
РезультатЗамечанияРезультатЗамечанияПеременная типа (void *), определяющая выделенную область памяти или принимающая значение null, если ее выделение невозмох^но. На самом деле выделяется область размера
Результат
Замечания
Результат
Замечания
(unsigned)(nelew * elsize),
а это ие то же самое, что nelem объектов размером glsize каждый.
Пример
Вывод надписи jb»
/* calloc */
#Include <stdio.h> ^include <alloc.h> inainO
{
char *Ref = celloc(3.1);
Ref[0]='』•;
Ref[l] н ・b'; printf("%s'\ Ref);
return 0;
ANSI
ИмяЗаголовокПрототип. ФункцияРезультатИмяЗаголовокПрототип. ФункцияРезультатceil 一 округление в сторону увеличения.
Имя
Заголовок
Прототип. Функция
Результат
Имя
Заголовок
Прототип. Функция
Результат
double
cel[(double х)
math.h
Формирование переменной типа (double), представляю щей собой наименьшее целое число, не меньшее х.
Число типа《double).
Пример
Вывод числа 5.00.
/* се11 */
•include <stdio.h>
•include <math.h> niainQ {
printf(MX.2rr ceil(4.01)); return 0;
}
516
Часть УЛ Библиотеки
cgets
TURBO
Имя
cgets - ввод последовательности символов с коисоли.
Заголовок
char *
cgets(char *string)
Прототип Функция
conio.h
Ввод с консоли ограниченного числа символов.
Ввод прекращается после того, как встретится символ конца строки, или после ввода string [0 ] символов. Замена символа конца строки символом с кодом 0. Размещение введенных символов, начиная с string [2], и п^шсвоение переменной string [1 ] значения, равного числу введенных знаков.
Результат а
Переменная типа (char *), которой соответствует первый введенный символ.
Пример
После ввода символов Qja вывод надписи Kaja. /* cgets */ •include <stdto.h> finclude <conio.h> ma1n() {
char Buffer[8];
*Buffer * 5;
(void)cgets(Buffer);
*(Buffer + 2 + Buffer[l]) = '\0';
printf(”\n*s"・ Buffer + 2): return 0;
chdir
TURBO
Имя
Заголовок
chdir - смена текущего каталога., int
chdir(const char * path)
Прототип Функция
dir.h
Назначение в качестве текущего каталога указанного диска каталога с именем path.
Результат
Переменная типа (int) со значением 0 в случае успе шного выполнения функции и со значением -1 в про тивном случае; при этом устанавливается также
еггпо = ENDE NT - дефектная дорохска.
Замечания
Если диск не указан, то по умолчанию принимается текущий диск.'
Пример
Замена каталога текущего диска В на \TC20.
/* chdir */
•include <dir.h> finclude <stdio.h> ma1n()
{
chdir(B:\\TC20B,);
return 0;
}
ciearerr
ANSI
Имяciearerr - обнуление указателей файла.
Заголовокvoid
ciearerr (FILE *stream)
Прототипstdio.h
ФункцияОбнуление указателя ошибки и указателя
файла.
Результатvoid
конца
Пример
Вывод цифр 1 и 0, определяющих значение указателя конца выполнением и после выполнения функции ciearerr.
файла
перед
/* ciearerr */ finclude <stdio.h> inainO {
FILE *0utIn;
Outln н fopenC'WORK", V); fclose(Outln);
Outln = fopenC*WORKMt >-);
(void)getc(Outln);
pEtf(,T. Hfeof(Outln)); clearerr(Outln);
pr1ntf(f,%do. Hfeof(Outln)); return 0;
}
clock
ANSI
Имя.clock - сообщение о времени выполнения
программы.
Заголовокlong
Прототип ФункцияРезультатЗамечанияПрототип ФункцияРезультатЗамечанияclock(vofd)
Прототип Функция
Результат
Замечания
Прототип Функция
Результат
Замечания
time.h
Формирование переменной типа (long) со значением, равным произведению t*1000, где t - число секунд, прошедших с момента начала выполнения программы.
Переменная типа (long) с указанным выше значением^
Если процессор не имеет часов, то результатом функции clock являетя величина -1.
Пример
Определение среднего времени операции, состоящей из открытия и немедленного закрытия файла.
/* clock */
•Include <time.h>
^Include <stdio.h>
•define Count ID
n)ain()
{
FILE *Doc; •
int i;
for(i = 1; i< Count; i++){
Doc 匸 fopen(”W0RK”,"w%;
fclose(Doc);
}
printf("T1me = %f ms".
100.0 * cluck。/ CLK—TCK / Count;
return 0;
TURBOTURBO}
TURBO
TURBO
Имя
core left - определение размера свободного места в “куче".
Заголовок
unsigned coreleft(void)
Прототип Функция
alloc.h
Оценка размера той часги "куим", которая может быть выделена с помощью функции для динамичес кого управления оперативной памятью.
Результат
Переменная типа (unsigned) со значением, равным числу свободных байтов в "куне".
coreieft
Пример
Определение размера свободного места в "куч©".
/* coreleft */ finclude <stdto.h> finclude <alloc.h>
main()
{
printf(MXu", coreleft()); return 0;
}
cos
ANSI
Имя
cos - вычисление косинуса.
Заголовок
double
cos(double х)
Прототип
math.h
Функция
Формирование переменной со значением cos х.
Результат
Переменная типа (double) со значением, равным косинусу аргумента. Это значение, принадлежит интервалу -L.1.
Замечания
Пример
Вывод числа 0.50.
/* cos */ finclude <stdio.h> finclude <math.h> maWn()
{
Аргумент функции выражается в радианах.
double const Pi =
3.141593;
printf(w%.2f, cos(Pi/3)); return 0;
}
cosh
ANSI
Имя
cosh - вычисление гиперболического косинуса.
Заголовок
double
cosh(double х)
Прототип.
math.h
Функция
Формирование переменной со значением cosh х.
Результат
Переменная типа (double) со значением, равным гиперболическому косинусу аргумента.
Замечания
В случае возникновения переполнения результат имеет значение HUGE_YAL (с соответствующим знаком).
Пример
Вывод разности между непосредственно определенным и вычисленным
520
Часть VI. Библиотеки
значениями гиперболического косинуса.
Z*cosh */
•include <stdio.h>
finclude <math.h>
matn()
{
printf(MXfM. cosh(2) - (exp(2) + exp(-2))/2); retyrn 0;
}
cprintf
TERBO
Имя
cprintf - редактирование и вывод иа консоль последовательности символов.
Заголовок
int
cprintf(const char "format. …)
Прототип Функция
conio.h
Вывод на консоль в соответствии с перечнем шаблонов, указанным аргументом format, значений apiyментов, представленных иг месте многоточия.
Результат *
Переменная типа (int) равна числу выводимых символов, или переменная со значением EOF в случае возникновения ошибки.
Пример
Вывод надписи Hello world.
/* cprintf */
•include <conio.h>
main()
{
cprintf(**Hello world');
return 0;
}
cputs
TURBO
Имя
Заголовок
cputs - вывод на консоль последовательности символов, int
cputs(const char *string)
Прототип Функция
conio.h
Вывод на консоль последовательности символов, указанной в аргументе string.
Результат
Переменная типа (int) со значением, равным коду последнего выводимого символа.
Замечания
Выводимая последовательность символов не дополняется символом конца строки.
Пример
Вывод на консоль надписи Kajusia.
/* cputs */ finclude <conio.h> n)ain()
{
cputs (*'Ka jus la*');
return 0;
}
cscanf
TURBO
Имя
cscanf - ввс.1 с клавиатуры и интерпретация последоват< ;1ьности символов*
Заголовок
int
csanf(const char *formatf...)
Прототип
conio.h
Функция
Ввод с клавиатуры в соответствии с перечнем шаблонов, указанным в аргументе format, набора литералов, находящихся в полях файла, и присвоение значений этих литералов переменным, указанным в аргументах, находящихся на месте многоточия.
Результат
Величина типа (int), равна числу переменных, которым присвоены значения.
Пример
Обращение с вопросом об имени и вывод приветствия.
/* cscanf */ finclude <conio.h> main()
{
char Name[20];
cprintf(wYour name:");
cscarjfCW, Name);
cprihtf("\n Hello %s”, Name);
return 0;
ctime
ANSI
Имя
ctime - преобразование даты и времени в
последовательность символов.
Заголовок
char *
ctime(const timet *clock)
Прототип Функция
time.h
Преобразование величины, задаваемой в аргументе *clock, созданной с помощью функции time и указывающей время (в секундах), прошедшее с 1 января 1970 г. (время по Гринвичу), в последовательность 26 символов, имеющую примерно следующий вид:
Sun Dec 13 06: 00: 00 1981\п \ 0
Результат
Переменная типа (char *), определяющая описанную последовательность символов.
Пример
Вывод последовательности символов, указывающей наименование месяца, номер дня месяца, время дня и год, например:
Wed Мау 24 08: 24: 44 1989.
/* cttme */
•include <stdio.h>
finclude <time5h>
main()
{
long Time;
(vo1d)time(&T1ine);
prlntfC'Xs**, ctime(&Ttme));
return 0;
}
delaydelayИмяЗаголовокПрототип ФункцияРезультатПримерИмяЗаголовокПрототип ФункцияРезультатПримерTURBO
delay
delay
Имя
Заголовок
Прототип Функция
Результат
Пример
Имя
Заголовок
Прототип Функция
Результат
Пример
delay - временная приостановка выполнения программы.
void
delay(unsigned time)
dos.h
Приостановка выполнения программы на time миллисекунд.
void
Генерация двух звуковых сигналов с интервалом в 2 с
/* delay */ finclude <dos.h> finclude <conio.h> main() {
putch('\a‘); delay(2000); putch(*\a'); return 0;
}
(fifftime
ANSI
Имя
Заголовок
difftime - определение разницы во времени, double
difftinie(tiiDe t ttme2. time t tlmel)
Прототип Функция
time.h
Вычисление разности между закодированным временем, задаваемым функцией time 2, и временем, отсчитываемым от 1 января 1970 г. и задаваемым функцией time 1.
Результат
Переменная типа (double) со значением, равным вычисленной разности времени в секундах.
Пример
Вывод числа -2.
/* difftime */
•include <time.h>
•include <stdio,h>
main()
{
long Time, Time2;
(voW)time(&Timel);
s1eep(2);
(void)time(&T1me2);
printf(w%.or, difftinie(Tiinelv T1me2));
return 0;
}
div
ANSI
Имя
dtv - вычисление частного и остатка от деления двух целых чисел.
Заголовок
dtv_t div(int num, Int den)
Прототип Функция
stdlib.h
Вычисление частного и остатка от деления num на den и присвоение их значений полям структуры типа d1v t (частного - полю quot, а остатка - полю rem)»
Результат
Структура типа div_t, состоящая из указанных выше полей.
Замечания
Тип d1v_t объявлен следующим образом: typedef struct{
int quot. rem;
} dW_t;
Пример
Вывод числа 17.
"div */
flnclude <stdMb.h>
♦include <stdio.h>
main()
{
dW_t Resultwe div(17,5);
pr1ntf(*W, Result, quot * 5 + Result, rem) return 0;
}
-EMIT-
TURBO
Имя
Заголовок
TMIT— — генерация открытой подпрограммы. /* void */
一end t _(par, par,..., pa》
Прототип Функция
dos.h
Генератщя машинных команд с кодами, определяемыми аргументами, соответствующими параметрам par.
Результат Замечания
Нет
Аргумент, представляющий п-байтовое число, генерирует п байтов. Исключения: а) литерал типа (integer) со значением в интервале 0...255 (например, 0x20) генерирует один байт; б) выражение, задающее автоматическую переменную, перемещаемую относительно регистра ВР на число из интервала -128.. 127, генерирует один байт. Для генерации другого числа байтов следует применять явные преобразования (например, соответственно Consigned) или (void) near *)).
Пример
Вывод числа 13.
/* _emit__ */
finclude <dos.h>
#inc】ude <stdio.h>
int
Fatal (void)
{
_emit_ (0xB8t (unsigned)13);
main()
pr1ntf("%d°f FatalO); return 0;
}
exit
ANSI
Имя
Заголовок
exit - окончание выполнения программы, void
exit(1nt status)
Прототип Функция
stdHb.h. process.h
Окончание выполнения программы с предшествующим закрытием всех еще не закрытых файлов.
Результат Замечания
void
Значение, которое принимает аргумент status, передается операционной системе. Обычно считается, что значение 0 обозначает нормальное завершение выполнения программы.
Пример
Проверка существования файла с именем SOURCE. DOC.
/* exit */
finclude <stdlib.h>
finclude <stdio.h> main() {
If(fopen(wSOURCE.DOCMr "r"))} printfCTile exitsts**); return 0;
pr*ntf("File does not exist"); exit(13);
}
ехр
ANSI
Имя
Заголовок
ехр - вычисление степени по основанию е. double
exp(double х)
Прототип Функция Результат Замечания
math.h
Формирование переменной со значением 6х.
Число типа (double), равное степени аргумента.
В случае возникновения переполнения результат имеет значение HUGE.VAL, a errno=ERANGE.
Пример
Вывод числа 2.72.
/* exp */
•include <stdio.h>
•include <math.h>
main()
{
prlntft^X.Zf", exp(l)); return 0;
}
fabs
TURBO
Имя Заголовок
з
fabs - вычисление абсолютного значения, double
fabs(double х)
Прототип Функция Результат
math.h
Формирование переменной со значением 1x1 Переменная типа (double), равная абсолютному значению аргумента.
Пример
Вывод числа 5J)0.
/* fabs */
finclude <stdio.h>
flnclude <math.h> main()
{
prlntfCX-Zf. fabs(-5));
return 0;
}
farcalloc
TUKBO
Имя Заголовок Прототип
farcalloc - выделение памяти void far *
farealloc(unsigned long nunits, unsinged long unitsz)
Функция
Выделение обнуленной области памяти, в которой можно разместить nun its объектов размером unitsz каждый.
Результат
Переменная типа (void far *), указывающая на выделенную область памяти, или пустое значение, если выделение области невозможно.
Пример
Выделение и освобождение области памяти для 10000 чисел с плавающей точкой.
/* farce Пос */ finclude <stdio.h> flnclude <alloc.h> ma1n() {
float huge * Ptr,
Ptr = farcaHoc(10000, sizeof(float)); if(Ptr g NULL){
printf(^^Failuгe^^); exit(13);
}
farfree(Ptr);
printf("Memory freed'*);
return 0;
}
farcoreleft
TURBO
Имя
farcoreleft - оценка свободного места в дальней “куие“.
Заголовок
unsigned long
farcoreleft(void)
Прототип
alloc.h
Функция
Оценка размера той части дальней “кучн", которую можно выделить с помощью функции для динамичес - кого управления оперативной - памятью.
Результат
Переменная типа (long) со значением, равным числу свободных байтов дальней “кунм".
Пример
Определение размера
свободного места в дальней "куне".
/* farcoreleft */ flnclude <stdio.h> flnclude <alloc.h> main()
{
printf("%1 d”,farcoreleftO); return 0;
farfree
TURBO
Имя
Заголовок
Прототип
farfree - освобождение места с дальней “куче"・ void
farfree (void far * block)
alloc.h
Функция
Освобождение ранее выделенной области в дальней "куне", указанной в аргументе block.
Результатvoid
Пример
Вывод трех чисел, характеризующих текущие размеры дальней “кучи".
/* farfree */
♦include <stdio.h> finclude <alloc.h> ma1n()
{
void far * Ref;
void Heap(votd);
Heap();/
Ref м far'tne Hoc(10000);
Heap; 神 farfree(Ref);
Heap();
return 0;
} void Heap(void) {
printf("\n Heap now = % 1dM. farcoreleft());
}
TURBOTURBOfarmalloc
TURBO
TURBO
Имя ЗаголовокПрототип ФункцияРезультатИмя ЗаголовокПрототип ФункцияРезультатfarmalloc - выделение памяти в дальней "ку«е". void far *
Имя Заголовок
Прототип Функция
Результат
Имя Заголовок
Прототип Функция
Результат
farmal1ос(unsigned long size)
alloc.h
Выделение в дальней "ку«е“ области памяти размером size байтов.
Переменная типа (void far *), указывающая на выделенную область памяти, или пустое значение, если выделение памяти невозможно.
Пример
Вывод надписи Allocation 1 inpossible.
/* farmalloc */ finclude <stdio.h> include <alloc.h> main();
{
prtntf("Al location");
If(farma1loc(1000000) = « NULL) printf("impossible");
else
prlntf("possible"); return 0;
}
farrealloc
TURBO
Имя
farrealloc - выделение или освобождение места в дальней “куие".
Заголовок
void far * farrealloc(void far * block, unsigned long newsize)
Прототип Функция
alloc.h
Такое увеличение или сокращение указанной в аргументе block области памяти дальней "куче", осуществляется, чтобы размер этой области после изменения оставил newsize.
Результат
Переменная типа (void far *), указывающая на область памяти с именившимся размером»
Замечания
Изменение размера области памяти может повлечь ее перенесение в другое место.
^Пример
Вывод надписи jb.
/* farrealloc */
#include <stdio.h> include <alloc.h> main();
{
char far * Ref;
Ref 工 farr'ealloc(Z);
Ref[0]=守;
Ref[*] =,b]
Ref = farr'ealloc(Ref, 3);
Ref[2] = '\0'; pгintf('•%Fs,,. Ref); return 0;
}
fclose
ANSI
Имя
Заголовок
fclose - закрытие файла, int
fclose(FILE *streani)
Прототип Функция
stdto.h
Закрытие файла, идентифицируемого аргументом stream.
Результат
Переменная типа (Int) со значением 0 или
переменная со значением EOF в случае удачного или неудачного выполнения функции соответственно.
ЗамечанияЗакрытию выходного файла предшествует неявное
выполнение функции fflush.
Пример
В случае успешного выполнения программы вывод надписи Done.
/* felose */ finclude <stdio.h> main();
{
FILE *0ut;
Out ^ fope—“TARGET".、”);
putc('j,・ Out);
putc('b'. Out);
printf(fclose(Out) ? "Fail": "Done");
return 0;
feoffeofИмяЗаголовокПрототип Определение ФункцияРезультатЗамечанияИмяЗаголовокПрототип Определение ФункцияРезультатЗамечанияANSI
feof
feof
Имя
Заголовок
Прототип Определение Функция
Результат
Замечания
Имя
Заголовок
Прототип Определение Функция
Результат
Замечания
feof - распознавание конца файла, int
feof(FILE *stream)
stdlo.h
stdio.h
Выявить, установлен ли в 1 указатель конца файла, идентифитдируемого аргументом stream.
Переменная типа (int) со значением, отличным от 0 или равным 0, если указатель конца файла установлен в 1 или не установлен, соответственно. При открытии файла этот указатель обнуляется. Установка указателя в 1 происходит при попытке ввода из файла, находящегося в конечной позиции. Обнуление указателя происходит при выполнении функций rewind, felose и clear'err.
Пример
Вывод надписи 0,1.
/* feof */
finclude <stdio.h> main();
{
FILE *Out;
FILE *Inp;
Out н fopen("TARGET"f,V,);
putc(*j*e Out);
fclQse(Out);
inp н fopen(M™GETer "rf,);
(void)getc(Inp);
prfnfcf(M%d*\ feof(Inp));
(vcid)getc(Inp);
printf(e,.%ds,, !! feof(Inp));
return 0;
ferror
ANSI
Имя
Заголовок
Прототип Определение Функция
Результат
Замечания
ferror - определение состояния указателя ошибки, int
ferror(FILE *st『eaw)
stdic.h
stdio.h
Выявить, установлен ли указатель ошибки файла, идентифицируемого аргументом stream.
Переменная типа (int) со значением 1 или 0 в случае возникновения или отсутствия ошибки при выполнений операиции ввода-вывода соответственно. Обнуление указателя происходит при открытии файла и при выполнении функций rewind, fclose и clearerr.
В случае возникновения ошибки ввода-вывода вывод надписи Fail в файл, идентифицируемый аргументом stderr。
/* ferror */
^include <stdio.h> main();
printf{e,To be or not to bes,); if (ferror(stdout))
fprintf(stderr. вТа1Г');
return 0;
}
fflush
ANSI
Имя
Заголовок
Прототип Функция с
fflush - очистка буфера
int
ff】ush(FILE ^stream)
stdio.h
Вывод прежнего содержимого выходного буфера в файл, идентифицируемый аргументом stream.
РезультатПеременная типа (int), равная 0 в случае неудачного
выполнения фунгщии.
Пример
Несмотря на аварийное завершение выполнения программы, вывод б файл TEXT надписи Kaja.
/* fflush */
^include <stdio.h>
main();
{
FILE *0ut;
Out = fopen (МТЕХТИ, ^*);
fpr1ntf(0u^, "Kaja");
fflush(Out);
abort();
return 0; /* Fomally required */
}
fgetc
ANSI
Имя
fgetc - ввод одного символа.•
Заголовок
int
fgetc(FILE *stream)
Прототип
stdio.h
Функция
Ввод одного символа из файла, идентифицируемого
аргументом stream。
Результат
Переменная тапа (int) со значением, равным коду
вводимого символа, или со значением EOF, если
установлен в 1 указатель конца файла.
Пример
Копирование символов из стандартного входного файла е стандартный
выходной файл.
Л fgetc */
#include <stdiD.h>
main();
{
int Chr;
wh11e((Chr = fgetc(stdin)) 1 = EOF)
putc(Chrp stdout);
return 0:
}
fgetpos
ANSI
Имя
fgetpos - выдача позиции файла.
ЗаголовокПрототип ФункцияРезультатПримерЗаголовокПрототип ФункцияРезультатПримерint fgetpos(FILE *stream, fpos_t *pos) stdio.h
Заголовок
Прототип Функция
Результат
Пример
Заголовок
Прототип Функция
Результат
Пример
Присвоение переменной, указанной аргументом pos, значения, определяющего текущую позицию файла, идентифицируемого аргументом stream.
Переменная типа (int) со значением, равным 0 в случае успешного определения позиции файла, или со значением, отличным от 0 и равным EBADF или EINVAL в противном случае.
Вывод числа 5.
/* fgetpos */
•include <stdio.h>
main();
{
FILE *0ut = FopenfWK", V1); fpos_t Pos;
printffOut, "Hello");
(void)fgetpos(Out, &Pos);
fprintf(Outr Mworld"J;
printf(*%ldw. (long)Pos); return 0;
Имя Заголовок.
fgets - ввод последовательности символов, char*
fgets(char "string.
int n, FILE *stream)
Прототип Функция
stdio.h
Ввод из файла, идентифицируемого аргументом stream, в указанный аргументом string буфер емкостью п символов последовательности символов и дополнение ее символом с кодом 0.
Результат
Переменная типа (char *), указывающая на первый символ буфера.
Заметан 〃兄
Ввод заканчивается в момент, когда возникает угроза переполнения буфера, или в момент ввода символа новой строки. Во втором случае перед символом с кодом 0 в буфере помещается символ '\п'.
fgets
ANSI
Пример
В случае, когда первая строка стандартного входного файла содержит последовательность символов Jan, вывод в стандартный выходной файл символов ’J', 'а', 'п' и '\п'・
/* fgetc */
finclude <stdio.h>
main();
{
char Buf[20];
printfC'Xs", fgets(Bufr 20, stdin));
return 0;
findfirst
TURBO
Имя
Заголовок 厘
findfirst - нахождение файла, int
findfirst(const char * name, struct ffblk *ffblk, Int attr)
Прототип. Функция
dtr.h
Размещение в структуре ffblk информации о первом из файлов с именем name и атрибутами attr.
Результат*
Переменная типа (int) со значением 0, если файл найден, и со значением -1 в противном случае; при этом еггпо приобретает одно из значений
ENOENT - дефектная дорожка, ENMFILE - файл не найден.
Замечания
Структура типа (strukt ffblk) объявлена следующим образом:
struct ffblk {
char ff_reserved[21]; /*резервированные*/
char ff_attr t b;/ *атрибуты* /
int ff^time;/*время и дата*/
int ff_date;/*создания файла*/
long ff_ffsize;/*размер файла*/
char ff_name[13];/*имя файла*/
}
Атрибуты файла могут быть заданы в виде логической суммы следующих характеристик:
FA_RDONLY- файл только для чтения,
FA—HIDDEN-скрытый файл,
FA_SYSTEM-системный файл,
FA_LABEL-метка тома,
FA_DIREC-каталог,
FA ARCH-архивированный файл.
〃 Принципы описания333
Пример
Вывод метки тома диска С.
/* findfirst */
♦include <dir.h>
finclude <stdio.h> finclude <dos.h> main();
{ struct ffblk Info; f1ndfirst("C:\\*.*e,. &Info( FA_LABEL); prtntf("\n%s”. Info. ff_name);
return 0;
}
findnext
TURBO
Имя
findnext - нахождение очередного файла с именем, заданным функцией findfirst.
Заголовок
Прототип Функция
int findnext(struct ffblk *ffblk) dir.h
Нахождение следующего файла co свойствами, заданными при вызове функции findfirst, и помещение информации о нем в структуру *ffblk.
Результат
Переменная тип (int) со значением 0, если файл найден, и со значением -1 в противном случае; в последнем случае еггпо приобретает одно из значений
ENOENT- дефектная дорожка
ENMFILE- файл не найден.
Замечания
Структура, задаваемая ffblk, должна быть той же структурой, к которой относился вызов функции findfirst.
Пример
Вывод имен подкаталогов основного каталога.
/* findnext */
finclude <dir.h>
finclude <stdio.h>
finclude <dos.h>
■include <conid7h>
main()
{
struct ffblk Info;
c】rcr();
536
Часть VI. Библиотеки
if(findf1rst("C:\\*M, Mnfo, FA_DIREC) “ 0) do
prin1:f("\ n%3”. Info. ff_name);
whi 7e(findnext(&Info) =* 0;
return 0;
floor
ANSI
Имя
Заголовок
floor - округление в сторону уменьшения, double
floor(double х)
Прототип
Функция №
math.h
Вычисление переменной типа (double) со значением, равным наибольшему целому числу, не превышающему х.
Результат
Переменная типа (double), найденная указанным способом.
Пример
Вывод чиаяа 4.00.
/* floor */
/include <stdio.h>
#include <math.h> main()
{
printf(wX.2f*. floor(4.99)); return 0;
}
fmod
ANSI
Имя
Заголовок
fmod - определение остатка от деления, double
fmod(double х, double у)
Прототип Функция Результат
math.h
Определение остатка от деления х на у.
Переменная типа (double) со значением, равным разности х-+*у для некоторого целого i.
Пример
Вывод числа 1.00.
"fmod*/
♦include <stdio.h>
•include <math.h>
main()
{
рг1п1Г(и%.2Г. fmod(B・3.5));
return 0;
}
fnmerge
TURBO
Имя
fnmerge ~ создание полного имени файла из его компонентов.
Заголовок
void
fnmerge(char "path.
const char *dir. const char *name, const char *ext)
Прототип Функция
dir.h
Создание имени файла, состоящего из имени каталога dir, основной части имени name и расширения ext, С последующим размещением его в области памяти, на первый элемент ко!орой указывает аргумент path.
Результат
void
Пример
Вывод надписи C:\TC20\Greet.EXE»
/* fnmerge */
finclude <dir.h>
finclude <stdio.h>
main()
{
char Fu】lName[30];
fiimergefFullName/T:-, \\TC20”「GREET", ”.EXE");
pr,ntf(''Xs''・ FullName);
return 0;
}
fnsplit
TURBO
Имя Заголовок
fnsplit - разбиение имени файла на его компоненты, int
fnsplit (const char *paihf char *drive.
char *dirr char *name, char *ext)
Прототип Функция
dir.h
Разбиение имени файла, заданного в аргументом path,
РезультатЗамечанияРезультатЗамечанияDRIVE DIRECTORY FILENAME EXTENSION WILDCARDSDRIVE DIRECTORY FILENAME EXTENSION WILDCARDS
Результат
Замечания
Результат
Замечания
DRIVE DIRECTORY FILENAME EXTENSION WILDCARDS
DRIVE DIRECTORY FILENAME EXTENSION WILDCARDS
на его компоненты: имя дисковода drive, имя каталога dir, основная часть имени папе и расширение ext» Переменная типа (int), состоящая из пяти однобитовых полей, указывающих, какие компоненты присутствуют в имени файла.
Названия полей могут быть следующими:
-имя дисковода,
-каталог,
-основная часть имени,
-расширение,
-символы * (звездочка) и ? (знак вопроса}.
Пример н Вывод надписи Greet.
/* fnsplit */
finclude <dir.h>
/include <stdio.h>
main()
{>
char FullName[30] = {MC:\\tc20\\Greet.EXE°};
char Name[20];/
fnsplit(FullName.NULLr NULL. Name. NULL);
printf("\n%s"・ Name);
return 0;
fopen
ANSI
Имя Заголовок
Прототип Функция
fopen - открытие файла.
FILE *
fopen(const char name, const char *mode)
stdio.h
Открытие канала, связывание его с файлом с именем, задаваемым filename, и открытие файла в режиме, определяемом аргументом mode. Последовательность символов, содержащаяся в mode, определяет режим открытия файла:
гчтение(read)
wзапись(write)
адобавление (append)
г+чтениеобновлением(read, write)
w+записьс обновлением
а+добавление с обновлением
РезультатЗамечанияРезультатЗамечанияПеременная типа (FILE*), идентифицирующая файл. Если последовательность символов, определяющую режим открытия, дополнить буквой t, то файл будет открыт в текстовом режиме; если же дополнить ее буквой Ь, то файл будет открыт в двоичном режиме. Открытие в текстовом режиме заключается в том, что вывод символа новой строки влечет за собой внесение в файл пары символов cr-】f, а ввод из файла пары символов сг-lf трактуется как ввод символа новой строки. По умолчанию принимается режим открытия, определяемый глобальной переменной fmode. Если ей присвоено значение вида О_ТЕХТ, то открытие произойдет в текстовом режиме, а если значение вида О—BINARY, то открытие произойдет в двоичном режиме. Переменная 一fmode описана в файле fcntl.h, а ее начальным значением является О ТЕХТ.
Результат
Замечания
Результат
Замечания
Пример
Вывод в файл TARGET символов 九 сгв К, Ь.
/* fopen */
finclude <stdio.h>
#fnclude <fcntl.h>
.main() {
FILE *0ut;
extern_fmode;
Out = fopenf'TARGET'*,,妙');
fprintf(Out, "jKn");
fclose(Out);
_fmode н o_BINARY;
Out - fopen(,BTARGETMf ,,а+и)
fprintf(Out, "b");
fclose(Out);
return 0;
TURBOTURBOFP-OFF
TURBO
TURBO
Имя ЗаголовокОпределение ФункцияРезультатИмя ЗаголовокОпределение ФункцияРезультатFP/FF - определение смещения.
Имя Заголовок
Определение Функция
Результат
Имя Заголовок
Определение Функция
Результат
/* unsigned */
FPOFF (/* void far **/ farptr)
dos.h
Выделение той части указателя, задаваемого farptr, которая определяет смещение относительно начала сегмента.
Переменная типа wns^ned) со значением, равным смещению в сегменте.
Пример
Вывод символа * (звездочка) •
/* FP_OFF */
finclude <dos.h>
finclude <stdio.h>
main()
{
char Chr 匸
char far *Ref = MK_FP(FP_SEG((void far *)&Chir)・ FP_OFF((void far *)&Chr));
putchar(* Ref);
return 0;
}
ANSIANSI^ fprintf
ANSI
ANSI
ИмяЗаголовокПрототип ФункцияРезультатЗамечанияИмяЗаголовокПрототип ФункцияРезультатЗамечанияfprintf - редактирование и вывод последовательности символов.
Имя
Заголовок
Прототип Функция
Результат
Замечания
Имя
Заголовок
Прототип Функция
Результат
Замечания
int
fprintf(FILE * stream, const char *format, …) stdio.h
Вывод в соответствии с перечнем шаблонов б последовательности, заданной аргументом format, в файл, идентифицируемый аргументом stream, значений аргументов, находящихся на месте многоточия.
Переменная типа (int) со значением, равным числу выведенных символов, или со значением EOF в случае возникновения ошибки.
Перечень шаблонов содержит обычные символы и шаблоны преобразования. Обычные символы (также называемые шаблонами) передаются в файл без изме нения. Шаблоны преобразования определяют способ редактирования данных, представленных аргументами. Если число аргументов превышает число шаблонов, то избыточные аргументы не редактируются. Не допуска ется, чтобы число аргументов было меньше числа шаблонов преобразования.
Шаблон преобразования
Шаблон преобразования состоит в общем случае из следующих элементов:
X f w р t
В этой записи символ % (процент) начинает шаблон; элемент f состоит из последовательности маркеров; элемент w - это число, определяющее минимальную ширину поля файла; элеменкр определяет число выводимых символов символьной переменной; элемент t указывает тип аргумента и способ редактирования поля файла.
Пример
Вывод надписи (+123.457). Элемент 9 определяет ширину внешнего поля, элемент .3 - число цифр после десятичной точки, элементы - (минус) и + (ил/ос) указывают соответственно, что число в выходном поле выравнивается влево и что числу предшествует знак плюс или минус.
/* fprlntf.l */
fInclude <stdio.h>
main()
{
fpr1ntf(stdout ₽ и(X-+9.3f)", 123.4567);
return 0;
}
Элемент t (тип аргумента)
Тип аргумента задается с помощью- однобуквенного кода преобразования, которому может предшествовать однобуквенныи квалификатор. Код преобразования (определяющий способ создания надписи, составляющей поле файла) имеет следующие значения:
Код
Tun
d
(int)
десятичное число
j
(int)
десятичное число
0
(int)
восьмеричное число без знака
u
(int)
десятичное число без знака
X
(int)
шестнадцатеричное чило без знака
X
(int)
шестнадцатеричное число без знака
f
(double)
число с фиксированной точкой
e
(double)
число с плавающей точкой
g
(double)
число с плавающей точкой
E
(double)
число с плавающей точкой
G
(double)
число с плавающей точкой
c
(char)
символ
s
(char ♦)
последовательность символов
n
(int ♦)
p
(type ♦)
адрес(S5SS: оооо или оооо)
%
%
Если код преобразования равен х, то цифры, большие 9, будут представлены малыми буквами, а если код преобразования равен X, то большими буквами.
Если код преобразования равен f, то поле будет иметь вид число с фиксированной точкой, в котором число цифр после точки задается элементом •Р (по умолчанию .6).
Если код преобразования равен е или Е, то поле будет иметь вид числа с плавающей точкой и показателем степени (содержащим соответственно букву е и Е), а число цифр после точки в мантиссе будет определяться элементом .р (по умолчанию .6). Целая часть числа будет содержать одну Цифру.
Если код преобразования равен g или G, то он будет интерпретироваться как f или (соответственно) как е иля Е. Запись с плавающей точкой выбирается в том случае, если показатель меньше -4 или если он превышает значение, определяемое элементом .р (по умолчанию .6).
Если код преобразования равен G, то он будет интерпретирован как g, при этом в возможном показателе степени будет фигурировать буква Е.
Квалификатор
В качестве квалификаторов могут фигурировать буквы F9 N, h, 1 и L, Квалификаторы F шш N не охвачены стандаркш ANSI и они могут относиться лишь к аргументам, являющимся указателями. F означает, что аргумент представляет собой близкий указатель, h означает, что аргумент представляет собой тип (short int) или (unsigned short int) 1 означает, что аргумент представляет собой тип (long double).
Примеры
Аргумент Шаблон Поле файла
12.4000
12.400 L240e+001
-4.6Е+002
Элемент / (маркер)
Маркером может быть знак мину О плюс (+), хеш (#) и пробел О. Очередность маркеров в элементе шаблона может быть произвольной. Маркеры имеют следующую интерпретацию:
- Надпись должна быть выровнена в выходном поле влезо и дополнена справа пробелами.
+ Числовой надписи должен предшествовать знак плюс или минус в соответствии со значением аргумента..
пробел Числовой надписи должен предшествовать знак минус или пробел в соответствии со значением аргумента.
# Аргумент должен выводиться специальным образом (см. описание ниже).
Если маркер минус (-) не использован, то надпись будет выровнена вправо и ей будут предшествоать нули или пробелы. Если маркеры плюс (+) и пробел () использованы одновременно, то пробел игнорируется.
Специальный вывод
В случае преобразований с, s, d, и маркер хеш (#) игнорируется.
В случае преобразования о надписи будет предшествовать цифра 0, а в случае преобразований х или X надписи будут предшествовать соответственно ашволы Ох или ОХ.
В случае преобразований е, Е, f надпись будет содержать точку, разделя-
ющую целую и дробную части числа (обычно эта точка опускается, если после нее не следуют цифры).
В случае преобразований g, G надпись будет содержать не только точку, но и нули в конце числа (обычно они опускаются).
Примеры (буква b означает пробел)
Аргумент Шаблон Поле файла
ооd ^ а^ ^ ^ f ^%%%%%%%d ^ а^ ^ ^ f ^%%%%%%%3 bb5 5bb b+5 bb5 5.000000 bSQQ
о
о
d ^ а^ ^ ^ f ^%%%%%%%
d ^ а^ ^ ^ f ^%%%%%%%
Элемент 即(ширина поля)
Этот элемент определяет минимальную ширину поля, в котором будет размещена иадпись. Ширина поля может быть указана числом или с помощью символа * Звездочка}. Во втором случае фактическая ширина поля будет определяться вторым аргументом» Этот ар!умент должен иметь тип (int)» Если ширина поля окажется слишком малой для размещения надписи, то она будет неявно увеличена настолько, чтобы это стало возможным. Например, это произойдет в том случае, когда в шаблоне отсутствует элемент w, ибо при этом по умолчанию будет принята ширина поля, равная нулю. Если ширина поля окажется больше, чем размер надписи, то она будет размещена в поле с выравниванием, которое задает маркер - {минус).
Исключением из этого правила является случай, когда ширина поля выражена числом, начинающимся с цифры 0. В этом случае надпись будет дополнена слева цифрами 0.
Примеры (буква b означает пробел)
АргументАргументШаблонПоле файлаШаблонПоле файла
Аргумент
Аргумент
ШаблонПоле файла
ШаблонПоле файла
13(long) 13 “Janek"13(long) 13 “Janek"^^^dw^^^%%%%%%%%^^^dw^^^%%%%%%%%
13
(long) 13 “Janek"
13
(long) 13 “Janek"
^^^dw^^^%%%%%%%%
^^^dw^^^%%%%%%%%
ььыз 13bbb 013
13
13 Janek Jan bJan
Элемент .p (точность)
Этот элемент определяет минимальное число цифр в числах с фиксированной точкой, число цифр после точки в числах с плавающей точкой и число символов в последозательнсстях, созданных с помощью шаблонов, заканчивающихся буквой s. Если ширина поля, предусматриваемая элементом •р, превышает ширину поля, предусматриваемую элементом w, то принима-
ется первая из этих величин. Как и для элемента w, часть р элемента .р может быть выражена с помощью символа * (звездочка). В этом случае точность определяется следующим аргументом функции. Этот аргумент должен иметь тип (int>.
Пример
Вывод надписи (13.00).
/* fprintf.2 */
•include <stdio.h>
main()
{
fprintf(stdout, •*(%-*. *f)”・ 6.2,13.);
return 0;
}補
FP-SEG
TURBO
Имя
Заголовок
FP-SEG - определение номера сегмента.
/* unsigned */
FP_SEG(/* void far **/ farprt)
OnpedeAethie Функция
dos.h
Выделение той части указателя, заданного farprt, которая определяет номер сегмента.
Результат
Переменная типа (unsigned) со значением, равным номеру сегмента.
Пример
Вывод знака ♦ (звездочка).
/* FP_SEG */ finclude <dos.h> •include <std1o.h> char Chr 匸'* '; mafn()
{
char far * Ref = MK_FP(FP_SEG((vo1d far *)&Chr).
FP_OFF((void far *)&Chr));
putchar (*Ref); return 0;
}
fputc
ANSI
Имя
Заголовок
fputc - вывод символа int
fputc(int ch, FILE *stream)
Прототип
stdio.h
17, Принципы описания545
функция
Вывод символа с кодом ch в файл, идентифицируемый
Результат
аргументом strean.
Переменная типа (int) со значением ch, а в случае неудачного вывода символа - со значением EOF.
Пример
Вывод буквы Е в стандартный выходной файл и возможный вывод знака вопроса в стандартный файл для сообщений об ошибках,
/* fputc */
•include <8td1o.h>
ma1n{)
{
1f(fputc(・E'. stdout) “ EOF){
fputc(*?*, stderr);
exit(l);
}
return 0;
}
fputs
ANSI
Имя Заголовок
fputs - вывод последовательности символов, int
fputs(const char *str1ngf
FILE *stream)
Прототип Функция
stdio.h
Вывод последовательности символов, определяемой аргументом string, в файл, идентифицируемый аргументом stream.
Результат
Переменная типа (int) со значением, равным коду последнего выводимого символа, а в случае неудачно го вывода какого-либо символа - со значением EOF.
Замечания
Единственное различие между функциями fputs и puts состоит в том, что после вывода заданной последова тельности символов при выполнении функции fputs не выводится автоматически символ новой строки.
Пример
Создание файла
ONELINE, содержащего надпись Kaja.
/* fputs */ finclude <stdio.h> main()
{
FILE *0ut « fopen(”ONELINE”. V) fputs("Kaja\nwv Out);
exit(l);
return 0;
}
Имя
Заголовок
fread - ввод группы блоков, size」
fread(void *ptr, size_t size. 8ize_t nitenis. FILE *stream)
Прототип Функция
stdio.h
Ввод из файла, идентифицируемого аргументом stream, в область памяти, указанную ptr, niterns блоков данных размером size каждый.
Результат
1»
Переменная типа (size_t) со значением, равным числу успешно введенных блоков, или со значением, меньшим niterns, если встретился конец файла или обнаружена ошибка.
fread
ANSI
Пример
Вывод надписи Count = 3.
/* fread */
#include <stdto.h>
char Arr[30];
mafn()
{
FILE *Upd = fopen("ARRAYSM, 3);
int Rep, Count;
for(Count = 1; Count I = 4; Count++){
Arr[0] = Count;
fwrite(Arr, sizeof Агг, 1, Upd);
}
rewind(Upd);
Count = 0;
do{
Rep = fread(Arr, sizeof Arr, 1. Upd): if(Rep<l)
break;
Count++;
} whtle(l);
pr1ntf(℃ount н %d". Count);
return 0;
freefreeИмяИмяANSI
free
free
Имя
Имя
free - освобождение места в "куче".
17. Принципы описания547
Заголовок
void
free(void *ptr)
Прототип Функция
stdlib.h, alloc.h
Освобождение ранее выделенной и заданной аргументом ptr области в ближней “куче".
Результат
void
Пример
Вывод пары чисел,
представляющих собой оценки свободного места в близ-
кой Мкучем' перед выполнением и после выполнения функции free.
/* free */ findude <alloc.h> main()
{
void *Ref;
Ref = ma Hoc (2000);
prlntffXu'*, coreleft(J);
free(Ref);
pr1ntf(”%u'、coreleftO);
return 0;
}
freopen
ANSI
Имя
Заголовок
freopen - замена одного файла другим. FILE *
freopen(const char *name, const char *type, FILE *stream)
Прототип Функция
stdlo.h
Закрытие файла, идентифицируемого аргументом stream, установка файла с именем паше и открытие его в режиме, указанном в аргументе type таким образом, чтобы его можно было идентифицировать аргументом stream.
Результат
Переменная типа (FILE *), идентифицирующая файл, или пустое значение, если открытие файла окажется невозможным.
Пример
Вывод буквы J в стандартный выходной файл и буквы Ь в файл WORK.
/* freopen */
fInclude <stdio.h>
matn()
{
putchar('J');
(voId)freopen(WWORKW,wwM, stdout); putchar('b');
return 0;
}
frexp
ANSI
Имя Заголовок
frexp - разбиение числа с плавающей точкой, double
frexp(double value, int *eptr)
Прототип Функция
math.h
Разбиение числа value на нормализованную мантиссу
修
и показатель степени по основанию 2« Присвоение значения показателя степени переменной, указанной в аргументе eptr, и вывод мантиссы.
Результат
Переменная типа (double), представляющая собой нормализованную мантиссу.
Пример
Вывод числа 0羽33333。
/* frexp */ ftnclude <std1o.h> ^Include <math.h> mafn() {
float const OneThird = 1/3.; double Man;
int Exp;
Man = frexp(OneThird, &Exp); printffXr. Man * pow(2, Exp); return 0;
}
fscanf
ANSI
Имя
fscanf - ввод и интерпретация последовательности символов.
Заголовок
1nt
fscanf(FILE *streamr const char *format.
Прототип Функция
•»•)
stdto.h
Ввод из файла, идентифицируемого аргументом stream, в соответствии с перечнем шаблонов, заданных аргументом format, последовательности находящихся в полях файла литералов и присвоение значений этих
РезультатЗамечанияРезультатЗамечаниялитералов переменным, находящимся на месте многоточия»
Результат
Замечания
Результат
Замечания
Переменная типа (int) со значением, равным числу значений, присвоенных указанным переменным. Каждому значению, полученному при интерпретации шаблона, должна соответствовать переменная, задаваемая аргументом. Если число аргументов превышает исло таких значений, то избыточные аргументы игнорируются. Перечень шаблонов содержит интервалы, шаблоны преобразования и обычные символы (также называемые шаблонами). Интервалами являются пробелы, табуляции и символы новой строки, а шаблонами преобразования - описываемые ниже последовательности символов, начинающиеся с символа % (процент). Результатом интерпретации интервала является игнорирование ближайшего интервала - если он присутствует в файле. Результатом интерпретации шаблона преобразования является анализ ближайшего поля файла и присвоение значения находящегося в этом поле литерала очередной переменной, задаваемой аргументом функции. Результатом интерпретации символа, не являющегося интерзалом и не принадлежащего к числу шаблонов преобразования, будет проверка того, идентичен ли следующий символ файла этому символу. При положительном исходе проверки данный символ игнорируется, в противном случае исполнение функции fscanf прекращается. Последнее имеет место также в том случае, если вид литерала в поле файла не соответствует требованиям шаблона преобразования. В обоих случаях последний рассмотренный входной символ возвращается в файл.
Пример
Ввод из стандартного входного файла последовательности символов в виде числа и вывод информации о его значении. Числу должна предшествовать надпись Val=. Перед словом Vai, а также с обеих сторон от знака равенства могут находиться интервалы. Если входная последовательность имеет другой вид, то результатом выполнения программы будет вывод числа -13.
/* fscanf.1 */
#1nc】ude <stdto.h>
main()
{
int Vai = -13;
fscanf(std1n, *'Val = %d", &Val);
pr1ntf(M\n\nVal = %d”. Vai);
return 0;
Шаблон преобразования
Шаблон преобразования состоит из следующих элементов:
% f w t
В этой записи символ % {процент) начинает шаблон, элемент f является маркером, элемент w - это число, определяющее максимальную ширину поля файла, а элемент t определяет тип аргумента и требуемый вид поля файла.
Пример
Ввод из поля с максимальной шириной 3 последовательности символов, определяющей некоторое число типа dnt), преобразование его в число типа (short) и дтрисвоение полученного значения переменийо Vai. В использованном шаблоне преобразования элемент 3 определяет ширину поля файла, код преобразования d определяет спобоб преобразования поля, а квалификатор h показывает, что значение должно присваиваться переменной типа short.
/* fscanf.2 */
flnclude <st中o.h>
main()
{
short Vai;
fscanf(stdin, "%3hd". &Val);
prlntf (w\n\nVal = %d\ Vai);
return 0;
Элемент t (тип аргумента)
Способ преобразования задается с помощью кода преобразования, которому может предшествовать однобуквенный квалификатор, или с помощью последовательности символов, заключенной в квадратные скобки. В соответствии с выбранным кодом преобразования должны соблюдаться следующие правила подготовки аргумента функции и поля файла:
Код преобразован ия
Тип аргументов
Поле файла
d
(Int *)
десятичное число
D
(long *)
десятичное число
о
(int *)
восьмеричное число
0
(long *)
восьмеричное число
«
(int *)
десятичное, восьмеричное, шестнадцатеричное число
I
(long *)
десятичное, восьмеричное, шестнадцатеричное число
и
(unsigned *)
десятичное число без знака
и
(uns.long *)
десятичное число без знака
X
(int *)
шестнадцатеричное число
X
(long *)
шестнадцатеричное число
17. Принципы
описания
е
(float *)
число с плавающей точкой
Е
(float *)
число с плавающей точкой
f
(float •)
число с плавающей точкой
F
(float *)
число с плавающей точкой
д
(float *)
число с плавающей точкой
G
(float *)
число с плавающей точкой
S
(char)
последовательность символов
с
(char *)
символ
п
(Int *)
р
(void *)
адрес
Если код преобразования равен s, то очередные символы поля, замыкаемые символом с кодом 0, будут размещены в массиве, первый символ которой задается аргументом функции. Если код преобразования равен с, то переменной, задаваемой аргументом, будет присвоено значение, состоящее из первого символа поля.
Если код преобразования равен п, то очередному аргументу будет присвоено значение, равное числу символов, введенных из файла при выполнении данной функции fscanf. Если код преобразования равен р, то адрес должен представлять собой пару шестнадцатиричных чисел, разделенных символом: (двоеточие), или шестнадцатиричное число в зависимости от того, является вводимый указатель дальним или ближним.
Квалификатор
Значениями квалификатора могут быть только буквы F, N, h, 1. Квалификаторы F и N не охвачены стандартом ANSI и могут относиться только к коду преобразования р. Квалификатор h может относиться только к кодам преобразования d, i, о, и, х, а квалификатор 1 может относиться только к кодам преобразования d, i, о, u, х, е, f.
Квалификатор h означает, что аргумент принадлежит типу (short •). Квалификатор 1, стоящий перед кодом преобразования е или f, означает, что аргумент принадлежит типу (double ♦), а квалификатор 1, стоящий перед кодом преобразования d, i, о, и, х, означает, что аргумент принадлежит типу (long *).
Пример (буква b означает пробел)
ШаблонШаблонПоле файлаЧислоПоле файлаЧислоd с f с к /го /го /го /го ^/ ч/ ч/ ч/ ч/d с f с к /го /го /го /го ^/ ч/ ч/ ч/ ч/13b ь13b ь
Шаблон
Шаблон
Поле файлаЧисло
Поле файлаЧисло
d с f с к /го /го /го /го ^/ ч/ ч/ ч/ ч/
d с f с к /го /го /го /го ^/ ч/ ч/ ч/ ч/
13b ь
13b ь
Если способ преобразования задан последовательностью символов, заключенной в квадратные скобки, то ограничителем поля является не интервал, а конечный символ, уже не принадлежащий полю. Если непосредственно после открывающей квадратной скобки следует символ “ (каре), то конечным символом является любой из последующих символов. В противном случае конечным символом является любой символ, не присутствующий в квадратных скобках. Шаблону преобразования, состоящему из символа % (процент) и
последовательности символов, заключенной в квадратные скобки, соответствует аргумент типа (char []). Очередные символы поля размещаются в массиве, указываемой аргументом.
Пример
Ввод из стандартного входного файла последовательности символов, заканчи> вающейся символом Enter, а затем вывод этих символов в обратном порядке
/* fscanf.3 */
•include <8tdio.h>
main()
{
char Arr[80];
int Count;
fscanf(stdin, "XC^XnlXn'*, Arr, &Count);
do
prfntf(w\n%c**t Arr[~Count]);
whf le(Count);
return 0;
}
Элемент / (маркер)
Маркером может быть только символ ♦ (звездочка). Если такой символ присутствует в шаблоне преобразования, то интерпретация шаблона сводится к игнорированию входного поля. Содержащему такой маркер шаблону не соответствует ни один из аргументов функции.
Пример
Для данных, имеющих вид надписи 13.0, вывод символа • (точка).
/* fecanf.4 */
•Include <stdio.h>
ma1n()
{
char Chr;
f8canf(stdinr "X*d%cH, &Chr);
prfntf("\n%c", Chr);
return 0;
}
Элемент w (ширина поля)
Этот элемент определяет максимальную ширину поля. Если он присутствует в шаблоне прсюбразования, то ближайшее поле файла состоит из самой длинной последовательности, насчитывающей * не более w символов и не содержащей интервала. Первым символом поля является ближайший символ файла (для преобразований с и [...], а первый (после возможного интервала) символ относится к остальным преобразованиям.
Если элемент ■ отсутствует в шаблоне, то ограничителем поля является интервал, а для преобразования - символ, определяемый содержимым квадратных скобок.
/X Принципы описания
Пример
Для данных, имеющих вид надписи j Ь, вывод числа 1.
/* fecanf.5*/
•tnclu* <etdio.h>
main()
{
cher Arr[3];
char Chr;
fscanf(8td1n, "%2s%c“, Arr. &Chr);
printfC^.Xhr “ ''); return 0;
}
fseekfseekANSI
fseek
fseek
ИмяЗаголовокИмяЗаголовокfseek - установка файла в заданную позицию int
Имя
Заголовок
Имя
Заголовок
寸 ПрототипФункция寸 ПрототипФункцияfseek(FILE *streaM, long offset, Int fronwhere) stdlo.h
寸 ПрототипФункция
寸 ПрототипФункция
Установка файла, идентифицируемого аргументом stream, в позицию, отстоящую на offset байтов в сторону конца файла от места, определяемого параметром fronwhere.
ПараметрПоложение
SEEK—SETНачало файла
SEEK^CURТекущая позицияфайла
РезультатЗамечанияРезультатЗамечанияSEEk[endКонец файла
Результат
Замечания
Результат
Замечания
Переменная типа (int) со значением 0 при успешном выполнении функции и со значением, отличным от нуля, в противном случае.
Различие между fseek(stream, 0L. SEEK_SET) и
геи1гк!(Stream) заключается в том, что fseek обнуляет только указатель конца файла, в то время как rewind обнуляет также указатель ошибки.
Пример
Вывод надписи Iza.
• г
/*fseek*/
Р" finclude <stdio.h>
FILE *Upd
char Name[3];
皿 Upd ■ fopenC*WORKMf Xt“);
fprintf(Upd, *'Ewa-Iza-JanM); fseek(Upd.-7, SEEK_CUR);
fscanf(Upd, "%3s," Name);
printf (”3s“,Name);
return 0;
}
fsetpos
ANSI
Имя
Заголовок
fsetpos - установка файла в заданную позицию, int
fsetpos(FILE *stream.
const fpos_t *pos)
Прототип
Функция 第
stdlo.h
Установка файла, идентифицируемого аргументом stream, в позицию, указанную аргументом pos.
Результат
Переменная типа (int) со значением 0 при успешном выполнении функции и со значением, отличным от нуля, в противном случае.
Замечания
Файл может быть установлен только в позицию, определяемую предшествующим выполнением функции
fgetpos. После выполнения функции fgetpos с файлом можно выполнять операции как ввода, так и вывода данных.
Пример
Вывод надписи Hello world!
/*fsetpos*/
flnclude <stdio.h>
main()
{
fpos_t Pos;
1nt Chr;
FILE *0ut == fopenCWORK'*, V)f
*Inp:
pfrintf(Out, "Hei1ои);
(void)fgetpos(Out, &Pos);
fprintf(Out, ••*****!••); (void)fsetpos(Out( &Pos);
pfrintf(Out, "world")J
fclose(Out);
Inp - fopenCWK", nrv)t
while((Chr 工 getc(Inp】)!匸 EOF) putchar(Chr);
return 0;
}
77. Принципы описания555
ftell
TURBO
Имя Заголовок
ftell - определение позиции файла, long
ftell(FILE *strea«)
Прототип Функция
stdlo.h
Определение числа байтов, отделяющих текущую позицию файла, идентифицируемого аргументом stream, от его начальной позиции.
Результат
Переменная со значением, равным указанному числу байтов, или со значением -1L в случае возникновения ошибки.
Пример
Вывод числа символов, содержащихся в файле STDIO.H.
/*ftell*/
finclude <stdio.h>
main()
{
FILE *Inp;
Inp = fopen(^'D:\\tc\\1nclude\\stdio.h',, V);
fseek(Inpt 0, SEEK_END);
printfC^ld**, ftell(Inp)); return 0;
}
fwrite
ANSI
Имя
Заголовок
fwrite - вывод блоков данных. size_t
fwrite(const void *ptr,
s5ze_t size, size_t nlterns, FILE~*stream)
Прототип Функция
stdlo.h
Вывод в файл, идентифицируемый аргументом stream, niterns - блоков размером size каждый из области оперативной памяти, указанной аргументом ptr.
Результат
Переменная типа (size_t) со значением, равным числу успешно выведенных блоков, или со значением, меньшим ni terns в случае возникновения ошибки.
Пример
Вывод в файл WORK
трех структур DATE.
/*fwrite*/
finclude <stdio.h> struct{
int Day;
char Month[3];
int Year;
} DATE [3]匸{13, "Dec*', 1981}; main()
{
FILE *Out = fopen("WORKw# ”『); fwrite(&Date, slzeof Date, 3, Out); return 0;
getCgetCANSIANSIИмяЗаголовок Прототип Функцияgetc - ввод символа.getc((FILE *stream)stdio.hВвод одного символа из файла, идентифицируемого аргументом stream.РезультатПеременная типа (int) со значением, равным неотрицательному коду введенного символа, или со значением EOF, если перед выполнением функции файл находился в конечной позиции или если возникла ошибка.ИмяЗаголовок Прототип Функцияgetc - ввод символа.getc((FILE *stream)stdio.hВвод одного символа из файла, идентифицируемого аргументом stream.РезультатПеременная типа (int) со значением, равным неотрицательному коду введенного символа, или со значением EOF, если перед выполнением функции файл находился в конечной позиции или если возникла ошибка.ПримерПримерВвод одного символа ный выходной файл.Ввод одного символа ный выходной файл.из стадратного входного файла и его вывод в стандарт-из стадратного входного файла и его вывод в стандарт-/*getc*/fInclude <stdio.h> main(){int Chr;Chr »= getc(stdin); printf("%c'*r Chr); return 0;/*getc*/fInclude <stdio.h> main(){int Chr;Chr »= getc(stdin); printf("%c'*r Chr); return 0;getchgetchTURBOTURBOИмя ЗаголовокПрототип ФункцияИмя ЗаголовокПрототип Функцияgetch - ввод символа с консоли.intgetch(votd)conlo.hВвод одного символа с клавиатуры без копирования его на экране.getch - ввод символа с консоли.intgetch(votd)conlo.hВвод одного символа с клавиатуры без копирования его на экране.
getC
getC
ANSI
ANSI
Имя
Заголовок Прототип Функция
getc - ввод символа.
getc((FILE *stream)
stdio.h
Ввод одного символа из файла, идентифицируемого аргументом stream.
Результат
Переменная типа (int) со значением, равным неотрицательному коду введенного символа, или со значением EOF, если перед выполнением функции файл находился в конечной позиции или если возникла ошибка.
Имя
Заголовок Прототип Функция
getc - ввод символа.
getc((FILE *stream)
stdio.h
Ввод одного символа из файла, идентифицируемого аргументом stream.
Результат
Переменная типа (int) со значением, равным неотрицательному коду введенного символа, или со значением EOF, если перед выполнением функции файл находился в конечной позиции или если возникла ошибка.
Пример
Пример
Ввод одного символа ный выходной файл.
Ввод одного символа ный выходной файл.
из стадратного входного файла и его вывод в стандарт-
из стадратного входного файла и его вывод в стандарт-
/*getc*/
fInclude <stdio.h> main()
{
int Chr;
Chr »= getc(stdin); printf("%c'*r Chr); return 0;
/*getc*/
fInclude <stdio.h> main()
{
int Chr;
Chr »= getc(stdin); printf("%c'*r Chr); return 0;
getch
getch
TURBO
TURBO
Имя Заголовок
Прототип Функция
Имя Заголовок
Прототип Функция
getch - ввод символа с консоли.
int
getch(votd)
conlo.h
Ввод одного символа с клавиатуры без копирования его на экране.
getch - ввод символа с консоли.
int
getch(votd)
conlo.h
Ввод одного символа с клавиатуры без копирования его на экране.
РезультатПеременная типа (int) со значением, равным коду
введенного символа.
Пример
Ввод одного символа, а затем его вывод.
/*getch*/
finclude <stdio.h>
♦Include <conio.h>
main()
{
putch(getch());
return 0;
getcharANSI
Имя
Заголовок
getchar - ввод символа, int
getchar(void)
Определение Функция Результат
stdio.h
Ввод одного символа из стандартного входного файла. Переменная типа (int) со значением, равным коду введенного символа, или со значением EOF, если ввод оказался неудачным.
Пример
Копирование содержимого стандартного входного файла в файл TEXT.
/*getchar*/
finclude <stdio.h>
main()
{
FILE *0ut;
1nt Chr;
Out = fopen(MTEXr. V1);
while((Chr = getchar( ))! = EOF)
putc(Chr, Out);
return 0;
getdateTURBO
ИмяЗаголовокПрототипИмяЗаголовокПрототипgetdate - вывод даты, void
Имя
Заголовок
Прототип
Имя
Заголовок
Прототип
getdate(struct date *date)
dos.h
558
Часть VI. Библиотеки
Функция
Присвоение палям структуры, указанной аргументом date, значений компонент системной даты.
Результат Замечания
void
Структура типа (struct date) объявлена следующим образом:
struct date {
Int de_year;/*год*/
char da_day;/*день*/
char da_mon;/*месяц*/
}"
Пример
Вывод наименования
месяца.
/*getdate*/ fInclude <dos.h> finclude <stdio.h>
main() {
struct date Today;
char *Names[J = {”JaFiJ "Feb”.屮ar', "Apr".屮ay”. Pun”, W, "AugM, “Sep”,“Oct”,“Nov工 “Dec”};
getdate(&Today);
printf(n%s"; Names[Today. daemon - 1]);
return 0;
}
getenv
ANSI
Имя
Заголовок
getenv - определение параметров окружения, char*
getenv(const char *envvar)
Прототип Функция
stdllb. h
Поиск среди параметров окружения того параметра, наименование которого указывает envvar, и вывод указателя строки символов, описывающих значение этого параметра.
Результат
Переменная типа (char*>, определяющая последовательность символов, описывающих значение параметра.
Пример
Вывод надписи, определяющей значение параметра PATH, например, \UTIL; \D0S330; \ТС.
"getenv*/
finclude <stdio.h>
finclude <stdlib.h>
main()
{
prtntf("Xs"; getevn(MPATHM); return 0;5
}
gets
ANSI
Имя
Заголовок
gets - ввод последовательности символов, char*
gets(char *string)
Прототип Функция
stdio. h
Ввод из стандартного входного файла одной строки текста и после замены символа конца строки символом с кодом 0 размещение введенных символов в поле памяти, на первый символ которого указывает аргумент string.
Результат
Переменная типа (char*), определяющая первый символ поля памяти, или пустое значение, если встретился конец файла или возникла ошибка.
Пример
Ввод, а затем вывод одной строки текста.
/*gets*/ finclude <stdio.h> main()
char L1ne[8l];
pr1ntf(”s"; gets(L1ne));
return 0;
gettime .
TURBO
Имя
Заголовок
gettlne - определение компонент времени, void
gett1ne(Struct time *t1me)
Прототип Функция
dos.h
Присвоение полям структуры, указанной аргументом time, значений компонент системного времени.
Результат Замечания
void
Структура типа (struct time) объявлена следующим образом: struct time {
unsigned char ti_min, /*минуты*/ tChour. /*часы*/
360
Часть У1. Библиотеки
ti_hund. /*сотые секунды*/ tCsec; /*секунды*/
}-
Пример
Вывод текущего часа.
/*gettime*/ finclude <dos.h> •include <stdio.h> main() {
struct time Now; gettime(&Now);
pr1ntf(**%d*', Now. ti_hour); return 0;帝
getvect
TURBO
Имя Заголовок • Прототип Функция
getvect - получение вектора прерываний.
void interrupt (far *getvect(int num))() dos.h
Получение вектора прерываний с номером num и его интерпретация как дальнего указателя функции для обработки прерываний.
Результат
Переменная типа (void (far ♦) ( )), указывающая функцию обработки прерываний.
Пример
Измерение времени, прошедшего с момента прекращения звукового сигнала до следующего нажатия клавиши клавиатуры.
/*getvect*/ finclude <stdio.h> finclude <dos.h>
〃 tV\A/"®〃A 户加
unsigned Timer;
void interrupt far Count();
void interrupt (*Ref)();
■ain()
{
Ref ■ getvect(OxlC);
putchar(r\a*);
setvect(0xlCr Count);
if(kbhit( ))getch();
wh1le(!kbh1t());
(vo1d)getch();
setvect(0xlC, Ref】; printfC^Xd'*. Timer);
return 0;
} void interrupt far
Count() {
T1mer++;
}
gmtime
ANSI
Имя
gmtime - преобразование даты и времени в дату и время по Гринвичу.
Заголовок
struct tm*
girt 1me(long *clock)
Прототип Функция
tlme.h
Преобразование времени, заданного аргументом clock, в статическую структуру типа (struct tn), содержащую
следующие компоненты времени: количество секунд с начала минуты (sec), количество минут с начала часа (min), количество часов от полуночи (hour), номер дня месяца (mday), количество месяцев, начиная с января (mon), количество лет с начала века (year), количество дней после воскресенья (wday>, количество дней, прошедших с 1 января (yday) и маркер, указывающий, действует ли летнее время (isdst).
Результат
Переменная типа (struct tm *), указывающая описанную структуру.
Замечания
Тип (struct tm ♦), объявлен следующим образом: struct tm {
1nt tm_sec, tm_m1n, tm_hour, tRLMday. tm_mon, tm_year, tm_wday, tutyday, tRV.isdst;
}
Пример
Вывод номера дня года с соответстйующим суффиксом, например, Today 1s the 252nd day of the year.
/*gmt1me*/
♦include <time.h>
♦include <std1o.h>
iMln()
char Rest;
long Time;
struct tin *Today;
(vo1d)time(&T1me);
Today « gmtiniB(&T1me);
prlntf("Today is the %dM, Today~> tm_yday + 1);
sw1tch(Rest M Today->tm_yday X 10){
pr1ntf(°%.2sMr "stndrd-' + Rest - 1);
break:
default;
printf(°th")
}
pr1ntf(Mday of the year");
return 0;第
inportinportTURBOTURBO
inport
inport
TURBO
TURBO
ИмяЗаголовок •Прототип Определение Функция РезультатИмяЗаголовок •Прототип Определение Функция Результатinport - ввод данных с порта.
Имя
Заголовок •
Прототип Определение Функция Результат
Имя
Заголовок •
Прототип Определение Функция Результат
Int
inport(int num)
dos.h
dos.h
Ввод слова с порта под номером num.
Переменная типа int, введенная с порта.
Пример
Ввод номера параллельного порта, а затем вывод находящегося в этом порте слова.
"Import*/
•include <dos.h>
^Include <stdio.h>
ma1n()
{
Int Num;
scanfCW, &Num);
pr1ntf(M%x*\ Inport(Num));
return 0;
inportbinportbИмяЗаголовокИмяЗаголовокTURBO
inportb
inportb
Имя
Заголовок
Имя
Заголовок
inportb - ввод данных с порта.
unsigned char
inportb(1nt num)
Прототип Определение Функция Результат
dos.h
dos.h
Ввод байта с порта под номером num.
Переменная типа (unsigned char), введенная с порта.
Пример
Ввод номера параллельного порта, а затем вывод находящегося в этом порте байта.
/*1mportb*/
finclude <dos.h>
finclude <std1o.h>
ma1n()
1nt Num;
scanf("%dM. &Num);
pr1ntf("%x", 1nportb(Num));
return 0;
}
int86
TURBO
Имя
Заголовок
1nt 86 - генерация программного прерывания. 1nt
1nt 86(Int num.
union REGS *Inregs,
union REGS *outregs.
Прототип Функция
dos.h
Загрузка регистров процессора данными, содержащими- ся в группе регистров, указанной аргументом inregs, генерация прерывания с номером num, перезапись данных, содержащихся в регистрах процессора, в группу регистров, указанную аргументе»! outregs (в частности,
Результат
копирование бита переноса в поле x.cflag).
Переменная типа (1nt), остающаяся в регистре
Замечания
АХ-процессора.
Тип (union REGS) объявлен следующим образом: union REGS.{
struct {
unsigned axf bx, ex, dx, st, di. cflag, flags;
}x;
struct {
unsigned char al. ah, bl. bh, cl. ch, dl. dh;
} h:
};
Пример
Вывод на графическое печатающее устройство двух горизонтальных линий разной толщнны.
7*1nt 86*/
^Include <dos.h>
fdeflne N 300
main()
{
Int nl « N X 256.
n2 - N / 256;
tnt j - 0;
void prchr(char);
prchr(27);
prchr('L');
prchr(m);
prchr(n2);
whtlejj卄 < N)
prchr(19];
prchrfXn* J;
return 0;
}
void
prchr(ch);
char ch;
union REGS regs;
regs.x.dx. * 0; Z*Pr1ntar no. 0*/ regs.h.ax. = 0;
regs.h.al. * ch;
int86xint86x1nt86(0xl7,®sP ®s);
int86x
int86x
Имя
Заголовок
1nt 86х - генерация программного прерывания. Int
Int 86x(Int hUffi.
union REGS *inregs, union REGS *outregs, struct SREGS *segregs)
Прототип Функция
dos.h
Временное хранение содержимого регистра DS, 3alpузка регистров процессора данными из группы, указанной аргументом Ingregs, и структуры segregs, генерация прерывания с номером num, сохранение данных из регистров процессора в группе, указанной аргументом outregs.
Результат
Переменная типа (int), остающаяся в регистре АХ-процессора.
Замечания
Тип (union REGS) объявлен следующим образом: union REGS
struct {
unsigned ax. bx, ex, dx. si, di, cflag. flags;
TURBO
} X;struct {
unsigned char al, ah, bl. bh. cl. chr dl, dh;
} h;
};
Тип (struct SREGS) описывается следующим образом: struct SREGS{
unsigned esr cs, ss, ds;
};
Пример
Вывод числа 13.
/*1nt 86x*/
•include <dos.h>
『include <alloc.h>
♦include «string.h>
main()
{
union REGS InOut;
struct SREGS Seg;
char *Ref;
Ref = malloc(7);
(void)itoa(13. Ref, 10);
Ref[strlen(Ref)] = '$';
Seg.ds = FP_SEG((vo1d far *)Ref);
InOut.x.dx = FP_0FF((vo1d far *)Ref);
InOut.h.ah = 0x9;
1nt 86x(0x21, &InOut, &In0ut, &Seg);
TURBOTURBOreturn 0;
TURBO
TURBO
Имя
Заголовок
intdos - генерация системного прерывания, intdos(union REGS *Inregs,
union REGS *outregsf
Прототип Функция
dos.h
Загрузка регистров процессора данными из группы, указанной аргументом inregs, генерация прерывания с номером 0x21 и перезапись данных из регистров
Результат
процессора в группу, указанную аргументом outregs Переменная типа (int), остающаяся в регистре
АХ-процессора.
Замечания
Тип (union REGS) объявлен следующим образом: union REGS{
struct {
unsigned ax( bx. ex, dx, si, di, cflag. flags;
intdos
} х;
struct {
unsigned char al, aht bl, bhr cl. ch, dl, dh;
} h;
};
Пример
Вывод надписи Ewa.
/*1ntdos*/
『include <dos.h>
ma1n()
{
union REGS InOut;
char *Name *■ HEwa$";.
InOut.h.ah = 0x9;
InOut.x.dx = FPjDFF(Name);
1ntdos(&InOut, &InOut);
return 0;
intdosxintdosxИмяЗаголовокИмяЗаголовокПрототип ФункцияРезультатЗамечанияПрототип ФункцияРезультатЗамечанияTURBO
intdosx
intdosx
Имя
Заголовок
Имя
Заголовок
Прототип Функция
Результат
Замечания
Прототип Функция
Результат
Замечания
Intdosx - генерация системного прерывания.
Int
Intdos(union REGS *1nregs, union REGS *outregsr struct SREGS *sregs) dos.h
Временное запоминание содержимого регистра OS, загрузка регистров процессора данными из группы, указанной аргументом Inregs, и структуры segregs, генерация прерывания с номером 0x21, перезапись данных из регистров процессора в группу, указанную аргументом outregs.
Переменная типа (1nt), остающаяся в регистре АХ-процессора.
Тип (union REGS) объявлен следующим образом: union REGS{ struct {
unsigned ax, bx( cxt dx, st, di, cflag, flags;
} x;
struct {
unsigned char al, ah. bl. bh, cl. ch. dl. dh;
} h;
};
Тип (struct SREGS) описывается следующим образом: struct SREGS{
unsslgned es, cs, ss, ds;
Пример
Вывод надписи Ewa.
/*1ntdosx*/
/Include <dos.h>
•Include <str1ngs.h>
flnclude <alloc.h>
main()
{
union REGS InOut;
'struct SREGS Seg;
char *Ref = farmalloc(5);
(void)strcpy(Ref r s'Ewa $"); InOut.x.dx = FP_OFF(Ref);
Seg.ds = FP_SEG(Ref);
InOut.h.ah = 0x9;
1ntdosx(&In0utr &InOut( &Seg);
return 0;
intr
TURBO
Имя
Заголовок
Intr - генерация системного прерывания, void
1ntr(1nt Num,
struct REGPACK *preg)
Прототип Функция
dos.h
Перезапись данных в регистры процессора из структуры, указанной в аргументе pregt генерация прерывания с номером num и перезапись данных, содержащихся в регистрах, в данную структуру.
Результат Замечания
void
Тип (struct REGPACK) объявлен следующим образом: struct REGPACK{
insigned r ax. r_bx, r_cxr r_dx, r_bp, r_s1, r_di. r_ds, r_es, r_flags,
}
Пример
Вывод текущего часа.
/*1ntr*/
•Include <do??h> ^Include <s1^io.h> ma1n()
struct REGPACK Regs;
Regs.r_ax * 0; /*Serv1ce 0*/
1ntr(0xl4t, /eg*); pr1ntf(*Xuw, Regs. r_cx);
return 0; }
isalnum
ANSI
Имя
Isalnum - классификация символа.
Заголовок
—
1 sa 1 num/*1nt*/ch) <.
Определение
ctype.h .
Функция
Проверка, равно ли значение ch коду
證
буквенно-цифрового символа, т. е. символа.
представляющего собой букву или цифру ('A'.JZ'.
М..丄・ U'.. У )•
Результат
Переменная типа (int) со значением, отличным от 0 при положительном результате проверки, и со значением 0 в противном случае.
Примеры *
Аргумент
Результат
•в*
1
・з‘
1
3
0
0x32
1
isalpha
ANSI
Имя
tsalpha - : классификация символа.
Заголовок
/*1nt*/ 「 1заIpha/*1nt*/ch)
Определение
ctype.h
Функция
Проверка, равно ли значение ch коду буквы (・A,..Z,、、」「>•
Результат
Переменная типа (Int) со значением, отличным от 0 при положительном результате проверки, и со значением 0 в противном случае.
Примеры
.
Аргумент
Результат
•м*
1. ―■— •—-
*5*
0. ,;j工3七用.■ ■
82
1
-27
0
iscntrl
ANSI
Имя Заголовок
Определение Функция
Результат
Iscntrl - классификации символа.
/♦mf/
1scntrl/*1nt*/ch)
ctype.h
Проверка, равно ли значение ch коду управляющего символа (символа delete - 0x7F или символа с кодом из интервала 0x0.» Ox If).
Переменная типа (1nt) со значением, отличным от 0 при положительном результате проверки, и со значением 0 в противном случае.
Примеры
Аргумент
'А' 'В 255 0x10
Результат
о»•«.#; •,.;•* ‘
1
0
1
isdigit
ANSI
Имя
Заголовок
Определение
/: Функция
Результат
Isdigit - классификация символа.
/%朮•/
1sd1g1t/*1nt*/ch)
ctype.h
Проверка, равно ли значение ch к@ду цифры
('О'..”
Переменная типа (1nt), со значением, отличным при положительном результате проверки, и со значением 0 в противном случае.
от 0
Примеры
Аргумент i -
Результат
■5'
5 ОхА Лх30г
1 0
0
1
isgraph
ANSI
Имяtsgraph - классификация символа.
Заголовок/*1nt*/.
1sgraph(/*1nt*/ch)
Определение Функция
Результат
Примеры.
ctype.h
Проверка, равно ли значение ch коду видимого символа, отличного от пробела ('!'.•'').
Переменная типа (1nt) со значением, отличным при положительном результате проверки, и со значением 0 в противном случае.
от
0
Аргумент
Результат
5
,?'
0x20
僦
1 0
1 0
islower
ANSI
Имя Заголовок
Определений
Функция
Результат
[slower - классификация символа.
/*int*/
islower/*1nt*/ch)
ctype.h
Проверка, равно ли значение ch коду малой буквы (X. Jz)
Переменная типа (int) со значением, отличным от при положительном результате проверки, и со значением 0 в противном случае.
0
Примеры
Аргумент
Тг F 060 0101
Результат
1
0
0
0
isprint
ANSI
Имя
1 sprint - классификация символа.
Заголовок
"int*/
1spr1nt(/*1nt*/ch)
Определение
ctype.h
Функция
Проверка, равно ли значение ch коду видимого символа С!'.”).
Результат
Переменная типа (int) со значением, отличным от 0
при положительном результате проверки, и со . значением 0 в противном случае.
Примеры.
Аргумент
0
128
Результат
1
1
0
0
ispunct
ANSI
Имя
ispunct - классификация символа.
Заголовок
/*1nt*/
1spunct/*int*/ch)
Определение
ctype.h
Функция
Проверка, равно ли значение ch коду знака
препинания (пробела или управляющего символа).
Результат
Переменная типа dnt) со значением, отличным от 0 при положительном результате проверки, и со значением 0 в противном случае.
Замечания
В соответствии со стандартом ANSI знаком препинания
является любой символ, отличный от пробела и буквенно-цифрового символа.
Примеры
Аргумент
Результат
0
0
•ов
0
0x20
'W
1
isspace
ANSI
Имя
isspace - классификация символа.
Заголовок
/♦int*/
1sspace(/*1nt*/ch)
Определение
ctype.h
Функция
Проверка, равно ли значение ch коду интервала
(''「\t— М, 2. '\f')・
Переменная типа (int) со значением, отличным от 0 при положительном результате проверки, и со значением 0 в противном случае.
Результат
Примеры
Аргумент
Результат
0x20
1
572
Часть К/. Библиотеки
0401.
1
,А'
0
isupper
ANSI
Имя
Заголовок
isupper - классификация символа. /*int*/
i supper(/*1nt*/ch)
Определение Функция
ctype.h
Проверка, равно ли значение ch коду большой буквы (•A、・Z)・
Результат
狰
Переменная типа (int) со значением, отличным от 0 при положительном результате проверки, и со значением 0 в противном случае.
Замечания
Функция isupper является макроопределением.
Примеры
Аргумент
Результат
'G'•
:д:
1 0 0
'W
0
isxdigit
ANSI
Имя
Заголовок
isxdigit - классификация символа.
/*int*/
isxdigit(/*1nt*/ch)
Определение Функция
ctype.h
Проверка, равно ли значение ch коду шестнадцатеричной цифры (”..‘9','a'.「1,匕二.'t').
Результат
Переменная типа (int) со значением, отличным от 0 при положительном результате проверки, и со значением 0 в противном случае.
Примеры
Аргумент
Результат
,А'
5
0x41
1
0
1.
itoa
TURBO
Имя
itaa - преобразование целого числа в строковую переменную.
Заголовок.
char*
itoa(int value.
char *string, int radix)
Прототип Функция
stdlib.h
Преобразование числа, заданного аргументом value, в последовательность символов, представляющую собой число с основанием radix, и размещение этой последовательности в области памяти, указанной аргументом string.
Результат
Переменная типа (char*) указывающая на первый символ в области памяти.
Замечания
Последним символом, размещаемым в поле памяти, является символ с кодом 0, основанием может быть целое число в интервале 2. .36. Если основание десятичное, а число отрицательное, то первым символом последовательности является знак - (минус).
Пример
Вывод надписи 1101.
/*itoa*/
finclude <std1o.h>
#include <std1ib.h>
main()
{
char Arr[17];
prlntfC*%s. 1toa(13, Arr, 2)); return 0;
}
kbhit
TURBO
Имя Заголовок
kbhit — убедиться в доступности символа, int
kbhit(void)
〃рототип Функция
conto.h
Убедиться в том, что первое же выполнение функции getch приведет непосредственно к вводу символа с консоли.
Результат
Переменная типа (int) со значением, отличным от 0, если в буфере консоли находится еще не введенный символ, или со значением 0 в противном случае.
5746
Пример
Часть УЛ Библиотеки
Вывод надписи Ready to finish, а после ввода любого символа завершение выполнения программы.
"kbhit*/
finclude <stdio.h>
#1nclude <connio.h>
nain()
{
printf(**Ready to finish”);
Bhi1e(!kbhit());
return 0;
}
labs
ANSI
Имя
Заголовок
labs - определение абсолютного значения.
long
labs(long n)
Прототип
Функция *
Результат
stdlib.h. inath.h
Определение абсолютного значения аргумента.
Переменная типа (long) со значением |п|.
Пример
Вывод числа 13.
/*labs*/
finclude <stdio.h>
•include <stdlib.h>
main()
{
printfCXld0, labs(-13L));
return 0;
}
Idexp
ANSI
Имя
Заголовок
Idexp - вычисление степени, double
Idexp(double value, int exp)
Прототип Функция Результат
Пример
math.h
Формирование переменной co значением value * 2exp. Переменная типа (double) с указанным значением.
Вывод числа 40.00.
/*ldexp*/
•include <stdio.h>
finclude <math.h> main()
{
printf(w%.2F\ ldexp(5,3)); return 0;
}
Idiv
ANSI
Имя
Заголовок
Idiv - вычисление остатка и частного.
Idiv」
ldiv(long num,
long den)
Прототип Функция
stdlib.h
Формирование структурной переменной, компонентами которой являются две переменные типа (int): значение первой из них равно частному num/den, а значение второй - Остатку от деления num на den.
Результат
Структурная переменная типа (ldiv_t) с компонентами quot (частное) и гет (остаток).
Пример
Вывод числа 17.
/*ldiv*/
finclude <stdlib.h>
•include <stdio.h>
main()
{
idiv_t Result = Id1v(l7.5);
printf(M%ld", Result.Quot * 5 + Result.rem); return 0;
}
localtime
ANSI
Имя
localtime - преобразование даты и времени в их компоненты.
Заголовок
struct tm *
locaItime(const time t *clock)
Прототип Функция
time.h
Преобразование переменной, заданной параметром *clock и полученной с помощью функции time, в структуру типа (struct tm), содержащую следующие компоненты времени: количество секунд с начала минуты (sec) количество минут с начала часа (т1п),
РезультатРезультатЗамечанияЗамечанияколичество часов с полуночи (hour), номер дня месяца (nday>, количество месяцев, начиная с января (шоп), количество лет с начала века (year), число дней с воскресенья (wday>, число дней начиная с 1 января (yday) и маркер (isdst), учитывающий действие летнего времени. Преобразование производится С учетом временного пояса (time zone) и поправки на экоиомию энергии (daylight savings time).
Результат
Результат
Замечания
Замечания
Структура типа (struct tm), содержащая компоненты даты и времени.
Тип (struct tn) объявлен следующим образом: struct tn{
Int tw_sec;
tw_min;
tM_hour;
tn_nday;
tm_mon;
tm^year; tm_wday; tm_yday; tm_isdst; };
Пример
Вывод местного времени с точностью до 1 минуты.
/* local time*/
finclude <t1me.h> finclude <stdio.h>
main()
long tine;
struct tn *Ref;
(void)time(&Time);
Ref « localtime(&Tine);
printf(M%d: 乂02@"・ Ref -> tm_hour. Ref -> tM_Mln);
return 0;
ANSI
ИмяЗаголовокПрототип Функция РезультатИмяЗаголовокПрототип Функция Результатlog - вычисление натурального логарифма.
Имя
Заголовок
Прототип Функция Результат
Имя
Заголовок
Прототип Функция Результат
double
log(double х)
math.h
Формирование переменной со значением 1п х.
Переменная типа (double) со значением, равным натуральному логарифму аргумента.
Пример
Вывод числа 3.00.
/*7од*/
finclude <stdio.h> finclude <math.h> ma1n()
{
printf("X.2F\ log(exp(3))); return 0;
}
loglO
ANSI
Имя
loglO - вычисление десятичного логарифма.
Заголовок
double
loglO(double x)
Прототип
math.h
Функция
Формирование переменной co значением log^x.
Результат
Пример
Вывод числа 2.00.
/*1од10*/
finclude <stdio.h>
•include <math.h> main()
{
Переменная типа (double) co значением, равным десятичному логарифму аргумента.
printf(”%.2f". loglO(lOO)); return 0;
longjmp
ANSI
Имя
longjmp ~ возвращение в точку запоминания состояния выполнения программы.
Заголовок
void
longjinp( jmp_buf eiw, int val)
Прототип Функция
setjmp.h
Возврат б точку запоминания состояния выполнения программы и его восстановление таким образом, как будто запоминание (с помощью функции setjmp) закончилось выводом переменной типа (int) со значением val.
Результатvoid
ЗамечанияЕсли val представляет величину, равную 0, то прини
мается, что она представляет величину, равную 1.
Пример
Вывод надписи Finished here.
/*longjmp*/
finclude <setjmp.h> finclude <stdio.h>
main()
{
jmp_buf State;
void sub(w);
if(setjmp(State)){ prlntf("Finished here"); return 0;
}
sub(State);
printf(f,Not here”);
}•
void
sub(par) jmp_buf par;
{ ~
longjmp(par, 13);
}
Имя
Заголовок
Itoa - преобразование целого числа в строку символов char *
Itoa(long value,
char "string, int radix)
Прототип Функция
stdlib.h
Преобразование значения числа, заданного аргументом value, в последовательность символов в виде числа с основанием radix и размещение этой последовательности в массиве, первый символ которой указывается аргументом string.
Результат
Переменная типа (char*), задающая первый символ массива.
Itoa
TURBO
Пример
Вывод надписи f4240.
/*ltoa*/
finclude <stdio.h>
finclude <stdlib.h>
main()
{
char Arr[33];
printf(”s"・ ltoa(1000000r Arr. 16));
return 0;
}
malloc
ANSI
Имя
Заголовок
malloc - выделение памяти, void*
malloc(size_t size)
Прототип Функция Результат
stdlib.h, alloc.h
Выделение области памяти размером size байтов.
Переменная типа (void*), локализующая выделенную область памяти, или значение NULL в случае, если выделение области невозможно.
Пример
Вывод числа 4.50.
/*malloc*/
finclude <stdio.h> finclude <alloc.h> main()
{
float *Ref = malloc(sizeof(float));
*Ref - 4.50;
printffX.Zf". Ref[0]);
return 0;
}
memchr
ANSI
Имя
Заголовок
memchr - поиск символа, void *
memchr(const void *s, int *sf char ch.
Прототип Функция
size t n)
string.h. mem.h
Просмотр первых n байтов массива, указанного параметром s, для нахождения символа с кодом ch.
Результат
Переменная типа (void ♦), указывающая тот элемент массива, который содержит искомый символ, или пустое значение, если символ не найден.
Пример
Вывод надписи Bielecki.
/* memchr */ finclude <stdio.h> finclude <mem.h> char Arr[13] = "Jan Bielecki**: main() {
printf(”s”・ (char *)memchr(Arr + 2, *Br. 5)); return 0;
}
memcmp 帚
ANSI
с*
Имя
Заголовок
memcmp - сравнение последовательностей символов, int
memcmp (const void *sl.
const void *s2, size t n)
Прототип Функция
string.h( mem.h
Сравнение двух строк символов длиной п, указанных параметрами si и s2.
Результат
Переменная типа (int) принимающая отрицательное значение, если si < s2, значение 0, если si == s2・ положительное значение, если si > s2.
Замечания
Сравнение произодится в предположении, что символы принадлежат типу (unsigned char).
Пример
Вывод положительного числа.
/*memcnip*/
finclude <stdio.h>
finclude <mem.h>
main()
{
printf("%d*', memanprjan”, ”Ewa”, 2)); return 0;
}
memcpy
ANSI
Имя
Заголовок
memcpy - копирование последовательности символов, void *
memcpy(void *destin.
17- Принципы описания58/
const void *sourcef
size」n)
Прототип Функция
string.h, mem.h
Копирование последовательности n символов из области, указанной параметром source, в область, указанную параметром destin.
Результат
Переменная типа (void *), указывающая область, в которую скопирована последовательность символов.
Пример
Вывод надписи Kaja.
/*memcpy */
finclude <stdio.h>
finclude <mem.h>
main()
char *Name = "Kaja";
printf("%s'*f -1 + char *) memcpy(Name + 1. Name, 2));
return 0;
memmove
ANSI
Имя
Заголовок
memmove - копирование блока памяти, memmove(void *trg, void *src, size t count)
Прототип Функция
string.h, meni.h
Копирование count байтов из области оперативной памяти, указанной параметром src, в область памяти, указанную параметром trg.
Результат
Переменная типа (void *), указывающая начало области, в которую производится копирование.
Пример
Вывод надписи Isa.
/*memmove*/ finclude <string.h> finclude <stdio.h> main()
{ char Source[ ] = "Isabel";
Target[ ] = *******; memmove(Target, Source. 3); printf(,,%s,,f Target); return 0;
}
582
Часть У/. Библиотеки
memset
ANSI
Имя
meinset - заполнение области.
Заголовок
void *
i№niset(void *s.
Int ch.
size^t n)
Прототип
string.h, mem.h
Функция
Заполнение области оперативной памяти, указанной
параметром s, п символами с кодом ch.
Результат
Указание адреса области памяти, заданной
параметром s.
Пример
铺
е
Вывод надписи Jan—Ewa.
/*memset*/
/Include <stdio.h>
•include <mem.h>
char Arr[ ] = "Jan..
Ewa*;
main{)
{
printff'Xs**, (char *) memeet(Arr + 3, '-', 2) - 3);
return 0;
}
mkdir
TURBO
Ймя
mkdir - создание каталога.
Заголовок
int
泳dir(const char *path)
Прототип
dlr.h
Функция
Создание каталога с именем, указанным параметром
path.
Результат
Переменная типа (int) со значением 0 в случае
успешного создания каталога и со значением -1
в противном случае; при этом переменной еггпо
присваивается одно из следующих значений:
EACCESS - доступ запрещен,
ENOENT - нет такого каталога.
Пример
Создание каталога Isabel.
/*mkd1r*/
finclude vdir.2
•include <stdio.h>
u)ain()
{
讦(lmkdir(”C:\\IsabeT'))
pr1ntf('*Isabel created");
return 0;
MK-FP
TURBO
Имя
Заголовок
MK_FP - создание указателя. /*void far**/
MK_FP(/Unsigned */ seg, /♦unsigned */ off)
Прототип Функция
dos.h
Создание указателя, номер сегмента которого равен значению переменной, заданной параметром seg, а смещение равно значению переменной, заданной параметром off.•
Результат
Переменная типа (void far*), представляющая собой созданный указатель.
Пример
Вывод символа, находящегося в нулевом байте нулевого сегмента памяти.
"MK_FP */ finclude <dos.h> finclude <stdio.h> main() {
printf(”c”,*(char *) MK_FP(O,O)X return 0;
}
modf
ANSI
Имя
Заголовок
niodf - разделение числа на целую и дробную части, double
modf(double value.
double *iptr)
Прототип Функция
math.h
Разделение числа, указанного параметром value, на целую и дробную части. Возвращение целой части и присвоение значения дробной части переменной, указанной параметром iptr.
Результат
Переменная типа (double) со значением, равным целой части заданного числа.
Пример
Вывод числа 13.60.
/*njodf*/
finclude <stdio.h>
/include <math.h>
main()
{
double Intp Fra;
Int = snodf(13.6. &Fra);
pr1ntf("%.2f, Int + Fra): return 0;
}
movedata
TURBO
Имя
Заголовок
movedata - копирование областей памяти, void
nnvedata(unsigned seqsrc.
unsigned offsrc,
unsigned segdest, unsigned cffdest size t num)
Прототип Функция
string.h. menkh
Копирование num байтов из области памяти с адресом segsrc:offsrc в область памяти С адресом segdst: offdst
Результат
void
Пример
Вывод надписи Jan Bielecki.
"irovedata */
/include <stdio.h>
■include <dos.h>
finclude <mem=h>
fdeflne FAR(vaid far *)
char Nan«[ ] = "Jan";
char Surname[ ] = "...Bielecki";
main()
{
rovedata(FP_SEG(FAR Name). FP_OFF(FAR Name),
FP_SEG(FAR Surname), FP_OFF(FAR Surname), 3); printf(”s”. Surname);
return 0;
nosound
TURBO
Имя
nosound - выключение динамика.
Заголовок
void
nosound(void)
Прототип
dos.h
Функция
Выключение динамика ЭВМ.
Результат
void
Пример
Трансляция звукового сигнала с частотой 440 Гц, прерываемого каждые
200 мс.
/*nosound*/
finclude <dos.h>
•include <conio.h>
main()
{
int i;
for(1 » 0; i < 20;
e){
sound(440);
delay(ZOO);
nosound();
delay(ZOO);
}
return 0;
}
outport
TURBO
Имя
Заголовок
outport - вывод переменной на пословный порт, void
outport(1nt num, int word)
Прототип Определение Функция
dos oh dos.h Вывод на словный порт с номером num переменной, заданной параметром word.
Результат
void
Пример
Ввод номера порта и слова данных, а затем вывод этого слова на порт
с указанным номером.
/*outport*/
•include <stdio.h>
finclude <dos.h>
main{)
{
int Port, Word;
scanf(”Xd%d”・・ &Port. Word);
outport(Port, Word);
return 0;
}
outportb
TURBO
Имя
outportb - вывод переменной на байтовый порт.
Заголовок
void
outport(int num,
不
unsigned char byte)
Прототип
dos.h
Функция
Вывод на байтовый порт с номером num переменной,
заданной параметром byte.
Результат
void
Пример
Ввод номера порта и байта данных, а затем вывод этого байта на порт с указанным номером.
/*outportb*/
•include <stdio.h>
#include <dos.h> main()
{
int Port, Byte;
scanf{^^%d%d'^. &Port, &Byte);
outport(Port, Byte);
return 0;
}
peek
TURBO
Имя
peek - вывод слова данных.
Заголовок
int
peek(unsigned seg. unsigned off)
Прототип
dos.h
Определение
dos.h
Функция
Вывод слова данных, находящегося в оперативной
памяти по адресу seg:off.
Результат
Переменная типа (int>, находящаяся по указанному
адресу.
Пример
В случае монитора, управляемого адаптером Hercules, вывод слова данных из экранного буфера.
"peek */
flnclude <stdio.h>
•include <dos.h>
main()
prlntfCW, peek(0xB000( 2));
return 0;
peekb
TURBO
Имя
peekb - вывод байта данных.
Заголовок
char
peekb(unsigned seg.
unsigned off)
Прототип
dos oh
Определение
dos.h
Функция
Вывод байта данных, находящегося в оперативной
памяти по адресу seg: off.
Результат
Переменная типа (int), находящаяся по указанному
адресу.
Пример
В случае монитора, управляемого адаптером Hercules, вывод байта данных из экранного буфера.
/*peekb */
•include <stdio.h>
•include <dos.h>
main{)
{
printffXc**, peek(0xB000t 2));
return 0;
}
реггог
ANSI
Имя
реггог - вывод сообщения об ошибке, произошедшей
при выполнении программы.
Заголовок
void
реггог(const char *string)
Прототип
stdio.h
Функция
Вывод в файл, идентифицируемый stderr, сообщения о
последней ошибке, произошедшей при обращении к системе» Выдаваемое сообщение состоит из последовательности символов, задаваемой параметром string, символа : (двоеточие) и связанного с ошибкой текста (номер ошибки находится в глобальной переменной еггпо>; текст завершается символом новой строки.
Результатvo i d
Пример
Вывод перечня сообщений об ошибках при выполнении программ.
/*реггог*/
#include <stdio.h>
•include <errno.h>
extern char 常 sys_errlist[];
extern sys_nerr;
main()
int Ind;
for(Ind *0; Ind < sys_nerr; Ind 卄)
printf (f,\n%3d Xs". Tnd, sys_errlist[Ind]);
return 0; *
}
pokeTURBO
Имя
роке - размещение слова данных в оперативной памяти.
Заголовок
vied
poke(unsigned segf unsigned off,• int value)
Прототип Определение Функция
dos.h
dos.h
Помещение переменной, заданной параметром value, в ячейку памяти с адресом seg:off.
Результат
void
Пример
В случае монитора, надписи jb в левом
управляемого адаптером Hercules, вывод мигающей верхнем углу экрана.
/* poke */
#include<stdfo.h> include<dos.h> main()
poke(0xB000,0/jr+(0x87«8)J;
poke(OxBOOO. 2 J b' +(0x87«8)); return 0;
pokeb
TURBO
Имя
pokeb - размещение байта данных в оперативной памяти
Заголовок
void
pokeb(unsigned seg.
unsigned off. char value)
Прототип
dos.h
Определение
dos.h
Функция
Помещение переменной, заданной параметром value, в байт памяти с адресом seg: off
Результат
Пример
void
В случае монитора, управляемого адаптером Hercules, вывод буквы Е в левом верхнем углу экрана.
/* pokeb */
#1nclude<dos.h>
main()
poteb(OxBOOOjO. ,E');
return 0;
}
pow
ANSI
Имя
pow - вычисление степени.
Заголовок
double pow(double xv
double у)
Прототип
math.h
Функция
Формирование переменной со значением 近
Результат
Переменная типа (double) со значением ху.
Замечания
В случае переполнения возвращается значение HUGE_VAL, при ЭТОМ errno»ERANGE.
Пример
Вывод числа 1024.
7* pow */
#include<stdio.h> f1nclude<math.h>
main{)
{
printf("%0r, рои(2Д0));
return 0;
printf
ANSI
Имя
printf - редактирование и вывод последовательности символов.
Заголовок
int
printf(const char *format,
Прототип Функция
• • •)
stdio.h
Вывод в стандартный выходной файл в соответствии с перечнем шаблонов, заданным параметром format, значений аргументов, стоящих на месте многоточия.
Результат
Переменная типа (int) со значением, равным числу выводимых символов, или со значением EOF в случае возникновения ошибки.
Замечания
Вызов
printf(/w/, argl, q芯2,…,argn) эквивалентен вызову
fprintf(stdout, fmt, argl9 arg2t …,〃®0
Пример
Вывод надписи Hello world.
/* printf */
finclude<stdio.h>
main()
{
printf(••Hello world**);
return 0;
}
putc
ANSI
Имя
Заголовок
putc - вывод символа, int
putc(1nt chf
FILE * stream)
Определение Функция
stdio.h
Вывод символа с кодом ch в файл, идентифицируемый параметром stream.
РезультатРезультатПеременная типа (int) со значением, равным коду выводимого символа, или со значением EOF в случае возникновения ошибки.
Результат
Результат
Пример
Бывод буквы К в стандартный выходной файл, а в случае возникновения ошибки вывод знака вопроса в стандартный ^йл сообщений об ошибках.
/* putc *
flnc1ude<std io.h>
matn()
{
if(putc('K', stdout) — EOF
putc('?*, stderr);
return 0;
}
putch
TURBO
Имя
putch - вывод символа на консоль.
Заголовок
int
putchar(int ch)
Прототип
conio.h
Функция
Вывод символа с кодом ch на консоль.
Результат
Переменная типа (int) со значением» равным коду
выводимого символа.
Пример
Вывод на консоль
надписи jb.
/* putch */
#tnclude«contc.h>
ma1n()
{
putch('j'j;
putchfb');
return 0;
}
putchar
ANSI
Имя
putchar - вывод символа.
Заголовок
int
putchar(int) ch)
Определение
stdio.h
Функция
Вывод в стандартный выходной файл символа с
кодом Ch.
Результат
Переменная типа (int) со значением, равным коду
592
Часть VI. Библиотеки
выводимого символа, или со значением EOF в случае возникновения ошибки.
Пример
Бывод в стандартный выходной файл надписи jb.
/* putchar */
finclude<stdio.h>
main()
{
putchar(putchar('j,)一8);
return 0;
}
putenv
TURBO
Имя
Заголовок
putenv - дополнение перечня параметров окружения, int
putenv(const char *envvar)
Прототип
Функция •
stdlib.h
Присоединение к перечню параметров окружения строки env = var.
Результат
заданной параметром envvar.
Переменная типа (int) со значением 0 или -1 в случае возникновения ошибки.
Пример
Вывод текста, характеризующего значение параметра PATH.
"putenv */
#1nclude<stdltb.h>
#include<std5o.h>
main()
{
putenv(”PATH=”);
putenv(MPATH=\\JB-D0S3;\\JB-TCM);
prir)tf("PATH = %s”. getenv(•'PATH^•)); return 0;
}
puts
ANSI
Имя
Заголовок
puts - вывод последовательности символов, int
puts(const char *string)
Прототип Функция
stdio.h
Вывод в стандартный выходной файл
последовательности символов, заданной параметром string и дополненной символом новой строки.
Результат
Переменная типа (int) со значением, равным коду последнего выводимого символа, или со значением, равным коду последнего выводимого символа, или со значением EOF в случае возникновения ошибки.
Пример
Вывод надписи Hello world.
/* puts */
*1nclude<stdio.h>
matn()
{
puts ("Helle world'*);
return 0;
qsort
ANSI
Имя
Заголовок
qsort - сортировка данных.
void
qsort(void *base.
size_t nelem.
sizet width, int (*fcmp)(const void *f const void*)))
Прототип Функция
stdlib.h
Сортировка nelem элементов данных размером width каждый, находящихся в области оперативной памяти, указанной параметром base. Для сравнения данных используется двухаргументная функция femp, подобранная таким образом, чтобы ее значение зависело от аргументов argl и arg2, соответствующих сравниваемым данным, следующим образом:
*argl < *arg2 - отрицательное значение,
*argl == *arg2 - значение 0,
*argl > *arg2 - положительное значение.
Результат
void
Пример
Сортировка структур по полю Age, вывод имен Ola, Ula. Ela
/* qsort */
#include<stdic.h>
#include<stdlib.h>
struct Girls{
char*Name;
unsigned char Age;
} Arr[3] h {“Ela”, 9’
•*01аи. 5,"
—7};
main ()
int Comp(Struct Girls *, Struct Girls *);
int Ind n 0;
qsort(Arr, 3, sizeof(struct Girls). Coinp);
while(Ind < 3)
printf('*\n%s*, Arr[Ind ++]. Name);
return 0;
}
int
Comp(elml, elm2)
struct Girls *elmlr *elm2;
{
if(elml->^Age<elm2->Age)
return -1;
return alnil -> Age > alm2 -> Age;
} 、
(4aise 丿ANSI
Имя
Заголовок
Прототип Функция Результат
Замечания
Пример
Если введенное число
Signal #8. Division by ze
/* raise */
#include<signal.h> finclude<stdio.h> void
zero(int sig) printfC^Signal #%d,
} matn() {
float Float = 100.0;
raise - генерация сигнала, int
raise(int sig)
signal.h
Генерация сигнала sig.
Переменная типа (int) co значением 0 в случае успешной генерации сигнала и со значением, отличным от 0, в противном случае.
Примерами генерируемых сигналов являются:
SIGABRT - аварийное завершение выполнения программы,
SIGFPE - ошибка в операции с плавающей точкой, например, деление на нуль.
имеет значение 0, то вывод надписи: го
Division by zero”, sig);
1nt Num;
signal(SIGFPE, zero);
ssnfrXd。&Num);
if(Num h= o)
raise(SIGFPE);
else
pr1ntf(M%r. Float / Num); retutn 0;
}
rand
ANSI
Имя
Заголовок
rand - генерация случайного числа, int
rand(void)
Прототип Функция
stdlib.h
Формирование псевдослучайного числа со значением в интервале 0. .32767.
Результат
Замечания
Псевдослучайное число типа (int>. Период генератора составляет 232в
Пример
Генерация псевдослучайных чисел.
/* rand */
#1nclude<stdio.h>
#include<stdlib.h>
main()
{
while(!kbhit ())
printf(M%2dMt rand( ) % 10);
return 0;
realloc
ANSI
Имя
Заголовок
realloc - выделение памяти, void *
realloc(void ptr, size t size)
Прототип Функция,
stdlib.h alloc.h
Увеличение или сокращение области памяти, указанной параметром ptr, таким образом, чтобы ее
Результат
новый размер был равен size.
Переменная типа (void), указывающая модифицированную область памяти.
Замечания
Модификация размера области может потребовать перенесения ее содержимого в другие места.
Пример
Бывод надписи jb.
"realloc */
#include<stdio.h> f1nclude<alloc.h> main ()
char *Ref * n)alloc(2);
RefEO] У;
Ref[l] = 'bf;
Ref N realloc(Ref,3);
Ref[2] h '\0r; printf("XsM, Ref);
ANSIANSIreturn 0; &
ANSI
ANSI
Имя
remove - удаление файла»
Заголовок .
Определение
int
remove(const char *name) stdio.h
Функция,
Удаление файла с именем, указанным параметром name.
Результат
Переменная типа (int) со значением 0 в случае успешного удаления файла или со значением -1 в противном случае.
Замечания
Во втором случае переменной errno присваивается одно из следующих значений: EACCESS -正айл только для чтения,
ENOENT -加йл отсутствует.
remove
Пример
Вывод числа 0.
"remove */
#include<stdio.h> nain()
{
FILE * Doc:
Int Res;
Doc « fopen("W0Rrr、“); fclose(Doc);
Res « remove ("WORK**); printf(M%d-r Res”; return 0;
rename
ANSI
Имя
Заголовок
rename - изменение имени файла, int
rename(const char *oldnamet
const char *newname)
Прототип Функция
stdio.h
Замена имени файла, заданного параметром oldname, именем, заданным параметром newname.
Результат
Переменная типа (int) со значением 0 или -1 в случае возникновения ошибки. Во втором случае переменная егггю принимает одно из следующих значений: errno=ENDENT -файл не найден,
errrro=EACCESS -переименование неразрешено,
errno=ENOTSAM -другое устройство.
Замечания
Объектом переименования может быть только один файл. Указание дисковода должно быть одним и тем же в oldname и newname. Каталоги могут быть разными.
Пример
Перемещение и переименование файла.
/* rename */
#include<stdio.h>
main()
{
printf"Xd'\ rename(M\\ISA\\JAN". И\\Е¥А\\КАЗАМ)); return 0;
}
rewind
ANSI
Имя, Заголовок
rewind - установка файла в начальную позицию, void
rewind(FILE *stream)
Прототип Функция
stdio.h
Установка файла, идентифицируемого параметром stream, в начальную позицию. Обнуление указателя
Результат
конца файла и указателя ошибки.
Переменная типа (int) со значением 0 или со значением, отличным от 0, в случае возникновения ошибки.
Пример
Троекратный вывод
в стандартный выходной файл содержимого файла
AUTOEXEC.BAT.
/* rewind */
findude stdio.h
main()
{
tnt Count = 3;
Int Chr;
FILE *Inp n fopen("WAUTOEXEC.ВАГ, "r"); while(Count --){
while((Chr = getc(Inp))! = EOF)
putc(Chr. stdout);
putc('\rf. stdout);
rewind(Inp);
}
return 0;
scanf - вывод и интерпретация последовательности символов.intscanf(const char *formatfscanf - вывод и интерпретация последовательности символов.intscanf(const char *formatfЗаголовокЗаголовок}
scanf - вывод и интерпретация последовательности символов.
int
scanf(const char *formatf
scanf - вывод и интерпретация последовательности символов.
int
scanf(const char *formatf
Заголовок
Заголовок
rmdir
TURBO
Имя
rmdir - удаление каталога.
Заголовок
int
rmdir(const char *path)
Прототип
dir.h
Функция •
Удаление каталога с именем, указанным параметром path.
Результат
Переменная типа (int) со значением 0 (в случае
успешного выполнения функции) или -1 (в противном
случае); в последнем случае переменной еггпо
Пример
присваивается одно из следующих значений: ЕACCESS - доступ запрещен, ENOENT - дефектная дорожка.
Удаление каталога
/* rmdir */ finclude<dir.h>
fi nc1ude<std1о.h> main(
{
Isabel.
rmdirrCAMsaKel"); return 0;
}
scanf
ANSI
Имя
17. Принципы описания599
Прототип Функция
stdio.h
Ввод из стандартного входного файла в соответствии с йеречнем шаблонов в последовательности, заданной параметром format, набора литералов, находящихся в полях файла, и присвоение значений этих литералов переменным, указанным аргументами, стоящими на месте многоточия.
Результат Замечания
Число значений, присвоенных указанным переменным. Вызов
scanf(//nZ, argl^ 〃rg2, …,argn}
равнозначен вызову
fscanf(stdin, fmt, argl、arg2,…,argn)
Пример
Ввод из стандартного входного файла одной строки текста, а затем ее вывод в стандартный выходной файл.
/* scanf */
#include<stdio.h>
matn()
{
char Агг[81];
scanf ('•Xs**, Arr);
prtntf(”s',. Агги);
return 0;
}
setbuf
ANSI
Имя
Заголовок
setbuf - замена буфера файла, void
setbuf(FILE "stream.
char *buf)
Прототип Функция
stdio.h
Замена буфера, автоматически выделенного для файла, идентифицируемого параметром stream, буфером, указанным параметром buf.
Результат
Замечания
void
Необходимо, чтобы размер буфера был равен BUFSIZE (макроопределение с таким именем находится в файле stdio.h). Если параметру buf будет соответствовать пустое значение, то операции над файлом будут выполняться без использования буфера.
Пример
Вывод в файл WORK символа * (звездочка). Это действие выполняется, несмотря на аварийное завершение выполнения программы.
/* setbuf */ f1nclude<std1o.h> main()
{
FILE *Out;
Out = fopenC'WORK", V); setbuf(Out. NULL);
putc('*'. Out);
abort();
return 0; /* Formally required */ }
setdate
TURBO
Имя睛
Заголовок
setdate - установка даты, void
setdate(struct date *date)
Прототип Функция
dos.h
Установка системной даты на основе полей структуры (struct date), заданной параметром date.
Результат
Замечания*
void
Структура типа (struct date) объявлена следующим образом:
struct date{
int da_year;/*год */
char da_day;/*день */
char da_wDn;/*месяц */
}
Пример
Вывод надписи 1981.
/* setdate */
finclude<dos.h>
struct date Savel, Save2, Date= {1981, 13. 12}; main()
{
getdate(&Savel);
setdate(&Date);
getdate(&Save2);
printf^Xd**, Save2.da_year);
setdate(&Savel);
return 0;
setdisk
TURBO
Имя
setdisk - замена текущего дисковода.
17. Приняты описания602
Заголовок
int
setdisk(1nt drive)
Прототип Функция
dlr.h
Дисковод, указанный в параметре drive, объявляется текущим.
Результат
Переменная типа dnt) со значением, равным числу дисководов системы.
Замечания
Дисковод а имеет номер 0, дисковод В номер 1 и т.д.
Пример
Объявление текущим
дисковода в.
/* setdisk */ #include<dir.h> finclude<stdio.h> main()
{
enum{ A. B( C}; setdisk(B);
return 0;
}
setjmp
ANSI
Имя
Заголовок
settjmp - запоминание состожия программы, int
setjmp(jmp but env)
Прототип Функция
setjmp.h
Запоминание состояния программы в виде значения переменной env.
Результат
Переменная типа (int) со значением 0 (или со значением, определяемым функцией longjmp в момент возврата).
Пример
Вывод числа 127.
/ *setjmp */ #include<setjmp.h> finclude<stdio.h> jmp_buf State;
main()
{
register Num = 13; if(setjmp(State)
printff*%d-t Num); return 0;
}
Num = 127;
602
Часть УА Библиотеки
1ongjmp(State, 1); }
settime
ANSI
Имя
Заголовок
set time - установка времени, void
settime(struct time *time)
Прототип Функция
dos.h
Установка системного времени на основе полей структуры, указанной параметром time.
Результат
Замечания
void
Структура типа (struct time) объявлена следующим
吊
образом:
struct time {
unsigned char tf_min, /• минута •/ tChour, /• час ♦/ t1_hund, /♦ сотые часа ♦/ t1_sec, /♦ секунда •/
}
Пример •
Установка часов на начало текущей минуты.
/* setttme */
f1nclude<dos.h>
#include<stdio.h>
ma1n()
struct time Clkck;
gett1гое(&Clock);
Clkcl.t1_sec = 0;
sett1me(&Clock);
return o;
}
setvbuf
ANSI
Имя
Заголовок
setvbuf - замена буфера файла. 1nf
setvbuf(FILE *stream, char *buf, int type; size t size)
Прототип. Функция
stdio.h
Замена буфера, автоматически выделенного файлу, идентифицируемому параметром stream, буфером размера size, первый символ которого указан параметром buf. Способ использования буфера задается значением параметра type.
РезультатЗамечанияРезультатЗамечанияПеременная типа (int) со значением 0 или со значением, отличным от 0 в случае возникновения ошибки.
Результат
Замечания
Результат
Замечания
Если type = IOFBF, то операции являются полностью буферизованными. Это означает, что в процессе ввода передача содержимого буфера в файл происходит только после полного заполнения буфера.
Если type ——IOLBF, то буферизация является построчной. Это означает, что в процессе ввода заполнение буфера прерывается после ввода символа новой строки, а в процессе вывода передача содержимого буфера в файл происходит сразу же после вывода такого символа.
Если type -=_IONBF, то буферизация прекращается.
Пример
Вывод в файл WORKER надписи Very long text (если бы из программы был удален символ '\п‘,то в файле была помещена только надпись Very long).
/* setvbuf */ finclude<stdio.h> void_Bxit(); main()
FILE *0ut = fopen("UORKERw;*V);
cher Buffer[10];
setvbuf(Out. Buffer,_IOLBF, 10);
fpr1ntf(0ut. MVery long —");
abort();
TURBOTURBOreturn 0; /* Formally required */ }
TURBO
TURBO
Имя
Заголовок
setvect - изменение вектора прерывания, void
setvect(int num, void Interrupt (*lsr)O)
Прототип Функция
dos.h
Изменение вектора прерывания таким образом, чтобы генерация прерывания с номером num привела к вызову функции обработки прерывания, указанной параметром isr.
Результат
void
setvect
Пример
Вывод надписи Неге I am.
/* setvect */ finclude<stdio.h> *1nc7ude<dos.h> ♦define INT 0x80 main() {
void Interrupt far Display(); void interrupt (far * Ref)(); struct REGPACK Dummy;
Ref = getVect(INT); setvect(INT. Display);
Шг(1МТ, &Dummy); setyect(Int, Ref); return 0;
}
void interrupt far
Display()
{
printf(**Here I am");
Имя Заголовок Прототип Функция
signal - регистрация обработки сигнала.
void (*s1gnaKlnt sig, void (*fun)(1nt sig)))(int)
signaLh
Регистрация функции *fun, которая должна быть вызвана с аргументом sig сразу же после передачи сигнала.
Результат
Переменная типа ((*)(1nt)>, представляющая собой второй ар1умент последнего вызова функции signal с первым аргументом sig или значение SIG—ERR в случае неудачного вызова функции signal.
Замечания
Непосредственно перед вызовом (*fun)(sig) неявно вызывается функция signal(sig, SIG_DFL), что приводит к заданию обработки сигнала sig по умолчанию. Кро ме обработки по умолчанию можно потребовать также игнорирования сигнала. Для этого можно всюпользо ваться вторым аргументом функции signal, придавая ему значение SIG IGN. Первый аргумент этой функции может принимать, например, следующие значения: SIGABRT - аварийное завершение выполнения программы,
SIGFPE - ошибка в операции с плавающей точкой, например, вследствие деления на 0.
signal *
ANSI
Пример
Суммирование последовательности цифр, заканчивающейся числом 0.
/* signal */ finclude<s1gna1.h> finclude<stdio.h> char Name[20];
char Flag; void Interrupt(sig) {
Flag « 1'sig; /* Disregard! s1g */ } main()
{
int Num, Sum = 0;
signal(SIGABRT, Interrupt);
wM1e(!Flag){
printf (”\n Enter a number:"); scanf("%d,,r &Num);
Sum += Num;
1f(Num == 0) raise(SIGABRT);
} pr1ntf("%dM. Sum); return 0;
ANSIANSIИмяЗаголовокИмяЗаголовокПрототип Функция РезультатПрототип Функция Результатsin - вычисление синуса double stn(double x)sin - вычисление синуса double stn(double x)ЗамечанияЗамечанияmaln.hФормирование переменной со значением sin х.Переменная типа (double) со значением, равным синусу аргумента.Аргумент выражен в радианах.maln.hФормирование переменной со значением sin х.Переменная типа (double) со значением, равным синусу аргумента.Аргумент выражен в радианах.
ANSI
ANSI
Имя
Заголовок
Имя
Заголовок
Прототип Функция Результат
Прототип Функция Результат
sin - вычисление синуса double stn(double x)
sin - вычисление синуса double stn(double x)
Замечания
Замечания
maln.h
Формирование переменной со значением sin х.
Переменная типа (double) со значением, равным синусу аргумента.
Аргумент выражен в радианах.
maln.h
Формирование переменной со значением sin х.
Переменная типа (double) со значением, равным синусу аргумента.
Аргумент выражен в радианах.
Пример
Вывод числа 0.50.
/* sin */
#1nclude<std1o.h> finclude<math.h> main()
{
const float P1 3 3.141593;
pr1ntf("%.2r. sin(Pi/6)); return 0;
606
Часть VI. Библиотеки
sinh
ANSI
Имя
Заголовок
sinh - вычисление гиперболического синуса, double
s1nh(double х)
Прототип Функция Результат
math.h
Формирование переменной со значением sinh х.
Переменная типа (double) со значением, равным
Замечания
гиперболическому синусу аргумента.
В случае переполнения результатом выполнения функции будет значение HUGE_VAL, при этом errno=ERANGE.
Пример 襟
Вывод сообщения.
sinh: OVERFLOW error sinh(lOOO): Result too large /* sinh */
'#include<syio.h> •include<math.h> flnclude<errno.h> main()
{
(void)slnh(lOOO);
perror(Msinh(1000)"); return 0;
}
sleep
TURBO
Имя
sleep - временное приостановление выполнения программы.
Заголовок
void
sleep(unsigned sec)
Прототип Функция
dos.h
Приостановление выполнения программы на период sec секунд.
Результат
void
Пример
Генерация звукового сигнала с частотой 0.5 Гц.
/* sleep */
flnclude<stdio.h>
#lnclude<dos.h>
*1nc1ude<con1o.h>
main()
{
whne(!kbh1t( )){ puchar(*\a*); sleep(2);
}
return 0;
}
sound
TURBO
Имя
Заголовок
sound - включение динамика, void
sound(unsigned freq)
Прототип Функция
dos.h
Включение динамика и трансляция непрерывного сигнала с частотой freq Герц.
Результат
void
Пример
Генерация звуков, прерываемая и возобновляемая при нажатии произвольной клавиши клавиатуры.
/* sound */
f1nclude<dos.h>
f1nclude<con1o。h>
ma1n()
{
unsigned Hz = 300;
1nt 1;
sound (Hz);
for(i = 1; 1< 6; i++){
while(lkbhltO);
(vo1d)getch();
1f(i & 1)
nosound();
else
sound(Hz);
}
return 0;
sprintf
ANSI
Имя
sprintf - редактирование и размещение в оперативной памяти последовательности символов.
Заголовок
int sprintf(char *spr1ng, const char *format.
Прототип ФункцияРезультатЗамечанияПримерПрототип ФункцияРезультатЗамечанияПримерstdio.h
Прототип Функция
Результат
Замечания
Пример
Прототип Функция
Результат
Замечания
Пример
Размещение в области памяти, первый элемент которой указан аргументом string, в соотвествии с перечнем шаблонов (первый символ которого указан аргументом format) значений аргументов, стоящих на месте многоточия. Последовательность вводимых символов заканчивается символом новой строки.
Переменная типа dnt) со значением, равным числу вводимых символов, или со значением EOF в случае возникновения ошибки.
Функция sprintf отличается от функции fprintf тем, что последовательность символов размещается не в файле, а в области оперативной памяти.
Вывод ш<сл£ 13.
〃 sprintf */
f1nc7ude<stdio.h>
main()
{
char Arr[3];
sprintf fArr.^Xd'1, 13);
retutn 0;
}
sqrtsqrtИмяЗаголовокПротокол Функция РезультатЗамечанияИмяЗаголовокПротокол Функция РезультатЗамечанияANSI
sqrt
sqrt
Имя
Заголовок
Протокол Функция Результат
Замечания
Имя
Заголовок
Протокол Функция Результат
Замечания
sqrt - вычисление квадратного корня.
double
sqrt(double х)
math.h.
Формирование переменной со значением Vx.
Переменная типа (double) со значением, равным квадратному корню из аргумента.
Если значение аргумента меньше 0, то результатом выполнения функции будет значение 0, при этом errno=ED0M.
Пример
Вывод числа 12.
"sqrt */ finclude<stdio.h> finclude<math.h> main()
{
prlntf("X.Of", sqrt(144)); return 0;
}
17. Пришщпы описания609
srand
ANSI
Имя
Заголовок
srand - заполнение генератора псевдослучайных чисел, void
srand(unsigned seed)
Прототип Функция
stlib.h
Очередное заполнение генератора псевдослучайных чисел.
Результат
Замечания
void
Перед первым применением генератора производится его заполнение с аргументом, равным 1. При выборе другого значения генерируется другая последовательность псевдослучайных чисел.
Пример
Вывод двух идентичных строк, содержащих псевдослучайные числа.
/* srand */
f1nclude<std1о.h>
#include<stdlib.h>
main()
{
int Count = 0;
wh1le(Count++ <40)
printf(,,%2d\n*\ rand( ) % 10);
Count = 0;
srand(l);
wh1 le(Count ++< 40)
printf(M%2d\n". rand( ) % 10);
return 0;
}
sscanf
ANSI
Имя
sscanf -извлечение и интерпретация последовательности символов.
Заголовок
int sscanf(const char string, const char *formatf
Прототип Функция
…J stdio.h
Извлечение из области памяти, первый элемент которой указан аргументом string, в соответствии с перечнем шаблонов, первый символ которого указан аргументом format, находящихся в этой области литералов и присвоение значений этих литералов переменным, указанным аргументами, находящимися на месте многоточия.
Результат ЗамечанияРезультат ЗамечанияЧисло значений, присвоенных указанным переменным. Функция sscanf отличается от функции fscanf тем, что последовательность полей извлекается не из файла, а из области оперативной памяти.
Результат Замечания
Результат Замечания
Пример
Вывод надписи 13!.
/* sscanf */
finclude<stdio.h>
main()
{
1nt Fix;
char Chr;
sscanfCTVx н 131”. “Fix = %d%c”. &Fix.&Chr);
printf(,,%d%c,,t Fix. Chr);
return 0;
ANSIANSI}
ANSI
ANSI
Имя
Заголовок
strcat - соединение последовательностей символов, char
strcat(char *dest1n, const char *source)
Прототип Функция
string.h
Присоединение к последовательности символов, указанной аргументом destin, последовательности символов, указанной аргументом source.
Результат
Переменная типа (char*), указывающая на первый символ объединенной последовательности.
Замечания
Первый символ последовательности, указанной аргументом source, размещается в байте, занимаемом символом с кодом 0.
strcat
Пример
Вывод надписи Izabela.
/* strcat */
#1nclude<stdio.h>
findude<string.h>
char Arr[8] = "Iza";
main()
{
pr1ntf("Xs**, strcat(Arr. "bela”)); return 0;
}
". Принципы описания6"
strchr
ANSI
Имя
Заголовок
strchr - поиск символа, char *
strchr{const char *str. int c)
Прототип Функция
string.h
Просмотр последовательности символов, указанной аргументом str, с тем, чтобы найти символ с кодом с
Результат
Переменная типа (char *>, указывающая найденный символ, или пустое значение, если символ в последовательности отсутствуете
Замечания
Просмотр ведется в направлении вперед, а при с 0 '\0“ объектом поиска будет символ с кодом 0.
Пример
Вывод надписи unia.
/strchr */
#include«stdio.h>
#include«string.h>
char Name[ ] = "Ewunia":
main()
{
printf(MXs", strchr(Name. *u*)); return 0;
}
stremp
ANSI
Имя
Заголовок
stremp - сравнение последовательностей символов, int
stremp(const char *strl, const char *str2)
Прототип Функция
string.h
Сравнение последовательности символов, указанной аргументом strl, с последовательностью символов.
Результат
указанной аргументом str2.
Переменная типа (int) со значением, отражающим результат сравнения последовательностей, а именно при strl V str2 - отрицательное значение, strl з str? - значение 0, strl > str2 - положительное значение.
Замечания
Сравнение производится в предположении, что символы принадлежат типу (slqned char).
Пример
Вывод отрицательного числа.
/* strcmp */
#1nclude<stdio.h>
#include<string.h>
ma1n()、
{
printf("%d", strcmpC13jan", "13kaja")); return 0;
}
strcpy
ANSI
Имя Заголовок
strcpy - копирование последовательности символов, char*
strcpy(char *destin,
const char *source)
Прототип Функция
string.h
Копирование последовательности символов, заданной параметром source, в область памяти, первый элемент которой указан аргументом destin.
Результат
Переменная типа (char*), указывающая на первый элемент области памяти, в которую производится копирование.
Замечания*
Последним копируемым символом является символ с кодом 0.
Пример
Вывод надписи 99.
/* strcpy */
#1nclude<std1o.h>
findude<string.h>
char Arr[ ] = •,1Z345";
main()
{
ptintff'Xs", strcpy(Arr + 1, "99"));
return 0;
}
strcspn
ANSI
Имя
strcspn - выделение последовательности символов, предшествующих заданному ограничителю.
Заголовок
sizet
strcspn(const char *strl, const char *str2)
Прототип Функция
string.h
Определение числа тех начальных символов последовательности, указанной аргументом strl, ни один из которых не принадлежит множеству символов, входящих в последовательность, указанную аргументом strZ.
Результат
Переменная типа (fnt) co значением, равным числу символов, предшествующих заданному аргументу.
Пример
Вывод числа 3.
/* strcspn */
#include<stdio.h>
findude<string.h>
main()
{
printffW, strcspn(M127, 13”,“J)); return 0;
}
streiTor
ANSI
Имя
Заголовок
strerror - вывод указателя сообщения, shar *
strerror(int num)
Прототип Функция
string.h, stdio.h
Вывод указателя последовательности символов, представляющей собой сообщение о появлении ошибки с номером num.
Результат
Переменная типа (char*), указывающая на первый из символов, составляющих сообщение.
Замечания
Указанная последовательность символов находится в статической области памяти. При каждом вызове функции strerror ранее находившаяся в этой области информация уничтожается.♦
Пример
Вывод текста следующего сообщения с номером 1: Invalid function number.
/* strerror */
#include«string.h>
#include<stdio.h>
main()
{
ptintf("%s". strerror(l));
return 0;
}
strlen
ANSI
Имя
strlen - определение длины последовательности символов.
Заголовок
sfze_t
strlen(const char *str)
Прототип Функция
strung.h
Определение числа символов в последовательности, указанной аргументом str.
Результат
Переменная типа (size~t) со значением, равным числу символов в последовательности, завершающейся символом с кодом 0.
Замечания
Символ с кодом 0 не засчитывается.
Пример
Вывод числа 7.
/* strlen */
#include<stdto.h>
#include<strfng.h>
main( }
{ printf("%d'\ strlen(f(Kajusiaw)); return 0;
}
strncat
ANSI
Имя Заголовок
strncat - соединение иоследсвательносте访 символов, char*
strncat(char *destin# const char *source, size_t maxlen)
Прототип Функция
string.h
Присоединение к последовательности символов, указанной аргументом des tin, не более, чем maxlen символов последовательности, указанной аргументсяи source.
Замечания
Первый символ присоединяемой последовательности размещается в байте, занимаемом символом с кодом 0.
Пример
Вывод надписи EINSTEIN.
/* strncat */
#include<stdic.h>
♦i nc1ude<string.h>
char Arr[9] = 'TIN";
main( }
{
printf("Xsw\ strncat(Arrv "STEINBERG", 5)); return 0;
}
strncmp
ANSI
Имя
Заголовок
strncmp - сравнение последовательностей символов, int
strncmp(const char *strl, const char *str2, size_t maxlen)
Прототип Функция
strlng.h
Сравнение последовательности символов, указанной аргументом strl, с последовательностью символов, указанной аргументом strZ. Сравнению подлежит не более, чем maxlen символов.
Результат
Переменная типа (int) со значением, отражающим результат сравнения последовательностей, в частности, при
strl < strZ - отрицательное значение, strl == str? - значение 0, strl > strZ - положительное значение.
Замечания
Сравнение производится в предположении, что символы принадлежат типу (signed char).
Пример
Вывод числа 0・
/* strncmp */
#1nclude<stdio.h>
findude<string.h>
main()
{
prfntg("Xd,\ strncmp("13jan"r ”13kaja”, 2)); return 0;
}
strncpy
ANSI
Имя
Заголовок
strncpy - копирование заданного числа символов, char*
strncpy(char *destion, const char *source, size t maxlen)
Прототип Функция
strlng.h
Копирование проследовательности символов, заданной аргументом source, в область памяти размером maxlen, первый символ которой указывается аргументом destin. Если число копируемых символов меньше maxlen, то остальная часть предназначенной для копирования области заполняется символами с кодом 0.
Результат
Переменная типа (char*), указывающая на первый
элемент области памяти, в которую происходило копирование.
Пример
Вывод надписи Kaja.
/* strncpy */
f1nclude<stdIo.h>
#include<string.h>
char Mame[ ] = "Iza";
matn()
{
printf(M%.4s", strncpy(Name, s'Kaja*', 4));
return 0;
}■
strpbrk
ANSI
Имя
strpbrk - поиск первого вхождения одного из заданных символов.
Заголовок
char*
strpbrk(const char *strl# const char *str2)
Прототип
string.h
Функция
Поиск в последовательности символов, заданной аргументом strl, такого символа, который содержится в последовательности символов, указанной аргумента str2.
Результат
Переменная типа (char*), указывающая на искони^
символ или пустое значение, если такай символ не
Пример
Выход числа 34.
/* strpbrk */
#1пс1ude<stdio.h>
#1nclude<string.h> main ()
{
найден.
prtntf(”s”・ strpbrk(M12.34".,\.M)+l);
return 0;
/ strrchr、、
ANSI
Имяstrrchr - пешек последнего вхождения заданного
символа.
Заголовокchar*
17. Принципы описания617
strrchr (const char *str, Int c)
Прототип Функция
string.h
Псжск в последовательности символов, заданной аргументом str, последнего символа с кодом с.
Результат
Переменная типа (char*), указывающая найденный символ, или пустое значение, если такой символ не
Пример
найден.
Вывод надписи 20.
/* strrchr */
#1nclude<stdio.h>
#include<string.h>
main()
{
printf(M%s", strrchr(T2:Z5:20\':,)+1); return 0;
}
strspn
ANSI
Имя
strspn - подсчет символов, принадлежащих заданной последовательности символов.
Заголовок
size_t
strspn(const char *strl, const char *str2)
Прототип Функция
string.h
Подсчет числа тех начальных символов последовательности, заданной аргументом strl, которые принадлежат множеству символов, содержащихся в последовательности, указанной аргументом str2.
Результат
Переменная типа (size_t) со значением, равным числу указанных символов.
Пример
Ввод целого числа, а затем вывод числа его цифр.
/* strspn */
finclude<stdio.h>
#include<string.h>
#include<stdlib.h>
main()
{
long Nun;
char Arr [33];
scanfC^Id*'; &Num);
printf(”%d"e strspn(ltoa(Nunr Arr, 10).
,,0123456789t,));
6/8
Часть VI. Би.блио1-пеки
return 0; }
strstr
ANSI
Имя
Заголовок
strstr - пешек последовательности, char*
strstr(const char *strlr
const char *str2)
Прототип Функция
string.h
Псмск в последовагельности символов, заданной аргументом strl, первой подпоследовательности, идентичной последовательности, заданной аргументом str.
Результат
Переменная типа (char*), указывающая на первый символ последовательности, заданной strl, с которого начинается подпоследовательность, заданная str2, или пустое значение, если такая подпоследовательность не содфжится.
Пример
Вывод надшей uni а.
/* strstr */
#1nclude<stdfo.h>
finclude<stri ng.h>
ma1n()
{
pr1ntf(”Xs”・ strstr(MEwunia". °unw)); return 0;
}
strtod
ANSI
Имя
strtod - преобразование последовательности символов в число с плавающей точкой.
Заголовок
double
strtcd(const char *stre char **endptr)
Прототип Функция
stdlib.h
Интерпретация начального фрагмента последовательности символов, заданной аргументом str, как записи числа с плавающей точкой и формирование переменной типа (double), равной этому числу.
Результат
Переменная типа (double) со значением, равным числу, записанному в виде последовательности символов.
Замечания
—
Если endptr ! ■ NULL, то переменной *endptr будет npi своено значение, указывающее на тот символ входной последовательности, заданной аргументом str, который
-1^я《яется1 элементом числа с плавающей точкой.
Пример
Проверка функции strtod, завершаемая вводом новой строки.
/* strtod */
#fnclude<std1o.h>
#fnclude<str1ng.h>
main()
{
char Buf[81];
gets(Buf);
whilefstrlen(Buf)){
printfCAnXfW, strtod(Buf, NULL));
gets(Buf);
}
return 0;
}
strtok
ANSI
Имя
Заголовок
strtok - поиск лексических единиц char*
strtok(char *strl.
const char *str2)
Прототип Функция
string.h
Интерпретация последовательнсхтш символов, заданной аргументом argl, как последовательности лексических единиц, разделенных ограничителями, содержащимися в последовательности, заданной аргументом str2, и возвращение очередных таких лексических единиц.
Результат
Переменная типа (char*), указывающая на первую из найденных лексических единиц, или пустое значение - если такой единицы нет.
Замечания
После выделения лексической единицы из последовательности, заданной аргументом strl, непосредственно за ней размещается символ с кодом 0. Вызов функции с первым аргументом, имеющим пустое значение, трактуется так, будто этот аргумент указывает на символ, следующий непосредственно после упомянутого символа с кодом 0.
Пример
Вывод идентификаторов, содержащихся в двух операторах присвоения (по одному в каждой строке).
/* strtok */
#include<stdio.h>
#include<string.h>
main()
{{char (Asg « "а = b + с + d;" "b = с + а; *;
{
{
char *Ref = strtok(Asg, **+■;");
do {
printf("\n%s-t Ref);
Ref « strtck(NULL( **+«;**);
} while(Ref);
return 0;
strtolstrtolANSI
strtol
strtol
Имя 舒ЗаголовокПрототип Функция .РезультатЗамечанияИмя 舒ЗаголовокПрототип Функция .РезультатЗамечанияstrtol - преобразование последовательности символов в целое число.
Имя 舒
Заголовок
Прототип Функция .
Результат
Замечания
Имя 舒
Заголовок
Прототип Функция .
Результат
Замечания
long
strtol(const char *str, char **endptr, Int base) stdlib.h
Интерпретация начального фрагмента последовательности символов, заданной аргументом str, как записи целого числа с основанием base и формирование переменной типа (long) со значением, равным этому числу Переменная типа (long) со значением, равным числу, записанному в виде указанной последовательности символов.
Если endptr!>=NULL, то переменной, заданной аргументом, которому соответствует endptr, будет присвоено значение, указывающее на тот символ входной последовательности, который не является элементом целого числа. Если base -=«= 0, то число, начинающееся с Ох или ох, рассмаривается как шестнадцатеричное число; число, которое не является шестнадцатеричным и начинается с 0, рассматривается как восьмеричное, а число, которое не начинается с 0, рассматривается как десятичное.
Пример
Проверка функции strtol, завершаемая вводом пустой строки.
/* strtol */ #1nclude<stdio.h> #include<stdlib.h> main()
char *Ter;
char Buf[81];
gets(Buf);
wh11e(strlen(Buf)){
pr1ntf(~\n%ld%c"t strtol(Bufr &Тег, 16). *Тег); gets(Buf);
return
system
ANSI
Имя
system - выполнение системной директивы.
Заголовок
1nt
system(const char "command)
Прототип
stdlib.h. process.h
Функция
Выполнение программы COMMAND.COM для интерпретации директивы, заданной аргументом command.
Результат
Переменная типа (int), возвращаемая выполненной программой.
Замечания
Поиск программы COMMAND.COM осуществляется на основе маршрута, определяемого строкой среды с именем COMMAND.
Пример
Вывод информации о
/* system */
#inc1ude<std1ib.h> ma1n()
{
system(”DIR");
return 0;
}
файлах текущего каталога.
tan
ANSI
Имя
tan ~ вычисление тангенса.
Заголовок
double tan(double х)
Прототип
math.h
Функция
Формирование переменной со значением tg х.
Результат
Переменная типа (double) со значением, равным тангенсу аргумента.
Замечания
Аргумент выражается в радианах. Если абсолютное значение аргумента близко к pl/2, то результатом выполнения функции будет 0, a errno=ERANGE.
Пример
Вывод числа 1.00.
/* tan */
#include<stdio.h>
#include<math.h>
main()
{
float const Pi - 3.141593;
printf:M%.2fHt tan(Pi/4));
return 0;
tanh
ANSI
Имя
Заголовок 銀
tanh - вычисление гиперболического тангенса, double
tanh(double х)
Прототип Функция Результат
math.h
Формирование переменной со значением tanh х.
Переменная типа (double) со значением, равным гиперболическому тангенсу аргумента.
Пример .
Вывод числа 0.00.
/* tanh */
♦include<stdio.h>
#inclucte<math.h>
main()
{
printffX.Zf. tanh(O));
return 0;
time
__ANSI
Имя Заголовок
time - сообщение о текущем времени.
time_t丿
time(time_t *tloc)
Прототип Функция
time.h
Присвоение переменной, указанной аргументом tloc, целочисленного значения, равного количеству секунд, прошедших от полуночи 1 января 1970 г. (время по Гринвичу).
Результат
Переменная типа (time_t) со значением, равным
Замечания
указанному количеству секунд.
Значение результата будет присвоено также переменной, указываемой аргументом функции.
Пример
Вывод числа 20.
/* time */
#include<stdio.h>
#include<time.h>
main()
{
tiwe_t Before, After;
(void)time(&Before);
s1eep(20);
printfC'Xd”. (int)(time(&After) - Before));
return 0;
ANSIANSItmpfile
ANSI
ANSI
Имя ЗаголовокПрототип ФункцияРезультатЗамечанияИмя ЗаголовокПрототип ФункцияРезультатЗамечанияtmpfile - создание рабочего файла.
Имя Заголовок
Прототип Функция
Результат
Замечания
Имя Заголовок
Прототип Функция
Результат
Замечания
FILE*
tmpfile(void)
stdio.h
Создание рабочего файла с уникальным именем, выбираемым сисгемой, указание для него канала и открытие канала в режиме 'Wb" (см. функцию fopen).
Переменная типа (FILE*), идентифицирующая канал.
Если создание файла или открытие канала невозможно, то результатом функции является пустое значение.
Нормальное завершение выполнения программы или закрытие канала влечет за собой автоматическое удаление созданного файла.
Пример
Вывод надписи Hello.
/* tmpfile */
#include<stx1io.h>
mainf )
{
FILE *ioF!LE = tmpfile();
int Chr;
fprintf(ioF11er wHel1ow);
rewind(ioFile);
while((Chr * fgets(ioFile)) ! * EOF) putchar(Chr);
return 0;
624
Часть VI. Библиотеки
tmpnam
ANSI
Имя
Заголовок
tmpnam - создание уникального имени файла, char*
tmpnam(char *name)
Прототип Функция
stdio.h
Создание уникального имени файла и помещение этого имени в область памяти, указанную аргументом name. Если namB==NULL, то имя помещается в область, принятую по умолчанию.
Результат
Указание первого элемента области, в которую помещено имя.
Замечания
й»
При реализации принято, что имя должно содержать не более 10 символов, а число уникальных имен, которые могут быть созданы, не превышает 32767.
Пример
Вывод трех уникальных имен файлов.
/* tmpnam */ 疊
#include<stdio.h>
main()
{
int Num;
for(Num к 1; Num < 4; Num++) printf(MXs\nH, tmpnam(NULL));
return 0;
}
tolower
ANSI
Имя
Заголовок
tolower - преобразование прописной буквы в строчную, int
tolower(int с)
Прототип Функция
ctype.h
Преобразование кода с прописной буквы в код строчной буквы.
Результат
Переменная типа (int) со значением, равным коду строчной буквы, соответствующей исходной прописной
Замечания
букве.
Если значение аргумента не является кодом буквы, то выполняется тождественное преобразование.
Пример
Вывод надписи e!・
/* tolower */
#1nclude<stdio.h> find ude<ctype. h> main()
{
putchar(tolower(•E')); putchar( to lower (4 *)); return Q;
toupper
ANSI
Имя
Заголовок
toupper - преобразование строчной буквы в прописную, int
toupper(1nt с)
Прототип Функция
ctype.h
Преобразование кода строчной буквы в код прописной
Результат
Переменная типа (int) со значением, равным коду прописной буквы, соответствующей исходной строчной
Замечания
Если значение аргумента не является кодом буквы, то выполняется тождественное преобразование.
Пример
Вывод надписи E!.
/* toupper */
#include<stdio.h>
#1nclude<ctype.h>
ma1n()
{
putchar(toupper(* e')); putchar(toupper('!')); return 0;
}
ultoa
TURBO
Имя
ultoa - преобразование целого числа без знака в последовательность символов.
Заголовок
char*
ultoa(unsigned long valie, char *string<, int radix)
Прототип Функция
stdlib.h
Преобразование числа, представляемого аргументом value, в последовательность символов, имеющую вид числа с основанием radix, и размещение этой последовательности в области памяти, первый элемент которой указан аргументом.
40—764
РезультатЗамечанияРезультатЗамечанияПримерПримерВывод надписи ffffffff./* ultoa */#include<stdio.h>#include<stdlib.h>main(){char Arr[33];printfC**%^, ultoa(-lr Arr. 16));return 0;Вывод надписи ffffffff./* ultoa */#include<stdio.h>#include<stdlib.h>main(){char Arr[33];printfC**%^, ultoa(-lr Arr. 16));return 0;ungetcungetcANSIANSIИмяЗаголовокИмяЗаголовокПрототип ФункцияРезультатПрототип ФункцияРезультатungetc - возвращение символа в канал, intungetc(int с.FILE *stream)stdio.hВозвращение символа с кодом с в буфер, связанный с каналом, идентифицируемым аргументом stream.Переменная типа (int) со значением, равным коду возвращаемого символа, или со значением EOF, если возвращено более одного симьола.ungetc - возвращение символа в канал, intungetc(int с.FILE *stream)stdio.hВозвращение символа с кодом с в буфер, связанный с каналом, идентифицируемым аргументом stream.Переменная типа (int) со значением, равным коду возвращаемого символа, или со значением EOF, если возвращено более одного симьола.ПримерВывод буквы j./* ungetc */ #includB<stdio.h> #include<conio.h> main() {char Chr;ungetc('f, stdin);Chr ■ getc(stdin); putchar(Chr); return o;ПримерВывод буквы j./* ungetc */ #includB<stdio.h> #include<conio.h> main() {char Chr;ungetc('f, stdin);Chr ■ getc(stdin); putchar(Chr); return o;
Результат
Замечания
Результат
Замечания
Пример
Пример
Вывод надписи ffffffff.
/* ultoa */
#include<stdio.h>
#include<stdlib.h>
main()
{
char Arr[33];
printfC**%^, ultoa(-lr Arr. 16));
return 0;
Вывод надписи ffffffff.
/* ultoa */
#include<stdio.h>
#include<stdlib.h>
main()
{
char Arr[33];
printfC**%^, ultoa(-lr Arr. 16));
return 0;
ungetc
ungetc
ANSI
ANSI
Имя
Заголовок
Имя
Заголовок
Прототип Функция
Результат
Прототип Функция
Результат
ungetc - возвращение символа в канал, int
ungetc(int с.
FILE *stream)
stdio.h
Возвращение символа с кодом с в буфер, связанный с каналом, идентифицируемым аргументом stream.
Переменная типа (int) со значением, равным коду возвращаемого символа, или со значением EOF, если возвращено более одного симьола.
ungetc - возвращение символа в канал, int
ungetc(int с.
FILE *stream)
stdio.h
Возвращение символа с кодом с в буфер, связанный с каналом, идентифицируемым аргументом stream.
Переменная типа (int) со значением, равным коду возвращаемого символа, или со значением EOF, если возвращено более одного симьола.
Пример
Вывод буквы j.
/* ungetc */ #includB<stdio.h> #include<conio.h> main() {
char Chr;
ungetc('f, stdin);
Chr ■ getc(stdin); putchar(Chr); return o;
Пример
Вывод буквы j.
/* ungetc */ #includB<stdio.h> #include<conio.h> main() {
char Chr;
ungetc('f, stdin);
Chr ■ getc(stdin); putchar(Chr); return o;
Переменная типа (char*), указывающая на первый символ сформированной последовательности.
Последним помещаемым в область памяти символом является символ с кодом 0. Основанием может быть целое число в интервале 2. .36.
ungetch
TURBO
Имя
ungetch - возвращение символа в буфер клавиатуры..
Заголовок.
int ungetch(1nt с)
Прототип
conio.h
Функция
Возвращение символа с кодом с в буфер клавиатуры.
Результат
Переменная типа (int) со значением, равным коду
возвращаемого символа, или со значением EOF, если возвращено более одного символа»
Пример
Вывод буквы j.
/* ungetch */
#include<stdio.h>
#inc1udevconiо.h> main()
{
char Chr;
ungetch(( jr):
Chr == getch();
putchar(Chr);
return 0;
}
unlink
TURBO
Имя
unlink - удаление файла.
Заголовок
int
un!1nk(const char *name)
Прототип
dos.h, io-hp stdio.h
Функция
Удаление файла с именем, заданным аргументом name.
Результат
Переменная типа (int) со значением 0 при успешном выполнении функции и со значением -1, если произошла ошибка. В последнем случае переменный еггпо присваивается одно из следующих значений: ENOENT- файл не найден,
EACCESS- доступ не разрешен.
Замечания
Файлы с признаком только для чтения удалению не подлежат.,
Пример
Создание файла, а
затем его удаление.
/* untinr */ #include<stxliOoh> #include<dos»h> main()
- char *Name * “ork”;
FILE *0ut = fopen(Name. "*•'); fclose(Out);
uni ink(Name);
return 0;
va-arg
ANSI
Имя Заголовок
Определение
Функция Й»
va_arg - возвращение аргумента.
/* type */
va_arg(/* va_list paramr type)
stdarg.h
Возвращение очередного аргумента типа (功ре>,
Результат
находящегося на месте параметра в списке param.
Переменная типа (type), равная значению очередного
Замечания
аргумента функции.
Использование функции va_arg требует предварительного выполнения функции va_start с аргументом рагап.
Пример
Вывод надписи jb.
/* va__arg */
#1nclude<stdart.h>
#1nclude<stdio.h>
main()
void sub(charr...);
subCJ'/b*);
return 0;
}
void sub(char Chrr...)
{
ve_1ist State;
va_staret(State, Chr);
printf(*'%cXc*\ Chr. va_arg(State, int));
}一
va-end
ANSI
Имя
Заголовок
va__end - завершение возвращения аргументов. /*"void */
Определение Функция
va_end(/*va_lbst */ paran)
stdarg.h
Завершение действий, связанных с возвращением
аргументов, находящихся на месте параметров списка param.
Результат ЗамечанияРезультат Замечанияvoid
Результат Замечания
Результат Замечания
Использование функции va_end требует предварительного выполнения функции va_start с аргументом param.
Пример
Вывод надписи jb.
/* va_end */
#include<stdart.h>
#include<stdio.h>
main()
{
char fun(int,...);
printf(M%c%c"f fun(2/*\ У), fun(3.'•'」•','b'));
return 0:
char
fun(int Count,...);
{va_list State:
char Chr;
va_start(State, Count);
while(—Count)
(void)va_arg(State# Int);
Chr * va_arg(State, int);
return 0;
}
ANSIANSIva—start
ANSI
ANSI
ИмяЗаголовокОпределение ФункцияРезультатЗамечанияИмяЗаголовокОпределение ФункцияРезультатЗамечанияva_start - подготовка к возвращению аргументов.
Имя
Заголовок
Определение Функция
Результат
Замечания
Имя
Заголовок
Определение Функция
Результат
Замечания
/* void */
va_start(va_l1st param. lastfix)
stdarg.h
Выполнение предварительных действий, предшествующих возвращению аргументов функции, стоящих на месте параметров списка рагап.
/* void */
Аргументами функции va_start являются: имя вспомогательной переменной типа (va_Hst) и lastfix - имя параметра, предшествующего списку параметров рагап.
Пример
Вывод суммы чисел 5, 6 н 7.
/* va_start */ finclude<stdarg.h>
#include<stdio.h>
main()
{
void sum(long *, int,...);
long Sum » 0;
suRi(&Sumf3f5t6t7);
printf("%ld"f Sunn);
return 0;
}
void
sum(long "Sum,int Count,...)
{
va_list State;
va-start(Siate₽ Count);
while(Count —)
*Sum += va_arg(State, int); va_end(State);
}
vfprintf *
ANSI
Имя
vfprintf - редактирование и вывод последовательности символов.
Заголовок
int
vfprintf(FILE *stream, const char *format, va_list paran)
Прототип Функция
stdio.h
Вывод в файл, идентифицируемый аргументом stream в соответствии с перечнем шаблонов в последовательности, заданной аргументом format, значений тех аргументов функции vfprintf, которые представлены списком параметров paran.
Результат
Переменная типа (int) со значением, равным числу выведенных символов, или со значением EOF в случае возникновения ошибки.
Замечания
Функция vfprintf отличается от функции fprintf тем, что ее неявными аргументами являются аргументы вызываемой функции, соответствующие параметрам списка param.
Пример
Вывод в файл TARGET
надписи Jan.
〃 vfprintf */ #1no]ude<stdio.h>
#include<stdarg.h> main()
FILE *Out - fopen("TARGET");
void output(FILE 1 •♦•); output(Out/j* ■“ rn*);
return 0;
}
void
output(FILE *Fid,...);
{
va_list Arg;
va_s tart(Arg,F id);
vfprintf(Fid. ,,%c%c%c*. Arg);
va end(Arg);
}
vfscanf
TURBO
Имя
vfscanf - ввод и интерпретация последовательности символов.
Заголовок
int vfscanf(FILE *stream, const char *format, va_list param)
Прототип Функция
stdio.h
Ввод из файла, идентифицируемого аргументом stream, в соответствии с перечнем шаблонов в последовательности, заданной артументом format, набора литералов, находящихся в канале, и присвоение значений этих литералов переменным, указанным теми аргументами вызываемой функции vfscanf, которые представлены списком параметров param.
Результат
Число значений, присвоенных указанным переменным.
Пример
Для входных данных 13! вывод надписи 13!
/* vfscanf */
finclude<stdio.h>
finclude<stdarg.h>
matn()
{
void input(intf...);
char Chr;
int Fix;
input(2,&Fix, &Chr);
printf("Xd%cM. Hx, Chr);
return 0;
}
void
input(int Count,...)
va_11st Arg;
va^startfArg, Count);
vfscanf(stdin, "%d%c*\ Arg);
va_end(Arg);
} 一
vprintfANSI
Имя
Заголовок
Прототип Функция
節
Результат
Замечания.
Пример
Вывод надписи Jb.
/* vprintf */ #include<stdarg.h> #inc1ude<stdio.h>
ma1n() {
void outputfchar,.. oututfj','b');
return 0;
} void outputfchar Chr,…)
{
va_Hst Arg;
va_start(Arg, Chr); pHntf(n%cMf Chr);
vpr1ntf("%c"t Arg); va_end(Arg);
vprintf - редактирование и вывод последовательности символов.
int
vprintf(const "format.
va_list param)
stdio.h
Вывод в стандартный выходной канал в соответствии с перечнем шаблонов в последовательнсхтги, заданном ар1ументом format, значений тех артументов вызываемой функции vprintf, которые представлены списком параметров рагага.
Переменная типа (int) со значением, равным числу выведенных символов, или со значением EOF (в случае возникновения ошибки).
Вызов функции
vprintf(/m^ argh arg2,…,argn) равнозначен вызову функции
vfprintf(stdout, fmt> arglf arg2, ..., argn),
.);
/7. Принципы описания633
vscanf
TURBO
Имя
vscanf - ввод и интерпретация последовательности символов.
Заголовок
int
vscanf(const char *fomate va_list paran)
Прототип Функция
stdio.h
Ввод из стандартного входного канала в соответствии с перечнем шаблонов в последовательности, заданной аргументом format, набора литералов и присвоение значений этих литералов переменным, указанным теми аргументами вызываемой функции vscanf, которые представлены списком параметров рагатл.
Результат
Замечания
Число значений, присвоенных указанных^ переменным. Вызов функции
vscanf(/m?, argJ, arg2t...9 argri) равнозначен вызову функции
vscanf (stdin,fmttargi,arg2,...targn),
Пример
Для входных данных 131 вывод надписи 13!
/* vscanf */ f1nc1ude<stdarg.h>
#1nc7ude<stdio.h>
ma1n() {
void input(Int *,...);
int Fix;
char Chr;
input(2,Fix, &Chr);
pr1ntf{°%d%c". Fix, Chr);
return 0;
} void
input(int Ref,...) {
va_11st Arg;
va_start(Arg, Ref);
sc£nf( "Xd%”. Ref);
vscanf (nXc*\ Arg);
}
vsprintf
ANSI
Имя
vsprintf - редактирование и вывод последовательности символов.
Заголовок
int
vsprintf(char *str1ngr const char "format. va_list param)
Прототип 0y"阿〃兄
stdio.h
Размещение в области памяти, первый элемент, который указан аргументом string, в соответствии с перечнем шаблонов, первый символ которого задан аргументом format, значений тех аргументов вызываемой функции vsprintf, которые представлены списком параметров param.
Результат
Переменная типа (Int) со значением, равным числу выведенных символов, или со значением EOF (в случае возникновения ошибки).
Пример
Вывод надписи jb.
/* vsprintf */ finclude<stdarg.h> finclude<stglio.h>
main()
{
void output(char,...);
output(,j,.*b,); return 0;
}
void
output(char Chr,...)
{
va_11st Arg;
char Buf[3];\
va_start(Arg, Chr);
sprintffBuf, ”c”. Chr);-—-—- vsPr1ntf(Buf + If. Arg);
TURBOTURBOprintffXs", Buf);
TURBO
TURBO
Имя
vsscanf - редактирование и ввод последовательности символов.
Заголовок
int
vsscanf (const char *strong, const char *format, va_list param)
Прототип Функция.
stdio.h
Ввод из ббласти памяти, первый элемент которой указан аргументом string, в соответствии с перечнем
vsscanf
шаблонов в последовательности, заданной аргументом format, набора литералов, и присвоение значений этих литералов переменным, указанным теми аргументами вызываемой функции vsscanf, которые представлены списком параметров.
РезультатЧисло значений, присвоенных указанным переменным.
Пример
Вывод надписи 13!.
/* vsscanf */
finelude<stdarg.h>
#include<std1o.h> '
matn()
{
Int Fix;
char Chr;
void input(char *,...);
1nputC'13r\ &Fix, &Chr);
printf('*%d%cM. Fix, Chr);
return 0;
}
void
input(char *Ptr....)
{
va_11st Arg;
va_start(Arg, Ptr);
vsscanf(Ptr MXd%cM, Arg);
vajend(Arg);
Valley,Valley,Valley,Valle»Valley,Valley,Valley,Valle»
Valley,
Valley,
Valley,
Valle»
Valley,
Valley,
Valley,
Valle»
Литература
Banhan М, The С Book, Addison-Wesley, Menlo Park, California, 1988.
Harbison S., Steele G., C: A Reference Manual, Prentice Hall, Englewood Cliffs, 1988.
Draft Proposed American National Standard for Information Interchange - Programming Language C, ANSI, New York, 1988.
International, Scotts Valley, California,International, Scotts Valley, California,Turbo C 2.0 - User飞 Guide, Borland
International, Scotts Valley, California,
International, Scotts Valley, California,
1988.\
TurboC 2.0 - ReferenceGuide,BorlandInternational,Scotts
California, 1988. I
TurboAssembler - UsctsGuide,BorlandInternational,Scotts
California, 1988.
Turbo Assembler - Reference Guide, Borland International, Scotts California, 1988.
Turbo Debugger - User's Guide, Borland International, Scotts
California, 1988.
OiZEyg9N86MaUa8HOiZEyg9N86MaUa8H
OiZEyg9N86MaUa8H
OiZEyg9N86MaUa8H
J
" o — zm寸 1c9小86...6V N a6。
Н⑤驚SJ需J?名冷。希當3篇?闫龍焉
3 ^?ЙЙЙЙЯЙЙЙЙЙ3332
22322^*2ййЯЙ^^«Й
iii—iiiiiiiiiiEi
JB8 XDH 3a JB5 XQH 3aJB8 XDH 3a JB5 XQH 3aJeqQ XQH Oda JequXDH 8aJeqQ XQH Oda JequXDH 8a
JB8 XDH 3a JB5 XQH 3a
JB8 XDH 3a JB5 XQH 3a
JeqQ XQH Oda JequXDH 8a
JeqQ XQH Oda JequXDH 8a
、pq jp и ■ bU・i・f*— «до
S3S33SigS2S^g^§gfe
^s^sgssssssssgsa
Illlllllll—I
京房京請送羽境。侯絵3田g,笈険
OlZEqg9cg6OIZ0寸
QQQ088S8888866666S
s н3 as н3 aу吟9186OIZEPWI I I I I Iу吟9186OIZEPWI I I I I I3SS533S-SPS!2iSf:?2jg:3SS533S-SPS!2iSf:?2jg:
s н
3 a
s н
3 a
у吟9186OIZEPW
I I I I I I
у吟9186OIZEPW
I I I I I I
3SS533S-SPS!2iSf:?2jg:
3SS533S-SPS!2iSf:?2jg:
◎ VHOGHH9HlC*尸共;2 a
<C<<<1<<<<
о — ечЕрддсообМ5s 父区異区 ooooooooooOOOOOO
©VaoaHH9Hl-УaKNO
WG导!5、場导!?导导5尊、a% =
ПРИЛОЖЕНИЕ Б. РЕДАКТОР
В отличие от других редакторов экранный редактор системы Турбо Си ориентирован на ввод текстов, а не на прием директив. В связи с этим управление операциями с текстом производится с помощью символов, не имеющих непосредственного графического представления. Такие символы называются управляющими, а их использование сводится к одновременному нажатию клавиши Ctrl и одной или двух буквенных клавиш. Поскольку при дальнейшем изложении придется очень часто ссылаться на эти симвойы, договоримся выделять управляющие символы знаком ' (каре), обозначающим нажатие клавиши Ctrl. Например, ввод с клавиатуры управляющего символа CtH-A (осуществляемый путем одновременного нажатия клавиши Ctrl и клавиши А) будет называться выполнением директивы ЛА, а ввод управляющего символа Ctrl-K-D (осуществляемый путем одновременного нажатия клавиши Ctrl и клавиш К и t>) будет называться выполнением директивы 'KD. Типичный сеанс работы с редактором начинается с активизации окна редактирования. В его ^заголовке выводится текущая информация о ходе редактирования:~ 、^
I-Лпе- номер строки, содержащей курсор,
Col- номер столбца, содержащего курсор.
Insert .- указание способа ввода символов.
Indent- указание способа размещения курсора в новой строке,
Tab- признак табуляции,
Name.ext- имя файла.
Как можно убедиться, любое нажатие клавиши приводит к появлению на экране одного символа. Этот символ появляется в позиции, занимаемой курсором. Если ввод символов производится в режиме Insert, то перед выполнением этого действия все символы в строке, начиная с символа, выделенного курсором, сдвигаются на одну позицию вправо. В режиме без Insert происходит лишь ввод символа и перемещение курсора. Перевод редактора из режима Insert в режим без Insert и обратно производится при помощи клавиши Ins.
Сразу же после нажатия клавиши Enter ^комплектация44 текущей строки текста заканчивается и происходит перемещение курсора на следующую строку. В режиме Indent курсор будет помещен под первым отличным от пробела символом предшествующей строки. Это очень удобно при подготовке программ, содержащих отступы. Перевод редактора из режима без Indent и обратно производится с помощью директивы *01.
Если при вводе текста будет нажата клавиша Tab, то курсор переместится на ближайшую позицию табулятора. Выполнение директивы РТ вызывает включение и отключение табуляции.
Ввод, изменение и удаление части текста
С точки зрения ввода текста редактор можно рассматривать как многофункциональную пишущую машинку. Эта машинка позволяет вводить символы и слова и выполнять операции над уже введенными словами. Под “словом" понимается любая последовательность символов, заканчивающаяся одним из следующих ограничителей:
пробел <>,:'"?)()[]*** + - / $
Перемещение курсора на одну позицию влево, вправо, вверх и вниз производится с помощью клавиш, обозначенных стрелками, или с помощью директив、Е, “S, "D и "X, соответствующие им клавиши образуют ромб
ТЕ
— fSD
1X
Нетрудно видеть, что директива "Е перемещает курсор на одну строку вверх, директива "X перемещает его на одну строку вниз, a "S 騒» соответственно на одну позицию влево и на одну позицию вправо. Благодаря такому решению функция директивы определяется не мнемоникой наименования ее клавиши, а положением клавиши в ромбе.
Перемещение курсора сразу на целое слово производится с помощью дополнительных директив, % н "F ( а также Ctrl— и Ctrl-* ):
Е
A SD F
X
Использование директивы *А приводит к перемещению курсора на одно слово влево, а использование директивы *F - на одно слово вправо.
Следующая пара директив “В и "С (а также PgUp и PgDn) служит для перемещения курсора соответственно в . предшествующий и последующий экраны. Клавиши этих директив расположены справа от оси, задаваемой клавишами Е-Х. Слева от этой оси расположена пара клавиш для сдвига текста, не умещающегося на экране, на одну строку: "W вниз и "Z вверх. Таким образом, схема размещения клавиш, используемых для управления положением курсора и определяющих отображаемую на экране часть текста, имеет следующий вид:
WЕR
A SD F
ZXс
Эта схема легко запоминается и не требует от пользователя» чтобы он идентифицировал клавиши по имеющимся на них надписям. Справа от рассмотренного набора клавиш находятся три клавиши директив "Т, "Y и JG, расположенные следующим образом:
ТТYGYG
Т
Т
Y
G
Y
G
Использование директивы Р вызывает удаление снм由эла, выделяемого курсором, использование директивы "Т вызывает удаление снмво}加^ начиная с символа, выделяемого курсором, и до конца слова, а использование директивы "Y ~ удаление строки, в которой находится курсор。
Приведенный перечень директив дополняют клавиши Backspace (<-) и Delete (Del). Нажатие первой из них приводит к удалению символа, находящегося слева от курсора, а нажатие второй - к удалению символа,
выделяемого курсором.
Сводка директив
TXTDFR сTXTDFR сперемещение курсора на одну строку вверх в том же столбце,
TXTDFR с
TXTDFR с
перемещение курсора на одну строку вниз в том же столбце,
перемещение курсора на одну позицию влево,
перемещение курсора на одну позицию вправо,
перемещение курсора на начало слова вправо,
пермещение окна, через которое пользователь видит документ,
• на один экран вверх,
-перемещение окна, через которое пользователь видит документ, на один экран вниз,
“W-перемещение текста на экране на одну строкувниз,
*Z-перемещение текста на экране на одну строкувверх,
*G-удаление, символа, выделяемого курсором,
ЛТ-удаление символа, выделяемого курсором, а также следующих
за ним символов данного слова,
"Y 〜удаление строки, в которой находится символ, выделяемый курсором.
Приведенный перечень директив, позволяющих отображать на экране и удалять с экрана произвольные части текста, дополнен списком директив, выполняющих функвди, которые сходны с только что описанными, но выполняются с большим “шагом". Каждая их них состоит из символа Q, непосредственно за которым следует один из символов, составляющих схему вида:
ЕR
SD
XС
Директива "QE (а также Ctrl-Home) вызывает перемещение курсора на первую строку экрана, директива "QX (а также Ctrl-End) - перемещение курсора на последнюю строку экрана, директива “QS (а также Ноте) приводит к перемещнию курсора на начало, а директива 'QD (а также End) -на конец той строки, в которой находится курсор. Остальные две
директивы - “QR и QC (соответственно Ctrl-PgUp и Ctrl-PgDn) перемещают курсор в начало и в конец текста. Перемещением курсора с помощью произвольных сочетаний перечисленных здесь директив можно пользоваться с двоякой целью: во-первых, просмотр текста для проверки его содержания и, во-вторых, переход в область, в которой необходимо внести изменения. Эти изменения могут состоять в дополнении данного текста или замене его другим текстом. Для дополнения текста достаточно ввести необходимые дополнения с клавиатуры. Редактор вставит этот текст перед символом, выделяемым курсором, одновременно сдвигая этот и следующий за ним символы. Чтобы заменить текст, можно его сначала удалить и заменить новым - путем добавления, или старый текст вытеснить новым. Второй способ ж самый лучший, потому что редко бывает, чтобы старый и новый тексты имели одну и ту же длину. Кроме того, его применение требует временного выключения режима Insert, для чего необходимо воспользоваться директивой 'V (или Ins).
Сложные операции с текстом
Рассмотренные до сих пор директивы позволяют не только создавать, но и практически произвольным образом обрабатывать документы. Тем не менее в некоторых случаях полезны операции, относящиеся к более крупным фрагментам текста, например, такие как перестановка или копирование групп соседних строк, а также замена определенных слов или предложений. Для этого предназначены директивы, рассматриваемое ниже.
Директива "QF
После выполнения этой директивы на экране появляется надпись
Find:•
т.е. запрос о той фразе, которую надлежит отыскать в тексте. Эта фраза представляет собой произвольную последовательность символов, завершающуюся символом Enter. Сразу же после нажатия клавиши Enter на экране появляется вопрос
Options:
на который следует ответить указанием режима поиска фразы.
В наиболее частом случае - поиск фразы, начиная с позиции, выделяемой курсором, в направлении конца текста - достаточно в ответ на этот вопрос нажать клавишу Enter. Если искомая фраза действительно находится в тексте, то курсор будет установлен непосредственно за последним символом найденной фразы. Как легко догадаться, применяя директиву "QF, мы пользуемся директивой контекстного редактора. Следует отметить, что среди опций, определяющих режим поиска фразы, имеются, в частности, следующие:
В - поиск назад,
W - поиск, ограниченный полными словами, U - отождествление больших и малых букв.
Кроме того, можно воспользоваться опцией, задаваемой в виде цифры. В случае указания числа п объектом поиска будет п-е вхождение заданной фразы.
Директива 'QA
Директива “QA является развитием директивы -QF. Непосредственно после ее ввода на экране также появляется вопрос о фразе, которую надлежит искать, но после нажатия клавиши Enter, завершающей ее, появляется вопрос
Replace with:
Ответом на него должна быть фраза, которая заменит фразу, указанную после Find: «После ввода этой второй фразы, также завершаемого нажатием клавиши Enter, появляется вопрос об опциях, определяющих режим поиска фразы. Кроме уже упомянутых допустимы также следующие опции:
G - замена фразы во всем тексте (тве» не с той позиции, которую указывает курсор, а с первого символа текста),
N - безусловная замена.
В случае выбора опции N директива исполняется вплоть до проведения всех замен. В противном случае всякий раз, когда находится очередное вхождение данной фразы, на экран выводится вопрос о том, следует ли проводить замену. Согласие на замену подтверждается ответом Y. При любом другом ответе данная замена не производится и начинается поиск следующего вхождения заменяемой фразы.
Директива "КВ
Выполнение директивы "КВ приводит к тому, что некоторое место в тексте обозначается как начало блока. Для определения этого блока необходимо дополнительно воспользоваться директивой “КК.
Директива ЛКК
Выполнение директивы "КК приводит к тому, что некоторое место в тексте обозначается как конец блока. Таким образом, эта директива вместе с директивой "КВ определяет блок. Как только блок определен, на экране выделяется последовательность символов текста, находящаяся между позициями курсора в моменты выполнения директив "КВ и "КК Описьпваемые далее директивы группы ЛКх относятся именно к этой части текста.
Директива “КС
Выполнение директивы "КС приводит к тому, что блок, заданный дир^стивами "КВ и 'КК, копируется на позиции, находящиеся перед символом, выделяемым курсором. После этого курсор устанавливается на первый символ скопированного текста.
Директива "KV
Выполнение директивы *KV вызывает перемещение блока, заданного директивами 'КВ и 、КК, на позиции, находящиеся перед символом, выделяемым курсором. После этой операции курсор будет установлен на первый символ перемещенного блока, который на своем новом месте остается выделенным блоком.
Директива "KY
Выполнение директивы 'KY приводит к удалению выделенного блока.
Директива "КН
Выполнение директивы “КН аннулирует признаки выделения блока.
Директива 'KR
Выполнение директивы AKR приводит к тому, что в место, выделяемое курсором, вставляется текст из файла на диске. Сразу же после ввода этой директивы на экране монитора появляется вопрос об имени этого файла
Read Block From File:
Директива"KW
Выполнение директивы “KW приводит к тому, что блок, заданный директивами 4KB и “КК, выводится в файл на диске. Сразу же после ввода этой директивы на экране монитора появляется вопрос
Write Block То File:
об имени того файла, в котором будет помещен выводимый блок. Если такой файл существует, то перед размещением в нем блока он будет удален, а затем создан вновь.
Вспомогательные директивы
Директива “N
Выполнение директивы “N приводит к тому, что в выделяемое курсором место вставляется пара символов cr-lf, т.е. вставляется новая строка.
Директива "I
Выполнение директивы 'I (или Tab) вызывает перемещение курсора в ближайшую позицию в режиме табуляции. Этой позицией является столбец с номером 1 + 8*п (1, 9, 17, 25.:.).
Директива 工
Выполнение директивы “L вызывает повторение последней из директив •QF и РА.
Директива Р
Выполнение директивы *U приостанавливает исполнение любой другой директивы (б частности "QF и AQA).
Директива ЛР
Выполнение директивы ~Р приводит к тому, что непосредственно следующий за ней символ вносится в тжст, даже если он составляет элемент директивы. В частности, при исполнении директивы "QF ввод последователБйости символов "P^M^P"J позволяет идентифицировать пару символов конца строки.
Пример
Вод с клавиатуры последовательности символов
QRsssss •
QAT MT J^P"M7sssssNGe
(е означает символ Enter, s означает пробел) приводит к перемещению всего редактируемого текста на пять столбцов вправо.
Окончание редактирования
Чтобы завершить редактирование достаточно вызвать основное меню и выбрать в нем пале File (клавиша Alt~F), а затем выбрать поле S (Save) или W (Write). В первом случае произойдет сохранение файла на диске (наряду с созданием файла с расширением .ВАК), а во втором случае произойдет запись файла с выбранным названием.
ПРИЛОЖЕНИЕ В. СИНТАКСИС
Определения синтаксических объектов мы будем давать с помощью простой нотации, принцип которой лучше всего рассмотреть на примере
одна из букв:
а b с
пара-букв:
буква буква
последовательность-букв:
буква
последовательность-букв буква
список-буквенных-последовательностей:
последовательность-букв
список-букеенных-последовательностещ последовательность-букв
Мета-имя буква означает одну из букв: а, b или с. Мета-имя пара-букв означает одно из следующих сочетаний букв: аа, ab, ас, ba, bb, be, са, cb, сс. Мета-имя последовательность-букв обозначает произвольные последовательности букв, например, ааа, ccabccabbb. Мета-имя список-буквенных-последовательностей обозначает произвольные списки, элементами которых являются последовательности букв, например список
a, bb, accbb с, ааа, сссса
Замечание: В тех редких случаях, когда элемент определения мета-имени не умещается в одной строке, он продолжается в следующей строке с отступом на два символа. В соответствии с этим соглашением определение мета-имени
список-буквенных-последовательностей
можно было бы записать в виде
список-буквенных- последовательностей: список-букв
список-буквенных-последовательностей
,последовательность-букв
Лексические единицы
Лексическая-единица: ключевое-слово идентификатор литерал оператор ограничитель
Ключевые слова
Одно из ключевых auto break case char const continue default do
слов: double intstruct
elselongswitch
enumrenter typedef
extern returnunion
floatshortunsigned
forsignedvoid
gotosizeofvolatile
ifstaticwhile
Идентификаторы
Идентификатор:片 буква идентификатор буква идентификат(^> цифра
Одна из цифр
0123456789
Литералы
Литералы:
литерал-символьный
литерал-строковый
литерал-с-фиксированной-точкой
литерал-перечислимый
литерал-с-олавающей-точкой
Литерал-символьный:
символьная-последовательность*
Символьная- последовательность:
с-символ
символьная-последователъность с-символ
с-символ:
произвольный символ, отличный от апострофа, обратной скобки и символа новой строки
описание символа
Одно из описаний-символа
Замечание: о - восьмеричная цифра, Л - шестнадцатери чная цифра
Литерал-строковый:
млитерал-строковыйм
Последовательность-строковая:
s-символ
последовательность-строковая s-символ
s-символ:
произвольный символ, отличный от кавычек, обратной cko6ki
описание-символа
Литерал-с-фиксированной-точкой:
литерал-с-фиксированной-точкой-без-суффикса
литерал-с-фиксированной-точкой-суффикс-U-L
Литерал-с-фиксированной-точкой~без-суффикса:
литерал-десятичный литерал-восьмеричный литерал-шестнадцатернчный
Литерал-десятичный:
цифра-ненулевая
литерал-десятичный цифра
Одна из цифр-ненулевых:
123456789
Литерал-восьмеричный:
О
литерал-восьмеричный цифра-восьмеричная
Одна из цифр-восьмеричных:
О 1234567
Литерал-шестнадцатеричный:
ОХ цифра-шестнадцатеричная
ОХ цифра-шестнадцатеричная
литерал-шестнадцатеричный цифра-шестнадцатеричная
Одна из цифр-шестнадцатеричных:
0123456789
а b с d е f
АВСD ЕF
Один из суффиксов -U-L:
ULuiULui UI uL LU iu IU Lu
Литерал-перечислимый:
идентификатор
Литерал-с-плавающей-точкой:
литерал-с-плавающей-точкой-без-суффикса
648Приложение В
литерал-с-плавающей-точкой-без-суффикса суффикс-F-L
Литерал-с-плавающей-точкой-без-суффикса:
часть-дробная
часть-дробная показатель-степени
часть-целая показатель-степени
Часть-дробная:
последовательность-цифр.
последовательность-цифр
последовательность-цифр . последовательность-цифр
Часть-целая:
последовательность-цифр
Последовательно€ть-ци4ч>:
цифра
последовате/Й>ность-цифр цифра
Один из суффиксов-F-L
F L f 1
Показатель-степени:
е последовательность-цифр
Е последовательность-ци4ч>
е знак последовательность-цифр
Е знак последовательность-цифр
Один из знаков:
Один из операторов:[]().->"!/%«»*:&&:!?:«=»=&=*=:=,Один из операторов:[]().->"!/%«»*:&&:!?:«=»=&=*=:=,Операторы
Один из операторов:
[]().->
"!/%«»
*:&&:!?:
«=»=&=*=:=,
Один из операторов:
[]().->
"!/%«»
*:&&:!?:
«=»=&=*=:=,
++—&*+-
<><=>==!=
=•=/=%=+=-=
### sizeof
Выражения
Примитив: идентификатсф литерал (выражение)
Последователь: примитив последователь последователь последователь последователь последователь последователь последователь
[выражение] (список-аргументов) ()
.идентификатор
-> идентификатор
++
Список-аргументов:
присвоение
список-аргументов, присвоение
Предшественник:
последсжатель
++ предшественник
—предшественник
оператор-одноаргументный обращение
sizeof предшественник
sizeof (имя-типа)
Один из операторов-одноаргументных:
Обращение:
предшественник
(имя-типа) обращение
Сомножитель:
обращение
сомножитель * обращение
сомножитель / обращение сомножитель % обращение
Слагаемое
сомножитель
слагаемое + сомножитель
слагаемое - сомножитель
Перемещение:
слагаемое
перемещение « слагаемое
перемещение » слагаемое
Отношение:
перемещение
отношение < перемещение
отношение > перемещение
отношение <= перемещение
отношение >= перемещение
Сравнение:
отношение
сравнение — отношение
сравнение != отношение
Произведение-битовое
сравнение
произведение-битовое & сравнение
Разность-битовая:
произведение-битовое
разность-битовая " произведение-битовое
Сумма-битовая:
разность-битовая
сумма-битовая : разность-битовая
Конъюнкция:
сумма-битовая
конъюнкция && сумма-битовая
Дизъюнкция:
конъюнкция
дизъюнкция » конъюнкция
Условие:
дизъюнкция
дизъюнкция ? выражение : условие
Присвоение:
условие
предшественник ситератор-присвоения присвоение
Один из операторов-присвоения:
=*=/=冲%=+=-=«»»=& 一=:=
Выражение:
присвоение
выражение, присвоение
Выражение-константа:
условие
Объявления
Объявление:
перечень-спецификаций;
перечень-спецификаций список-деклараторов-с-инициированием
Перечень-спецификаций: спецификация-класса спецификация-типа спецификация-класса перечень-спецификаций спецификация-типа перечень-спецификаций
Спецификация-класса: typedef extern static auto register
Спецификация-типа: char short int long signed unsigned float double const volatile void
спецификация-структуры-или-группы
спецификация-перечисления ммя-определяемого-типа
Список-деклараторов:
декларатор
декларатор = инициатор
список-деклараторов, декларатор
список-деклараторов, декларатсф = инициатор
Спецификация-структуры-или-группы:
struct {перечень-обьявлений-полей]
struct обозначение {перечень-обьявлений-полей}
union {перечень-объявлений-полей]
union обозначение {перечень-объявлений-полей] struct обозначение
union обозначение
Перечень-объявлений-полей:
сбъявление-поля
перечень-объявлений-полей объянление-поля
Обьявление-поля:
перечень-спецификаций-типа список-деклараторов-пс
Список-декларатороа-полей:
декларатор-поля
список-деклараторов-полей , деклара i ор-поля
Декларат(ф*-поля:
декларатор
:ширина-поля
декларатор : ширина-поля
Ширина-поля:
выражение-константа
Обозначение:
идентификатор
Спецификация-перечисления:
enum {список-перечислений}
enutn обозначение {список-перечислений}
епшп обозначение
Список-перечислений:
перечисление
список-перечисление . перечисление
Перечисление:
литерал-перечислитель
литерал-перечислитель = выражение-юэнстанта
Декларатор: субдекларатор указатель
Субдекларатор:
идентификатор
(декларатор) субдекларатор 口
субдекларатор [выражение-константа]
с^бдекларатор < )
субдекларатор <расширенный-список-типов-параметров)
субдекларатор (список-имен-прараметров>
Указатель
♦ указатель
* перечень-спецификаций-типа
* перечень-спецификаций-типа указатель
Перечень-спецификаций-типа:
спецификация-типа
перечень-спецификаций-типа спецификация-типа
Расширенный-список-типот-параметров:
void
список-типов-параметров
список-типой-парщиетров,...
Список-типов-параметров:
void
объявление-параметра
список-типов-параметров , объявление-парамечрг.
Объявление-параметра:
перечень-спвцификаций-параметра декларатор имя-типа
Список-имеи-параметров:
имя-параметра
список-имен-параметров , имя-параметра
Имя-гшраметра:
идентификатор
Имя-типа:
перечень-спецификаций-типа
перечень-спецификаций-типа псевдодекларатор
Псевдодекларатор:
указатель
псевдосубдекларатор
указатель псевдосубдекларатор
Псевдосубдекларатор:
<псевдодекларат(ф)
[】
[выражение-константа]
псевдосубдекларатор [выражение-константа]
< )
(расширенный-список-типов-параметрс®)
псевдосубдекларатор (расширенный-список-типов-параметро!
Имя-определяемого-типа:
идентификатор
Список-инициаторов:
инициатор
список-инициат(фов , инициатор
Инициатор:
присвоение
{список-инициаторов}
(список-мнициаторов J
Операции
Операция:
операция-с-меткой операция-с-выражением операция-фуппирующая операция-пустая операция-с-выбором операция-итеративная операция-управляющая
Операция-с-меткой:
метка : операция
case выражение-константа : операция default : операция
Операция-с-выражением: выражение ;
Операция-группирующая:
{)
{перечень-объяилений} (перечень-операций) {перечень-объявлеиий перечень-операций}
Перечень-объявлений: объявление перечемь-обьявлений объявление
Операция-пустая:
Операция-с~выбором:
if (выражеиие) операция
if (выражение) операция else операция
switch (выражение) операция
Операция-с-циклом:
white (выражение) операция
do операция while (выражение);
for (выражение^ выражениео; выражениео) операция
Замечание:
выражение。означает выражение, которое может быть опущено.
Операция-управляющая:
goto идентификатор;
continue;
break;
return;
return выражение;
Внешние определения
Модуль-исходный:
объ)шление-внешнее
модуль-исходный объявление-внешнее
Обьявление-внешнее:
определение-функции
объявление
Определение-функции:
заголовок-функции тело-функции
Заголовок-функции:
декларатор
перечень-спецификаций декларатор
〃екларат(ф перечень-обьявлений
перечень-спецификаций декларатор перечень-объявление
Тело-функции:
операция-группирующая
Препроцессор
Замечание:
Символом @ (at> обозначено место завершения строки.
Файл-исходный:
группа
файл-исходный группа
Группа:
подкупна
группа подгруппа
Подг^ппа:
@
последовательность-лексических-единиц @
директива-условная директива-безусловная
Последовательность-лексических-единиц:
лексическая-единица
последснвательность-лексических-единиц лексическая-единица
Директнва-условная: фраза-if фраза-endif фраза-if перечень-фраз-elif фраза-endif фраза-if фраза-else фраза-endif фраза-if перечень фраз-eilf фраза-else фраза-endif
Фраза-If:
#if выражение-константа @ группа
#if выражение-константа @
#ifdef идентификатор @ группа
#ifdef выражение-константа @
#ifndef идентификатор @ группа
#ifndef выражение-константа @
Перечень-фраз-eiif:
фраза-eiif
перечень-фраа-eiif фраза-elif
Фраза-eiif:'
#elif выражение-ксжстанта @ ipynna
#elif выражение-константа @
Фраза-else:
#else @ группа
#else @
Фраза-endif :
#endif @
Директива-безусловная:
#include〈последовательность-^ @
#inciude “последовательность" “ @
# include идентификатор @
#define макропоследовательность-лексических-единиц
define макро @
#define макро(гшраметры) последовательность-лексических-единиц @
define макро ( ) гюследовательность-лексических-единиц
#define макро(параметры)@
define макро( )@
#undef макро @
#iine последовательность-цифр литерал-стр(жотый @
#line последовательность-цифр @
#pragma последовательность-! @
#@
Последовательность-!:
символ-1
последовательность-! символ-i
Символ-i
любой СИМВОЛ, ОТЛИЧНЫЙ от @
Макро:
идентификатор
БИБЛИОТЕКИ ФУНКЦИЙ И МАКРООПРЕДЕЛЕНИЙ
Типы и макроопределения <stddef.h>
ptrdiffT size-t NULL
Диагностика <assert.h>
ndebug
void assert (int expession);
Операции над символами <ctype.h>
int
isalnum (int c);
Int
isaipha
(int
c);
Int
iscntrl (
[int c);
int
isdigit <
'int c
:);
int
isgraph
(int
c);
int
islower
(int c);
int
isprint (int c);
int
ispunct
(int
C);
int
isspace
(int
c);
int
Isupper
(int
c);
int
isxdigit
(int
c);
int
tolowa
(int
c);
int
toupper
(int
C);
Математические функции <math.h>
EDOM
ERANGE
HUGE-VAL
double acos(double x);
double asin (double x);
double atan (double x);
douWe atan2(double y, double x);
double cos (double x);
double sin (double x);
double tan (double x);
double cosh (double x);
double sinh (double x);
double tanh (double x);
double exp(double x);
double frexp (double value, int *exp);
double Idexp(double x, int exp);
double log (double x);
double loglO(doub!e x);
double modf(double x, value, double *iptr);
double pow(doub!e x, double y);
double sqrt(double x);
double ceil (double x);
double fabs(double x);
doubie floor (double x);
double fmod(double x, double y);
Возвраты vsetjmp.hA
jmp-buf
ini setjmp(jmp-buf env);
void iongjmp(jmp-buf env, int val);
Сигналы vsignaLh>
SIGABRT
SIGFPE
SIGILL
SIGINT
SIGSEGV
SIGTERM
SIG-DFL
SIG-ERR,
SIG-IGN
void (*signai(int sig, void (♦func) (int))) (int);
int kiii(int pid, int sig);
Операции над аргументами <stdarg.h>
va-iist
void va-start(va—list ap, parmN); type va-arg(va-iist ap, type);
void va-end(va—list ap);
Ввод-вывод <stdio.h>
-IOFBF
-IOLBF
-IONBF
BUFSIZ
EOF
FILE
b-tmpnam
SEEK-CUR
SEEK-END
SEEK-SET
SYS-OPEN
TMP-MAX
stderr
stdin
stdout
int remove (const char *pathname);
nt rename (const char *&d. (const char ♦new);
FILE *tmpfiie(void);
char *tmpnam(char *s);
ini fclose(FILE、tream);
int fflush (FILE ♦stream);
FILE ♦fopen (const char *pathname, const char *type);
FILE f reopen (const char *pathname, const char *type file
FILE *stream);
void setbuf(FILE *strea叫 char *buf);
int setvbuf(FILE ♦stream, char *buf. Int type, slze-t size);
ini fprintf(FILE .stream, const char *fonnat,...);
ini fscanf(FILE *stream, const char *f(Minat,...);
int printf(const char ♦format,...);
Int scanf(const char *fOTmat,...);
ini sprintf(char % const char ♦format,...);
int sscanf(const char *s, const char *fonnat,...);
int vprintf((FILE *stream, const char *format, va-list arg);
ini vprintf(const char *fc«inat, va—list arg);
int vsprintf(char *s. const char ♦format, va-list arg);
>一
ini fget(FILE *stream);
char *fgets(char *s, int n, FILE *stream);
int fputc(int c, FILE *stream);
int fputc(int c, FILE *stream);
int fputs (const char *s, FILE •stream);
int getc(FILE *streani);
int getchar(void);
char ♦getstehar *s);
int putc(int c, FILE *ctream);
int putchardnt c);
int puts (char *s);
int un^etc(int c, FILE *streain);
size—t fread(vdd *ptr, slze-t size, size—t nelem, HLE *stream);
size—t fwrite(const void *p(r, size—t size, size—t neiem, FILE ♦stream);
int fseek(FILE *stream, long offset, int ptrname);
long fteil(FILE /stream);
void rewind (FILE *stream);
void clearerr(FILE ♦stream);
int feof(FILE ♦stream);, int ferror(FILE *stream); void perror(const char *s);
Служебные /функции <stdlib.h>
RAND-MAX id J ediv—t onexii—t double atof (const char *nptr); int atoi (const char *nptr); long atoi (const char *nptr); double striod (const char *nptr, char ♦♦endptr); int strtol((const char *nptr, char **endptr, int base); ini rand (void);
void srand(unsigned int seed);
void *cailoc(sizei nelem, size—t size); void free (void *ptr);
void *malloc(size *ptr, size-t size);
void abort (vc4d);
void exiKint status);
char ♦getenv (const char *name); onexii onexit(oneKi^-t(*func) (void)); int system (const char *string);
void *bsearch(const void *key, const void *base, saze-t nel, size-t key兩ze, int(*compar) (const vdd *, const void ♦));
void qsort(void *base, size-t nei, size-t keyaze, hit(*compar) (const void *, const void ♦));
int absCint i);
idiv—t idiv(int numer, int denom); idiv—t ediv(iong numer, long denom);
Операции над последовательностями символов <string.h>
void *memcpy(void *sl, const void *s2, size-t n);
char ♦strcpytehar *sl, const char %2);
char *strncpy(char *sl, const char *s2, size-i n);
char ♦strcat (char *sl, const char *s2);
char фв1гсса1(сЬаг *sl, const char *s2, size-t n);
int memcmp(char void *sl, const void *s2, size~l n>;
int strcpm (const char *sl, snst char *s2);
ini stfhcmp(const char *sl, const char *s2. size-i n);
void *memchr(const void *s, int c, size-t n);
char *strchr(co«st char *8, Int c);
size-i strcspnr (const char *sl. const char *»2);
char *strpbrk(const char *sl, const char *s2);
char ♦strrchr(const char *s, int c);
size-t strapn(const char *sl, const char *s2);
char ♦stratr(const char *sl, const char *s2);
char ♦strtok(char *sl, const char *s2>;
void memse"vNd *s, Int c, size-1 n>;
char •strerrordnt errnum);
size-t strlen (const char *s);
Дата и время <time.h>
clk-tck
clock-t
time-t struct tm clock—1 clock (void);
time-t time (time—t *timer);
char *abctime (const struct tm *timer);
char *ctime (const time-t *fimer);
double dlffUme (time—t, tiineOl, time—t tiineO); struct tm *gmtime(const time—t ♦timer);
struct tm *locaitin)e (const time—1 *Mmer>;
ПРИЛОЖЕНИЕ『・ ГРАФИКА
Некоторые объявления, находящиеся в файлах conio.h и graphics.h (приводятся с разрешения фирмы Borland International);
/ *************************************************************
/*conio.h - selection*.
/*Direct MSDOS console input/output.
/* Copyright (c) Borland International 1987, 1988
/ ************************************************************
struci texMnfo {
unsigned char winieFt;
wintop;
winright;
winbottom; attribute;
norrnattr;
curnnode;
screenheight; screewidth;
curx;
cuiy;
епшп text-modes {LASTMODE=~1.
BW40=0, C40, BW80, C80, MONO=7}; enum COLORS {
BLACK,/♦ dark colors ♦/
BLUE, GREEN, CYAN, RED, MAGENTA, BROWN, LIGHTGRAY, DARKGRAY,/* light colors ♦/
LIGHTBLUE,•
LIGHTGREEN,
LIGHTCYAN, LIGHTRED, LIGHTMAGENTA, YELLOW, WHITE
/♦ blink bit ♦//♦ blink bit ♦/#define BLINK 128
/♦ blink bit ♦/
/♦ blink bit ♦/
extern int directvideo;
/*graphics.h - selection*/
/*Definitions for Graphics Package.*/
/*Copyright (c) Borland International1987, 1988*/
/************■■*****************»**************************** /
/"Graph result error return codes */
1 2 3 41 2 3 4enum graphics-errors { gBk grNoInitGraph = grNotDelected = r grFileNotFound =
1 2 3 4
1 2 3 4
一 grlnvalidDriver = grNoLoadMem = grNoScanMem = grNoFioodMem = grFontNotFound
grNoFontMein = -9 grfnvalidMode = -10 grError grlOerror grtnvalidFont = -13, grlnvalidFontNum grlnvalidVersion
/♦ Graphics drivers */ enum graphics- drivers { DETECT, /* requests autodetection */ CGA, MCGA, EGA. EGA64, EGAMONO, IBM8514, HERMONO, ATT400, VGA, PC3270, CURRENT-DRIVER = -1
};
/* Graphics modes for each driver */ enum graphics-mode {
CGACO= 0, /♦ 320x200 palette 0; 1 page ♦/
CGAC1=1,/♦320x200palette1;1page*/
CGAC2=2,/♦320x200palette2;1page*/
CGAC3=3,/*320x200palette3;1page♦/
CGAHI=4,/*640x2001 page♦/
MCGACO=0,/e320x200palette0;1page*/
MCGAC1=1,/♦320x200palette1;1page•/
MCGAC2=2,/电320x200palette2;1page*/
MCGAC3=3,/♦320x200palette3;1page*/
MCGAMED=4,/*640x2001 page ♦/
MCGAHI=5,/*640x4801 page ♦/
EGALO=0,/*640x20016 color 4pages♦/
EGAHI = 1, /* 640x350 16 coior 2 pages */
EGA64LO=0,/*640x20016 color 1pages♦/
EGA64HI=1,/*640x3504 color 1 pages */
EGAMONOHI = 0, /* 640x350
64K on card, 1 page ♦/ 256K on card. 4 pages ♦/
HERCMONOHI=0,/*720x3482 page♦/
ATT400C0=0,/♦320x200palette0;1page*/
ATT400C1=1,/♦320x200palette1;1page•/
ATT4O0C2=2,/♦320x200palette2;1page♦/
ATT400C3=3,/♦320x200palette3;1page♦/
ATT400MED 匸 4, /♦ 640x200 1 page ♦/
ATT400HI=5,/♦640x4001 page ♦/
VGALO-0./♦640x20016 color 4pages*/
VGAMED=1,/*640x35016 color 2pages*/
VGAHI » 2, /♦ 640x480 16 color 1 pages ♦/ PC3270HI=0,/*720x3501 pages ♦/
IBM8514LO=0,/*640x480256 colors*/
IBM8514HI= 1, /♦ 1024x768 256 colors ♦/
ъ o^ X L3>h3 a a乳 ^ 7^ ^ ^ те^ ^ & ^ ==-=-二-- =-- 一二二二二二一-=ъ o^ X L3>h3 a a乳 ^ 7^ ^ ^ те^ ^ & ^ ==-=-二-- =-- 一二二二二二一-=/* Palette CO Color Names ♦/=2,=3./* Palette Cl Color Names♦//* Palette C2 Color Names =2,V/* Palette C3 Color Names♦//* Palette CO Color Names ♦/=2,=3./* Palette Cl Color Names♦//* Palette C2 Color Names =2,V/* Palette C3 Color Names♦/2,2,
ъ o^ X L3>h3 a a乳 ^ 7^ ^ ^ те^ ^ & ^ ==-=-二-- =-- 一二二二二二一-=
ъ o^ X L3>h3 a a乳 ^ 7^ ^ ^ те^ ^ & ^ ==-=-二-- =-- 一二二二二二一-=
/* Palette CO Color Names ♦/
=2,
=3.
/* Palette Cl Color Names
♦/
/* Palette C2 Color Names =2,
V
/* Palette C3 Color Names
♦/
/* Palette CO Color Names ♦/
=2,
=3.
/* Palette Cl Color Names
♦/
/* Palette C2 Color Names =2,
V
/* Palette C3 Color Names
♦/
2,
2,
/& Colors for setpalette and setallpalette ♦/
enum COLORS { BLACK, BLUE, GREEN, CYAN, RED, MAGENTA, BROWN, LIGHTGRAY, DARKGRAY, LIGHTBLUE, LIGHTGREEN, LIGHTCYAN, LIGHTRED, LIGHTMAGENIA, YELLOW。 WHITE
.enum CGA-COLORS { CGA-LIGHTGREEN CGA-LIGHTRED CGA-YELLOW CG^-LIGHTCYAN CGA-LIGHTMAGENTA CGA-WHITE CGA-GREEN CGA-RED CGA-BROWN CGA^CYAN CGA-MAGENTA CGA-LIGHTGRAY
};
enum EGA-COLORS { EGA-BLACK EGA-BLUE EGA-GREEN EGA-CYAN EGAYED EGA-MAGENTA EGAr-BROWN EGAr-LIGHTGRAY EGA-DARKGRAY EGA-LIGHTBLUE EGA-LIGHTGREEN EGAr-LIGHTCYAN, EGA-LIGHTRED EGA-LIGHTMAGENTA EGA-YELLOW EGA^WHITE
/* Line styles for getlinestyle / setllnestyle ♦/ enum line-styles {
SOLID-LINE
DOTTED-LINE
CENTER-LINE
DASHED-LINE
USERBIT-LINE
=3,
==4,
/* User defined line style */
};
/♦ Line widths for getlineslyle / setilnestyle */
enumJlHe—widths{
NORM-WIDTH
=1.
THICK-WIDTH
=3,
);
enum font-names {
DEFAUET-FONT
=o.
/* 8x8 bit mapped font ♦/
TRIPLEX-FONT
=1«
/♦ “Stroked“ fonts ♦/
SMALL-FONT
=2,
SANSh-SERIE-FONT
=3*
GOTHIC-FONT
=4
);
#define HORfZ—DIR
0/♦ left
to right ♦/
#define VERT—DIR
0
/* bottom to top */
#define USER—CHAR-SIZE0/♦ user-defined char size */
/♦ Fill patterns for getfillstyle / setfillstyle *//♦ Fill patterns for getfillstyle / setfillstyle */enum fill—patterns { EMPTY-FILL, SOLID-FILL, LINE-FILL, LTSLASH-FILL SLASH-FILL, BKSLASH-RLL, LTBKSLASH-FILL, HATCH-FILL, XHATCH-FILU INTERLEAVE-FILL, WIDE-DOT-FILU CLOSE-DOT-FILL, USER-FILLenum fill—patterns { EMPTY-FILL, SOLID-FILL, LINE-FILL, LTSLASH-FILL SLASH-FILL, BKSLASH-RLL, LTBKSLASH-FILL, HATCH-FILL, XHATCH-FILU INTERLEAVE-FILL, WIDE-DOT-FILU CLOSE-DOT-FILL, USER-FILL/* in background color */
/♦ Fill patterns for getfillstyle / setfillstyle */
/♦ Fill patterns for getfillstyle / setfillstyle */
enum fill—patterns { EMPTY-FILL, SOLID-FILL, LINE-FILL, LTSLASH-FILL SLASH-FILL, BKSLASH-RLL, LTBKSLASH-FILL, HATCH-FILL, XHATCH-FILU INTERLEAVE-FILL, WIDE-DOT-FILU CLOSE-DOT-FILL, USER-FILL
enum fill—patterns { EMPTY-FILL, SOLID-FILL, LINE-FILL, LTSLASH-FILL SLASH-FILL, BKSLASH-RLL, LTBKSLASH-FILL, HATCH-FILL, XHATCH-FILU INTERLEAVE-FILL, WIDE-DOT-FILU CLOSE-DOT-FILL, USER-FILL
/* solid fill color ♦/
/♦fiU ♦/
/* /// fill ♦/
/♦ /// fill with thick lines ♦/
/* \\\ fill with thick lines ♦/
/* \\\ 朗*/
/* light hatch fill */
/* heavy cross hatch fill •/
/♦ Interleaving line fill ♦/
/* Widely spaced dot fill */
/♦ Closely spaced doi fill */
/♦ user defined fill ♦/
/* BitBlt operators for putimage ♦/ enum putimage—ops {
COPY-PUT, XOR-PUT. OR-PUT, AND-PUT, NOT-PUT,
/♦ MOV *//♦ XOR ♦//♦ OR ♦//♦ AND ♦//♦ NOT ♦//♦ MOV *//♦ XOR ♦//♦ OR ♦//♦ AND ♦//♦ NOT ♦//• Horizontal and vertical justification for settextjustify ♦/ enum text-just {
/♦ MOV */
/♦ XOR ♦/
/♦ OR ♦/
/♦ AND ♦/
/♦ NOT ♦/
/♦ MOV */
/♦ XOR ♦/
/♦ OR ♦/
/♦ AND ♦/
/♦ NOT ♦/
LEFT-TEXT= 0,
CENTER-TEXT= 1,
RIGHT-TEXT= 2,
BOTTOM-TEXT
/♦ CENTER-TEXT TOP-TEXT
};
#define MAXCOLORS 15
already defined above */
struct palettetype {
unsigned char size;
singed char colors [MAXCOLORS + 1];
struct linesettingstype { Int linestyle; unsigned upattern; Int thickness;
struct textsettingstype { Int fond;
Int direction; Int chardze; int horiz;
int vert;
struct fillsettingstyp^ {
Int pattern; int color;
struct pointtype { int x* y;
struct viewporttype {
Int lift, top. right, bottom; Int clip;
struct arccoordstype {
Int X, y;
int xstart, ystart, xend, yend;
Вызов Турбо Ассемблера в общем случае имеет вид
TASM filset; fileset} ...; fileset
処е каждый fileset имеет структуру
options, sourses, object, list, xref
В этой второй строке options означает возможные опции, sources - имя исходного файла или последовательность таких имен, разделенных символами + (плюЬ или пробелами, object - имя результирующего объектного файла (.OBJ), list - имя файла листинга, в котором будет помещен отчет о компиляции, a xref - имя файла, в котором будет помещен отчет о перекрестных ссылках.
В случае если ассемблер вызывается без аргументов, на экран будут выведены возможные опции, в число которых входят:
/А .- Указание упорядочить сегменты в алфавитном порядке.
Пример: /А.
/В - Опция игнорируется.
Пример: /В
/С - Внесение в отчет о компиляции таблицы перекрестных ссылок.
Пример: /С
' /D - Определение имени. Запись /Dsymbol влечет за собой определение имени symbol без присвоения ему значения, а запись /^symbol-value влечет определение имени и присвоение ему значения value.
Пример: /DSlze =20
/® - Генерирование команд, эмулирующих операции с плавающей точкой.
Пример: /Е
/Н * Вывод на экран перечня опций.
Пример: /Н
/I - Определение имени каталога вклюиаемьгх файлов. При вводе
/Т&г производится поиск файлов, включаемых в каталог dir.
Эта опция применима только к именам файлов, не составляющим маршрут. Опции /I могут входить многократно.
Пример: ^Headers
/J - Указание директивы, которая будет выполняться до начала
компиляции исходного файла. Для выполнения директивы action.
следует ввести /Saction.
П^мер: /JIdeal
/КН - Создание условий для компиляции модуля, содержащего
указанное число имен. Вводя /кНсомя* мы указываем count
имен. По умолчанию принимается соил/=8192.
П(М1мер: /КН10000
/KS - Создание условий для компиляции модуля, требующего указанной области для строк. Вводя /KSsize, мы указываем область
.размером size Кбайт. По умолчанию принимается 150 Кбайт.
■ Пример: /KS200.
/L ~ Генерация отчета о компиляции даже в том случае, если в' *
директиве компилятора отсутствует list.
Пример: /L
/LA -Вывод кода, генерируемого сегментными директивами высокого
уровня, например .MODEL и .CODE.
.Пример: /LA
/ML - Указание считать малые буквы отличными от больших.
Пример: /ML
/MU - Преобразование всех малых букв в большие.
/Пример: /MU
/МХ - Указание считать малые буквы отличными от больших, но
только в пределах внешних имен.
Пример: /МХ
/N - Указание об исключении из отчета о компиляции сведений о таблице символов.
Пример: /N
/Р - Проверка факта использования в исходном модуле команд, модифицирующих сегмент кода (посредством (.protected mode).
Пример:/Р
/R - Генерация действительных (а не эмулируемых эмулятором) команд сощюцессора.
Пример: /к
/S - Упорядочение сегментов в порядке их появления в исходном коде.
Пример: /S
/Т -Отмена сообщения о правильной компиляции.
Пример: /Т
/V -Опция игнорируется.
Пример: /V.
/W - Генерация предупредительных сообщений. При вводе /W дается
команда на генерацию таких сообщений, при вводе /W- команда на прерывание их генерации.
Пример: /W-
/X - Указание о включении в отчет о компиляции не участвовавших в компиляции ветвей условных директив.
Пример: /X
/Z - Указание о включении в сообщения об ошибках строк исходного текста, находящихся вблизи мест обнаружения ошибок.
Пример: /Z
/ZD - Указание о внесении в результирующий файл сведений о номерах строк исходного файла.
Пример: /2D
/ZI - Указание о внесении в результирующий файл полных сведений о номерах стоок и именах исходного модуля.
Пример: /ZI
В любом месте директивы компиляции может присутствовать фрагмент вида @Name9 где Name - имя файла. В этом случае находящийся в данном файле текст помещается на место фрагмента @Name. Если текст содержит более одной строки, то символы конца строки интерпретируются как символы пробелов.
Пример
Если файл OPTIONS.ASM содержит текст
/zi
/шх
то директива
tasm/1 @options.asm main
интерпретируется как директива
tasm/1 /zi /тх main
Еще одним удобством является возможность использования конфигурационного файла TASM.CFG. Заключенный в этом файле текст неявно включается в любую директиву TASM, как если бы она начиналась с @TASM.CFG・
В общем случае вызов стартера имеет вид
TD opt name args
где opt - опции, пате - имя запускаемой программы, a args - ее ар^умен- ты. Если фрагмент args пуст, то программа активизируется без apiyментов, а если пуст фрагмент opf, то применяются опции, встроенные в стартер. Каждая из опций opt начинается со знака - (минус) и отделяется от следующей опции или имени программы по крайней мере одним пробелом. Если последним символом опции также является минус /например, -vg- /, то опция исключается. Это необходимо лишь в том случае, если некоторая опция включена как постоянная, а стартер нужно вызвать без этой опции.
Опции -d
-do Программа использует основной экран, а стартер использует вспомогательный экран.
-dp Стартер использует дополнителные страницы цветной карты (принятие этой опции имеет смысл лишь в том случае, если программа не использует дополнительных страниц).
-ds Стартер запоминает в выделенной области памяти как свой экран, так и исходный экран запускаемой программы.
Опции -h и -?
-h Стартер выводит на экран пояснения, как правильно вызывать стартер,
・? Аналогично предыдущей опции.
Опция -i
i Стартер заимствует идентификаторы процессов из того же пула1), что и запускаемая программа (применение этой опции имеет смысл лишь в том случае, если Вы хотите проследить исполнение программы внутри системы DOS).
Опция 4
1 Запуск программы начинается в режиме ассемблера.
Опция -т
т п Стартеру выделяется “куиа“ размером п Кбайт (по умолчанию п = 40〉.
)Пул, накопительный блок (анпл. pooling block) - область памяти, используемая для заполнения множества коротких записей, подлежащих передаче на устройство или из устройства, для которого время доступа велико по сравнению с действительным (реальным) временем передачи данных. - Прим. ред.
Опция -г
-г
Запуск производится в условиях удаленного доступа через последовательный интерфейс (по умолчанию принимается СОМ1 и 9600 бод>.
-гр п
-rs и
Стартер пользуется портом СОМп (п « 1,2>. Стартер выбирает скорость передачи данных для п-19600бод,
для п-240Кбод,
для п=3115Кбод.
Опции
-S
-SC
Стартер не отличает в идентификаторах малых букв от больших (п^менение этой опции по отношению к программам на Турбо Паскале является излишним)»
-sdJ
Принимается, что d - это имя каталога, в котором стартер может вести поиск исходных модулей (опция -sd может использоваться многократно; каталоги просматриваются в порядке их перечисления; если такие каталоги присутствуют также в конфигурационном файле, то они просматриваются в первую очередь).
Опции -V
-V
Графический образ, сгенерированный программой, запоминается в оперативной памяти (для этого требуется дополнительно 8 Кбайт, но это необходимо, если работа стартера неблагоприятно сказывается на виде экрана).
-vn
Исключается возможность увеличения числа строк экрана (43 - EGA, 50 - VGA).
-vp
Запоминание палитры адаптера EGA.
ПРИЛОЖЕНИЕ Ж. РЕДАКТОР СВЯЗЕЙ
Вызов редактора связей в общем случае имеет вид
TLINK obj, exe, тар, lib
где obj представляет имя объективного файла или последовательность имен таких файлов, разделенных знаками + (плюс) или пробелами; ехе - имя файла, в котором будет помещена скомпонированная исполняемая программа; тар - имя файла, в котором будет помещена карта сборки, a lib 一 имя библиотеки или последовательность таких имен, разделенных знаками + (плюс) или пробелами. Если имя того или иного файла указывается без расширения, то по умолчанию для obj принимается .ЕХЕ, для тар - .МАР, для lib - .LIB. Если опущено имя того или иного файла, то для ехе и тар по умолчанию принимается такое же имя, как в файле obj. Если редактор связей вызывается без аргументов, то на экран выводится перечень его опций, к числу которых относятся:
/с - Указание различать большие и малые буквы во внешних именах. Пример: /с
/d - Указание сообщать о присутствии некоторого имени более чем в одной библиотеке.
Пример: /d
/е - Указание игнорировать расширенный словарь библиотек. Пример: /е
/i - Указание о размещении в результирующем файле заключитель ных сегментов, даже если они не содержат записей данных. Пример: /i
/1 - Указание о внесении в карту сборки сведений о номерах строк. Пример: /1
/т ・ Указание о дополнении карты сборки списком обших имен. Пример: /ш
/п - Указание об игнорировании библиотек, заданных по умолчанию. Пример: / п
/s - Указание о дополнении карты сборки перечнем общих имен и картой сегментов.
Пример: /s
/I - Указание создать из модуля, скомпилированного в модели TINY, исполняемой программы типа .СОМ, а не .ЕХЕ. Пример: /t
/v - Указание включить в файл, содержащий исполняемую программу, полных сведений о запуске.
Пример: /у
/х - Указание не генерировать карту сборки. Пример: / х
В любом месте директивы компиляции может присутствовать фрагмент вида @Name, гце Name - имя файла. В этом случае находящийся в этом файле текст вставляется на место фрагмента @Name.
Если текст содержит более одной строки, то символы конца строки ин
терпретируются как символы пробелов.
670Приложение Ж
Пример
Если файл OPTIONS.ASM содержит текст
/V
/с
то директива
Шпк /1 ©options.asm main интерпретируется как директива tasm /1 /v /с main
Конструировать многомодульные программы легче в интегрированной системе, чем в пакетном режиме, поскольку как запуск, так и компоновка результирующих моделей проводятся автоматически и в нужной очередности. В тех случаях, когда желательно пользоваться пакетным режимом, можно упростить организацию цикла запуска, состоящего из редактирования, компиляции и компоновки, обратившись к услугам программы, которую мы назовем организатором. Организатор вызывается (в простейшем случае) директивой
МАКЕ
или
MAKE -Шате
где Name - имя файла, содержащего указания по организации и макроопределения. Если директива МАКЕ используется в своей первой форме, то по умолчанию принимается опция
MAKEFILE
а если файл MAKEFILE не существует, то опция
-fMAKEFILE.MAK
Независимо от используемой директивы в файле Name помещаются указания по организации в виде
outfile9 outflle,…,outfile: Inf lie infile ... infile
action action action
где outfile - имена файлов, которые должны быть созданы автоматически с помощью организатора, каждый tn file - имя файла, от которого зависит outfile, a action - директивы DOS.
Организационная директива интерпретируется следующим образом:
если некоторое имя infile присутствует в другой, явной или неявной (см. ниже) организационной директиве, то интерпретация данной директивы прерывается с тем, чтобы интерпретировать сначала эту другую директиву;
после возможной интерпретации таких дополнительных директив проверяется существование файлов * outfile;
если хотя бы один файл outfile не существует, или если дата и время создания некоторого файла infile оказываются более поздними, чем дата создания файла outfile, то выполняются все директивы action и на этом исполнение данное организационной директивы завершается;
Замечание. Поиск директив action осуществляется в текущем каталоге, а затем в каталогах, определяемых маршрутом окружения PATH.
Пример. Организационная директива
greet.exe: greet tasm greet.asm tlink greet.obj
Если файл greet.exe “старше" файла greet, то будет выполнена компиляция файла greet.asm директивой
tasm greet.asm
а затем его сборка директивой
tlink greet.obj
Комментарии
Если в одной из строк директивы организатора присутствует символ # (хеш), то остальные символы этой строки игнорируются. Полностью игнорируются также строки, начинающиеся с такого символа.
Строки
Директивы, не умещающиеся на одной строке, могут быть продолжены. Последним символом продолжаемой строки должен быть символ \ {обратная косая). Однако продолжать таким образом комментарии не разрешается.
Директивы
Отдельные организационные директивы разделязотся пустыми строками. Требуется, чтобы слово outfile начиналось с первой позиции строки и чтобы каждому из слов action предшествовал хотя бы един символ пробела или табуляции.
Пример. Директивы организатора
main.exe : main.asm
test.asm
tasm /\ main.asm
tasm /1 test.asm
tlink main test,prog
main.obj : main.asm
tasm /t main.asm
test.obj : test.asm
tasm /t /ml test.asm
Директивы по умолчанию
Неявным расширением организационных директив являются директивы по умолчанию, следующие из правил вывода. В общем случае правило вывода имеет вид
.fromExt JoExt:
action action
action
ще ,fromExt и .toExt являются расширениями имен файлов. По определению принимается, что каждое правило вывода такого вида генерирует семейство неявных организационных директив.
name.toExt : name.fromExt
action action
action
Правила, выраженные директивами по умолчанию, применяются к тем организационным директивам, которые не содержат директив системы DOS.
Пример. Правила вывода
Если интерпретируемый файл содержит правило вывода
.pas.exe: warn
или директивы
main.exe : main.pas и
test.exe : test.pas
то эти директивы трактуются как директивы
main.exe : main.pas warn
test.exe : test.pas warn
Макроопределения и макровызовы
Использование организационных директив значительно облегчается благодаря возможности применения макроопределений и макровызовов.
Макроопределение записывается очень просто и сводится к указанию
Name = Text
тае Name - имя макроопределения, a Text - произвольный фрагмент текста, не содержащий пробелов. В результате интерпретации макроопределения текст Text связывается с именем Name. В области действия макроопределения любая запись
$(Ncifn0
заменяется текстом Text. Имя Name считается определенным вплоть до отмены директивой
lundef Name
Предварительно объявленные макроопределения
Несколько макроопределений объявлены заранее и имеют несколько отличный синтаксис. Их вызов влечет за собой вывод на экран следующей ин- формавди:
$d(Name) - цифра 1, если макроопределение Name определено, и ци$ра 0 в противном случае;
$** - маршрут и основная часть имени файла outfile;
Пример: С:\ТР\ GREET.PAS «> C:\TP\GREET
$<- полное имя файла outfile (если $< присутствует в
организавдонной директиве) или полное имя файла с расширением .fromExt (если $< присутствует в правиле вывода);
Пример: С:\ТР\ GREET.PAS => C:\TP\GREET.PAS
$:- маршрут, заключенный в имени outfile;
Пример: С:\ТР\ GREET.PAS 工> С:\ТР\
$. -полное имя файла outfile^ но без маршрута;
Пример: С:\ТР\ GREET.PAS «> GREET.PAS
$& -основная часть имени файла outfile;
Пример: С:\ТР\ GREET.PAS =а GREET
Пример. Макроопределения и макровызовы
Если интерпретируемый файл содержит директивы
.esm.obj. sni/t
uiain«obj : main.asm
то его интерпретация равнозначна ^штерпретации директивы
uiain.obj : main.asm
tasm/t main.asm
Включение файлов, условная компиляция
Организатор дает возможность использования директив включения файлов и директив условной компиляции. В общем случае директива включения файла имеет вид
!indude “Name"
@е Name - имя включаемого файла, а директива условной компиляции-вид
!if Exp
Text
lelif Expl
TeM
!elif Exp2
Text2
!elif Expn
Textn
!else
TextO
!endif
где Exp - некоторые выражения, a Text - директивы или последовательности директив.
Результатом интерпретации директивы включения файла является замена этой директивы в месте ее вхождения текстом, содержащимся в файле Name.
Интерпретация директивы условной компиляции влечет за собой замену фразы
!else
ТехЮ
фразой
lelif 1
а затем замену всей директивы в месте ее вхождения тем текстом Text, который следует после первого выражения со значением, отличным от 0.
Операторы
В выражениях могут использоваться следующие операторы:
ОператорФунк^ил
二изменение знака
отрицание значения бита
•запрещение
+сложение
-вычитание
43*умножение
деление остаток сдвиг влево сдвиг вправо логическое произведение битов логическая сумма битов сложение по модулю 2 конъюнкция дизъюнкции больше меньше
меньше или равно больше или равно равно не равно условие
(если а н 0, то условие а ? b : с имеет значение Ь; в противном случае значение с)
Пример. Директивы условной интерпретации
alpha = 4 °
!if alpha + 1 ! = 5
.asm.obj.
tasm $<
!else
/asm.obj.
tasm/t $< fendif
Результат интерпретации этих директив в точности совпадает с результатом интерпретации директив
alpha = 4
.asm.obj
tasm/t $*.ASM
Вызов организатора в общем виде производится следующим образом:
MAKE options Namef Name,…,Name
где options представляет опции, а каждое Name - имя файла, к которому будут применяться директивы, находящиеся в файле, подвергающемся интерпретации. Если в директиве МАКЕ присутствуют имена Name, то для каждого из них ^штерпретируется директива организатора, начг/нающаяся с этого имени. Если в интерпретируемом файле такая органшационная директива отсутствует, то обработка идет так, будто в его начале находилась организационная директива
Name:
677677Организатор (Менеджер)
677
677
(без inf Не м action). Это позволяет на основании правил вывода применять директивы по умолчанию.
Замечание, Правила вывода, применяемые чаще других, могут быть помещены в файл BUILTINS»MAK. Содержимое этого файла неявно включается в • начало 碗йла, подлежащего интерпретации. Перечень имеющихся опций
-а
указание проверить возвратные ссылки
-D№me
указание определить имя Name
-DName^Val
указание определить имя Name и присвоить ему значение
Vai
AName
указание интерпретаровать имя Name
-h
указание сообщить опции
ADir
указание о поиске файлов, включаемых в каталог Dir
-n
указание о выводе директив без их исполнения
-s
указание приостановить вывод исполняемых директив
-UName
указание считать имя Name не определенным.
'Замечание» Если возникает необходимость в обновлении даты создания файла, можно воспользоваться программной TOUCH. Она вызывается с помощью директивы
TOUCH filename, filename, ..., filename 夕
в которой filename 一 имена файлов. В результате с каждым из этих файлов связывается текущая дата и время. Выполнение этой операции обычно рассматривается как подготовка к выполнению программы-организатора МАКЕ.
ПРИЛОЖЕНИЕ И. ГЕНЕРАТОР
кода,Турбокода,ТурбоЧтобы дать читателю возможность познакомиться с качеством генерируемого компилятором, приведем простую программу на языке Си и ее аналог на языке Ассемблера»
кода,Турбо
кода,Турбо
Программа на языке Турбо Си
•include <stdio.h>
char Stringl[81],
String2[7];
Int Number;
int atoi(char *).
isSpace(char);
void itoa(int,char *).
digit(fTit);
main()
{
scanf("%S0sMr Stringl);
Nuiaber = atoi(Stringl);
itoa(Number,StringZ);
rintfCW. StringZ);
return 0;
int
atoi(char *s)
{
int c.val.slgc;
khile(1sSpase(*s))++s;
val « 0, sign = 1;
if(*s ” T
++s, sign = -1;
else 1f(*s == *+*)
Hh11e(isDigit(c = *s++))
val = 10 * val + c - *0*;
return sign > 0 ? val : -va】;
int
1sSpace(char c)
return c == ' *;
int
1sDigit(char c)
return c > = '0* && c < = '9';
void
itoa(int val₽ char *str)
extern char *extptr;
if(val < 0)
*str++ = •-*, val н -val;
exptr = str;
digit(val);
*extptr = '\0';
}
char *extptr;
void
digit(val)
int val;
{
int head;
1f((head « val / 10) I * 0) digit(head);
*extptr++ = val % 10 + 'O';
Программа на языке Турбо Ассемблер
ifndef
??version
?debug
macro
endm
endif
?debug S "disass ・c"
TEXT
segment
byte public 'CODE'
DGROUP
group
_DATA,_BSS
assume cs:
JEXt.ds:DGROUP,ss:DGROUP
_TEXT
ends
_DATA
segment
word public 'DATA,
label
byte
d0w
label
word
一data
ends
-BSS
segment
word public 'BSS'
label
byte
b@w
label
word
?debug
C E9704DE312086469736173732E63
?debug
CE900101D1117433A5C544332305C494E434C5544+
?debug
C 455C737464696F
Tdebug
С 2E68
『debug
CE900101D1118433A5C544332305C494E434C5544+
?debug
С 455C7374646172
?debug
С 672E68
_BSS
ends
.TEXT
segment
byte public 'CODE'
?debug
L'13
main
proc
near
;
Tdebug
L 15
mov
ax,offset DGROUP:._String 1
push
ax
push
axfoffset DGROUP:s0
push
ax
cal]
near ptr _scanf
POP
ex
pop
ex
;
?debug
L 16
lUOV
ax,offset DGROUP:_String1
push
ax
call
near ptr _atoi
POP
ex
IFOV
word ptr DGROUP:_Number,ax
?debug
L 17
mov
ax.offset DGROUP:_String2
push
ax
push
word ptr DGROUP:_Nurnber
cal]
near ptr _atoi
pop
ex
popex
?debugL 17
movax,offsetDGROLP:_String2
pushax
movax,offsetDGR0UP:_s&+5
pushax
pushwordptr DGROUP: Numbu
callnearptr _itoa
popex
popex
?debuqL 18
movax.offsetDGROJP:-Strinq2
pushax
movax.offsetDGROUP:_s&+5
pusax
cal】near ptr_prinrf
popex
popex
?debugL 19
xorax.ax
jmpshort@1
@1:
?debugL 20
ret
_main
endp
• TdebugL 23
_atoi
procnear
pushbp
movbp,sp
subspr4
pushsi
pushdi
movsifwordptr[bp+4]
?debugL 26
jmpshort@3
@5:
TdebugL 26
incsi
03:
TdebugL 26
pushwordptr[si]
callnearptr_1sSpace
popex
oraxrax
jne05
@4:
TdebugL 27
xordi.di
movwordptr[bp-2],l
?debugL 28
empbyteptr[si],45
jne@6
?debugL 29
incsi
movwordptr[bp-2]f-l
?debugL 29
jmpshort @7
06:
?debugL 30
empbyte ptr [si],43
jne Tdebug inc
©8
L 31 si
ев:
07:
Jmp
short @9
011:
Tdebug
L 33
mov
ax(di
mov
dx.10
mul
dx
add
ax.word ptr [br-4]
add
ax,-48
mov
di.ax
69:
Tdebug
L 32
mov
bx.sl
inc
si
mov
al.byte ptr [bx]
cbw
mov
word ptr [bp-4].ax
push
、ax
call
near ptr _1sOigit
POP
ex
or
ax, ax
jne
en
ею:
Tdebug
L 34
crnp
word ptr [bp-2],0
Ve
@13
mov
ax. di
613:
jmp
short @12
mov
ax.dl
neq
ax
012:
short 62
62:
Tdebug
L 35
di
si
sp,bp
bp
_atoi
_1sSpace
endp Tdebug
L 38
push
procnear
bp
mov
bp.sp
Tdebug
L 40
cmp
byte ptr[bp+4],32
jne
016
mov
ахД
jmp
short @15
ei6:
xor
axrax
015:
jmp
short 014
ей:
Tdebug
L 41
popbp
ret
-IsSpace
endp
Tdebug
L 44
JsDtglt
push
procnear
'bp
mov
bp.sp
Tdebug
L 46
cnip
byte ptr [bp+4].4S
X
@19
cnip
byte ptr [bp+4]r 57
Jg
@19
mov
ax.l
翻P
short @18
619:
xor
ax,ax
618:
浦
j叩
short 017
017:
?debug POP ret
L 47 bp
JsDIgit
endp
_1toa
?debug
L 50;
proc
near
push
bp
mov
bp,sp
push
s1 di
push
mov
di,word ptr [bp+6]
mov
s1.word ptr [bp+4]
?debug
L 53
or
st.si
Jge
621
Tdebug
L 54
・ mov
byte ptr [di].45
1nc
d1
F1OV
ax(s1
neg
ax
mov
si.ax
621:
Tdebug
L 55
mov
word ptr DGROUP: extptrvdi
;
Tdebug
L 56
push
s1
call
near ptr _d1glt
pop
ex
Tdebug
L 57
mov
bx.word ptr DGROUP:_extptr
mov
byte ptr [bx].O
820:
Tdebug
L 58
POP
POP
POP
ret
_itoa
endp
?debug
L 63
一digit
proc
near
push
bp
movbp.sp
pushsi
?debugL 67
movax,word ptr[bp+4]
-movbxr10
cwd IdWbx
movs1rax
movaxts1
orax,ax
je623
?debugL 68
pushs1
callnearptr_digit
popex
023:
?debugL 69
movax.word ptr[bp+4]
movbx,10
cwd idivbx
adddl,48
movbx.word ptr DGROUP:_extptr
movbyte ptr [bx],d1
incword ptr DGROUP:_extptr
022:
?debugL 70
popsi
popbp
ret
digit ~ТЕХТ 二BSS _Str1ngl
endp
ends
segmentword public'BSS'
labelbyte
db81 dup (?)
_Str1ng2
labelbyte
db7 dup (?)
—Number
labelword
db2 dup (?)
_extptr
labelword
db2 dup (?)
_BSS
ends ?debugС E9
DATA se
segmentword.public 'DATA'
labelbyte
db37
db56
db48
db115
db0
db37
db115
db0
_DATA _TEXT
ends
segmentbyte public 'CODE'
extrn_printf:near
extrn_scanf:near
_TEXT
ends public_isDig1t
public_extptr
public public public public public public public public endpublic public public public public public public public end
public public public public public public public public end
public public public public public public public public end
_1sSpace .Number 二 digit _ma1n _atoi _itoa _String2 一Strlngl