С++ обзор языка


delete [] выражение-приведения где выражение-приведения указывает на массив. Последствия выполнения над массивом операции delete



страница3/10
Дата22.06.2019
Размер1.54 Mb.
1   2   3   4   5   6   7   8   9   10

delete [] выражение-приведения

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


Память, освобожденная операцией delete, снова может исрользоваться операцией new. Никакого "сборщика мусора", который ищет объекты, на которые нет ссылок, и предоставляет их в распоряжение new для повторного использования не существует.
5.4. Явное преобразование типа
Явное преобразование типа можно записать либо в функциональном виде (5.2.3), либо как приведение (cast):
выражение-приведения:

унарное-выражение

(имя-типа) выражение-приведения
Явное преобразование типа необходимо для указания нестандартного преобразования значения одного типа в значение другого типа.
Любой тип, который можеь быть преобразован к другому посредством стандартного преобразования (4), может быть преобразован явно и в том же смысле. Примеры:
float f;

char* p;

// . . .

long ll = long(p); // преобразует p в long

int i = int(f); // преобразует f в int
Указатель можно явно преобразовать к любому целочисленному типу, достаточно вместительному для этого. Значение целочисленного типа может быть преобразовано в указатель. Указатель, преобразованный в целое и обратно должен иметь первоначальное значение. Пример:
char* f(char* p)

{

int i = (int)p;

return (char*)i; // f(arg) == arg?

}
Указатель на объект одного типа может быть явно преобразован в указатель на объект другого типа.
Указатель на объект класса B может быть явно преобразован в указатель на объект класса D, для которого В является прямым или косвенным базовым классом, если существует однозначное преобразование от D к В (10.1.1). Такое приведение базового класса к производному предполагает, что объект базового класса является подобъектом объекта производного класса; результирующий указатель будет нацелен на объемлющий объект производного класса. Если объект базового класса не является подобъектом объекта производного класса,

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


5.5. Операции над указателями на компоненты класса
Операции над указателями на компонент группируются слева направо.
рт-выражение:

выражение-приведения

рт-выражение .* выражение-приведения

рт-выражение ->* выражение-приведения


Бинарная операция “.*” связывает второй операнд, который должен иметь тип “указатель на компонент класса Т”, с первым операндом, который должен быть объектом класса Т или класса, для которого Т есть однозначно доступный базовый класс. Результатом является объект или функция типа, заданного вторым операндом.
Бинарная операция “->*” связывает второй операнд, который должен иметь тип “указатель на компонент класса Т”, с первым операндом, который должен быть указателем на объект класса Т или класса, для которого Т есть однозначно доступный базовый класс. Результатом является объект или функция типа, заданного вторым операндом. Пример:
(ptr_to_obj ->* ptr_to_mfct)(10)
вызывает компонентную функцию, указываемую ptr_to_mfct, из объекта, указываемого ptr_to_obj.
5.6. Мультипликативные операции
Мультипликативные операции группируются слева направо.
мультипликативное-выражение:

рт-выражение

мультипликативное-выражение * рт-выражение

мультипликативное-выражение / рт-выражение

мультипликативное-выражение % рт-выражение
Операнды операций “*” (умножение) и “/” (деление) должны иметь арифметический тип; операнды операции “%” (остаток от деления) должны иметь целочисленный тип. Обычные арифметические преобразования (4.5) выполняются над операндами и определяют тип результата. При делении двух целых результат - целое число, зависящее от реализации.
5.6. Аддитивные операции
Аддитивные операции группируются слева направо. Обычные арифметические преобразования (4.5) выполняются над операндами и определяют тип результата.
аддитивное-выражение:

мультипликативное-выражение

аддитивное-выражение + мультипликативное-выражение:

аддитивное-выражение - мультипликативное-выражение:


