Это сообщение поясняющее что выполняется в данном месте программы

Обновлено: 06.07.2024

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

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

Функция TranslateMessage связана с вводом с клавиатуры. Он преобразует нажатия клавиш (Клавиша вниз, клавиша вверх) в символы. Вам не обязательно быть уверенным в том, как работает эта функция. просто не забудьте вызвать ее перед DispatchMessage. Если вас интересуют, ссылка на документацию MSDN предоставит вам дополнительные сведения.

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

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

Терминология этого отличия может быть запутанной:

Комментарий может занимать более чем одну строку. Если комментарий занимает только одну строку он может начинаться символами //, за которыми следует любой текст. Если комментарий занимает более одной строки, то либо каждую строку комментария нужно начинать с //, либо выделить начало его символами /* (начало) и */ (конец).

Типы данных

Данные в С(С++) могут быть простыми и структурированными. К данным простого типа относятся целые и вещественные числа, текстовая информация, указатели (адреса). В С имеются следующие 5 базовые типов: char( символьный), int (целый), float (вещественный), double (вещественный с двойной точностью), void (пустой тип). За исключением типа void перечисленные типы данных могут иметь модификаторы. К модификаторам относятся: unsigned (беззнаковый), signed (знаковый), short (короткий), long (длинный).

Тип данных и модификатор типа определяют:

- формат хранения данных в оперативной памяти (внутреннее представление данных);

- диапазон значений, в пределах которого может изменяться переменная;

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

Все типы данных можно разделить на две категории: скалярные и составные (рис.8).


Рис 8. Типы данных .

В языке С(С++) различают понятия: описание и объявление. Описание устанавливает свойства объекта: тип, размер и так далее. Объявление приводит к выделению памяти для объекта некоторого типа. Для рассмотрения различия указанных типов данных (с точки зрения их размеров) надо познакомиться с терминами "биты", "байты", "слова".

Наименьшая единица памяти называется бит. Она может принимать одно из двух значений 0 или 1. Наименьшей адресуемой единицей памяти ПЭВМ является байт. Байт представляет собой комбинацию из 8 бит. Для удобства обмена информацией байты могут быть объединены (информационно) в слова (16,32,64 - разрядные).

Целые числа и числа с плавающей запятой в ЭВМ отличаются по размеру и способу хранения.

Данные целого типа

В таблице 1 приведены характеристики данных целого типа:

signed short int

unsigned short int

signed long int

unsigned long int

0. 4 294 967 295

double long int

Как видно из приведенной таблицы размер памяти для типов int и unsigned int не определены в языке C(С++). По умолчанию размер int соответствует размеру машинного слова. Например, на 16-разрядной машине тип int всегда 16 бит, или 2 байта (слово). На 32-разрядной машине тип int всегда 32 бита, или 4 байта (слово). Таким образом, тип int эквивалентен типам short int или long int в зависимости от реализации. Аналогично тип unsigned int эквивалентен типам unsigned short или unsigned long. Поэтому программы, зависящие от спецификации размера int и unsigned int, могут быть непереносимы.

В процессе объявления переменные могут быть инициализированы, т.е. им присваиваются начальные значения, которые в ходе выполнения программы могут изменяться. При этом компилятор, как правило, не выполняет проверку на соответствие присваиваемого значения и типа переменной (например, int i=999999), а выдает лишь предупреждение.

Если в процессе работы требуется информация о размере некоторого объекта (или его типа), то может быть использована операция sizeof (имя_объекта), возвращающая число байт объекта. Например:

i=sizeof(int); // i равно числу байт отводимых для объектов типа int

j=sizeof(long int); // j аналогично, но для данных типа типа long int

k=sizeof(i); // к размер памяти занимаемой переменной i

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


На этом уроке учащиеся вспомнят о том, как организованы разветвляющиеся алгоритмы, и перейдут к изучению их программирования на языке Pascal. Будут рассмотрены сокращённая и полная формы записи условного оператора, а также составной оператор. Также будет разобрано решение нескольких задач с использованием этого типа алгоритмов.


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

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

