![](/user_photo/_userpic.png)
Яп
.pdf![](/html/75508/276/html_8rnNSBwA5c.Iz7G/htmlconvd-6VjTN_61x1.jpg)
Реализация методов передачи параметров
241
ЛОКАЛЬНЫЕ И ГЛОБАЛЬНЫЕ ОБЪЕКТЫ
243
2/27/2023
Реализация методов передачи параметров
•Параметры, передаваемыепо значению, заносятся в ячейки стека. Далее эти ячейки хранят соответствующие формальныепараметры.
•При передачепо результату значения, предназначенные для фактических параметров, помещаются в стек, откуда они извлекаются вызывающим программныммодулем (после завершения работы вызванной подпрограммы).
•Передача параметров позначению-результату
реализуется как комбинация передачипозначению и передачипо результату. Ячейка стека инициализируется вызовом и затемиспользуетсякак локальная переменнаяв вызванной подпрограмме.
•Передача параметров поссылкенезависимо от типа фактического параметрав стек помещается лишьего адрес.
242
Локальные переменные
•Локальныепеременныеможноиспользовать тольков внутриблока,где они объявлены.
•Локальная переменнаясоздается при входев блок и разрушается сразу после выхода из него, значение теряется.
•По умолчаниюлокальныепеременныехранятсяв стеке.
•Локальнуюпеременнуюможно проинициализировать неким значением.Онобудет присваиваться переменной каждый раз при входе в блок.
void func1 (void) |
void func2 (void) |
{{
intx; |
intx; |
x = 10; |
x = 20; |
}}
244
61
![](/html/75508/276/html_8rnNSBwA5c.Iz7G/htmlconvd-6VjTN_62x1.jpg)
Глобальные переменные
•можноиспользовать в любомвыражении,в каком бы блоке оно не находилось;
•объявления глобальныхпеременныхдолжныразмешаться
вне всех функций;
•сохраняютсвои значенияна всем протяжениивыполнения программы;
•занимаютпамять во время всего выполненияпрограммы, даже когда уже не нужны;
•ослабляетнезависимость функций, поскольку они вынужденызависеть от сущности, определеннойв другом месте.
245
Квалификаторы const и volatile
•Квалификаторы указываются передмодификаторамитипов и именами типов, которые они уточняют.
•Переменныетипа const не могут изменяться,однако их можноинициализировать:
1.можноиспользовать дляпредотвращения модификации
переменных.
2.можноиспользовать длязащиты объектов,передаваемых в функциюв качестве аргументов.
size_t strlen(const char *str); // защитили от изменений
//строку, на которую она ссылается
247
2/27/2023
Глобальные переменные
include <stdio.h> |
void func1(void) |
int count; // глобальная |
{ |
переменная |
int temp; |
|
temp = count; |
void func1(void); |
func2(); |
void func2(void); |
} |
|
void func2(void) |
int main (void) |
{ |
{ |
int count; |
count = 100; |
for(count=1; count<10; ++count) |
func1(); |
putchat(‘.’) |
return 0; |
} |
} |
|
|
246 |
Квалификаторы const и volatile
•Квалификатор volatile сообщает компилятору, что значение переменной может изменяться неявно.
•Большинство компиляторов автоматически оптимизируют некоторые выражения, считая, что значения переменных не изменяются, если они не указаны в левой части оператора присваивания. Т.е. считают, что нет смысла перепроверять при каждом обращении.
•Квалификатор volatile предотвращает такие изменения –
программист просит компилятор не оптимизировать переменную.
bool cancel = false; while( !cancel ) { ; }
Если cancel не меняется, то ее и проверять каждый раз незачем
volatile bool cancel = false; while( !cancel ) { ; }
Оптимизиации не будет. Предполагаем, что переменная cancel могла измениться каким-то волшебным образом.248
62
![](/html/75508/276/html_8rnNSBwA5c.Iz7G/htmlconvd-6VjTN_63x1.jpg)
Спецификаторы хранения. extern
•Программу C/C++ можно разделить на несколько файлов, скомпилировать их отдельно, а затем отредактировать связи между ними.
•Чтобы обратиться к переменной, определенной в другой части программы, ее следует объявить, используя спецификатор extern.
•extern позволяет объявить переменную, не определяя ее.
249
Спецификаторы хранения. register
•Спецификатор register - компилятор сохраняет значение переменной в регистре ЦП, а не памяти, как обычно.
•Операции над регистровыми переменными выполняются намного быстрее.
•Спецификатор register можно применять только к локальным переменным и формальным параметрам. К глобальным переменным он не применяется.
•Регистровые переменные имеет смысл применять там, где к одной и той же переменной происходит очень много обращений.
251
2/27/2023
Спецификаторы хранения. static
•Если локальнаяпеременная объявлена с помощью спецификатора static, компиляторвыделит длянее постоянноеместохранения, как и для глобальной переменной
переменнаяseries_num продолжает существовать между вызовами функции,а локальная переменнаякаждый раз создавалась бы при входе и уничтожалась при выходе из функции.
•Применение спецификатора static к глобальной переменной заставляет компиляторсоздать глобальную переменную,видимуютольков пределах текущего файла.
250
ИСКЛЮЧИТЕЛЬНЫЕ
СИТУАЦИИ
252
63
![](/html/75508/276/html_8rnNSBwA5c.Iz7G/htmlconvd-6VjTN_64x1.jpg)
Традиционные вариант обработки ошибки
1.Завершить программу, выдав сообщение об ошибке.
2.Возвратить условное значение, обозначающее ошибку.
3.Возвратить значение, как при нормальном завершении, выставив некоторый внешний признак ошибки.
4.Вызвать функцию, предназначенную для вызова в случае ошибки (error handler function).
253
Исключительные ситуации
•В любой жизнеспособнойсистемедолжна предусматриватьсяреакция на чрезвычайные (исключительные) ситуации.
•Такую реакцию в языке программирования предусматриваетаппарат исключений.
•Исключение - ситуация, когда состояние данных, устройств ввода-вывода или системыв целом делает дальнейшие вычисления в соответствии с базовым алгоритмом невозможным или бессмысленным.
•Ошибки - исключительныеситуации, которые времяот времени могут возникать в известных местах программы.
255
2/27/2023
Традиционные вариант обработки ошибки
•Вызов методавстраивается в if оператор, обрабатывающий ошибку в случае неуспехазавершения метода:
Bool MyMethod(…) {}
If !MyMethod(){ // обработка ошибки } { // нормальное выполнение }
Недостатки:
1.Мало информации о причине возникновения ошибки, поэтому через поля класса или через аргументыметода нужно передавать доп. информацию.
2.Блок обработки встраивается в каждый вызов, что приводитк раздуванию кода.
254
Обработчик исключений
•Обработка производится обработчиком исключения
(ловушкой) - это специализированная подпрограмма, которая реагирует на аварию (конкретное исключение) и максимально минимизирует ее последствия.
•Обработчик исключений не является заменой условного оператора.
•Если ситуация может возникать, это не является ошибкой и должно быть запрограммированоявным образом.
256
64
![](/html/75508/276/html_8rnNSBwA5c.Iz7G/htmlconvd-6VjTN_65x1.jpg)
Требования к аппарату исключений
1.Полнота исключений — на любое исключение должна быть предусмотрена реакция исполнителя (компьютера).
2.Минимальность возмущений — затратына учет чрезвычайных ситуаций должны быть минимальны.
3.Минимальность повреждений — ущерб при возникновении исключений должен быть минимален.
257
Предопределенные исключения
•Различают предопределенные и определяемые
программистом исключения.
•Предопределенныеисключения встроены в язык программирования. Например:
1.Ошибки ограничений (Constrain_Error)
2.Ошибки памяти (Storage_Error).
3.Программные ошибки (Program_Error):
Bounded_Error - выход поведения за допустимые границы; Erroneous_Execution - проявление причин, ведущих к неправильному выполнению).
4.Ошибки задачи (Tasking_Error).
5.и т.д.
259
2/27/2023
Синхронные и асинхронные исключения
•Синхронные исключения могут возникнуть только в определённых, заранее известных точках программы.
•Примерамитаких исключений могут быть: ошибки чтения файла, нехватка памяти, ошибка деления на ноль и т.д.
•Асинхронные исключения могут возникать в любой момент времени и не зависят от того, какую конкретно инструкцию программы выполняет система.
•Примерамитаких исключений могут быть: аварийный отказ питания, поступление новых данных и т.д.
258
Определяемыеисключения
•Определяемые исключения расширяют возможности аппарата исключений.
•Ориентированы на ошибки, которые не могли предугадатьавторы языка, но о которых знают разработчики конкретных программных систем.
•Эти исключения явно определяются программистом с помощью объявления новых типов исключений.
260
65
![](/html/75508/276/html_8rnNSBwA5c.Iz7G/htmlconvd-6VjTN_66x1.jpg)
Определяемыеисключения
•Определяемые исключения расширяют возможности аппарата исключений.
•Ориентированы на ошибки, которые не могли предугадатьавторы языка, но о которых знают разработчики конкретных программных систем.
•Эти исключения явно определяются программистом с помощью объявления новых типов исключений.
261
Обработка с возобновлением
•Обработка с возобновлением подразумевает, что обработчик исключения ликвидирует возникшую проблему и приводит программу в состояние, когда она может работать дальше по основному алгоритму.
•После обработчика, управление передается обратно в ту точку программы, где возникла исключительная ситуация и выполнение программы продолжается.
•Обработка с возвратомтипична для обработчиков
асинхронных исключений.
•Недостаток: нет гарантии, что процесс сможет нормальноработать.
263
2/27/2023
Определяемыеисключения
•При распространении исключения используетсяпринцип динамическойловушки— выбирается обработчик, динамически ближайший к месту происшествия.
262
Обработка без возобновления
•Обработка без возобновления заключается в том,
что после выполнения кода обработчика исключения управление передается в некоторое, заранее заданноеместо программы, и с него продолжается исполнение.
•Основнаястратегия - считать появление исключения свидетельством полной непригодности «аварийного процесса» к нормальной работе.
264
66
![](/html/75508/276/html_8rnNSBwA5c.Iz7G/htmlconvd-6VjTN_67x1.jpg)
Операторы обработки исключений
try {
// Код, где возможновозникновениеисключений throw[выражение]
}
catch (формальныйпараметр) { // тело первогообработчика
}
…
catch (…) { // … - обработчикпо умолчанию // тело m-го обработчика
}
finally{
// код, который надо выполнитьв любом случае
} |
265 |
Генерация исключения
1.Создается и запоминается копияобъекта (переменной). Если в точке генерации исключения оказывается недоступен копирующийконструктор,то возникает сообщения об ошибке.
2.Раскручиваетсястек, вызывая деструкторы локальных объектов, выходящих из области видимости.
3.Передается управление ближайшему catсhобработчику, совместимому с типом выброшенного исключения.
•Раскручивание программного стека – процесс удаления из него значений, в результате которого уничтожаются стековые фреймы вызванных функций.
267
2/27/2023
Операторы обработки исключений
•Нормальная ситуация обрабатывается кодом, следующим за ключевым словом try
•Код, располагающийся за ключевым словом catch (в некоторых языкахexcept,resque),выполняется только в исключительных случаях
•Принудительноевыбрасывание исключения осуществляется с помощью оператора throw(в некоторых языкахraise).
•При выбросе исключения выполнение блока try останавливается и начинается выполнение блока catch (обработчика исключения).
•Блок finally выполняется всегдав независимостиоттого имелали местобыть исключительная ситуацияилинет.
266
Обработка исключения
•Обработчик считается найденным, а исключение обработанным, если:
1.Тип исключения соответствует типу, ожидаемому в обработчике. Переменной с типом T соответствует обработчик, перехватывающийT, constT, T&, const T&
2.Обработчик ожидает указатель, и исключениеявляется указателем,который может быть преобразованк типу обработчика по стандартным правилам преобразованиятипа.
3.Встретился обработчик по умолчанию: catch (…) { /*тело обработчика*/}
268
67
![](/html/75508/276/html_8rnNSBwA5c.Iz7G/htmlconvd-6VjTN_68x1.jpg)
Многоуровневая система исключений
•Многоуровневая система должна обеспечить реакцию на любые исключения.
•Компетентные решения по всем аварийным
ситуациям принимаются на высшем уровне. |
269 |
Многоуровневая система исключений
•Можноопределитьперечислениес соответствующими значениями:
enummatherror{ overflow, underflow, zerodivide, /*…*/}; try {
// … matherrorm; throwm;
}
catch ( matherror) { switch (m) {
case overflow: /*…*/ break; case underflow: /*…*/ break; case zerodivide: /*…*/ break; default : /*…*/ ;
}
} |
271 |
|
2/27/2023
Многоуровневая система исключений
•Исключения естественным образом группируются в
семейства.
•MathError (OverflowError, UnderflowError, ZeroDivideError…).
•Без группировки на основе наследованияэто приводит к длинным последовательностям обработчиков.
270
Схема Бертрана Мейера
•Главный недостаток – позволяетуведомить о возникновении исключительнойситуации и продолжить работу => неверныерезультаты.
•Схема Б. Мейера - проектирования по контракту.
1.Модули программнойсистемы, вызывающие друг друга, заключают между собой контракты.
2.Вызывающий модуль обязан обеспечитьистинность предусловия, необходимогодля корректной работы вызванного модуля.
3.Вызванный модуль обязан гарантировать истинность постусловия позавершении своей работы.
4.Возникновение исключительнойситуации в вызванном модуле означает, что он не можетвыполнитьсвою часть контракта - корректно выполнитьвозложенную на него
работу. 272
68
![](/html/75508/276/html_8rnNSBwA5c.Iz7G/htmlconvd-6VjTN_69x1.jpg)
Схема Бертрана Мейера
•Обработчик исключительнойситуации:
•Попытатьсявнести коррективы и вернуть управление охраняемомумодулю Retry, который можетпредпринять очередную попыткувыполнить свой контракт.
•В случае успеха и если работа модулясоответствует его постусловию, то исключение рассматривается как временная успешно преодоленная проблема.
•Если ситуация повторяется, то обработчик применяет стратегию Rescue - выбрасывает исключение и передает управление вызывающему модулю, который должен исправить ситуацию.
•Обработчик должен восстановить состояние, предшествующее вызову модуля, который привел к
исключительнойситуации, и это гарантирует нахождение
всей системыв корректномсостоянии. |
273 |
Полиморфизм
•Полиморфныеобъекты – объекты, принимающие разные формы.
•Полиморфизм– возможность использовать один объект языка (идентификаторили операцию) для выполнения различных действий.
•Полиморфные функции - это те функции, которые имеют полиморфные аргументы.
•Классический полиморфныйоператор – сложение +
1.Складывание целых чисел.
2.Вещественных.
3.Конкатенация строк.
4. И т.д. |
275 |
2/27/2023
ПОЛИМОРФИЗМ
274
Статический полиморфизм
•Статический полиморфизм – множественныеформы конкретизируются на этапе компиляции:
1.Преобразование типов – значение преобразуется из одноготипа в другой;
2.Перегрузка (overloading) – одно и то же имя используется для двух или нескольких разных объектов или подпрограмм (включая операции);
3.Родовой (настраиваемый) сегмент –
параметризованныйшаблон подпрограммы, используется для создания различных конкретных экземпляров подпрограмм.
276
69
![](/html/75508/276/html_8rnNSBwA5c.Iz7G/htmlconvd-6VjTN_70x1.jpg)
Динамический полиморфизм
•Динамический полиморфизм – структурная неопределенность сохраняется до этапа выполнения.
1.Вариантные и неограниченные записи – одна переменная может иметь значение разных типов
2.Диспетчеризация во время выполнения –
механизм, посредством которого разрешение обращения к переопределенному методу осуществляется во время выполнения, а не в о время компиляции. Этот полиморфизм реализуется с помощью виртуальных функций в С++..
277
Преобразование типов
•Изменение типа, которое не затрагиваетбазовые биты значения, называют непреобразующимявным приведением типа.
•Непреобразующее приведение типа в С достигается взятием адреса от объекта, преобразованием типа полученного указателя и последующим разыменованием:
ПримерС, неявное приведение типа: intn;
float r;
r = ((float ) & n);
279
2/27/2023
Преобразование типов
•Преобразование типов – операция преобразования значения одного типа к значению другого типа.
1.Переводзначения одного типа к значению другого типа.
2.Пересылка значения как неинтерпретируемойстроки битов.
ПримерС, явное приведение типа intn;
float r;
r= (float) n; // C n = (int) r; // C
float f = i; // C++ неявное преобразование типов
278
Явное приведениетипов в С++
•Современная версия языка С++ предлагаетчетыре специальных оператора для выполнения явного приведения типа:
•static_cast - обеспечиваетобычные,статические приведения типа.
Пример с++
var_int= static_cast<int>( var_float);
280
70