Операнды должны быть указателями или иметь арифметический тип. Результатом операции “+” является сумма операндов. Указатель на элемент массива можно сложить с целым; результатом является указатель того же типа, что и исходный, указывающий на другой элемент массива.
Результатом операции “-” является разность операндов. Значение любого целочисленного типа можно вычесть из указателя на элемент массива. Можно взять разность двух указателей на объекты одного и того же типа. Результатом является целое со знаком, определяющее количество объектов, разделяющее указываемые объекты (указатели на смежные элементы массива различаются на 1).
5.8. Операции сдвига
Операции сдвига группируются слева направо
выражение-сдвига:

аддитивное-выражение

выражение-сдвига << аддитивное-выражение

выражение-сдвига >> аддитивное-выражение


Операции проводятся над целочисленными аргументами, над которыми проводятся целочисленные расширения. Тип результата определяется типом левого операнда. Значением Е1 << Е2 является Е1, сдвинутое влево на Е2 битов; освобождаемые биты заполняются нулями. Значением Е1 >> Е2 является Е1, сдвинутое вправо на Е2 битов; освобождаемые биты заполняются нулями. Правый сдвиг будет логическим, если Е1 имеет беззнаковый тип или дает неотрицательное значение; в противном случае результат зависит от реализации.
5.9. Операции отношения
Операции отношения группируются слева направо, но надо понимать, что aвыражение-отношения:

выражение-сдвига

выражение-отношения < выражение-сдвига

выражение-отношения > выражение-сдвига

выражение-отношения <= выражение-сдвига

выражение-отношения >= выражение-сдвига


Операнды должны иметь арифметический тип или тип указателя. Операции “<” (меньше, чем), “>” (больше, чем), “<=” (меньше или равно) и “>=” (больше или равно) дают результат 0, если отношение ложно, и 1, если оно истинно. Тип результата есть int.
5.10. Операции равенства
выражение-равенства:

выражение-отношения

выражение-равенства == выражение-отношения

выражение-равенства != выражение-отношения


