Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Программирование – 1 курс осень 2021 – 7 занятие

F21d69109b1c03921abf7d12f0fb6654?s=47 ТиМПИ
October 22, 2021

Программирование – 1 курс осень 2021 – 7 занятие

F21d69109b1c03921abf7d12f0fb6654?s=128

ТиМПИ

October 22, 2021
Tweet

Transcript

  1. 22 октября 2021 aak@dscs.pro Анастасия Андреевна Корепанова Стек вызовов

  2. 2/38 2/38 Порядок выполнения main() bar(a, b, c) foo(a, b,

    c)
  3. 3/38 3/38 Память программы Источник: https://learnc.info/c/program_structure.html Область памяти для глобальных

    и статических переменных Область динамической памяти (куча) Стек вызовов Область кода
  4. 4/38 4/38 Стек 1/2 • При запуске программы (процесса) операционная

    система выделяет ей область в оперативной памяти. В этой области среди прочего располагается стек. • Стек вызовов — это структура, хранящая локальную информацию исполняемой функции, а также информацию для возврата управления из подпрограмм (функций) в программу или подпрограмму. • LIFO — «last in first out». • Максимальный размер стека всегда ограничен. Может быть 4 Мб (для Windows обычно 1 МБ). данные функции 1 данные функции 2 данные функции 3 данные функции 4 данные функции 5 данные функции 6
  5. 5/38 5/38 Стек 2/2 Вот почему очень важно инициализировать переменные!

    Данные функции 1 Данные функции 2 Данные функции 1 Данные функции 2 Данные функции 1 Данные функции 2 Данные функции 3 x = 4 str = “Слава СССР” bin = true … Призрак функции 3 x = 4 str = “Слава СССР bin = true … Данные функции 4 y = 4 b = “Слава СССР” d = true …
  6. 6/38 6/38 Кадр стека • Данные одной функции лежат в

    одном кадре стека (stack frame) • В одном кадре стека содержатся локальные переменные функции, значения регистров процессора, которые надо будет восстановить после выполнения следующей вызываемой функции, адрес инструкции, которая будет выполнена после возврата из функции, резервируется место для возвращаемого значения вызываемой функции, промежуточные значения при вычислении сложных выражений тоже хранятся на стеке • На самом деле, всё зависит от конкретной архитектуры, но примерно так реализовано Локальные переменные функции Аргументы вызова следующей функции Место возвращаемого значения следующей функции Адрес возврата Регистры процессора Frame pointer Stack pointer Локальные переменные функции Frame pointer Stack pointer
  7. 7/38 7/38 Кадр стека: пример

  8. 8/38 8/38 Уязвимости 1/2 • Переполнение стека (stack overflow) Стек

    очень ограничен в объёме, при вызове слишком большого числа вложеннных функций / инициализации слишком большого числа переменных стек может переполниться Причины возникновения: 1. Бесконечная рекурсия 2. Очень глубокая рекурсия 3. Очень большие переменные
  9. 9/38 9/38 Уязвимости 2/2 • Переполнение буффера (buffer overflow) Функции

    начинают писать и обращаться не к своим кадрам стека. Данные функции 1 Данные функции 2 Данные функции 3 x = 4 str = “Слава СССР” bin = true …
  10. 10/38 10/38 Код, который не вызывает stackoverflow

  11. 11/38 11/38 Рекурсия и хвостовая рекурсия • Рекурсивная функция –

    это функция, которая вызывает сама себя. • Хвостовая рекурсия – рекурсия, в которой последней операцией перед выходом из функции является рекурсивный вызов. • Давайте напишем факториал!
  12. 12/38 12/38 Ещё раз про память программы Источник: https://learnc.info/c/program_structure.html Область

    памяти для глобальных и статических переменных Область динамической памяти (куча) Стек вызовов Область кода Не так всё просто!!!
  13. 22 октября 2021 aak@dscs.pro Анастасия Андреевна Корепанова Библиотека ввода и

    вывода
  14. 14/38 14/38 План занятия 1. Кодировки 2. Работа со строками

    3. Ввод и вывод 4. Понятие файла
  15. 15/38 15/38 Кодировки: зачем?

  16. 16/38 16/38 Кодировки • ASCII, UTF-8 и т.д. • Char,

    wchar_t, char16_t и char32_t • В начале файла может быть BOM • А как понять, какая кодировка? Количество октетов Значащих бит Шаблон 1 7 0xxxxxxx 2 11 110xxxxx 10xxxxxx 3 16 1110xxxx 10xxxxxx 10xxxxxx 4 36 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
  17. 17/38 17/38 Строки • Строки — массивы символов типа char,

    заканчивающиеся нулевым символом. • Строки могут содержать управляющие последовательности: 1. \n — перевод строки, 2. \t — символ табуляции, 3. \\ — символ «\», 4. \” — символ «”» 5. \0 — завершающий строку символ. Экранирование служебных символов * Вспомним: что такое массивы?
  18. 18/38 18/38 Инициализация строк

  19. 19/38 19/38 Вопрос 1 Вывод: ??? 1. \n — перевод

    строки, 2. \t — символ табуляции, 3. \\ — символ «\», 4. \” — символ «”» 5. \0 — нулевой символ.
  20. 20/38 20/38 Ответ 1 Вывод: He____ll 1. \n — перевод

    строки, 2. \t — символ табуляции, 3. \\ — символ «\», 4. \” — символ «”» 5. \0 — нулевой символ.
  21. 21/38 21/38 Работа со строками в стиле C • Библиотека

    cstring предлагает множество функций для работы со строками. Под строками в данной библиотеке подразумеваются указатели типа char (char *)
  22. 22/38 22/38 Работа со строками в стиле C++ • Библиотека

    string предлагает обёртку над строками, которая позволяет упростить все операции со строками.
  23. 23/38 23/38 Вопрос 2 Вывод: ??? 1. \n — перевод

    строки, 2. \t — символ табуляции, 3. \\ — символ «\», 4. \” — символ «”» 5. \0 — нулевой символ.
  24. 24/38 24/38 Ответ 2 Вывод: He____ll 4 1. \n —

    перевод строки, 2. \t — символ табуляции, 3. \\ — символ «\», 4. \” — символ «”» 5. \0 — нулевой символ.
  25. 25/38 25/38 String vs Cstring • Cstring позволяет экономить память.

    • Требует больше внимательности. • Следует использовать, есть очень жёсткие требования по памяти, а также если придётся работать с C библиотеками, которые требуют такой формат ввода. • String более удобна. • Выделение/высвобождение динамической памяти может вести к дефрагментации памяти. • В целом требует больше ресурсов. • Следует использовать во всех остальных случаях.
  26. 26/38 26/38 Потоки ввода и вывода • Поток (англ. stream)

    – это абстракция, используемая для чтения и записи файлов, сокетов и т.п. в единой манере. Потенциально бесконечная последовательность данных, к которым можно получать последовательный доступ.
  27. 27/38 27/38 Ввод и вывод в стиле C • Библиотека

    cstdio Почему может быть небезопасно?
  28. 28/38 28/38 Ввод и вывод в стиле C++ 1/2 •

    Библиотека <iostream> Плюсы: 1. Типобезопасна. 2. Гораздо более удобна ☺. 3. Есть строковые потоки. 4. Можно писать вывод для своих структур и классов.
  29. 29/38 29/38 Ввод и вывод в стиле C++ 2/2 •

    <iostream>: • istream, wistream — читают данные из потока. • ostream, wostream — записывают данные в поток. • iostream, wiostream — читают и записывают данные в поток. • <fstream>: • ifstream, wifstream — читают данные из файла. • ofstream, wofstream — записывают данные в файл. • fstream, wfstream — читают и записывают данные в файл. • <sstream> • istringstream, wistringstream — читают данные из строки. • ostringstream, wostringstream — записывают данные в строку. • stringstream, wstringstream — читают и записывают данные в строку.
  30. 30/38 30/38 Методы класса iostream operator>> Оператор извлечения данных. Игнорирует

    все пробелы, символы табуляции и символ новой строки get Извлекает символ из входного потока. Не считывает символ новой строки getline Извлекает символ из входного потока. peek Подсматривает следующий символ в потоке putback Кладет последний считанный символ обратно
  31. 31/38 31/38 Буфер • Каждый объект ввода-вывода управляет буфером, используемым

    для хранения данных, которые программа читает или записывает. • Использование буфера позволяет операционной системе объединить несколько операций вывода данной программы. • Запись в устройство медленное, возможность операционной системы объединить несколько операций вывода в одну способствует повышению производительности.
  32. 32/38 32/38 Сброс буфера • Программа завершается нормально. Все буфера

    вывода освобождаются при выходе из функции main (). • В некий случайный момент времени буфер может оказаться заполненным. В этом случае перед записью следующего значения происходит сброс буфера. • Сброс буфера можно осуществить явно, использовав такой манипулятор, как endl. • Используя манипулятор unitbuf, можно установить такое внутреннее состояние потока, чтобы буфер освобождался после каждой операции вывода. Для объекта cerr манипулятор unitbuf установлен по умолчанию, поэтому запись в него приводит к немедленному выводу.
  33. 33/38 33/38 Внимание • Буфер вывода не сбрасывается, если программа

    завершается аварийно. • При попытке отладить аварийно завершающуюся программу необходимо гарантировать, что любой подозрительный вывод будет сброшен сразу.
  34. 34/38 34/38 Ввод и вывод в файл fstream fstrm Создает

    несвязанный файловый поток, fst ream — это один из типов, определенных в заголовке fstream fstream fstrm(s) Создает объект класса fstream и открывает файл по имени s. fstream fstrm (s, режим) Подобен предыдущему конструктору, но открывает файл s в указанном режиме fstrm.open (s) fstrm.open (s, режим) Открывает файл s и связывает его с потоком fstrm. fstrm.close() Закрывает файл, с которым связан поток fstrm. fstrm.is_open () Возвращает значение типа bool, указывающее, был ли cвязанный с потоком fstrm файл успешно открыт и не был ли он закрыт
  35. 35/38 35/38 Класс std::ios_base Константа Описание ios_base::in открыть файл для

    чтения ios_base::out открыть файл для записи ios_base::ate при открытии переместить указатель в конец файла ios_base::app открыть файл для записи в конец файла ios_base::trunc удалить содержимое файла, если он существует ios_base::binary открытие файла в двоичном режиме
  36. 36/38 36/38 Резюме Язык C++ использует библиотечные классы для обработки

    потоков ввода и вывода. • Класс iоstrеam отрабатывает ввод-вывод на консоль. • Класс fstream отрабатывает ввод-вывод в именованным файл. • Класс stringstream отрабатывает ввод-вывод в строки в оперативной памяти. Классы fstream и stringstream связаны происхождением от класса iostream. Классы ввода происходят от класса istream, а классы вывода— от класса ostгearn. Таким образом, операции, которые могут быть выполнены с объектом класса istream, могут быть также выполнены с объектом класса ifstream или istringstream. Аналогично для классов вывода, происходящих от класса ostream.
  37. 37/38 37/38 Задачи на практику • Написать вычисление чисел Фибоначчи

    с помощью рекурсии и без неё. • Попробовать уронить программу с помощью переполнения стека. • Ввести строку и заменить все встречающиеся в ней суммы натуральных чисел на их результаты. Например, при вводе 5+26-72+35gh32+45. Результат должен быть 31-107gh77. • Написать программу, которая из файла получает строку с математическим выражением и разбивает ее на обратную польскую запись и выводит в файл следующей строкой. • Ввести строку и после каждого вхождения в нее подстроки «password:» заменить восемь следующих символов на звездочки.
  38. 22 октября 2021 aak@dscs.pro Анастасия Андреевна Корепанова Стек вызовов