|
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Справочная информация по программированиюПримечание: настоящий раздел представляет собой сводный обзор основных правил, обычно, используемых для написания программы, и обзор некоторых тем, часто необходимых в качестве справочного материала. Более строгую информацию можно найти в руководстве по Borland C++ 4.0 или в быстрой интерактивной помощи Help. В основном информация этого раздела применима и для Турбо С++ и Borland C++ 4.0. Версия 4.0 Borland C++ поможет вам создавать 16- и 32-битовые приложения для операционных систем Chicago и Windows NT. Это очень гибкая и открытая среда разработчика, обеспечивающая простое взаимодействие с ней. Интегрированная среда Borland C++ обладает по-настоящему открытой архитектурой и имеет большой набор инструментов визуального программирования. Такие новые возможности, как обработка исключительных ситуаций, интегрированный отладчик графического пользовательского интерфейса (GUI), клавиатурная эмуляция и собственный текстовый редактор Borland (Brief) делают версию более гибкой. В Borland C++ реализован очень гибкий доступ к утилитам. В частности, эта среда позволяет программистам приспособить под свои нужды панель инструментальных средств. В Borland C++ 4.0 предлагаются графические меню, подобные используемым в Quattro Pro и Paradox. При нажатии правой кнопки "мыши" появляется панель с другим набором инструментальных средств программирования. В исключительных ситуациях версия 4.0 перехватывает и распознает ошибки, позволяя программистам аккуратно выходить из любого затруднения. Новая версия включает в себя Object Windows 2.0 - объектно-ориентированную библиотеку, поддерживающую 32-разрядное программирование и перенос приложений между 16- и 32-разрядным режимом Windows. Работа компилятора Borland C++ начинается с просмотра текста программы препроцессором, который ищет в нем специальные директивы. Например, директива #include <включаемый_файл> добавляет (или включает) в программу перед фазой компиляции содержимое файла <включаемый_файл>. Препроцессор также выполняет расширение любых обнаруженных в программах или файлах включений макрокоманд. Ниже, в справочных таблицах, даются наиболее важные сведения по конкретной реализации С++ фирмы Borland. Начинаются они с перечня ключевых слов, которые не должны использоваться в качестве обычных имен идентификаторов. Ключевые слова Borland C++
Расширения Borland C++ по сравнению с Си стандарта ANSI
(1) - доступны только для 16-разрядных компиляторов (2) - доступны только для 32-разрядных компиляторов Ключевые слова, специфические для C++
Регистровые псевдопеременные Borland C++
(*) - для 32-разрядного компилятора эти псевдопеременные всегда доступны. 16-разрядный компилятор может их использовать только при указании параметра генерации инструкций 80386. ИдентификаторыХарактерным для Borland C++ и для других реализаций языка является учет регистра букв в идентификаторах. Последние могут содержать буквы от A до Z и от a до z, символ подчеркивания (_) и цифры от 0 до 9 и должны начинаться с буквы. Константы Константами называются лексемы, представляющие собой фиксированные числовые или символьные значения. Borland C++ поддерживает четыре класса констант: константы с плавающей точкой, целочисленные константы, константы перечислимого типа и символьные константы (включая строковые). Целочисленные константы представлены десятичным, восьмиричным и шестнадцатиричным форматом. Символьные константы записываются одним или более символами, заключенными в одинарные кавычки, например 'F', '=', '\n'. Описание операцийОперациями называются лексемы, вызывающие некоторые вычисления с переменными и прочими объектами, указанными в выражении. Borland C++ имеет особенно богатый набор операций, включающий в себя помимо обычных арифметических и логических операций средства манипуляции с данными на битовом уровне, доступа к элементам структур и объединений, а также операции с указателями (ссылка и разыменование). Унарные операции
Бинарные операции
ПунктуаторыВ Borland C++ пунктуаторы, также называемые разделителями, определяются следующим образом:
пунктуатор: одно из
[ ] ( ) { } , ; : ... * = #
Ассоциативность и приоритеты операций Borland C++
СсылкиПоскольку освоить работу со ссылками языка С++, начинающему программисту иногда бывает сложно, ниже дается некоторая информация о них. С++ позволяет передавать аргументы как по значению, так и по ссылке. Типы ссылок С++ тесно связаны с типами указателей и служат для создания псевдонимов объектов и позволяют передачу аргументов функциям по ссылке. Простые ссылкиДля объявления ссылок вне функции может использоваться описатель ссылки:
int i = 0;
int &ir = i; // ir является псевдонимом i
ir = 2; // то же, что i = 2
В данном примере создается именующее значение ir, являющееся псевдонимом i, при условии, что инициализатор имеет тот же тип, что и ссылка. Выполнение операций с ir имеет тот же результат, что и выполнение их с i. Например, ir = 2 присваивает значение 2 переменной i, а &ir возвращает адрес i. Отметим, что type& var, type &var и type & var эквивалентны. Аргументы типа ссылкиОписатель ссылки может также использоваться для объявления в функции параметров типа ссылки:
void func1 (int i);
void func2 (int &ir); // ir имеет тип "ссылка на int"
...
int sum=3;
func1(sum); // sum передается по значению
func2(sum); // sum передается по ссылке
Переданный по ссылке аргумент sum может изменяться прямо в func2. Напротив, func1 получает только копию аргумента sum (переданного по значению), поэтому сама переменная sum функцией func1 изменяться не может. При передаче фактического аргумента x по значению соответствующий формальный аргумент в функции принимает копию x. Любые изменения этой копии в теле функции не отражаются на самом значении x. Разумеется, функция может возвратить значение, которое затем может использоваться для изменения x, но самостоятельно изменить напрямую параметр, переданный ей по значению, функция не может. Традиционный метод Си для изменения x заключается в использовании в качестве фактического аргумента &x, то есть адреса x, а не самого значения x. Хотя &x передается по значению, функция получает доступ к x благодаря тому, что ей доступна полученная копия &x. Даже если функции не требуется изменять значения x, тем не менее полезно (хотя это чревато возможностью нежелательных побочных эффектов) передавать &x, особенно если x представляет собой большую по размерам структуру данных. Передача x непосредственно по значению ведет к бесполезным затратам памяти на копирование такой структуры данных. Сравним три различных реализации функции treble: Реализация 1:
int treble_1(n)
{
return 3*n;
}
...
int x, i = 4;
x = treble_1(i); // теперь x = 12, i = 4
...
Реализация 2:
void treble_2(int* np)
{
*np = (*np)*3;
}
...
treble_2(int &i); // теперь i = 12
Реализация 3:
void treble_3(int& n) // n имеет тип ссылки
{
n = 3*n;
}
...
treble_3(i); // теперь i = 36
Объявление формального аргумента type& t (или, что эквивалентно, type &t) устанавливает t как имеющую тип "ссылки на тип type". Поэтому при вызове treble_3 с действительным аргументом i, i используется для инициализации формального аргумента ссылки n. Следовательно, n играет роль псевдонима i, и n = 3*n также присваивает i значение 3*i. Если инициализатор представляет собой константу или объект нессылочного типа, то Borland C++ создаст временный объект, для которого ссылка действует как псевдоним:
int& ir = 16; /* создается временный объект int, с именем
псевдонима ir, который получает значение
16 */
float f;
int& ir2 = f; /* создается временный объект int, с именем
псевдонима ir2, f перед присваиванием
преобразуется */
ir2 = 2.0 /* теперь ir2 = 2, но f остается без измене-
ний */
Если формальные и фактические аргументы имеют различные (но совместимые по присваиванию) типы, то автоматическое создание временных объектов позволяет выполнять преобразования ссылочных типов. При передаче по значению, разумеется, проблем с преобразованием типов меньше, поскольку перед присваиванием формальному аргументу копия фактического аргумента может быть физически изменена. Предопределенные макрокомандыBorland C++ имеет следующие предопределенные глобальные идентификаторы. За исключением __cplusplus и _WINDOWS, каждый из них и начинается, и заканчивается двумя символами подчеркивания (__). Эти макрокоманды также называют именованными константами.
Что такое поток?Потоком называется абстрактное понятие, относящееся к любому переносу данных от источника (или поставщика данных) к приемнику (или потребителю) данных. Когда речь идет о вводе символов от источника, используются также синонимы извлечение, прием и получение, и вставка, помещение или запоминание, когда речь идет о выводе символов в приемник. В качестве источников и приемников данных (или и того и другого) существуют классы для поддержки буферов памяти (iostream.h), файлов (fstream.h) и строк (strstream.h). Библиотека iostreamБиблиотека iostream (определенная в файле iostream.h) содержит два параллельных семейства классов: классы, которые являются производными (порожденными) из streambuf, и классы, производные из ios. Оба эти классы являются классами нижнего уровня, и каждый из них выполняет различный набор задач. Один из этих двух классов является базовым классом для всех классов потоков. Класс iostreamКласс iostream обеспечивает общие методы буферизации и обработки потоков при небольшом объеме или отсутствии форматирования. streambuf это полезный базовый класс, используемый другими частями библиотеки iostream, хотя также вы можете создавать производные от него классы для собственных функций и библиотек. Классы strstreambuf и filebuf являются производными от streambuf.
streambuf
^ ^ ^
filebuf strstreambuf
conbuf
Класс streambuf обеспечивает интерфейс с памятью и физическими устройствами. Семейство функций-элементов streambuf используется классами, основанными на ios. Класс iosКласс ios (и следовательно, производные от него классы) содержит указатель на streambuf. Он выполняет форматированный вводвывод с контролем ошибок, используя streambuf. На следующем рисунке показана схема наследования для всего семейства классов ios. Например, класс ifstream является производным от istream и fstreambase, а класс istrstream является производным от istream и strstreambase. Поскольку имеет место множественное наследование, данная схема показывает не просто иерархию классов. При множественном наследовании один класс может наследовать от нескольких базовых классов. Это означает, например, что все элементы (данные и функции) iostream, istream, ostream, fstreambase и ios являются частью объектов класса fstream. Все классы в сети ios используют streambuf (либо filebuf или strstreambuf, которые представляют собой специальные случаи streambuf) в качестве источника и/или приемника.
ios
^ ^ ^ ^
istream fstreambase strstreambase ostream
^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^
ifstream istrstream ofstream ostrstream
istream_withassign istream strstream ostream_withassign
confstream
v v
iostream
^
iostream_withassign
istream_withassign ostream_withassign
Потоковый выводПотоковый вывод выполняется с помощью операции включения <<. Стандартная операция сдвига влево << для операций вывода переопределяется. Ее левый операнд - это объект типа ostream, а правый операция может иметь любой тип, для которого определен потоковый вывод (то есть основной тип или любой из переопределенных для него типа). Операция << ассоциируется слева направо и возвращает ссылку на объект ostream, для которого она вызывается. Это позволяет выполнять каскад операций. Основные типыНепосредственно поддерживаются основные типы char, short, int, long, char* (интерпретируется как строка), float, double, long double и void*. Интегральные типы форматируются в соответствии заданными по умолчанию типами для printf (если вы не изменили эти правила установками флагов ios). Форматирование ввода-выводаФорматирование ввода и вывода определяется различными флагами состояний формата, перечисленными в классе 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 после
// вставки
};
Эти флаги читаются и устанавливаются функциями-элементами flags, setf и unsetf. МанипуляторыПростой способ изменения некоторых форматных переменных состоит в использовании специальной функциональной операции, которая называется манипулятором. Манипуляторы воспринимают в качестве аргументов ссылку на поток и возвращают ссылку на тот же поток, поэтому манипуляторы могут объединяться в цепочку занесений в поток (или извлечений из потока) для того, чтобы изменять состояния потока в виде побочного эффекта, без фактического выполнения каких-либо занесений (или извлечений). Например:
#include <iostream.h>
#include <iomanip.h> // Тpебуется для паpаметpизованных
// манипулятоpов
int main(void) {
int i = 6789, j = 1234, k = 10;
cout << setw(4) << i << setw(6) << j;
cout << "\n";
cout << setw(6) << i << setw(6) << j << setw(6) << k;
return(0);
}
дает на выходе:
678912346789101234
6789 1234 10
Манипуляторы потока
Потоковый вводПотоковый ввод аналогичен выводу, но использует переопределенную операцию сдвига вправо, >>, и называется операцией извлечения, или извлечением. Левый операнд операции >> представляет собой объект типа класса istream. Как и для вывода, правый операнд может быть любого типа, для которого определен вывод потоком. По умолчанию операция >> опускает пробельные символы (как определено функцией isspace в ctype.h), а затем считывает символы, соответствующие типу объекта ввода. Пропуск пробельных символов управляется флагом ios::skipws в перечислимой переменной состояния. Флаг skipws обычно устанавливает пропуск пробельных символов. Очистка этого флага (например, при помощи setf) выключает пропуск пробельных символов. Отметим также специальный манипулятор "приемника", ws, который позволяет игнорировать пробельные символы. Рассмотрим следующий пример:
int i;
double d;
cin >> i >> d;
Последняя строка вызывает пропуск пробельных символов. Цифры, считываемые со стандартного устройства ввода (по умолчанию это клавиатура), преобразуются затем во внутренний двоичный формат и записываются в переменную i. Затем снова пропускаются пробельные символы, и наконец считывается число с плавающей точкой, которое преобразуется и записывается в переменную d. Для типа char (signed или unsigned) действие операции >> состоит в пропуске пробельных символов и записи следующего (непробельного) символа. Если вам требуется прочесть следующий символ, неважно, является ли он пробельным или нет, то можно использовать одну из функций-элементов get. Для типа char* (рассматриваемого как строка) действие операции >> состоит в пропуске пробельных символов и записи следующих (непробельных) символов до тех пор, пока не встретится следующий пробельный символ. Затем добавляется завершающий нулевой (0) символ.
Назад | Содержание | Вперед | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
CITForum © 1997–2025