- •1.Принципиальная схема компьютера. Потоки управления и потоки данных.
- •3. Принципы фон Неймана.
- •4. Создание исполняемых программ в машинных кодах, на Ассемблере и на языках высокого уровня.
- •5. Компиляторы и интерпретаторы, их преимущества и недостатки.
- •6. Классификация программных кодов. Схема создания исполняемого кода.
- •8. Определение и свойства алгоритма. Способы записи алгоритмов.
- •9. Блок-схемы. Основные управляющие структуры блок-схем.
- •10. Технологии программирования. Структурное программирование.
- •17. Операторы присваивания, инкремента и декремента. L-value выражения.
- •18. Условный оператор. Оператор запятая.
- •19. Инструкция-выражение. Инструкции выбора if и switch.
- •20. Инструкции передачи управления..
- •22. Алгоритмы обработки числовых данных (алгоритм Евклида, нахождение всех делителей числа, нахождение простых делителей числа, нахождение простых чисел, чисел Фибоначчи).
- •23. Указатели. Типизированные и безтиповые указатели. Операция разыменования и операция получения адреса.
- •25. Арифметические операции над указателями.
- •26. Проблемы и типичные ошибки при работе с указателями.
- •30. Двумерные и многомерные массивы (алгоритмы обработки матриц).
- •31. Многомерные массивы. Реализация многомерных массивов с помощью указателей.
- •32. Динамическое выделение памяти под одномерные и двумерные массивы.
- •34.Передача массивов в качестве параметров.
- •35. Подпрограммы. Определение и объявление подпрограмм. Процедуры и функции.
- •36.Формальные и фактические параметры. Соответствие типов в формальных и фактических параметрах.
- •38. Механизм работы с модифицируемыми параметрами, использующий указатели.
- •40. Использование ссылочного типа при выходе из подпрограмм. Константные ссылки.
- •41. Побочный эффект подпрограмм, его преимущества и недостатки.
- •42. Рекурсия. Формы рекурсивных подпрограмм. Глубина и текущий уровень рекурсии.
- •43. Зацикливание рекурсивных подпрограмм. Примеры неэффективности рекурсии.
- •44. Перегрузка функций. Ошибки, возникающие при перегрузке функций.
- •45.Указатели на функции. Callback-функции.
- •46. Функция main. Передача параметров в функцию main.
- •47. Директивы препроцессора. Директивы #pragma и #include.
- •48. Директивы #define и #undef. Константы времени компиляции.
- •49. Макросы. Преимущества и недостатки использования макросов.
- •50.Директивы условной компиляции. Страж включения.
- •51. Пространства имён. Работа с пространствами имён. Оператор using. Приоритеты и конфликты имён.
- •52. Строки. Операции над строками.
- •54. Строки string. Функции стандартной библиотеки для обработки строк.
- •55. Основные алгоритмы обработки строк (выделение слова, подстроки, разбиение на слова, поиск символа, поиск слова).Ответ в 53.
- •56. Пользовательские типы данных. Перечислимый тип enum.
- •57. Пользовательские типы данных. Тип struct. Массивы структур.
- •58. Объединения (union). Битовые поля.
- •59. Понятие сложности алгоритма. Оценка сложности с использованием о-символики.
- •60. Алгоритмы сортировки и поиска. Обменные сортировки. Сортировки вставками. Сортировки выбором. Сравнительный анализ методов сортировки.
- •61. Последовательный поиск. Бинарный поиск. Сравнительный анализ методов поиска.
- •62. Файлы. Основные принципы работы с файлами. Механизм чтения данных из файла. Определение конца файла. Открытие и закрытие файлов.
- •63. Текстовые файлы. Создание и обработка. Функции ввода/вывода в стиле с. Ввод-вывод нуль-терминированных строк. Посимвольный ввод-вывод. Форматированный ввод-вывод.
- •66. Исключительные ситуации. Системные и пользовательские исключения. Оператор try …catch. Виды блоков catch. Выброс исключений. И их обработка. Оператор throw.
- •70. Структура данных очередь. Кольцевая очередь. Реализация очереди с использованием списков.
- •71. Структура данных стек. Реализация стека с использованием массива.
- •72. Структура данных стек. Реализация стека с использованием списков.
- •73. Структуры данных. Списки. Типы списков. Представление этих структур в статической и динамической памяти. Обработка однонаправленных и двунаправленных списков. Сборка мусора.
- •75. Реализация линейного однонаправленного списка с использованием массивов.
- •76. Деревья. Обходы деревьев.
- •77. Бинарные поисковые деревья. Определение, концевой обход бпд.
- •78. Поиск и вставка нового элемента в бпд.
- •79.Удаление элемента из бпд.
- •80. Реализация бпд с использованием динамической памяти.
26. Проблемы и типичные ошибки при работе с указателями.
Неинициализированные указатели. Указатели являются переменными, и как любые другие переменные они должны быть инициализированы перед использованием, либо присваиванием им другого указателя, либо используя подпрограммы типа New или GetMem, ; P1 := @I; // OK: используя оператор @ P2 := P1; // OK: присвоением другого указателя New(P3); // OK: New Dispose(P3);end;Если вы просто объявите, скажем, указатель типа PInteger, но не проинициализируете его, то указатель, вероятно, будет содержать какие-то случайные байты, т.е. он фактически будет указывать на случайное место в памяти.Если вы попробуете получить доступ к памяти по такому указателю, будут происходить плохие вещи. Если эта память не будет зарезервирована вашим приложением, то вы получите исключение Access Violation - вылет программы (program crash). Но если эта память будет частью вашей программы, то вы можете переписать данные, которые не должны меняться. Если эти данные используются в другой части вашей программы, то чуть позже, получаемые результаты выполнения вашей программы будут ошибочны. Такие ошибки чрезвычайно тяжело искать.
.Мусорные указатели Мусорные указатели (stale pointers) - это указатели, которые когда-то были допустимыми, но теперь уже нет. Это может произойти, если память, на которую указывает указатель, была освобождена и/или повторно использована.
Один из частых случаев мусорного указателя - это когда память освобождается, но сам указатель ещё используется после этого. Для предотвращения этого некоторые программисты всегда устанавливают указатели в nil, после освобождения памяти. Они также проверяют на nil, прежде чем пытаться получить доступ к памяти. Другая частая ошибка: иметь более чем один указатель на один и тот же кусок памяти. Вы можете освободить память по одному указателю и даже об-nil-ить его, но другой указатель всё также будет содержать старое значение, указывающее на уже освобождённую памятьНапример, частой грубой ошибкой является функция, возвращающая указатель на свои локальные переменные. Ведь как только мы выходим из подпрограммы, её локальные данные больше не существуют, а возвращённый вызывающей стороне указатель оказывается указывающим в никуда Использование неверного базового типа.Тот факт, что указатели могут указывать на любое место в памяти и что два указателя разных типов могут указывать на одно и то же место, фактически означает, что вы можете обращаться к одной памяти разными способами. Используя указатель на Byte (^Byte), вы можете изменять индивидуальные байты Integer-а или любого другого типа.Но вы также можете что-то ошибочно записать или прочитать. Например, если вы получаете доступ к месту, которое хранит только Byte, с помощью указателя на Integer, вы можете записать 4 байта, среди которых только 1 байт является допустимым, а остальные три - просто Указатели также позволяют вам установить значение переменной без присваивания его самой переменной. Это может сильно огорчать вас во время отладки..Владельцы и забытая память (Owners and orphans)Указатели не только могут иметь различные базовые типы, но и различную семантику владения. Если вы выделяете память, Одно из общих правил: тот, кто выделяет память, обязан её и освободить, так что это ваша обязанность. Частая ошибка: использовать указатель для выделения памяти, а затем снова использовать этот же указатель для выделения другой памяти или присвоить ему другой указатель. Указатель, который содержал адрес старого выделенного блока памяти, начинает указывать на новый блок памяти, а старый адрес оказывается потерян навсегда Другими словами, у нас есть утечка памяти. Заметим, что указатель не обязан владеть памятью. Указатели часто используются для движения по массиву или для получения доступа к части структуры. Если вы не выделяете для указателя память, то нет никакой причины не изменять его. При этом указатель используется как временная переменная, которую можно в любой момент выбросить, не заботясь об освобождении памяти.
27. Константные указатели и указатели на константу.
Константные указатели - это указатели, значение которых не изменяется в ходе выполнения программы. Они описываются так:указательный_тип const имя инициализатор
Пример: int a; int * const p=&a; Изменить значение константного указателя нельзя, а изменить значение памяти, адрес которой находится в указателе – можно:
p++; // нельзя!(*p)++; // можно!]Указатели на константу - Это указатели, содержащие адрес константы.Они описываются так:const указательный_тип имя [инициализатор]
Пример: int a; const int *p=&a; Изменить значение такого указателя можно, а изменить значение памяти, адрес которой находится в указателе – нельзя: p++; // можно!
(*p)++; // нельзя! a++; // можно!
28. Массивы. Статические массивы. Реализация одномерных массивов с помощью указателей. Массив – это структурированный тип данных, состоящий из элементов (компонентов) одного и того же типа, называемого базовым.
Статические массивы Количество элементов в статическом массиве известно при написании программы и никогда не меняется. Память под такой массив выделяет компилятор.
Организация массивов с использованием указателей int Vector [10];
Реализация этого описания выполнена так: Vector представляет собой константный указатель, содержащий адрес первого из элементов массива. Память под элементы выделяется подряд: *Vector– обращение к начальному элементу(с индексом 0)
*(Vector+1) – обращение к элементу с индексом 1
*(Vector+i) – обращение к элементу с индексом i Таким образом, запись Vector[i] – синоним записи *(Vector+i) Кроме того Vector – это тоже самое, что &Vector[0]
29. Обработка одномерных массивов (заполнение массива, поиск в массиве, преобразование элементов, сортировка).// array.cpp: определяет точку входа для консольного приложения.#include "stdafx.h" #include <iostream>using namespace std;
int main(int argc, char* argv[]){ cout << "obrabotka massiva" << endl; int array1[16] = { 5, -12, -12, 9, 10, 0, -9, -12, -1, 23, 65, 64, 11, 43, 39, -15 }; // объявление и инициализация одномерного массива cout << "indeks" << "\t\t" << "element massiva" << endl; // печать заголовков for (int counter = 0; counter < 16; counter++) //начало цикла { //вывод на экран индекса ячейки массива, а затем содержимого этой ячейки, в нашем случае - это целое число cout << "array1[" << counter << "]" << "\t\t" << array1[counter] << endl; } system("pause"); return 0;}2. // array_sum.cpp: определяет точку входа для консольного приложения. #include "stdafx.h"#include <iostream>using namespace std; int main(int argc, char* argv[]){ int array1[10]; // объявляем целочисленный массив cout << "Enter elementi massiva: " << endl; int sum = 0; for ( int counter = 0; counter < 10; counter++ ) // цикл для считывания чисел cin >> array1[counter]; // считываем вводимые с клавиатуры числа cout << "array1 = {"; for ( int counter = 0; counter < 10; counter++ ) // цикл для вывода элементов массива cout << array1[counter] << " "; // выводим элементы массива на стандартное устройство вывода for ( int counter = 0; counter < 10; counter++ ) // цикл для суммирования чисел массива sum += array1[counter]; // суммируем элементы массива cout << "}\nsum = " << sum << endl; return 0;СортировкаОбычно сортировку подразделяют на два класса: внутреннюю и внешнюю. При внутренней сортировке все элементы хранятся в оперативной памяти, таким образом, как правило, это сортировка массивов. При внешней сортировке — элементы хранятся на внешнем запоминающем устройстве, это сортировка файлов. Одно из Основных требований к методам сортировки — экономное использование памяти. Это означает, что переупорядочение нужно выполнять «на том же месте», то есть методы пересылки элементов из одного массива в другой не представляют интереса. Удобной мерой эффективности является подсчет числа С — сравнений элементов и М — присваиваний элементов. Достаточно хороший алгоритм затрачивает на сортировку N элементов время порядка N×log2(N). Изначально отсортированная часть состоит из нулевого количества элементов.
procedure sort(var a : mas; n : byte);var i, j, min: byte; vsp : integer;begin for i := 1 to n - 1 do begin min:=i; for j := i+1 to n do if a[j]<a[min] then min := j; vsp:=a[i]; a[i]:=a[min]; a[min]:=vsp; end; end; Сортировка обменом (пузырьковая)Массив просматривается N-1 раз. При каждом просмотре сравниваются каждые два соседних элемента. Если элемент с меньшим индексом оказывается больше, производится их обмен.
procedure obmen(var a : mas; n : byte); var i, j: byte; vsp : integer; begin for i := 1 to n - 1 do
for j := 1 to n - i do if a[j]>a[j+1] then begin vsp:=a[j]; a[j]:=a[j+1]; a[j+1]:=vsp; end end; Сортировка вставкамиПусть часть массива отсортирована. Выбираем в отсортированной части очередной элемент и вставляем его в отсортированную так, чтобы упорядоченность элементов сохранилась. При поиске места вставки осуществляем сдвиг элементов в сторону возрастания номеров. procedure vstavka(var a : mas; n : byte);var i, j: byte; vsp : integer;begin for i := 2 to n do begin vsp:=a[i]; j:= i-1; while (a[j]>vsp) and (j>1) do beginъ
a[j+1]:=a[j]; j:=j-1 end; if (a[j]>vsp) and (j=1) then begin a[2]:=a[1];
a[1]:= vsp end else a[j+1]:=vsp; end end;
пузырек for(a=1;a<size;a++) for(b=size-1;b>=a;b- -){if(nums[b-1]>nums[b]){//меняем местами
t=numsp[b-1];nums=[b-1]=nums[b];nums[b]=t;