рефераты

рефераты

 
 
рефераты рефераты

Меню

Реферат: Turbo C++ Programer`s guide рефераты

while (ptr != NULL)...

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

char str[10]="Borland";

char *ptr=&str[0];

int count=0;

//...

while (*ptr++)  // цикл до конца строки

count++;

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

Операторы do while

Общий формат этих операторов следующий:

do выполняемый-оператор while (условное-выражение)

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

Операторы for

Формат оператора for в С следующий:

for(<выражение-инициализации>;<выражение-проверки>; <выражение-инкремента>) оператор

В С++ <выражение-начального-значения> может быть как выражением, так и объявлением.

Последовательность действий при выполнении данного оператора следующая:

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

2. Выражение-проверки вычисляется по правилам, приводимым для циклов while. Если выражение-проверки ненулевое (истина), то оператор тела цикла выполняется. Пустое выражение трактуется в данном случае как while(1), то есть как если бы условие проверкивыполнялось всегда.Если выражение-проверки дает значение ноль (ложь), то цикл for прекращается.

3. Выражение-инремента выполняет приращения одного или нескольких цикловых счетчиков.

4. Выражение "оператор" (возможно, пустое) вычисляется, после чего управление возвращается на шаг 2.

Если какие-либо из опциональных элементов опущены, то вместо них должны быть заданы соответствующие точки с запятой:

for (;;) (* // то же, что и for(;1;)

// вечный цикл

*)

C++: Правила С для операторов for применимы и в С++. Однако, выражение-инициализации в С++ может также включать в себяи объявление. Контекст объявленного идентификатора продолжается до конца данного оператора, не далее. Напрмер,

for (int i = 1; i < j; ++i)

(*

if (i ...) ...// здесь обращаться к значению i можно *)

if (i ...)// а здесь нельзя : i вне контекста

Операторы перехода

При выполнении оператор перехода происходит безусловная передача управления в некоторую точку программы. Существует четыре таких оператора: break, continue, goto и return.

Операторы break

Синтаксис следующий:

break;

Оператор break можно использовать только внутри операторов итерации (while, doи for - циклы) или с оператором switch. Он прекращает выполнение итерации или оператора switch. Поскольку операторы итерации и оператор switch могут комбинироваться и иметь любуюглубину вложенности, следует обращать особое внимание на то, чтобы оператр break выполнял выход именно из нужного цикла или оператора switch. Правило состоит в том, что оператор break заканчивает выполнение ближайшего к нему объемлющего цикла итерации или оператора switch.

Операторы continue

Синтаксис следующий:

continue;

Оператор continue может быть использован только внутри оператора итерации; он передает управление на проверку условия циклов while и do, либо на выражение инкремента цикла for.

При вложенностициклов итерации оператор continue считается принадлежащим ближайшей объемлющей итерации.

Операторы goto

Синтаксис следующий:

goto метка;

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

С++: В С++ допустимо обойти объявление с явным или неявным инициализатором, если это объявление не находится во внутреннем блоке, который также обходится.

Операторы return

Если тип возврата функции не равен void, то тело функции должно содержать как минимум один оператор return следующего формата:

return выражение-возврата;

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

t = func(arg);                         // так можно

func(arg) = t; /* в С так нельзя; в С++ так можно, если типом возврата func является ссылка */

(func(arg))++; /* в С так нельзя; в С++ так можно,если типом возврата func является ссылка */

Выполнение вызова функции заканчивается, когда встретился оператор return; если оператор return отсутствует, то выполнение "проваливается" к последней закрыващей фигурной скобке тела функции.

Если тип возврата void, то оператор return можно записать как:

(*

...

return;

*)

без выражения-возврата, либо оператор return вообще может быть опущен.

С++

В целом, С++ является над-множеством языка С. Это означает, что, вообще говоря, можно компилировать программы С в среде С++, однако компилировать программы С++ в среде С при наличии в них каких-либо специфических для С++ конструкций нельзя. Некоторые ситуации требуют специального внимания. Одна и та же функция func, дважды объявленная в С с различными значениями аргументов, вызовет ошибку повторения имен. Однако, в С++ func интерпретируется как перегруженная функция - а то, допустимо это или нет,зависит от других обстоятельств. Общие вопросы программирования на С++ см. в главе 5, "Основы С++" документа "Начало работы". Глава 6, "Краткий справочник по С++" в том же документе поможет вам быстро понять, как именно работают конструкции языка.

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

Ссылки

Установка ссылок при помощи указателей и обращение по ссылкам рассматриваются на стр.80 оригинала.

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

Простые ссылки

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

int i = 0;

int &ir = i;   // ir является алиасом i

ir = 2;   // то же, что i = 2

В данном примере создается именующее значение ir, являющееся алиасом i, при условии, что инициализатор имеет тот же тип, что и ссылка. Выполнение операций с ir имеет тот же результат, что и выполнение их с i. Напрмер, ir = 2 присваивает 2 переменной i, а &ir возвращает адрес i.

Аргументы типа ссылки

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

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.

Если инициализатор представляет собой константуили объект нессылочного типа, то Turbo C++ создаст временный объект, для которого ссылка действует как алиас:

int& ir = 6; /* создается временный объект int, с именем алиаса ir, который получает значение 6 */

float f;

int& ir2 = f; /* создается временный объект int, с именем алиаса ir2, f перед присвоением преобразовывается */

ir2 = 2.0 // теперь ir2 = 2, но f остается без изменений

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

Операция доступа к контексту

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

int i;                 // глобальная переменная i

...

void func(void);

(*

int i=0; // локальная i скрывает глобальную i i =  3;  //

эта i - локальная

::i = 4;                   // эта i - глобальная

printf ("%d",i);  // будет напечатано значение 3

*)

Приведенный кодработает также, если i является статической переменной уровня файла.

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

Операции new и delete

Операцииnew и delete выполняют динамическое распределение и отмену распределения памяти, аналогично, но с более высоким приоритетом, нежели стандартныке библиотечные функции семейства malloc и free (См. справочник по библиотеке).

Упрощенный синтаксис:

указатель-имени = new имя <инициализатор-имени>;

delete указатель-имени;

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

new пытается создать объект с типом "имени", распределив (при возможности) sizeof(имя) байт в свободной области памяти (которую также называют "кучей"). Продолжительность существования в памяти данного объекта - от точки его создания и до тех пор, пока операция delete не отменит распределенную для него память, либо до конца работы программы.

В случае успешного завершения new возвращает указатель нового объекта. Пустой указатель означает неудачное завершение операции (например, недостаточный объем или слишком большая фрагментированность кучи). Как и в случае malloc, прежде чем пытаться обращаться к новому объекту, следует проверить укеазатель на наличие пустого значения. Однако, в отличие от malloc, new сама вычисляет размер "имени", и явно указывать операцию sizeof нет необходимости. Далее возвращаемый указатель будет иметь правильный тип, "указатель имени", без необходимости явного приведения типов.

name *nameptr // name может иметь любой тип, кроме функции

...

if (!(nameptr = new name)) (*

errmsg("Недостаточно памяти для name");

exit (1);

*)

// использование *nameptr для инициализации объекта new name

...

delete nameptr;  // удаление name и отмена распределения

// sizeof(name) байтов памяти

new, будучи ключевым словом, не нуждается в прототипе.

Операция new с массивами

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

mat_ptr = new int[3][10][12];                                   // так можно

mat_ptr = new int[3][][12];                                       // нельзя

mat_ptr = new int[][10][12];                                     // нельзя

::operator new

При использовании с объектами, не являющимися классами, new вызывает стандартную библиотечную подпрограмму, global ::operator new. Для объектов классов типа "имя" может быть определена специальная операция имя::operator new. new, применительнок объектам класса "имя", запускает соответствующую операцию имя::operator new; в противном случае используется стандартная операция ::operator new.

Инициализаторы с операцией new

Другим преимуществом операции new по сравнению с malloc является опциональный инициализатор (хотя calloc очищает его распределение к нулю). При отсутствии явных инициализаторов объект, создаваемый new, содержит непредсказуемые данные ("мусор"). Объекты, распределяемые new, за исключением массивов, могут инициализироваться соответствующим выражением в круглых скобках:

int_ptr = new int(3);

Массивы классов с конструкторами инициализируются при помощи конструктора-умолчания (см. стр.115 оригинала). Определяемая пользователем операция new с задаваемой пользователем инициализацией играет ключевую роль в конструкторах С++ для объектов типа класса.

Классы

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

В С++ структуры и объединения рассматриваются как классы с определенными умолчаниями правил доступа.

Упрощенный, в "первом приближении", синтаксис объявления класса следующий:

ключ-класса                                                                                       имя-класса

<:базовый-список>[<список-компонентов>]

Ключ-класса - это class, struct или union.

Опциональный базовый-список перечисляетбазовый классили классы, из которогоимя-класса берет (или наследует) объекты и правила. Если объявлены некоторые базовыеклассы, то класс "имя-класса" называется производным классом (см.стр.110, "Доступ к базовым и производным классам"). Базовый список содержит спецификаторы доступа по умолчания и опциональные их переопределения, которые могут модифицировать права доступа производного класса к компонентам базовых классов(см. стр.108 оригинала, "Управление доступом к компонентам").

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

Имена классов

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

Типы классов

Объявление создает   уникальный   тип,                                тип           класса

"имя-класса". Это позволяет вам объявлять последующие объекты класса (или вхождения класса) данного типа, а также объекты, являющиеся производными от этого типа (такие как указатели, ссылки, массивы объектов "имя-класса" и т.д.):

class X (* ... *);

X x, &xr, *xptr, xarray[10];

/* четыре объекта: типа X, ссылка на X, указатель на X и масив элементов типа X */

struct Y (* ... *);

Y y, &yr, *yptr, yarray[10];

// С позволяет иметь

// struct Y y, &yr, *yptr, yarray[10];

union Z (* ... *);

Z z, &zr, *zptr, zarray[10];

// С позволяет иметь

// union Z z, &zr, *zptr, zarray[10];

Отметим различие между объявлением структур и объединений в С и С++: в С ключевые слова struct и union обязательны, но в С++ они нужны только в том случае, когда имена классов, Y и Z, скрыты (см. следующий раздел).

Контекст имени класса

Контекст имени класса является локальным, с некоторыми особенностями, характерными для классов. Контекст имени класса начинается с точки его объявления и заканчивается вместе с объемлющим блоком. Имя класса скрывает любой класс, объект, нумератор или функцию с тем же именем в объемлющем контексте. Еслиимя класса объявлено в контексте, содержащем объявление объекта, функции или нумератора с тем же именем, обращение к классу возможно только при помощи уточненного спецификатора типа. Это означает, что с именем класса нужноиспользовать ключ класса, class, struct или union. Например,

Страницы: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40