Получите невероятные возможности




Конспект урока "Программирование разветвляющихся алгоритмов. Простой и составной условные операторы"

· Определение разветвляющегося алгоритма.

· Операторы, используемые для записи разветвляющихся алгоритмов в языке Pascal.

· Простой и составной условные операторы.

Далеко не все алгоритмы можно свести к простой последовательности действий. Иногда действия изменяются в зависимости от некоторых условий. Например, если будет солнечная погода – Миша пойдёт играть в футбол, в противном случае – он останется дома и будет придумывать полезные программы, которые он мог бы написать.


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

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


Блок-схема разветвляющегося алгоритма

Для записи конструкции ветвления в языке Pascal используется условный оператор. У условного оператора в языке программирования Паскаль есть две формы записи: полная и сокращённая. В сокращённой форме для записи условного оператора используется служебное слово if. После него через пробел следует условие. В роли условия выступает логическое выражение, простое или сложное. После условия на следующей строке записывается служебное слово then. После него следует оператор, который будет выполнен, если будет выполняться указанное условие. После оператора следует точка с запятой. В полной форме записи условного оператора следует всё тоже самое, однако после оператора, следующего после слова then, точка с запятой не ставится. Вместо этого знака на следующей строке записывается служебное слово else. После него следует оператор, который будет выполнен, если указанное условие выполнятся не будет. После него следует точка с запятой.


Задача: Написать программу для определения наибольшего из двух чисел, введённых пользователем. Если числа равны между собой – вывести любое из них.


program max;

writeln ('Программа нахождения большего из 2 чисел. Введите 2 числа.');

then write (a, ' - наиболешее из 2 чисел.')

else write (b, ' - наибольшее из 2 чисел.');

Исходный код программы

Запустим программу на выполнение. Введём сначала числа 35 и 74. Число 74 действительно наибольшее.


Снова запустим программу и введём числа 100 и 99. Наибольшим действительно является число 100.


Снова запустим программу и дважды введём 5. Так, как числа равны между собой программа вывела что наибольшее число – 5.


Программа работает правильно, задача решена.

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

Составной условный оператор

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

Вложенный условный оператор

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

Обозначим через a, b и с длины отрезков. Давайте вспомним, как определить, могут ли отрезки быть сторонами треугольника. Для этого необходимо, чтобы длина наибольшего из отрезков была меньше суммы двух остальных.


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


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

Вводимые данные направляются системой для каждого окна отдельно. В этих целях каждое окно связано с функцией называемой ОКОННОЙ ПРОЦЕДУРОЙ. Если для какого-либо из окон есть какая-то входящая информация, то система запускает (вызывает) соответствующую оконную процедуру, передавая ей введенную информацию. Оконная процедура должна обработать полученную информацию и вернуть управление обратно системе.

MSG msg;
BOOL bRet;

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

Тупиковые ситуации

Перечень функций, которые могут не вернуть управление потоку:
DialogBox
DialogBoxIndirect
DialogBoxIndirectParam
DialogBoxParam
GetMessage
MessageBox
PeekMessage
SendMessage

PostQuitMessage - показывает системе, что поток сделал запрос на свое завершение.

SendAsyncProc - функция используемая совместно с функцией SendMessageCallback

П рограмма, написанная на языке Python, останавливается сразу как обнаружит ошибку. Ошибки могут быть (как минимум) двух типов:

  • Синтаксические ошибки — возникают, когда написанное выражение не соответствует правилам языка (например, написана лишняя скобка);
  • Исключения — возникают во время выполнения программы (например, при делении на ноль).

Как устроен механизм исключений

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

💁‍♂️ Пример : напишем скрипт, в котором функция ожидает число, а мы передаём сроку (это вызовет исключение "TypeError"):

