
- •Цели программирования
- •Области языков программирования. Научные приложения.
- •Области языков программирования. Коммерческие приложения.
- •Области языков программирования. Искусственный интеллект.
- •Области языков программирования. Системное программирование.
- •Области языков программирования. Языки сценариев.
- •Области языков программирования. Web-программирование.
- •9. Уровни языков программирования. Языки ассемблера(история возникновения, отличительные особенности, пример языков).
- •10. Уровни языков программирования. Языки высокого уровня(история возникновения, отличительные особенности, пример языков).
- •11. Методы реализации программ. Компиляция (схема получения результата из исходного кода, преимущества и недостатки, сравнительная таблица).
- •12. Методы реализации программ. Интерпретация (схема получения результата из исходного кода, преимущества и недостатки, сравнительная таблица).
- •14. Методы реализации программ. Трансляция (схема получения результата из исходного кода, преимущества и недостатки, сравнительная таблица).
- •15. Критерии качества программ:
- •16. Алгоритм:
- •17. Способы записи алгоритма. Блок-схемы.
- •18. Способы записи алгоритма. Псевдокод.
- •19. Способы записи алгоритма. Сравнение различных подходов:
- •22. Концепция памяти
- •23. Принципы типизации данных.
- •24. Иерархия простых типов данных.
- •25. Смотри таблицу в конспектах
- •26. Правила приведения типов.
- •27. Оператор sizeof.
- •28. Переменные (объявление, инициализация, присвоение).
- •29. Константы. Специальные символы. Квалификатор const.
- •30. Область видимости переменных.
- •31. Операторы управления областью видимости.
- •32. Группы операций (особенности записи, таблица приоритетов).
- •37. Структурное программирование: историческая справка.
- •38. Принципы структурного программирования.
- •39. Структурное программирование: три базовые конструкции.
- •40. Основные операторы.
- •Пустой оператор.
- •Оператор присваивания (синтаксис, логика работы, полная и сокращённая форма, порядок выполнения, контекст вычисления, пример).
- •Составной оператор (синтаксис, логика работы, пример).
- •Условный оператор.
- •Неоднозначность условного оператора .
- •Оператор выбора (синтаксис, логика работы, пример)
- •48. Цикл с предусловием.
- •49. Цикл с предусловием.
- •50. Цикл с параметром
- •51. Взаимозаменяемость циклов
- •52. Оператор break
- •53. Оператор continue
- •54. Оператор ?: (синтаксис, логика работы, пример)
- •55. Ссылки (понятие, способы применения).
- •56. Подпрограммы (синтаксис, виды подпрограмм, контекст, пример).
- •57. Оператор return.
- •58. Прототипы функций (понятие, назначение, способы применения).
- •59. Библиотеки функций. Оператор #include.
- •60.Создание пользовательских библиотек
- •61. Способы передачи параметров в функции.
- •Способы передачи значения из одной функции в другую.
- •63. Рекурсия
- •64. Значения по умолчанию.
- •65. Перегрузка функции.
- •66.Перезагрузка операторов.
- •67.Шаблоны функций.
- •68. Разрешение неоднозначности при вызове функций.
- •69. Одномерные массивы (объявление, индексация, хранение в памяти, сортировка).
- •70. Типовые алгоритмы обработки элементов массива.
- •71.Двумерные массивы
- •72. Представление двумерного массива в виде одномерного. Соответствие индексов двумерного и одномерного
- •73. Многомерные массивы (объявление, индексация, хранение в памяти, сортировка). Пример
- •74. Указатели (назначение синтаксис, операции).
- •75. Различие между указателями и ссылками.
- •76. Динамическая память (выделение и освобождение памяти под переменные, одномерные массивы, двумерные массивы).
- •77. Тип данных «Массив массивов»
- •78. Представление строк в языках программирования. Достоинства и недостатки различных представлений (отличие ‘a’ от “a”).
- •Функции библиотеки cstring
- •Макросы
- •Типы данных
- •82. Файлы (понятие, текстовые и двоичные файлы, структурированные и неструктурированные, операции, основные библиотеки для работы с файлами).
- •Файловый ввод-вывод с использованием потоков
- •83. Потоковый ввод-вывод. Библиотека потокового ввода-вывода.
- •85. Файловый ввод-вывод. Стандартная библиотека ввода-вывода
- •87.Типовые алгоритмы обработки файлов
- •89.Создание простых бд с помощью массива структур.
- •90. Списки (определение, типовые операции, использование).
- •91. Создание простых бд с помощью списков.
76. Динамическая память (выделение и освобождение памяти под переменные, одномерные массивы, двумерные массивы).
Для хранения информации можно использовать систему динамического выделения памяти. При таком способе память под данные выделяется по мере необходимости из объема свободной памяти, которая располагается между вашей программой (вместе с ее областью хранения постоянных данных) и стеком. Эта область памяти называется – кучей.
Динамическое выделение памяти осуществляется во время выполнения программы. Программа может создать столько переменных, сколько ей требуется в зависимости от ситуации.
ДВП обеспечивает значительное повышение гибкости, но имеет свои ограничения, т.к. память берется из кучи и может исчерпаться.
В С++ существуют два оператора для ДВП: new (выделяет память и возвращает указатель на ее начало) и delete (освобождает память, предварительно выведенную посредством оператора new).
Синтаксис.
x=new тип;
delete x;
Выделение и удаление памяти под одномерные массивы.
x=new тип-массива [размер];
delete []x;
При выделении памяти под массивы им нельзя присвоить начальное значение.
Выделение и удаление памяти под двумерные массивы.
// объявление двумерного динамического массива на 10 элементов: float **ptrarray = new float* [2]; // две строки в массиве for (int count = 0; count < 2; count++) ptrarray[count] = new float [5]; // и пять столбцов // где ptrarray – массив указателей на выделенный участок памяти под массив вещественных чисел типа float
// высвобождение памяти отводимой под двумерный динамический массив:
for (int count = 0; count < 2; count++)
delete [] ptrarray[count];
// где 2 – количество строк в массиве
Динамическое выделение памяти необходимо для эффективного использования памяти компьютера. Например, мы написали какую-то программку, которая обрабатывает массив. При написании данной программы необходимо было объявить массив, то есть задать ему фиксированный размер (к примеру, от 0 до 100 элементов). Тогда данная программа будет не универсальной, ведь может обрабатывать массив размером не более 100 элементов. А если нам понадобятся всего 20 элементов, но в памяти выделится место под 100 элементов, ведь объявление массива было статическим, а такое использование памяти крайне не эффективно.
В С++ есть свой механизм выделения и освобождения памяти — это функции new и delete.
Пример использования new:
int * p = new int[1000000]; // выделение памяти под 1000000 int`ов
Т.е. при использовании функции new не нужно приводить указатель и не нужно использовать sizeof().
Освобождение выделенной при помощи new памяти осуществляется посредством следующего вызова:
delete [] p;
Если требуется выделить память под один элемент, то можно использовать
int * q = new int;
или
int * q = new int(10); // выделенный int проинциализируется значением 10
в этом случае удаление будет выглядеть следующим образом:
delete q;
Существует также специальная операция взятия адреса, обозначаемая символом &. Ее результатом является адрес объекта. Следующий оператор присваивает указателю pint адрес переменной ival:
int *pint;
pint = &ival; // pint получает значение адреса ival
Мы можем обратиться к тому объекту, адрес которого содержит pint (ival в нашем случае), используя операцию разыменования, называемую также косвенной адресацией. Эта операция обозначается символом *. Вот как можно косвенно прибавить единицу к ival, используя ее адрес:
*pint = *pint + 1; // неявно увеличивает ival
Это выражение производит в точности те же действия, что и
ival = ival + 1; // явно увеличивает ival
В этом примере нет никакого реального смысла: использование указателя для косвенной манипуляции переменной ival менее эффективно и менее наглядно. Мы привели этот пример только для того, чтобы дать самое начальное представление об указателях. В реальности указатели используют чаще всего для манипуляций с динамически размещенными объектами.
Основные отличия между статическим и динамическим выделением памяти таковы:
статические объекты обозначаются именованными переменными, и действия над этими объектами производятся напрямую, с использованием их имен. Динамические объекты не имеют собственных имен, и действия над ними производятся косвенно, с помощью указателей;
выделение и освобождение памяти под статические объекты производится компилятором автоматически. Программисту не нужно самому заботиться об этом. Выделение и освобождение памяти под динамические объекты целиком и полностью возлагается на программиста. Это достаточно сложная задача, при решении которой легко наделать ошибок. Для манипуляции динамически выделяемой памятью служат операторы new и delete.
Оператор new имеет две формы. Первая форма выделяет память под единичный объект определенного типа:
int *pint = new int(1024);
Здесь оператор new выделяет память под безымянный объект типа int, инициализирует его значением 1024 и возвращает адрес созданного объекта. Этот адрес используется для инициализации указателя pint. Все действия над таким безымянным объектом производятся путем разыменовывания данного указателя, т.к. явно манипулировать динамическим объектом невозможно.
Вторая форма оператора new выделяет память под массив заданного размера, состоящий из элементов определенного типа:
int *pia = new int[4];
В этом примере память выделяется под массив из четырех элементов типа int. К сожалению, данная форма оператора new не позволяет инициализировать элементы массива.
Некоторую путаницу вносит то, что обе формы оператора new возвращают одинаковый указатель, в нашем примере это указатель на целое. И pint, и pia объявлены совершенно одинаково, однако pint указывает на единственный объект типа int, а pia – на первый элемент массива из четырех объектов типа int.
Когда динамический объект больше не нужен, мы должны явным образом освободить отведенную под него память. Это делается с помощью оператора delete, имеющего, как и new, две формы – для единичного объекта и для массива:
// освобождение единичного объекта
delete pint;
// освобождение массива
delete[] pia;
Что случится, если мы забудем освободить выделенную память? Память будет расходоваться впустую, она окажется неиспользуемой, однако возвратить ее системе нельзя, поскольку у нас нет указателя на нее. Такое явление получило специальное название утечка памяти. В конце концов программа аварийно завершится из-за нехватки памяти (если, конечно, она будет работать достаточно долго). Небольшая утечка трудно поддается обнаружению, но существуют утилиты, помогающие это сделать.
Наш сжатый обзор динамического выделения памяти и использования указателей, наверное, больше породил вопросов, чем дал ответов. В разделе 8.4 затронутые проблемы будут освещены во всех подробностях. Однако мы не могли обойтись без этого отступления, так как класс Array, который мы собираемся спроектировать в последующих разделах, основан на использовании динамически выделяемой памяти.