Инициализатор конструктора (см. "инициализатор-конструктора" в описании синтаксиса декларатора класса в таблице

Turbo C++ Programer`s guide
Первый символ должен являться буквой или символом подчеркивания Тело функции, представляющее собой коды, выполняемые при вызове функции Выражение-приведения это пустой (null) указатель Е1 является указателем, а Е2 - константой типа пустого указателя Выражение-инремента выполняет приращения одного или нескольких цикловых счетчиков Вызвать конструктор тем же образом, что и обычную функцию, нельзя. Вызов деструктора допустим только с полностью квалифицированным именем Инициализатор конструктора (см. "инициализатор-конструктора" в описании синтаксиса декларатора класса в таблице Или 16). Ноль означает по умолчанию десятичную Мы будем обозначать все семейство математических сопроцессоров 80x87 термином "сопроцессор" В режиме эмуляции 80Х87 циклический переход в регистрах, а также ряд других особенностей 80х87 не поддерживается GrOk No error Нет ошибки Кроме того, обратите внимание на то, что функция прерывания выполняет выход с помощью команды IRET (возврата из прерывания) Как идентифицировать диагностические сообщения Что происходит, когда доступ к компоненту объекта типа объединения происходит при помощи компонента другого типа Печатаемые диагностические сообщения и поведение при завершении функции assert
668870
знаков
13
таблиц
0
изображений

8. Инициализатор конструктора (см. "инициализатор-конструктора" в описании синтаксиса декларатора класса в таблице

1.12 на стр.37 оригинала) вычисляется в контексте самого внешнего блока конструктора, и поэтому разрешает ссылки на имена аргументов конструктора.

Директивы препроцессора Turbo C++

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

CPP позволяет обращение к документации по нему в диалоговом режиме.

Следующее обсуждение директив препроцессора, их синтаксис и семантика, применимы, следовательно, как к самому препроцессору CPP, так и к его функциям, встроенным в компиляторы Turbo C++.

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

Препроцессор Turbo C++ включаетв себя сложный процессор макросов, сканирующий исходный код перед обработкойего компилятором.Препроцессор обеспечивает мощные средства и гибкость, заключающиеся в следующем:

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

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

- Установка условной компиляции для улучшения мобильности получаемых кодов и для целей отладки.

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

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

Полный синтаксис препроцессора Turbo C++ показан в следующей таблице:

Синтаксис директив препроцессора Turbo C++ Таблица 1.23

файл-для-препроцессора:

группа

группа:

часть группы

группа часть-группы

часть-группы:

<лексемы-препроцессора> новая-строка

if-раздел

управляющая строка

if-раздел:

if-группа <elif-группы> <else-группа> endif-строка

if-группа:

#if выражение-типа-константы новая-строка <группа>

#ifdef идентификатор новая-строка <группа>

#ifndef идентификатор новая-строка <группа>

elif-группы:

elif-группа

elif-группы elif-группа

elif-группа:

#elif выражение-типа-константы <группа>

else-группа:

#else новая-строка <группа>

endif-строка:

#endif новая-строка

управляющая-строка:

#include лексемы-препроцессора новая-строка

#define идентификатор список-замены новая-строка

#define идентификатор левая-круглая-скобка

<список-идентификаторов>) список-замены новая-строка

#undef идентификатор новая-строка

#line <лексемы-препроцессора> новая-строка

#pragma <лексемы-препроцессора> новая-строка

#pragma warn действие сокращение новая-строка

#pragma inline новая-строка

? новая-строка

действие: одно из

+ - .

сокращение:

amb ampapt aus big cincpt

def dupelf mod par piapro

rch retrng rpt rvf sigstr

stu stvsus ucp use volzst

левая-круглая-скобка:

символ левой круглой скобки без предшествующих пробельных символов

список-замены:

<лексемы-препроцессора>

лексемы-препроцессора:

имя-заголовка (только для директивы #include)

идентификатор (без различения ключевого слова)

константа

строковый-литерал

операция

пунктуатор

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

имя-заголовка:

<последовательность-символов-заголовка>

последовательность-символов-заголовка:

символ-заголовка

последовательность-символов-заголовка символ-заголовка

символ-заголовка:

любой символ из исходного множества символов, за исключением символа новой-строки (\n) или символа "больше чем" (>).

новая-строка:

символ новой строки

Пустая директива #

Пустая директива состоитиз строки, вкоторой содержится единственныйсимвол #. Эта директива всегда игнорируется препроцессором.

Директивы #define и #undef

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

Простые макросы #define

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

#define идентификатор_макроса <последовательность_лексем>

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

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

Пустая последовательность лексем позволяетэффективное удаление всех найденных идентификаторов макросов из исходного кода:

#define HI "Добрый день!"

#define empty

#define NIL ""

...

puts(HI); /* расширяется в: puts("Добрый день!"); */

puts(NIL); /* расширяется в: puts(""); */

puts("empty"); /* расширения empty не происходит ! */

/* расширение empty не будет выполнено и в комментариях! */

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

#define GETSTD #include <stdio.h>

...

GETSTD /* ошибка компиляции */

GETSTD будет расширен в #include<stdio.h>. Однако, препроцессор не станет сам обрабатывать эту вполне допустимую в других условиях директиву, а передаст ее в таком виде компилятору. Компилятор воспримет#include <stdio.h> как недопустимый ввод. Макрос не может быть расширен во время собственногорасширения. Поэтому выражения типа #define A A недопустимы вследствие неопределенности результата.

Директива #undef

Можно отменить определение макроса при помощи директивы #undef:

#undef идентификатор_макроса

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

Макрорасширения внутри строк #undef не выполняются.

Состояние определенности и неопределенности является важным свойством идентификатора, независимо от его фактического определения. Условные директивы препроцессора #ifdef и #ifndef, которые служат для проверки того, является ли идентификатор в текущий момент определенным, или нет, представляют собой гибкий механизм управления многими аспектами компиляции.

После того, как идентификатор макроса стал

неопределенным, он может бытьдалеепереопределендирективой

#define, с использованием той же самой или другой последовательности лексем.

#define BLOCK_SIZE 512

...

buff = BLOCK_SIZE*blks; /* расширяется в: 512*blks */ ...

#undef BLOCK_SIZE

/* использование BLOCK_SIZE теперь невозможно - это "неизвестный" препроцессору идентификатор */

...

#define BLOCK_SIZE 128 /*переопределение размера блока*/

...

buf = BLOCK_SIZE*blks; /* расширяется в: 128*blks */

...

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

#ifndef BLOCK_SIZE

#define BLOCK_SIZE 512

#endif

Если идентификатор BLOCK_SIZE в текущий момент определен, то средняя строка не обрабатывается препроцессором; в противном же случае выполняется определение средней строки.

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

Программисты, привыкшие работать на языке ассемблера, должны преодолеть желание написать:

#define BLOCK_SIZE = 512 /* почему последовательность лексем включает символ = */

Опции -D и -U

Определение и отмена определения идентификаторов выполняется также при помощи опций компилятора командной строки - D и -U (см. Главу 4,"Компилятор командной строки" в Руководстве пользователя). Идентификаторы могут быть определены, но не могут бытьявно отменены, при помощи меню интегрированной среды разработки Options \! Compiler \! Defines (см. Главу 1,"Справочник по интегрированнойсредеразработки", также в Руководстве пользователя.)

Командная строка

tcc -Ddebug=1; paradox=0; X -Umysym myprog.c

эквивалентна помещению в программу строк:

#define debug 1

#define paradox 0

#define X

#undef mysym

Ключевые слова и защищенные слова

Допустимо, но не рекомендуется, использовать ключевые слова Turbo C++ в качестве идентификаторов макросов:

#define int long /* допустимо, но может привести к катастрофическим последствиям */

#define INT long /* допустимо и, вероятно, полезно */

Следующие предопределенные глобальные идентификаторы не могут появляться непосредственно следом за директивами #defineили #undef:

__STDC__ __DATE__

__FILE__ __TIME__

__LINE__

Отметим наличие в этих именах ведущих и хвостовых двойных символов подчеркивания.

Макросы с параметрами

Для определения макросов с параметрами используется следующий синтаксис:

#define идентификатор_макроса(<список-аргументов>) последовательность-лексем

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

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

Вызов таких макросов выполняется записью

идентификатор-макроса<пробельный-символ>(<список-фактическихаргументов>)

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

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

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

#define CUBE(x) ((x)*(x)*(x))

...

int n,y

n = CUBE(y):

дает в результате следующую замену:

n = ((y)*(y)*(y));

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

#define SUM ((a) + (b))

...

int i,j,sum;

sum = SUM(i,j);

при расширении даст sum = ((i)+(j)). Причина кажущегося избытка круглых скобок станет очевидной, если рассмотреть пример:

n = CUBE(y+1);

Без внутренней пары круглых скобок в определении расширение даст запись: n=y+1*y+1*y+1, что при лексическом анализе равно:

n = y + (1*y) + (1*y) + 1; // если y не равен 0 или -3, то в // куб возводится (y+1) !

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

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

1. Вложенные круглые скобки и запятые:

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

#define ERRMSG(x, str) showerr("Error",x,str)

#define SUM(x,y) ((x) + (y))

...

ERRMSG(2, "Press Enter, then Esc");

// расширится в: showerr("Error",2,"Press Enter, then Esc"); */ return SUM(f(i,j), g(k.l));

// расширится в: return ((f(i,j)) + (g(k,l))); */

2. Склеивание лексем при помощи ##: можно выполнить склеивание (слияние) двух лексем, разделив их символами ## (и плюс опциональными пробельными символами с каждой стороны). Препроцессор удаляет пробельные символы и##, объединяядве отдельные лексемыв одну новуюлексему. Это средство можно использовать для конструированияидентификаторов; например, выполнив определение

#define VAR(i,j) (i##j)

и затем вызвав VAR(x,6), можно получить расширение (x6). Этот метод заменяет старый (не обеспечивающий мобильность кода) метод использования (i/**/j).

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

#define TRACE(flag) printf(#flag "=%d\n",flag)

фрагмент кода

int highval = 1024;

TRACE(highval);

станет равным

int highval = 1024;

printf("highval" "= %d\n", highval);

что в свою очередь будет рассматриваться как

int highval = 1024;

printf("highval=%d\n", highval);

4 Символ обратной наклонной черты для продолжения строки: длинная последовательность лексем может продлитьстрокупри помощи обратной наклонной черты (\). Символы обратной наклонной черты и новой строки оба вырезаются, и в результате образуется фактическая последовательность лексем, используемая в расширении:

#define WARN "фактически это одно\

строчное сообщение"

...

puts(WARN);

/* на экране будет: фактически это однострочное сообщение */

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

int cube(int x) (*

return x*x*x;

*)

#define CUBE(x) ((x)*(x)*(x))

...

int b =0, a = 3;

b = cube(a++);

/* cube() передается фактический аргумент = 3; поэтому b = 27, и теперь a = 4 */

a = 3;

b = CUBE(a++);

/* расширяется в: ((a++)*(a++)*(a++)); и теперь a = 6 */

Итоговое значение b зависит от того, что компилятор делает с расширенным выражением.

Включение файлов директивой #include

Директива #include подключает к исходному коду заданные в ней файлы, известные как включаемые файлы, файлы заголовковили заголовки. Синтаксис этой директивы имеет три формы:

#include <имя_заголовка>

#include "имя_заголовка"

#include идентификатор_макроса

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

Третий вариант записи предполагает, что ни символ <, ни символ " не являются первым не-пробельным символом, следующим за #include; кроме того, предполагается, что существует такое макроопределение, которое расширит идентификатор макроса в допустимое, следующее за разделителем имя заголовка в формате либо <имя_заголовка>, либо "имя_заголовка".

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

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

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

Различиемежду форматами <имя_заголовка> и "имя_заголовка" заключается в алгоритме поиска включаемого файла, применяемом в каждом случае; эти алгоритмы описаны в следующих двух разделах.

Поиск файла заголовка при формате <имя_заголовка>

Вариант <имя_заголовка>задает стандартный включаемый файл; поиск последовательно выполняется во всех включаемых директориях в той последовательности, в которой они определены. Если ни в одной из этих директорий по умолчанию искомый файл не найден, то выдается сообщение об ошибке.

Поиск файла заголовка при формате "имя_заголовка"

Вариант "имя_заголовка" задает включаемый файл, создаваемый пользователем; сначала выполняется его поиск в текущей директории (обычно в той директории, в которой находится исходный компилируемый файл). Если там файл не найден, то поиск продолжается во всех включаемых директориях, как в случае формата <имя_заголовка>.

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

#include <stdio.h>

/* заголовок из стандартной включаемой директории */

#define myinclude"c:\tc\include\mystuff.h"

/* Примечание: здесь допустимы одинарные символы обратной

наклонной черты; в операторе С пишется:

"c:\\tc\\include\\mystuff.h" */

#include myinclude

/* макрорасширение */

#include "myinclude.h"

/* макрорасширение отсутствует */

После расширения второй оператор#include заставит препроцессор искать нужный файл в C:\TC\INCLUDE\mystuff.h, и нигде более. Третий пример #includeзаставляет препроцессор выполнить поискmyinclude.h сначала в текущей директории, а затем во включаемых директориях.

Условная компиляция

Turbo C++ поддерживаетусловную компиляцию путем замены соответствующих строк исходного кода пустой строкой. Игнорируемые таким образом строки это те строки, что начинаются с символа # (за исключением директив #if, #ifdef, #ifndef, #else, #elif и #endif), а также любые строки, которые в результате выполнения директив не должны компилироваться. Все директивы условной компиляции должны завершаться в том же исходном или включаемом файле, где находится их начало.

Директивы условной компиляции #if, #elif, #else и #endif

Директивы условной компиляции #if, #elif, #else и #endif работают аналогично обыкновенным условным операторам

С.Они используются следующим образом:

#if выражение-1-типа-константы

<раздел-1>

<#elif выражение-2-типа-константы новая-строка раздел-2>

...

<#elif выражение-n-типа-константы новая-строка раздел-n>

<#else последний-раздел>

#endif

...

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

В случае "истина" после обработки раздела-1 препроцессором управление передается соответствующейдирективе #endif (которая заканчивает даннуюусловную конструкцию) и продолжается в следующем-разделе. В случае "ложь" управление передается следующей строке #elif (если она определена в данной конструкции),где вычисляетсявыражение-2-типа-константы. В случае "истины" обрабатывается раздел-2, после чего управление передается соответствующей директиве #endif, и т.д.,до тех пор, пока не будет достигнута последняя директива #else или #endif. Опциональная директива #else используется в качестве альтернативного условия в том случае, если все предыдущие проверки дали значение "ложь". Последовательность условных директив заканчивается директивой #endif.

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

Итоговым результатом вышеописанного сценария является то, что для дальнейшей обработки передается только один раздел (возможно, пустой). Опущенныеразделы служат только для отслеживания возможных вложенных условных конструкций, так что каждая директива #if должна обязательно иметь соответствующую ейзавершающую директиву #endif.

Проверяемые выражения-типа-константы при вычислении должны давать целочисленную константу.

Операция defined

Операция defined дает альтернативный, более гибкий способ проверки того, определены ли комбинации идентификаторов, или нет. Данная операция допустима только в выражениях #if и #elif.

Выражение defined(идентификатор)или defined идентификатор (скобки необязательны) дает 1 (истина), если данное символическое имя было ранее определено (при помощи директивы # defined) иэто определение не было впоследствии отменено (при помощи #undef); в противном случае оно дает 0 (истина). Поэтому директива

#if defined(mysym)

это то же, что

#ifdef mysym

Преимущество заключается в том, что можно использовать defined циклически в сложном выражении, следующем за директивой #if, например

#if defined(mysym) && !defined(yoursym)

Условные директивы #ifdef и #ifndef

Условные директивы #ifdef и #ifndef позволяют проверить, определен лив текущий момент данный идентификатор, то есть была ли обработана предыдущаядиректива #define для данного идентификатора и продолжает ли она действовать в текущий момент.

Строка

#ifdef идентификатор

имеет точно такой же эффект, что и

#if 1

если идентификатор в текущий момент определен, и такой же эффект, что и

#if 0

если идентификатор в текущий момент не определен.

#ifndef, напротив, дает значение "истина", если идентификатор "не определен", поэтому строка

#ifndef идентификатор

имеет точно такой же эффект, что и

#if 0

если идентификатор в текущий момент определен, и такой же эффект, что и

#if 1

если идентификатор в текущий момент не определен.

Синтаксис следует синтаксису директив #if, #elif, #else и #endif, описанному в предыдущем разделе.

Идентификатор, определенный как имеющий пустое (NULL) значение, считается определенным.

Директива управления нумерацией строк #line

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

#line целочисленная-константа <"имя-файла">

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

/* TEMP.C: пример директивы #line */

#include <stdio.h>

#line 4 "junk.c"

void main()

(*

printf(" in line %d of %s",__LINE__,__FILE__);

#line 12 "temp.c"

printf("\n");

printf(" in line %d of %s",__LINE__,__FILE__);

#line 8

printf("\n");

printf(" in line %d of %s",__LINE__,__FILE__);

*)

Включение stdio.h означает, что на выходе препроцессора будет нечто большее.

Если запустить TEMP.C через CPP (cpp temp), то на выходе получится файл TEMP.I, который выглядит так:

temp.c 1:

c:\borland\tc\cpp\include\stdio.h 1:

c:\borland\tc\cpp\include\stdio.h 2:

c:\borland\tc\cpp\include\stdio.h 3:

...

c:\borland\tc\cpp\include\stdio.h 212:

c:\borland\tc\cpp\include\stdio.h 213:

temp.c 2:

temp.c 3:

junk.c 4: void main()

junk.c 5: (*

junk.c 6: printf(" in line %d of %s",6,"junk.c");

junk.c 7:

temp.c 12: printf("\n");

temp.c 13: printf(" in line %d of %s",13,"temp.c");

temp.c 14:

temp.c 8: printf("\n");

temp.c 9: printf(" in line %d of %s",9,"temp.c");

temp.c 10: *)

temp.c 11:

Если вызатем компилируете TEMP.C, то получится следующий выход:

in line 6 of junk.c

in line 13 of temp.c

in line 9 of temp.c

Макросы расширяются в аргументах #line, как в директивах #include.

Прежде всего назначение директивы #line заключается в использовании ее в утилитах, имеющих на выходе коды С, а не в кодах, создаваемых человеком "вручную".

Директива #error

Директива #error имеет следующий синтаксис:

#error сообщение-об-ошибке

Директива генерирует сообщение:

Error: имя-файла номер-строки : Error directive: сообщение

Данная директива обычно встраивается в условные конструкции препроцессора, которые отслеживают какие-либо нежелательные условия времени компиляции.Обычноэто условие "ложно". Если условие "истинно", то компилятор может выдать сообщение об ошибке и прекратитьработу. Для этого директива# error помещается в условную ветвь, которая дает для искомого нежелательного условия результат "истина".

Например, вы определили #define MYVAL, принимающую значения 0 или 1. Затем можновключить в исходный код условную директиву, которая будет проверять MYVAL на предмет неверного значения:

#if (MYVAL != 0 && MYVAL != 1)

#error MYVAL must be defined to either 0 or 1

#endif

Директива #pragma

Директива #pragma позволяет использовать специфичные для конкретных реализаций директивы в форме

#pragma имя-директивы

При помощи #pragma Turbo C++позволяет определить любые желаемые директивы, не обращаясь дляэтогок другим, поддерживающим их компиляторам. Если компилятор не поддерживает данное имя-директивы, то он просто игнорируетдирективу #pragma, не выдаваяпри этом никаких сообщений об ошибкахили предупреждений.

Turbo C++ поддерживает следующие директивы #pragma:

- #pragma argsused

- #pragma exit

- #pragma inline

- #pragma option

- #pragma saveregs

- #pragma startup

- #pragma warn

Директива #pragma argsused

Директива #pragma argsused допустима только между определениями функций и действует только на следующую функцию. Она отменяет сообщение уровня предупреждения:

"Parameter name is never used in function имя-функции" ("имя параметра нигде не используется в функции имя-функции")

Директивы #pragma exit и #pagma startup

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

Синтаксис этих директив следующий:

#pragma exit имя-функции <приоритет>

#pragma startup имя-функции <приоритет>

Заданное имя-функции должно относиться к ранееобъявленной функции, не принимающей аргументов и возвращающей значение void; другими словами, эта функция должна быть объявлена как:

void func(void);

Опциональный параметр приоритет должен являться целым числом в диапазоне от 64 до 255. Старшим приоритетом является 0. (Приоритеты от 0 до 63 используются библиотеками С и не должны использоваться пользователем). Функции со старшими приоритетами вызываются первыми при загрузке программы и последними при выходе из нее. Если приоритет не задан, то по умолчанию он равен 100. Например,

#include <stdio.h>

void startFunc(void)

(*

printf("Startup function.\n");

*)

#pragma startup startFunc 64

/* приоритет 64 --> вызывается при загрузке первой */

void exitFunc(void)

(*

printf("Wrapping up execution.\n");

*)

#pragma exit exitFunc

/* приоритет по умолчанию равен 100 */

void main(void)

(*

printf(This is main.\n");

*)

Отметим, что имя функции, используемой в #pragma startupили exit, должно быть определено (или объявлено) до того,как встретится соответствующая строка с директивой #pragma.

Директива #pragma inline

Данная директиваэквивалентна опции компилятора командной строки -B или соответствующей опции интегрированной среды Turbo. Она сообщаеткомпилятору, что программа содержит встроенные ассемблерные коды (см. главу 6, "Интерфейс с языком ассемблера"). Синтаксис ее следующий:

#pragma inline

Эту директиву лучше всего помещать вверху файла, поскольку, встретив директиву #pragma inline, компилятор перезапускает себя с опцией -B. Фактически можно опустить и опцию -В, и директиву #pragma inline, и компилятор тем не менее выполнитперезапуск, когда встретит операторы asm. Назначение опции и директивы состоит в том, чтобы сэкономить время компиляции.

Директива #pragma option

Директива #pragma option используетсядля включения опций компилятора командной строки в код вашей программы. Синтаксис этой директивы следующий:

#pragma option [опции...]

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

Ниже приводятсяопции,которые не могут находиться в директиве pragma option:

-B (компиляция с использованием ассемблерных кодов)

-c (компиляция без компоновки)

-dxxx (определение макроса)

-Dxxx = ccc (определение макроса с текстом)

-efff (имя .EXE-файла fff)

-lfff (имя включаемой директории)

-Lfff (имя директории с библиотекой)

-lxset (опция компоновщика x)

-M (создание при компоновке .MAP-файла)

-o оверлеи

-Q EMS

-S (создание на выходе .ASM-файла и остановка)

-Uxxx (отмена определения макроса)

-V (virtual)

-Y (оверлеи)

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

Использование имени макроса, начинающегося двумя символами подчеркивания (которое может являться именем встроенного макроса), в директивах #if, #ifdef, #ifndef или #elifизменяет состояние компилятора на состояние кодирования.

Появление первой реальной лексемы (первого объявления

С) также изменяет состояние компилятора на кодирование.

Другими словами, можноиспользовать директивы #pragma, # include, #define и некоторые разновидности #if во время состояния лексического анализакомпилятора. Во время этой фазы вы имеете возможность при помощи #pragma option изменять опции командной строки.

В числоопций,которые могут быть заданы в #pragma option только в состоянии лексического анализа компилятора, входят:

-Efff (строка с ассемблерным именем)

-f* (любая опция плавающей точки, кроме -ff)

-l# (значащие символы идентификатора)

-m* (любая опция модели памяти)

-nddd (выходная директория)

-offf (имя выходного файла fff)

-u (использование символов подчеркивания в именах cdecl)

-z* (опция задания любого имени сегмента)

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

-1 Управление набором команд

-2 Управление набором команд

-a Управление выравниванием. (Отметим, что выравнивание компонентов структурыустанавливается в точке определения структуры, а не далее, при использовании этой структуры объектами.)

-ff Управление быстрыми операциями с плавающей точкой

-G Генерация кода, оптимизированного по быстродействию

-k Стандартное управление стековым фреймом

-N Управление контролем стека

-O Управление оптимизацией

-P Установка по умолчанию соглашений о связях Pascal

-r и -rd Управление регистровыми переменными

-v Управление отладкой по действиям

-y Управление строчной информацией

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

-A Управление ключевыми словами

-C Управление вложенностью комментариев

-d Слияние повторяющихся строк

-gn Остановка компиляции после n предупреждений

-jn Остановка компиляции после n ошибок

-K Тип char устанавливается как unsigned

-wxxx Предупреждение (то же самое, что и #pragma warn)

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

Директива #pragma saveregs

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

Директива #pragma warn

Данная директива позволяет переопределять конкретные опции командной строки -wxxx (или управлять опцией Display Warnings в диалоговом поле Options \! Compiler \! Messages).

Например, если в вашем исходном коде имеются директивы

#pragma warn +xxx

#pragma warn -yyy

#pragma warn .zzz

то выдача предупреждения xxx будет разрешена (даже если в меню Options \! Compiler \! Messages она была переведена в состояние off), предупреждения yyy запрещена, а статус выдачи сообщения zzz будет восстановлен в то состояние, которое было к моменту начала компиляции файла.

Полный список трехбуквенных сокращений и сообщений, к которым они относятся, см. в Главе 4, "Компилятор командной строки" в Руководстве пользователя.

Предопределенные макросы

Turbo C++ имеет следующие предопределенные глобальные идентификаторы. За исключением __cplusplus, каждое из них и начинается, и заканчиваетсядвумя символами подчеркивания (__). Эти макросы также называют буквальными константами.

__CDECL__

Данный макрос специфичен для Turbo C++. Он сообщает о том, что флаг -p не использовался (меню Cflling Conventions...C) : он устанавливается равным целочисленной константе 1, если -pне использовался; в противном случае он неопределен.

Следующие символические имена определяются согласно выбранной во время компиляции модели памяти:

__COMPACT__ __MEDIUM__

__HUGE__ __SMALL__

__LARGE__ __TINY__

Для конкретной компиляции определенным является только один из этих макросов; прочие, по определению, не определены. Например, если при компиляциивыбрана модель памяти small, то макрос __SMALL__ определен, а остальные неопределены, поэтому директива

#if defined(__SMALL__)

даст значение "истина", а

#if defined(__HUGE__)

либо любая другая из оставшихся) даст значение "ложь". Фактическое значение любого из этих макросов, когда он определен, равно 1.

__cplusplus

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

__DATE__

Данный макрос дает дату начала обработки препроцессором данного исходного файла (в виде строкового литерала).

Каждое включение __DATE__ в данный файл дает одно и то же значение, независимо от того, сколько времени продолжается обработка файла препроцессором. Дата имеет форму mmmddyyyy,где mmm это месяц (Jan, Feb и т.д.), dd равно числу месяца (от 1 до 31, причем если это число меньше 10, то первый символ d равен пробелу), а yyyy это год (1990, 1991 и т.д.)

__FILE__

Данныймакрос дает имя текущего обрабатываемого препроцессором исходного файла (в виде строкового лите-

рала). Когда препроцессор обрабатывает директиву #include

или #line, либопри завершении обработки включаемого файла,

данный макрос соответствующим образом меняет свое значение.

__LINE__

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

__MSDOS__

Данный макрос специфичен для Turbo C++. Он дает целочисленную константу 1 для всех случаев компиляции.

__OVERLAY__

Данный макрос специфичен для С++. Он предопределен равным 1, еслимодуль компилируетсяс опцией -Y (включена поддержка оверлейных структур). Если оверлейные структуры не поддерживаются, то данный макрос неопределен.

__PASCAL__

Данный макрос специфичен для С++. Он сообщает о том, чтобыл использован флаг -p. Макрос установлен равным целочисленной константе 1, если флаг -p использовался; в противном случае он неопределен.

__STDC__

Данный макрос определен равным константе 1, если компиляция выполняется при установленном флаге совместимости с ANSI (-Aили менюANSI Keywords Only...On); в противном случае макрос неопределен.

__TIME__

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

Как и в случае макроса __DATE__, каждое включение __TIME__ будет содержать одно и то же значение, независимо от того, сколько времени продолжалась обработка файла. Он имеет формат hh:vv:ss, где hh это часы (от 00 до 23), mm это минуты (от 00 до 59), а ss это секунды (от 00 до 59).

__TURBOC__

Данный макрос специфичендля С++. Он дает номер текущей версии TurboC++ ввиде шестнадцатиричной константы. Например, версия 1.0 будет представлена в виде 0x0100.

Глава 2. Перекрестные ссылки по библиотеке исполняющей системы

Данная глава содержит обзор библиотечных подпрограмм Turbo C++ и включаемых файлов.

В данной главе

- объясняется, зачем вам могут понадобиться исходные коды библиотеки исполняющей системы Turbo C++

- перечисляются и описываются файлы заголовка

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

Turbo C++ поставляется с более чем 450 функциями и макросами, которые вы можете вызыватьиз своей программы для выполнения широкого круга задач, включая задачи ввода/вывода как высокого, так и низкого уровня, манипуляции с потокамии файлами, распределенияпамяти, преобразования данных, математических вычислений имногиедругие. Эти функции и макросы, называемые библиотечными подпрограммами, подробно описаны в Справочнике по библиотеке.

Подпрограммы Turbo C++содержатся в библиотечных файлах (Cx.LIB, CPx.LIB, MATHx.LIB и GRAPHICS.LIB). Поскольку TurboC++ поддерживает шесть различных моделей памяти, каждая модель, за исключением модели tiny, имеет свой собственный библиотечный файл и файл математических функций, в которых находятся версии этих подпрограмм специально для соответствующей модели памяти. (Модель tiny использует одни файлы с моделью small).

В С++ всегда нужно использовать прототипы. Дополнительную информацию о прототипах функций см. на стр.60 оригинала).

Turbo C++ является реализацией последнего стандарта ANSI C, который, помимо всего прочего, позволяет (и усиленно рекомендует) задавать прототипы функций для используемых в вашей программе на С подпрограмм.

Библиотечные подпрограммы Turbo C++ объявляются со своими прототипами в одном или более файлов заголовка.

Зачем нужен доступ к исходным кодам библиотеки исполняющей системы

Библиотека исполняющей системы Turbo C++ содержит свыше 450 функций, относящихся к широкому диапазону задач: управление IBM PC на нижнем уровне, интерфейс с DOS, ввод/вывод, управление обработкой, манипуляции со строками и памятью, математические вычисления, сортировка и поиск, и т.д. Существует несколько веских причин, по которым вам может понадобиться доступ к исходным кодам этих функций:

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

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

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

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

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

По всем этим причинам, а также по многимдругим, вам может понадобитьсядоступк исходным кодам библиотекиисполняющей системы Turbo C++. Поскольку фирма Borland придерживается принципа "открытой архитектуры", мы предоставляем возможность лицензированного доступа к исходным кодам библиотеки исполняющей системы Turbo C++. Все, что вам нужно для этого сделать,это заполнить бланк, поставляемый с пакетом Turbo C+ +, приложить платежный чек, и вам будутвысланы исходные коды библиотеки исполняющей системы Turbo C++.

Файлы заголовка Turbo C++

Файлы заголовка, определяемые стандартом ANCI C, соответственно обозначены на полях. Файлы заголовка С++ также обозначены на полях слева.

Файлы заголовка, называемые также включаемыми файлами, содержат объявления прототипов библиотечных функций. В них также находятся определения типов данных и символических имен констант библиотечных функций, а также глобальные переменные, определяемые TurboC++ и библиотечными функциями. Имена файлов заголовка и их содержимое в библиотеках Turbo C ++ следуют стандарту ANSI C.

alloc.h Объявляет функции управления памятью (распре-

деление и отмена распределения памяти и т.д.)

ANSI C assert.h Определяет отладочный макрос assert

C++ bcd.h Определяет класс С++ bcd и перегруженные опе-

рации для класса bcd и математические функции

для bcd

bios.h Объявляет различные функции, используемые при

вызове подпрограмм ROM BIOS IBM PC

C++ complex.h Объявляет комплексные математические функции С++

conio.h Объявляет различные функции, используемые при

вызове подпрограмм DOS ввода/вывода с консоли

ANSI C ctype.h Содержит информацию, используемую макросами символьной классификации и символьных преобразований (такими, как isalpha и toascii)

dir.h Содержит структуры, макросы и функции для

работы с директориями и путями доступа

dos.h Определяет различные константы и содержит объявления, необходимые при вызовах DOS и специальных вызовах 8086

ANSI C errno.h Определяет мнемонические константы кодов

ошибок

fcntl.h Определяет символические константы, исполь-

зуемые совместно с библиотечной подпрограммой

open

ANSI C float.h Содержит параметры подпрограмм обработки чисел с плавающей точкой.

C++ fstream.h Объявляет классы потоков С++, поддерживающие ввод-вывод в файлы

C++ generic.h Содержит макрос для объявлений родовых файлов

graphics.h Объявляет прототипы графических функций

io.h Содержит структуры и объявления подпрограмм

ввода/вывода низкого уровня

C++ iomanip.h Объявляет манипуляторы ввода/вывода потоков С++ и содержит макрос для создания параметри-

зованных манипуляторов

C++ iostream.h Объявляет подпрограммы (ввода/вывода) потоков базового (версии 2.0) С++

ANSI C limits.h Содержит параметры среды программирования, информацию об ограничениях времени компиляции, а также численные диапазоны интегральных типов

ANSI C locale.h Объявляет функции, содержащие информацию, специфичную для конкретной страны и языка

ANSI C math.h Объявляет прототипы математических функций; определяет макрос HUGE_VAL и объявляет структуру исключения, используемую подпрограммой matherr

mem.h Объявляет функции манипулирования памятью.

(Многие из них также определены в string.h)

process.h Содержит структуры и объявления для функций

spawn... и exec...

ANSI C setjmp.h Определяет тип jmp_buf, используемый функциями

longjmp и setjmp, и объявляет подпрограммы

longjmp и setjmp

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

работающих с разделением файла

ANSI C signal.h Определяет макросы, используемые для чтения списков аргументов функций, объявленных как принимающие переменное число аргументов (например, vprintf, vscanf и т.д.)

ANSI C stddef.h Определяет несколько общих типов данных и макросов

ANSI C stdio.h Определяет типы данных и макросы, необходимые для пакета стандартного ввода/вывода (Standard I/O Package), определенного Керниганом и Ритчи и расширенного в Системе UNIX V.

Определяет предопределенные потоки стандартного ввода/вывода stdin, stdout, stdprn и stderr, а также объявляет подпрограммы ввода/ вывода уровня потоков

C++ stdiostr.h Объявляет классы потоков С++ для использования в файловых структурах stdio FILE.

ANSI C stdlib.h Объявляет некоторые широко используемые подпрограммы: подпрограммы преобразования, подпрограммы поиска/сортировки и прочие

C++ stream.h Объявляет подпрограммы (ввода/вывода) потоков С++ (версии 1.2)

ANSI C string.h Объявляет несколько подпрограмм строковых манипуляций и манипуляций с памятью

C++ strstrea.h Объявляет классы потоков С++ для работы с байтовыми массивами в памяти

sys\stat.h Объявляет символические константы, используемые при открытии и создания файлов

sys\timeb.h Объявляет функцию time и структуру timeb,

возвращаемую time

sys\types.h Объявляет тип type_t, используемый функциями

времени

ANSI C time.h Определяет структуру, заполняемую подпрограммами преобразования времени asctime, localtime и gmtime, а также тип, используемый подпрограммами ctime, difftime, gmtime, localtime и stime; также содержит прототипы этих подпрограмм.

values.h Определяет важные константы, включая машинозависимые константы; обеспечивает совместимостью с системой UNIX V

Категории библиотечных подпрограмм

Библиотечные подпрограммы Turbo C++выполняют большое количество различныхзадач.В данном разделе перечислены все подпрограммы, а также включаемые файлы, в которых они объявлены, разбитые на несколько общих категорий по выполняемым задачам. Полную информацию по перечисленным ниже функциям см.в главе 1 "Библиотека исполняющей системы" Справочника по библиотеке.

Подпрограммы классификации ------------------------------

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

isalnum (ctype.h) isascil (ctype.h) isdigt (ctype.h)

isalpha (ctype.h) iscntrl (ctype.h) isgraph (ctype.h)

islower (ctype.h) ispunct (ctype.h) isupper (ctype.h)

isprint (ctype.h) isspace (ctype.h) isxdigit(ctype.h)

Подпрограммы преобразования -----------------------------

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

atof (stdlib.h) itoa (stdlib.h) _tolower (ctype.h)

atof (stdlib.h) itoa (stdlib.h) tolower (ctype.h)

atof (stdlib.h) strtod (stdlib.h) _tolower (ctype.h)

ocvt (stdlib.h) strtol (stdlib.h) tolower (ctype.h)

fcvt (stdlib.h) strtcul (stdlib.h) ultoa (stdlib.h)

gcft (stdlib.h) toascil (ctype.h)

Подпрограммы управления директориями-----------------------

Эти подпрограммы манипулируют директориями и именами пути доступа.

cndir(dir.h) fnsplit (dir.h) mkdir (dir.h)

findfirst (dir.h) getcurdir (dir.h) mktemp (dir.h)

findnext(dir.h) getcwd (dir.h) rmdir (dir.h)

fnmerge(dir.h) detdisk (dir.h) searchpath(dir.h)

setdisk (dir.h)

Диагностические подпрограммы-------------------------------

Эти подпрограммы реализуют встроенные средства поиска ошибки.

assert(assert.h)

matherr(math.h)

perror(errno.h)

Графические подпрограммы --------------------------------

Эти подпрограммы позволяют создавать экранные графические представления с текстовой частью.

arc (graphics.h) fillellipse (graphics.h)

bar (graphics.h) fillpoly (graphics.h)

bar3d (graphics.h) floofill (graphics.h)

circle (graphics.h) getarccoords (graphics.h)

cleardevice (graphics.h) getaspectratio (graphics.h)

clearviewport(graphics.h) getbkcolor (graphics.h)

closgraph (graphics.h) getcolor (graphics.h)

detectgraph (graphics.h) getdefaultpallette(graphics.h)

drawpoly (graphics.h) getdrivername (graphics.h)

ellipse (graphics.h) getfillpattern (graphics.h)

getfillsettings (graphics.h) outtext (graphics.h)

getgraphmode (graphics.h) outtextxy(graphics.h)

getimage (graphics.h) pieslice (graphics.h)

getfinesettings (graphics.h) pufimage (graphics.h)

getmaxcolor (graphics.h) pulpixel (graphics.h)

getmaxmode (graphics.h) rectangle(graphics.h)

getmaxx (graphics.h) registerbgidriver(graphics.h)

getmaxy (graphics.h) registerbgifont (graphics.h)

getmodename (graphics.h) restorecrtmode (graphics.h)

getmoderange (graphics.h) sector (graphics.h)

getpalette (graphics.h) settaffpalette (graphics.h)

getpixel (graphics.h) setaspectratio (graphics.h)

gettextsettings (graphics.h) setbkcolor (graphics.h)

getviewsettings (graphics.h) setcolor (graphics.h)

getx (graphics.h) setcursortype (conio.h)

gety (graphics.h) setfillpattern (graphics.h)

graphdefaults (graphics.h) setfillstyle (graphics.h)

grapherrormsg (graphics.h) setgraphbufsize (graphics.h)

_graphfreemem (graphics.h) setgraphmode (graphics.h)

_graphgetmem (graphics.h) setlinestyle (graphics.h)

graphresult (graphics.h) setpalette (graphics.h)

imagesize (graphics.h) setrgbpalette (graphics.h)

initgraph (graphics.h) settextjunistify (graphics.h)

installuserdriver(graphics.h)settexttyle (graphics.h)

installuserfont (graphics.h)setusercharsize (graphics.h)

line (graphics.h)setviewport (graphics.h)

linerel (graphics.h)setvisualpage (graphics.h)

lineto (graphics.h)setwritemode (graphics.h)

moverei (graphics.h)textheight (graphics.h)

moveto (graphics.h)textwidth (graphics.h)

Подпрограммы ввода/вывода --------------------------------

Эти подпрограммы реализуют средства ввода/вывода на уровне потоков и DOS.

access (io.h)creatnew (io.h)

cgets (conio.h)creattemp (io.h)

_chmod (io.h)cscanf (conio.h)

chmod (io.h)dup (io.h)

chsize (io.h)dup2 (io.h)

clearerr (stdio.h)eof (io.h)

_close (io.h)fclosse (stdio.h)

close (io.h)fcloseali (ctdio.h)

cprintf (conio.h)fdopen (stdio.h)

cputs (conio.h)foof (stdio.h)

_creat (io.h)ferror (stdio.h)

creat (io.h)fflush (stdio.h)

fgetc (stdio.h)printf (stdio.h)

fgetchar (stdio.h)putc (stdio.h)

fgetpos (stdio.h)putch (conio.h)

fgets (stdio.h)putchar (stdio.h)

fllelength (io.h)puts (stdio.h)

flleno (stdio.h)putw (stdio.h)

flushall (stdio.h)_read (io.h)

fopen (stdio.h)read (io.h)

fprintf (stdio.h)remove (stdio.h)

fputc (stdio.h)rename (stdio.h)

fputchar (stdio.h)rewind (stdio.h)

fputs (stdio.h)scanf (stdio.h)

fread (stdio.h)setbuf (stdiio.h)

freopen (stdio.h)setcursortype (conio.h)

fscanf (stdio.h)setftime (io.h)

fseek (stdio.h)setmode (io.h)

fsetpos (stdio.h)setvbuf (stdio.h)

fstat (sys\stat.h)sopen (io.h)

ftell (stdio.h)sprintf (stdio.h)

fwrite (stdio.h)sscanf (stdio.h)

getc (stdio.h)stat (sys\stat.h)

getch (conio.h) _strerror (string.h,stdio.h)

getchar (stdio.h) strerorr (stdio.h)

getche (conio.h) tell (io.h)

getftime (io.h) tmpfile (stdio.h)

getpaus (conio.h) tmpnam (stdio.h)

gets (stdio.h) ungetc (stdio.h)

getw (stdio.h) ungetch (conio.h)

iocti (io.h) unlock (io.h)

isatty (io.h) vfprintf (stdio.h)

kbhit (conio.h) vfscanf (stdio.h)

lock (io.h) vprintf (stdio.h)

iseek (io.h) vscanf (stdio.h)

_open (io.h) vsprintf (stdio.h)

open (io.h) vsscanf (io.h)

perror (stdio.h) _write (io.h)

Подпрограммы интерфейса --------------------------------- (DOS, 8086, BIOS)

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

absread (dos.h) bioskey (bios.h) dosexterr (dos.h)

abswrite (dos.h) bioskey (bios.h) enable (dos.h)

bdos (dos.h) biosprint (bios.h) FP_OFF (dos.h)

bdosptr (dos.h) biostime (bios.h) FP_SEG (dos.h)

bioscom (bios.h)country (dos.h) freemem (dos.h)

blosdisk (bios.h)ctrlbrk (dos.h) geninterrupt(dos.h)

biosequip(bios.h)disable (dos.h) getcbrk (dos.h)

getdfree (dos.h) int86 (dos.h) poke (dos.h)

getdta (dos.h) int86x (dos.h) pokeb (dos.h)

getfat (dos.h) intdos (dos.h) randbrd (dos.h)

getfatd (dos.h) intdosx (dos.h) randbwr (dos.h)

getpsp (dos.h) intr (dos.h) segread (dos.h)

getvect (dos.h) keer (dos.h) setcbrk (dos.h)

getverity(dos.h) MK_FP (dos.h) setdta (dos.h)

harderr (dos.h) outport (dos.h) setvect (dos.h)

hardresume(dos.h)outportb (dos.h) setverity (dos.h)

hardretn(dos.h)parsfnm (dos.h) sleep (dos.h)

inport(dos.h)peek (dos.h) unlink (dos.h)

inportb(dos.h)peekb (dos.h)

Подпрограммы манипуляции --------------------------------

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

memccpy(mem.h,string.h) stricmp(string.h)

memchr(mem.h,string.h) stricmpi(string.h)

memcmp(mem.h,string.h) sprien(string.h)

memcpy(mem.h,string.h) striwr(string.h)

memicmp(mem.h,string.h) stncat(string.h)

memmoye(mem.h,string.h) stncmp(string.h)

memset(mem.h,string.h) strncmpi(string.h)

movedata(mem.h,string.h) strncpy(string.h)

movmem(mem.h,string.h) strnicmp(string.h)

setmem(mem.h) strnset(string.h)

stpcpy(string.h) strpbrk(string.h)

strcat(string.h) strrchr(string.h)

strchr(string.h) strrev(string.h)

strcmp(string.h) strset(string.h)

strcoll(string.h) strspn(string.h)

strcpy(string.h) strstr(string.h)

strcspn(string.h) strtok(string.h)

strdup(string.h) strupr(string.h)

strerror(string.h) strxfrm(string.h)

Математические подпрограммы ----------------------------- Эти подпрограммы выполняют математические вычисления и

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

abs (complex.h,stdlib.h) atof(stdlib.h,math.h)

acos (complex.h,math.h) atoi(stdlib.h)

arg (complex.h) atol(stdlib.h)

asin (complex.h,math.h) bcd(std.h)

atan (complex.h,math.h) cabs(math.h)

atan2 (complex.h,math.h) ceil(math.h)

clear87 (float.h) ltoa(stdlib.h)

complex (complex.h) _matherr (math.h)

conj (complex.h) matherr(math.h)

_control(float.h) modf(math.h)

cos (complex.h,math.h) norm(complex.h)

cosh (complex.h,math.h) polar(complex.h)

div (math.h) poly(math.h)

ecvt (stdlib.h) pow(complex.h,math.h)

exp (math.h) pow10(math.h)

fabs (math.h) rand(stdlib.h)

fcvt (stdlib.h) random(stdlib.h)

floor (math.h) randomize(stdlib.h)

fmod (math.h) real(complex.h)

_fpreset(float.h) _rotl(stdlib.h)

frexp (math.h) _rotr(stdlib.h)

gcvt (stdlib.h) sin(complex.h,math.h)

hypot (math.h) sinh(complex.h,math.h)

imag (complex.h) sqrt(complex.h,math.h)

itoa (stdlib.h) srand(stdlib.h)

labs (stdlib.h) _status87(float.h)

ldexp (math.h) strtod(stdlib.h)

ldiv (math.h) strtol(stdlib.h)

log (complex.h,math.h) strtoul(stdlib.h)

log10 (complex.h,math.h) tan(complex.h,math.h)

_lrotl (stdlib.h) tanh(complex.h,math.h)

_lrotr (stdlib.h) ultoa(stdlib.h)

Подпрограммы управления памятью -------------------------

Эти подпрограммы обеспечивают динамическое распределение памяти для моделей данных small и large

allocmem (dos.h) farrealloc (alloc.h)

brk (alloc.h) free (alloc.h,

calloc (alloc.h) stdlib.h)

coreleft (alloc.h, heapcheck (alloc.h)

stdlib.h) heapcheckfree (alloc.h)

farcalloc (alloc.h) heapcheckknode (alloc.h)

farcoreleft (alloc.h) heapwalk (alloc.h)

farfree (alloc.h) malloc (alloc.h,

farheapcheck (alloc.h) stdlib.h)

farheapcheckfree(alloc.h) realloc (alloc.h,

farheapchecknode(alloc.h) stdlib.h)

farheapfllfree (alloc.h) sbrk (alloc.h)

farheapwalk (alloc.h) setblock (dos.h)

farmalloc (alloc.h)

Разные подпрограммы -------------------------------------

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

delay (dos.h) setjmp (setjmp.h)

localeconv (locale.h) setlocale (locale.h)

longjmp (setjmp.h) sound (dos.h)

nosound (dos.h)

Подпрограммы управления процессами ----------------------

Эти подпрограммы запускают и завершают выполнение одних процессов из других.

abort (process.h) execvp (process.h) spawnl (process.h)

execl (process.h) execvpe(process.h) spawnle (process.h)

execle (process.h) _exit (process.h) spawnlp (process.h)

execlp (process.h) exit (process.h) spawnlpe(process.h)

execlpe(process.h) getpid (process.h) spawnv(process.h)

execv (process.h) reise (signal.h)spawnve (process.h)

execve (process.h) signal (signal.h)spawnvp (process.h)

spawnvpe(process.h)

Стандартные подпрограммы --------------------------------

Эти подпрограммы являются стандартными.

abort (stdlib.h) exit (stdlib.h)malloc(stdlib.h)

abs (stdlib.h) fcvt (stdlib.h)putenv(stdlib.h)

atexit (stdlib.h) free  (stdlib.h)qsort(stdlib.h)

atof (stdlib.h) gcvt (stdlib.h)rand(stdlib.h)

atol (stdlib.h) getenv (stdlib.h)realloc (stdlib.h)

atol (stdlib.h) itoa (stdlib.h)srand(stdlib.h)

bsearch(stdlib.h) labs (stdlib.h)stdtod(stdlib.h)

calloc (stdlib.h) lfind (stdlib.h)strtol(stdlib.h)

ecvt (stdlib.h) lsearch(stdlib.h)swab(stdlib.h)

_exit (stdlib.h) itoa (stdlib.h)system(stdlib.h)

Подпрограммы вывода на дисплей текстовых окон -------------

Эти подпрограммы выводят текст на экран.

clreol (conio.h) gotoxy (conio.h)

clrscr (conio.h) highvideo (conio.h)

delline (conio.h) insline (conio.h)

gettext (conio.h) lowvideo (conio.h)

gettextinvo(conio.h) movetext (conio.h)

normvideo (conio.h) textcolor (conio.h)

puttext (conio.h) textmode (conio.h)

necursortype (conio.h) wherex (conio.h)

textattr (conio.h) wherey (conio.h)

textbackground(conio.h) window (conio.h)

Подпрограммы времени и даты -----------------------------

Эти подпрограммы предназначены для преобразований и манипуляций временем и датой.

asctime (time.h) mktime (time.h)

ctime (time.h) setdate (dos.h)

difftime (time.h) settime (dos.h)

dostounix (dos.h) stime (time.h)

ftime (sys\timeb.h)strftime (time.h)

getdate (dos.h) time (time.h)

gettime (dos.h) tzset (time.h)

gmtime (time.h) unixtodos (dos.h)

locoltime (time.h)

Подпрограммы для обработки переменного списка аргументов

Эти подпрограммы используютсядля доступа к переменным спискам аргументов (например, vprintf и т.д.).

va_arg (stdarg.h)

va_end (stdarg.h)

va_stsrt (stdarg.h)

Глава 3 Потоки С++

Данная глава содержит краткий обзор ввода/вывода потоков С++. Ввод/вывод потоков в С++используется для преобразования типизированных объектов в читаемый текст, и обратно. Он позволяет определять функции ввода/вывода, которые затем автоматически используются применительно к соответствующим определенных пользователем типам. Последующие примеры находятся в Главе 5, "Основы С++" документа "Начало работы"; приводимая там же библиография предлагает несколько названий книг для углубленного изучения данного примера.

Новые потоки вместо старых

Turbo C++ поддерживает как старую библиотеку С++ stream, так и новую усовершенствованную библиотеку iostream С++ версии 2.0. Возможность работы с обеими версиями поможет вам, если у вас имеются программы, написанные по старым соглашениям, и вы желаете использовать Turbo C++ для перехода к более эффективным потокам ввода/вывода версии2.0. Мы настоятельно рекомендуем вампри создании новых программ пользоваться библиотекой iostream версии 2.0. Приводя некоторые материалы, необходимые дляперехода к потокам версии 2.0 (начиная со стр.184 оригинала), данная глава главным образом посвящается классам иправилам потоков iostream версии 2.0.

Использование потоков 2.0

Усовершенствованные потоки iostream версии 2.0, хотя и обеспечивают по большей части совместимость для старой версии С++, предлагают тем не менее новые возможности, связанные с использованием множественного наследования и прочими средствами, появившимися в С++ версии 2.0.

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

Концепция потоков С++ нацелена на решение нескольких проблем, решаемых стандартными библиотечнымифункциями ввода/ вывода С, такими какprintfи scanf. Последние, разумеется остаются доступными для программиста, работающего в С++, но улучшенная гибкость и элегантность потоков С++ уменьшают привлекательность функций библиотеки stdio.h. Классы, связанные с потоками С++, предлагают вам расширяемые библиотеки, позволяющие вам выполнять форматированный ввод/выводс контролемтипов какдля предопределенных, так и для определяемых пользователем типов данных спомощью перегруженных операцийи прочих объектно-ориентированных методов.

Для обращения к вводу/выводу потоком ваша программа должна включать файл iostream.h. Для некоторых функций потоков требуются и другие файлы заголовка. Например, для выполнения форматирования в оперативной памяти с использованием классов istrstream и ostrstream необходим файл strstream.h. Файл заголовка strstream.h включает также iostream.h. Если вам требуется класс fstream, включите файл fstream.h,такжевключающий iostream.h. И разумеется, можно включить одновременно и fstream.h, и strstream.h.

Что такое поток?

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

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

Библиотека iostream

Библиотека iostream имеет два параллельных класса: streambuf и ios. Оба они являются классами низкого уровня и каждый выполняет свой круг задач.

streambuf

Класс streambufобеспечивает общие правила буферизации и обработки потоков в тех случаях, когда не требуется значительного форматирования этих потоков. streambuf представляет собой удобный базовый класс, используемый другими частями библиотеки iostream, хотя он доступен также и для производных классов в ваших функциях и библиотеках. Большинство функций-компонентов (правил) streambuf являются встраиваемыми для обеспечения максимальной эффективности. Классы strstreambuf и filebuf являются производными от streambuf.

ios

Класс ios (и следовательно, производные от него классы) содержит указатель на streambuf.

ios имеет два производных класса: istream (для ввода) и ostream (для вывода). Другой класс, iostream, является производным классом сразуот istream иostream вследствие множественного наследования:

class ios;

class istream : virtual public ios;

class ostream : virtual public ios;

classiostream : public istream, public ostream;

Кроме того, существуеттри класса withassign, являющихся производными классами от istream, ostream и iostream:

class istream_withassign : public istream;

class ostream_withassign : public ostream;

class iostream_withassign : public iostream;

Классы потоков

- Класс ios содержит переменные состояния для интерфейса с streambuf и обработки ошибок.

- Класс istream поддерживает как форматированные, так и неформатированные преобразования потоков символов, извлекаемых из streambuf.

- Класс ostream поддерживает как форматированные, так и неформатированные преобразования потоков символов, помещаемых в streambuf.

- Класс iostream объединяет классы istream и ostream для двунаправленных операций, в которых один поток действует и как источник, и как приемник.

- Производные классы withassign обеспечивают четыре предопределенных "стандартных" потока: cin, cout, cerr и clog, описываемые в следующем разделе. Классы withassign добавляют к соответствующим базовым классам операции присвоения, следующим образом:

class istream_withassign : public istream (*

istream_withassign();

istream& operator=(istream&);

istream& operator=(streambuf*);

*)

и аналогично для ostream_withassign и

iostream_withassign.

Классом потока называется любой класс, производный от классов istream и ostream.

Четыре стандартных потока

Программы С++ начинаются с четырьмя предопределенными открытыми потоками, объявленными как объекты классов withassign в iostream.h следующим образом:

extern istream_withassign cin;

extern ostream_withassign cout;

extern ostream_withassign cerr;

extern ostream_withassign clog;

Их конструкторывызываются всякий раз при включении iostream.h, но фактическая инициализация выполняется только один раз.

Четыре стандартных потока выполняют следующее:

cin Стандартный ввод (дескриптор файла 0)

(Соответствует stdin)

cout Стандартный вывод (дескриптор файла 1) (Соответствует stdout)

cerr Стандартный вывод ошибок (дескриптор файла 2). cerr буферизуется поблочно; очистка буфера происходит при каждой новой вставке

(Соответствует stderr)

clog Данный поток представляет собой полностью буферизуемую версию cerr.

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

Вывод

Вывод потока осуществляетсяоператором вставки,или помещения, <<. Для операций вывода перегружаетсястандартная операция сдвига влево <<. Ее левый операнд представляет собой объект типа класса ostream. Правый операнд может иметь любой тип, для которого определен вывод потоком (подробнее об этом говорится ниже). Вывод потоком определен для встроенных типов. Операция<<, перегруженнаядля типа type, называется вставкойэтого типа. Например,

cout << "Hello!\n";

записывает строку "Hello!" в cout (стандартный поток вывода, который обычно направлен на экран), после чего следует новая строка. Здесь << - это строка вставки типа char*.

Операция << обладает ассоциативностью слева и возвращает ссылку на объект ostream, для которого она вызывалась.Это позволяет организовать каскадные вставки:

void function_display(int i, double d)

(*

cout << "i=" << i << ", d=" << d << "\n";

*)

Это вызовет вывод чего-либо вроде:

i = 8, d = 2.34

на стандартное устройство вывода.

Отметим, что перегрузка не изменяет нормального приоритета выполнения операции <<, поэтому можно записать:

cout << "sum = " << x+y << "\n";

без круглых скобок. Однако, в случае

cout << (x&y) << "\n";

круглые скобки нужны.

Встроенные типы

Типы вставок, поддерживаемые непосредственно,это : char (signed и unsigned), short (signed иunsigned), int (signed и unsigned), long (signed и unsigned), char* (рассматриваемый как строка), float, double, long double и void*. Интегральные типы преобразовываются по правилам, по умолчанию действующим для printf (еслиэти правила не изменены путем установки различных флагов ios).Например, если заданы объявления int i; long l;, то следующие два оператора

cout << i << " " << l;

printf("%d %ld, i, l);

приведут к одному и тому же результату.

Аналогичным образом, типы сплавающей точкой преобразовываются правилам умолчания для printf с преобразованием %g. Итак, в случае объявления double d;, операторы

cout << d;

printf("%g", d);

дают один и тот же результат.

Вставка указателя (void*) также предопределена:

int i = 1;

cout << &i; // указатель выводится на дисплей в шестнадцати// ричном формате

Вставка char работает следующим образом:

char ch = 'A';

cout << ch; // на дисплей выводится А

Функции put и write

Для вывода двоичных данных или отдельного символа можно использовать функцию-компонент put, объявленнуюв ostream следующим образом:

ostream ostream::put (char ch);

При объявлении int ch='x'; следующие две строки эквивалентны:

cout.put(ch);

cout << (char)ch;

Функция-компонент writeпозволяет вывод больших по размеру объектов:

ostream& ostream::write(const signed char* ptr, int n);

ostream& ostream::write(const unsigned char* ptr, int n);

Функции write выводят nсимволов (включая любые входящие пустые символы) в двоичномформате. В отличие от строковой вставки, write не прекращает работу, встретив пустой символ. Например,

cout.write((char *)&x, sizeof(x))

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

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

Форматирование вывода

Форматирование ввода и вывода определяется различными флагами состояний формата, перечисленными в классе ios. Эти состояния определяются битами числа типа long int следующим образом:

public:

enum (*

skipws = 0x0001, // пропуск пробельного символа на вводе

left = 0x0002, // вывод с левым выравниванием

right = 0x0004, // вывод с правым выравниванием

internal = 0x0008, // заполнитель после знака или

// указателя системы счисления

dec = 0x0010, // десятичное преобразование

oct = 0x0020, // восьмеричное преобразование

hex = 0x0040, // шестнадцатиричное преобразование

showbase = 0x0080, // показать на выходе указатель

// системы счисления

showpoint = 0x0100, // показать позицию десятичной точки

// (на выходе)

uppercase = 0x0200, // вывод шестнадцатиричных значений

// буквами верхнего регистра

showpos = 0x0400, // показать знак "+" для положительных

// чисел

scientific = 0x0800, // использовать запись чисел с плава-

// ющей точкой с выводом экспоненты Е

// например, 12345E2

fixed = 0x1000, // использовать запись чисел с плава-

// ющей точкой типа 123.45

unitbuf = 0x2000, // стирание всех потоков после вставки

stdio = 0x4000, // стирание stdout и stderr после

// вставки

*);

Разумеется, этифлаги наследуются производными классами ostream и istream. Приотсутствии специальных действий пользователяфлагиустанавливаются таким образом, чтобы выполнялось показанное впримерах выше форматирование по умолчанию. Существуют функции, позволяющие установке,проверку и сбросфлаговформата, как по отдельности, так и связанными группами. Некоторые флаги автоматически очищаются после каждого ввода/ вывода.

Основание системы счисления при преобразованиях

По умолчанию вставкаинтегральных типов выполняется в десятичной записи. Это можно изменить соответствующими установками флагов ios::dec, ios::oct и ios::hex (см. раздел "манипуляторы"). Есливсе эти флаги равнынулю (по умолчанию), то вставка выполняется в десятичном формате.

Ширина

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

int ios::width(int w); // устанавливает поле ширины в w

// и возвращает предыдущую ширину

int ios::width(); // возвращает текущую ширину --

// не внося никаких изменений

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

int i = 123;

int old_w = cout.width(6);

cout << i; // на выводе будет bbb123, где bbb =

// пробелы. Затем ширина устанавлива-

// ется равной 0

cout.width(old_w); // восстановление предыдущей ширины // поля

Отметим, что после каждой форматированной вставки ширина очищается в ноль, так что в

int i, j;

...

cout.width(4);

cout << i << " " << j;

i будет представлена минимум четырьмя символами, однако пробел в середине выражения и j будут представлены минимально необходимым числом символов.

Манипуляторы

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

cout << setw(4) << i << setw(6) << j;

эквивалентно более широкой записи

cout.width(4);

cout << i;

cout.width(6);

cout << j;

setw представляет собой параметризованный манипулятор, объявлениекоторого находится в iomanip.h. Прочие параметризованные манипуляторы, setbase, setfill, setprecision, setiosflags и resetiosflags, работают аналогичнымобразом (см таблицу 3.1). Для того, чтобы использовать эти манипуляторы, ваша программа должна включать iomanip.h. Вы можете писать свои собственные манипуляторы, без параметров:

ostream& dingy( ostream os)

(*

return os << "\a\a";

*)

...

cout << i << dingy << j;

Манипуляторы с параметрами более сложны и требуют включения iomanip.h.

Манипуляторы Таблица 3.1

Манипулятор Синтаксис Действие

dec outs<<dec Установка флага форма-

ins>>dec тирования с десятичными

преобразованиями

hex outs<<hex Установка флага форма-

ins>>hex тирования с шестнадцати-

ричными преобразованиями

oct outs<<oct Установка флага форма-

ins>>oct тирования с восьмеричными

преобразованиями

ws ins>>ws Извлечение пробельных

символов

endl outs<<endl Вставка символа новой

строки и очистка потока

ends outs<<ends Вставка оконечного

пустого символа в строку

flush outs<<flush Очистка ostream

setbase(int) outs<<setbase(n) Установка системы счис-

ления при преобразованиях с основой n (0, 8,


Информация о работе «Turbo C++ Programer`s guide»
Раздел: Информатика, программирование
Количество знаков с пробелами: 668870
Количество таблиц: 13
Количество изображений: 0

Похожие работы

Скачать
14945
0
7

... к сожалению, обратное утверждение не верно. C++ Builder содержит инструменты, которые при помощи drag-and-drop действительно делают разработку визуальной, упрощает программирование благодаря встроенному WYSIWYG - редактору интерфейса и пр. Delphi — язык программирования, который используется в одноимённой среде разработки. Сначала язык назывался Object Pascal. Начиная со среды разработки Delphi ...

Скачать
225728
6
0

... ориентированы на 32 разрядные шинные архитектуры компьютеров с процессорами 80386, 80486 или Pentium. Фирма Novell также подготовила варианты сетевой ОС NetWare, предназначенные для работы под управлением многозадачных, многопользовательских операционных систем OS/2 и UNIX. Версию 3.12 ОС NetWare можно приобрести для 20, 100 или 250 пользователей, а версия 4.0 имеет возможность поддержки до 1000 ...

Скачать
49224
0
9

... завдання поширюється на розробку системи обліку зареєстрованих автомобілів в ДАІ, призначеної для збору, зберігання, а також полегшення для доступу та використання інформації. Програма з обліку зареєстрованих автомобілів в ДАІ, представляє собою, перехід від паперових носіїв інформації до електронних. Система обліку зареєстрованих автомобілів значно допоможе працівникам ДАІ з обліку, аналізу та ...

Скачать
132529
1
5

... меньше времени и ответ клиенту агентство может дать уже в день подачи заявки. Каждая турфирма разрабатывает индивидуальный образец листа бронирования. Согласно Федеральному Закону «Об основах туристской деятельности в Российской Федерации» (гл. IV, ст. 9) – это конкретный заказ туриста или лица, уполномоченного представлять группу туристов, туроператору на формирование туристского продукта. ...

0 комментариев


Наверх