В данном примере мы запускаем файл " test.py " (через консоль). Вызывается функция " a ", внутри которой вызывается функция " b ". Все работает хорошо до сточки print(value + 1) . Тут интерпретатор понимает, что нельзя конкатенировать строку с числом, останавливает выполнение программы и вызывает исключение "TypeError".

Далее ошибка передается по цепочке в обратном направлении: " b " → " a " → " test.py ". Так как в данном примере мы не позаботились обработать эту ошибку, вся информация по ошибке отобразится в консоли в виде Traceback.

Traceback (трассировка) — это отчёт, содержащий вызовы функций, выполненные в определенный момент. Трассировка помогает узнать, что пошло не так и в каком месте это произошло.

Traceback лучше читать снизу вверх ↑

В нашем примере Traceback содержится следующую информацию (читаем снизу вверх):

  1. TypeError — тип ошибки (означает, что операция не может быть выполнена с переменной этого типа);
  2. can only concatenate str (not "int") to str — подробное описание ошибки (конкатенировать можно только строку со строкой);
  3. Стек вызова функций (1-я линия — место, 2-я линия — код). В нашем примере видно, что в файле "test.py" на 11-й линии был вызов функции "a" со строковым аргументом "10". Далее был вызов функции "b". print(value + 1) это последнее, что было выполнено — тут и произошла ошибка.
  4. most recent call last — означает, что самый последний вызов будет отображаться последним в стеке (в нашем примере последним выполнился print(value + 1) ).

В Python ошибку можно перехватить, обработать, и продолжить выполнение программы — для этого используется конструкция try . except . .

Как обрабатывать исключения в Python (try except)

В Python исключения обрабатываются с помощью блоков try/except . Для этого операция, которая может вызвать исключение, помещается внутрь блока try . А код, который должен быть выполнен при возникновении ошибки, находиться внутри except .

Например, вот как можно обработать ошибку деления на ноль:

try: a = 7 / 0 except: print('Ошибка! Деление на 0')

💭 PEP 8 рекомендует, по возможности, указывать конкретный тип исключения после ключевого слова except (чтобы перехватывать и обрабатывать конкретные исключения):

try: a = 7 / 0 except ZeroDivisionError: print('Ошибка! Деление на 0')

Однако если вы хотите перехватывать все исключения, которые сигнализируют об ошибках программы, используйте тип исключения Exception :

try: a = 7 / 0 except Exception: print('Любая ошибка!')

As — сохраняет ошибку в переменную

Перехваченная ошибка представляет собой объект класса, унаследованного от "BaseException". С помощью ключевого слова as можно записать этот объект в переменную, чтобы обратиться к нему внутри блока except :

try: file = open('ok123.txt', 'r') except FileNotFoundError as e: print(e) > [Errno 2] No such file or directory: 'ok123.txt'

В примере выше мы обращаемся к объекту класса "FileNotFoundError" (при выводе на экран через print отобразится строка с полным описанием ошибки).

У каждого объекта есть поля, к которым можно обращаться (например если нужно логировать ошибку в собственном формате):

import datetime now = datetime.datetime.now().strftime("%d-%m-%Y %H:%M:%S") try: file = open('ok123.txt', 'r') except FileNotFoundError as e: print(f" [FileNotFoundError]: , filename: ") > 20-11-2021 18:42:01 [FileNotFoundError]: No such file or directory, filename: ok123.txt

Finally — выполняется всегда

При обработке исключений можно после блока try использовать блок finally . Он похож на блок except , но команды, написанные внутри него, выполняются обязательно. Если в блоке try не возникнет исключения, то блок finally выполнится так же, как и при наличии ошибки, и программа возобновит свою работу.

Обычно try/except используется для перехвата исключений и восстановления нормальной работы приложения, а try/finally для того, чтобы гарантировать выполнение определенных действий (например, для закрытия внешних ресурсов, таких как ранее открытые файлы).