Операции “==“ (равно) и “!=“ (не равно) аналогичны операциям отношения, но имеют меньший приоритет (поэтому a5.11. Побитовая операция “И”
выражение-И:

выражение-равенства

выражение-И & выражение-равенства
Операция "&" применима только к целочисленным аргументам, над которыми может выполняться обычные арифметические преобразования; результат есть логическое произведение операндов.
Одно из стандартных применений этой и следующих двух операций - реализация маленького множества (вектора битов). В этом случае каждый бит беззнакового целого представляет один член множества, а число членов ограничено числом битов. Для именования элементов такого множества можно использовать перечисление.
5.12. Побитовая операция “исключающее ИЛИ”
выражение-исключающее-ИЛИ:

выражение-И

выражение-исключающее-ИЛИ ^ выражение-И
Операция “^”применима только к целочисленным аргументам, над которыми может выполняться обычные арифметические преобразования; результат есть логическая симметричная разность (exclusive OR) операндов.
5.13. Побитовая операция “включающее ИЛИ”
выражение-включающее-ИЛИ:

выражение-исключающее-ИЛИ

выражение-включающее-ИЛИ | выражение-исключающее-ИЛИ
Операция “|”применима только к целочисленным аргументам, над которыми может выполняться обычные арифметические преобразования; результат есть логическая сумма (inclusive OR) операндов.
5.14. Логическая операция “И”
логическое-выражение-И:

выражение-включающее-ИЛИ

логическое-выражение-И && выражение-включающее-ИЛИ
Операция “&&” группирует операнды слева направо. Результат равен 1, если оба операнда отличны от нуля, и 0 - в противном случае. В отличае от операции “&”, операция “&&” гарантирует порядок вычисления операндов слева направо; более того, второй операнд не вычисляется, если первый операнд равен 0.
Операнды не приводятся к одному типу, но должны быть указателями или числами. Результатом является целое типа int.
5.15. Логическая операция “ИЛИ”
логическое-выражение-ИЛИ:

логическое-выражение-И

логическое-выражение-ИЛИ || логическое-выражение-И
Операция “||” группирует операнды слева направо. Результат равен 1, если один из операндов отличен от нуля, и 0 - в противном случае. В отличае от операции “|”, операция “||” гарантирует порядок вычисления операндов слева направо; более того, второй операнд не вычисляется, если первый операнд отличен от нуля.
Операнды не приводятся к одному типу, но должны быть указателями или числами. Результатом является целое типа int.
5.16. Условная операция
условное-выражение:

логическое-выражение-ИЛИ

логическое-выражение-ИЛИ ? выражение : условное-выражение
Условные выражения группируются слева направо. Первое выражение (логическое-выражение-ИЛИ) должно быть числом или указателем. Если оно не нуль, результатом становится значение второго выражения, в противном случае - третьего выражения.
В случае, когда оба второе и третье выражение - числа, если они имеют один тип, то и результат имеет тот же тип, иначе для приведения к общему типу над одним из них выполняются обычные арифметические преобразования.
В противном случае, когда оба второе и третье выражение - указатели либо равные нулю константные выражения, выполняются преобразования указателей для их приведения к общему типу.
В противном случае, когда оба второе и третье выражение - ссылки, выполняются преобразования ссылок для их приведения к общему типу.
В противном случае, когда оба второе и третье выражение имеют тип void, результат имеет тип void.
В противном случае, когда оба второе и третье выражение имеют типом класс Т, результат имеет типом класс Т.
В противном случае, условное выражение ошибочно.
5.17. Операция присваивания
В С++ имеется несколько операций присваивания; все они группируются справа налево и требуют l-значения в качестве левого операнда. Типом результата является тип левого операнда. Результатом является значение, запомненное в левом операнде сразу после выполнения операции и рассматриваемое далее как l-значение.
выражение-присваивания:

условное-выражение

унарное-выражение операция-присваивания выражение-присваивания

операция-присваивания: ОДНА ИЗ = *= /= %= += -= >>= <<= &= ~= |=


В случае простого присваивания (=) значение правого операнда заменяет значение объекта, именуемого левым операндом. Если оба операнда - числа, правый операнд до присваивания преобразуется к типу левого операнда. Если левый операнд - указатель, правый операнд тоже должен быть указателем или константным выражением, равным нулю; правый операнд до присваивания преобразуется к типу левого операнда.
Выражение вида Е1 op= Е2 эквивалентно выражению Е1 = Е1 op Е2, за исключением того, что Е1 вычисляется только один раз.
5.18. Операция запятая
Операция группирует вычисления слева направо.
выражение:

выражение-присваивания

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

f(a, (t=3, t+2), c);

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


5.19. Константные выражения
В следующих случаях С++ требует, чтобы значение выражения было целочисленной константой: граница массива (8.2.4), выражение в метке case (6.4.2), длина битового поля (9.6) и значение, инициализирующее элемент перечисления (7.2).
константное-выражение:

условное-выражение


константное-выражение может включать только литералы (2.5), элементы перечислеия, константные значения целочисленного типа, инициализированные константным выражением (8.4).
5.20. Сводка операций
В следующей сводке после каждой операции приведено ее название и пример использования. В этих примерах class_name это имя класса, member - имя компонента, object - выражение, дающее в результате объект класса, pointer - выражение, дающее в результате указатель, expr - выражение, а lvalue - выражение, дающее неконстантный объект. Type может быть произвольным именем типа, только когда он стоит с скобках, во всех остальных случаях существуют ограничения. Унарные операции и операции присваивания правоассоциативны, все остальные - левоассоциативны. Это значит, что a = b = c означает a = (b = c), a+b+c означает (a+b)+c, и *p++ означает *(p++), а не (*p)++.
-------------------------------------------------------------------------------------------------

:: разрешение области видимости class_name::member

:: глобальное ::name

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

. выбор компонента object.member

-> выбор компонента pointer->member

[] индексация pointer[expr]

() вызов функции expr(expr-list)

() построение значения type(expr-list)

sizeof размер объекта sizeof expr

sizeof размер типа sizeof(type)

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

++ приращение после lvalue++

++ приращение до ++lvalue

-- уменьшение после lvalue--

-- уменьшение до --lvalue

~ дополнение ~expr

! не !expr

- унарный минус -expr

+ унарный плюс +expr

& адрес объекта &lvalue

* разыменование *expr

new создание (размещение) new type

delete уничтожение (освобождение) delete pointer

() приведение (преобразование типа) (type)expr

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

.* выбор компонента object.*pointer-to-member

->* выбор компонента pointer.->*pointer-to-member

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

* умножение expr*expr

/ деление expr/expr

% взятие по модулю expr%expr

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

+ сложение (плюс) expr+expr

- вычитание (минус) expr-expr

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

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

<< сдвиг влево expr << expr

>> сдвиг вправо expr >> expr

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

< меньше expr < expr

> больше expr > expr



<= меньше или равно expr <= expr

>= больше или равно expr >= expr

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

== равно expr == expr

!= не равно expr != expr

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

& побитовое И expr & expr

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

^ побитовое исключающее ИЛИ expr ^ expr

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

| побитовое включающее ИЛИ expr | expr

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

&& логическое И expr && expr

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

|| логическое включающее ИЛИ expr || expr

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

?: арифметический IF expr ? expr : expr

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

= простое присваивание lvalue = expr

*= умножить и присвоить lvalue *= expr

/= разделить и присвоить lvalue /= expr

%= взять по модулю и присвоить lvalue %= expr

+= сложить и присвоить lvalue += expr

-= вычесть и присвоить lvalue -= expr



<<= сдвинуть влево и присвоить lvalue <<= expr

>>= сдвинуть вправо и присвоить lvalue >>= expr

&= И и присвоить lvalue &= expr

|= включающее ИЛИ и присвоить lvalue |= expr

^= исключающее ИЛИ и присвоить lvalue |= expr

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

, запятая expr, expr

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



6. Операторы
Операторы выполняются последовательно, если явно не указано обратное.
оператор:

помеченный-оператор

оператор-выражение

составной-оператор

выбирающий-оператор

оператор-цикла

оператор-перехода

оператор-объявление


6.1. Помеченный оператор
помеченный-оператор:

идентификатор : оператор

case константное-выражение : оператор

default : оператор


Идентификатор объявляет идентификатор метки, который может употребляться в операторе перехода. Областью действия метки является функция, в которой она объявлена. Метка может быть использована до ее объявления. Метки образуют свое собственное пространство имен и не конфликтуют с другими идентификаторами. Метки case и default могут появляться только в операторе выбора.
6.2. Оператор-выражение
Большинство операторов в программе обычно являются операторами-выражениями, которые имееют вид:
оператор-выражение:

выражение opt;


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

{ список-операторов opt }

список-операторов:

оператор


список-операторов оператор
Заметим, что объявление тоже считается оператором (6.7).
6.4. Выбирающие операторы
Выбирающие ператоры выбирают один из нескольких путей исполнения программы.
выбирающий-оператор:

if (выражение) оператор

if (выражение) оператор else оператор

switch (выражение) оператор
Оператор в выбирающем операторе не может быть объявлением.
6.4.1. Условный оператор (оператор if)
Значение выражения должно быть числом, указателем или объектом класса, для которого существует однозначное преобразование к числу или указателю (12.3).
В С++ нет отдельного булевского типа. Операции сравнения

"==", "!=", "<", ">", "<=", ">="

возвращают целое 1, если сравнение истинно, иначе возвращают 0. Поэтому

выражение вычисляется и, если результат не равен нулю, выполняется первый оператор. В противном случае, если есть часть else, выполняется ее оператор. Из этого следует, что if (a) эквивалентно if (a != 0).
Логические операции "&&" и "||" наиболее часто исрользуются в условиях. Они не вычисляют второй операнд, если этого не требуется. Например,
if (p && 1 < p->count)
сначала проверит, является ли р нулем, и только если это не так, проверит

1 < p->count.
Некоторые условные операторы могут быть с удобством заменены условными выражениями, например:
if (a <= b)

max = b

else max = a:
лучше выражается так:
max = (a <= b) ? b : a;
6.4.2. Оператор выбора (оператор switch)
Оператор выбора передает управление одному из нескольких операторов в зависимости от значения выражения, которое должно быть числом или объектом класса, для которого существует однозначное преобразование к числу (12.3). Любой оператор может быть помечен меткой case:

case константное-выражение:

где константное-выражение (5.19) приводится к типу выражения из оператора выбора.
В одном операторе выбора может быть одна метка вида default
Выполнение оператора заключается в вычислении выражения и сравнении его значения с метками выбора. Если одна из меток равна значению выражения, управление передается оператору, следующему за меткой. Если ни одна из меток выбора не равна значению выражения, управление передается оператору, помеченному меткой default, если есть таковой. Пример:
switch (val) {

case 1: f(); break;

case 2: g(); break;

default: h(); break;

}
Необходимо заботиться о завершении каждой ветви, чтобы избежать выполнения следующей. Например,
switch (val) {

// осторожно!

case 1: cout << "case1 \n";

case 2: cout << "case2 \n";

default: cout << "default: case не найден \n;

}
при val = 1 напечатает
case1

case2

default: case не найден
6.5. Операторы цикла
Операторы цикла задают многократное исполнение.
оператор-цикла:

while (выражение) оператор

do оператор while (выражение)

for (оператор-иниц-for выражение opt; выражение opt) оператор

оператор-иниц-for:

оператор-выражение

оператор-объявление


Оператор в операторе-цикла не может быть объявлением.
6.5.1. Оператор ПОКА (while)
В операторе ПОКА входящий в него оператор повторно выполняется до тех пор, пока значение выражения не становится равным нулю. Проверка производится перед каждым исполнением оператора. Значение выражения должно быть числом, указателем или объектом класса, для которого существует однозначное преобразование к числу или указателю (12.3).
6.5.2. Оператор ПОВТОРИТЬ (do)
В операторе ПОВТОРИТЬ входящий в него оператор повторно выполняется до тех пор, пока значение выражения не становится равным нулю. Проверка производится после каждого исполнения оператора. Значение выражения должно быть числом, указателем или объектом класса, для которого существует однозначное преобразование к числу или указателю (12.3).
6.5.3. Оператор итерации (for)
Оператор итерации
for (оператор-иниц-for выражение-1 opt; выражение-2 opt) оператор
эквивалентен оператору
оператор-иниц-for

while (выражение-1) {

оператор

выражение-2;

}
за исключением того, что оператор ПРОДОЛЖИТЬ (continue) в операторе приводит к выполнению выражения-2 и далее очередному вычислению выражения-1. Таким образом:
первый оператор задает инициализацию, необходимую для выполнения цикла,
первое выражение определяет проверку, выполняемую перед каждым

повторением, так что цикл завершается, когда выражение-1 становится

равным нулю,
второе выражение обычно осуществляет приращение переменных цикла после

каждого повторения.


Значение выражения-1 должно быть числом, указателем или объектом класса, для которого существует однозначное преобразование к числу или указателю (12.3). Пропуск выражения-1 подразумевает, что фраза while в эквивалентном представлении сводится к while(1). Пример:
const int sz = 24;

int ia[sz];

for (int i = 0; i
Если оператор-иниц-for является объявлением, область действия объявленных имен простирается до конца блока, содержащего оператор for.



Поделитесь с Вашими друзьями:
1   2   3   4   5   6   7   8   9   10


База данных защищена авторским правом ©vossta.ru 2019
обратиться к администрации

    Главная страница