В следующем примере откроем файл и обратимся к несуществующей строке:

file = open('ok.txt', 'r') try: lines = file.readlines() print(lines[5]) finally: file.close() if file.closed: print("файл закрыт!") > файл закрыт! > Traceback (most recent call last): > File "test.py", line 5, in > print(lines[5]) > IndexError: list index out of range

Даже после исключения "IndexError", сработал код в секции finally , который закрыл файл.

p.s. данный пример создан для демонстрации, в реальном проекте для работы с файлами лучше использовать менеджер контекста with.

Также можно использовать одновременно три блока try/except/finally . В этом случае:

  • в try — код, который может вызвать исключения;
  • в except — код, который должен выполниться при возникновении исключения;
  • в finally — код, который должен выполниться в любом случае.

Else — выполняется когда исключение не было вызвано

Иногда нужно выполнить определенные действия, когда код внутри блока try не вызвал исключения. Для этого используется блок else .

Допустим нужно вывести результат деления двух чисел и обработать исключения в случае попытки деления на ноль:

b = int(input('b = ')) c = int(input('c = ')) try: a = b / c except ZeroDivisionError: print('Ошибка! Деление на 0') else: print(f"a = ") > b = 10 > c = 1 > a = 10.0

Несколько блоков except

В программе может возникнуть несколько исключений, например:

  1. Ошибка преобразования введенных значений к типу float ("ValueError");
  2. Деление на ноль ("ZeroDivisionError").

В Python, чтобы по-разному обрабатывать разные типы ошибок, создают несколько блоков except :

try: b = float(input('b = ')) c = float(input('c = ')) a = b / c except ZeroDivisionError: print('Ошибка! Деление на 0') except ValueError: print('Число введено неверно') else: print(f"a = ") > b = 10 > c = 0 > Ошибка! Деление на 0 > b = 10 > c = питон > Число введено неверно

Теперь для разных типов ошибок есть свой обработчик.

Несколько типов исключений в одном блоке except

try: b = float(input('b = ')) c = float(input('c = ')) a = b / c except (ZeroDivisionError, ValueError) as er: print(er) else: print('a = ', a)

При этом переменной er присваивается объект того исключения, которое было вызвано. В результате на экран выводятся сведения о конкретной ошибке.

Raise — самостоятельный вызов исключений

Исключения можно генерировать самостоятельно — для этого нужно запустить оператор raise .

min = 100 if min > 10: raise Exception('min must be less than 10') > Traceback (most recent call last): > File "test.py", line 3, in > raise Exception('min value must be less than 10') > Exception: min must be less than 10

min = 100 try: if min > 10: raise Exception('min must be less than 10') except Exception: print('Моя ошибка') > Моя ошибка

Кроме того, ошибку можно обработать в блоке except и пробросить дальше (вверх по стеку) с помощью raise :

min = 100 try: if min > 10: raise Exception('min must be less than 10') except Exception: print('Моя ошибка') raise > Моя ошибка > Traceback (most recent call last): > File "test.py", line 5, in > raise Exception('min must be less than 10') > Exception: min must be less than 10

Как пропустить ошибку

Иногда ошибку обрабатывать не нужно. В этом случае ее можно пропустить с помощью pass :

try: a = 7 / 0 except ZeroDivisionError: pass

Исключения в lambda функциях

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

20 типов встроенных исключений в Python

Иерархия классов для встроенных исключений в Python выглядит так:

BaseException SystemExit KeyboardInterrupt GeneratorExit Exception ArithmeticError AssertionError . . . ValueError Warning

Все исключения в Python наследуются от базового BaseException :

  • SystemExit — системное исключение, вызываемое функцией sys.exit() во время выхода из приложения;
  • KeyboardInterrupt — возникает при завершении программы пользователем (чаще всего при нажатии клавиш Ctrl+C);
  • GeneratorExit — вызывается методом close объекта generator ;
  • Exception — исключения, которые можно и нужно обрабатывать (предыдущие были системными и их трогать не рекомендуется).

От Exception наследуются:

1 StopIteration — вызывается функцией next в том случае если в итераторе закончились элементы;

2 ArithmeticError — ошибки, возникающие при вычислении, бывают следующие типы:

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

3 AssertionError — выражение, используемое в функции assert неверно;

4 AttributeError — у объекта отсутствует нужный атрибут;

5 BufferError — операция, для выполнения которой требуется буфер, не выполнена;

6 EOFError — ошибка чтения из файла;

7 ImportError — ошибка импортирования модуля;

8 LookupError — неверный индекс, делится на два типа:

  • IndexError — индекс выходит за пределы диапазона элементов;
  • KeyError — индекс отсутствует (для словарей, множеств и подобных объектов);

9 MemoryError — память переполнена;

10 NameError — отсутствует переменная с данным именем;

11 OSError — исключения, генерируемые операционной системой:

  • ChildProcessError — ошибки, связанные с выполнением дочернего процесса;
  • ConnectionError — исключения связанные с подключениями (BrokenPipeError, ConnectionResetError, ConnectionRefusedError, ConnectionAbortedError);
  • FileExistsError — возникает при попытке создания уже существующего файла или директории;
  • FileNotFoundError — генерируется при попытке обращения к несуществующему файлу;
  • InterruptedError — возникает в том случае если системный вызов был прерван внешним сигналом;
  • IsADirectoryError — программа обращается к файлу, а это директория;
  • NotADirectoryError — приложение обращается к директории, а это файл;
  • PermissionError — прав доступа недостаточно для выполнения операции;
  • ProcessLookupError — процесс, к которому обращается приложение не запущен или отсутствует;
  • TimeoutError — время ожидания истекло;

12 ReferenceError — попытка доступа к объекту с помощью слабой ссылки, когда объект не существует;

13 RuntimeError — генерируется в случае, когда исключение не может быть классифицировано или не подпадает под любую другую категорию;

14 NotImplementedError — абстрактные методы класса нуждаются в переопределении;

15 SyntaxError — ошибка синтаксиса;

16 SystemError — сигнализирует о внутренне ошибке;

17 TypeError — операция не может быть выполнена с переменной этого типа;

18 ValueError — возникает когда в функцию передается объект правильного типа, но имеющий некорректное значение;

19 UnicodeError — исключение связанное с кодирование текста в unicode , бывает трех видов:

  • UnicodeEncodeError — ошибка кодирования;
  • UnicodeDecodeError — ошибка декодирования;
  • UnicodeTranslateError — ошибка перевода unicode .

20 Warning — предупреждение, некритическая ошибка.

💭 Посмотреть всю цепочку наследования конкретного типа исключения можно с помощью модуля inspect :

import inspect print(inspect.getmro(TimeoutError)) > ( , , , , )

📄 Подробное описание всех классов встроенных исключений в Python смотрите в официальной документации .

Как создать свой тип Exception

В Python можно создавать свои исключения. При этом есть одно обязательное условие: они должны быть потомками класса Exception :

class MyError(Exception): def __init__(self, text): self.txt = text try: raise MyError('Моя ошибка') except MyError as er: print(er) > Моя ошибка

С помощью try/except контролируются и обрабатываются ошибки в приложении. Это особенно актуально для критически важных частей программы, где любые "падения" недопустимы (или могут привести к негативным последствиям). Например, если программа работает как "демон", падение приведет к полной остановке её работы. Или, например, при временном сбое соединения с базой данных, программа также прервёт своё выполнение (хотя можно было отловить ошибку и попробовать соединиться в БД заново).

Вместе с try/except можно использовать дополнительные блоки. Если использовать все блоки описанные в статье, то код будет выглядеть так:

Подробнее о работе с исключениями в Python можно ознакомиться в официальной документации .

Читайте также: