- •1) Системы счисления. Перевод чисел из одной системы счисления в другую
- •4) Арифметические выражения. Приемы, используемые для минимизации вычислений: вынесение общих множителей за скобки, использование дополнительных переменных
- •5) Ввод чисел с клавиатуры и вывод чисел в окно программы, формат ввода и вывода.
- •6) Средства разработки программ разветвляющейся структуры. Условные и безусловные операторы перехода.
- •8) Рекурсия. Использование рекурсии для вычисления числа Фибоначчи.
- •9) Уточнение корней уравнений: метод простых итераций, метод половинного деления, метод касательных.
- •10)Организация программ со структурой вложенных циклов. Транспонирование матриц
- •11)Массивы. Сохранение результатов вычислений в массиве.
- •12)Метод сортировки массива вставками.
- •13) Метод прямого обмена (метод пузырька) и его модификация.
- •14) Метод прямого выбора и его модификации: сортировка методом поиска минимального/максимального элемента, сортировка методом поиска индекса
- •15) Указатели
- •16) Матрицы. Обработка матриц. Многомерные статические массивы.
- •17) Массивы указателей. Динамические массивы. Операции new, new [], delete, delete [], malloc, free.
- •18) Программирование с использованием подпрограмм. Объявление функций. Глобальные переменные. Передача параметров. Передача массивов в качестве параметров.
- •19) Рекурсивные функции.
- •20) Перегружаемые функции, параметры со значениями по умолчанию, функции с переменным числом параметров.
- •21) Указатели на функции, передача указателей на функции в качестве параметров.
- •22) Классы. Конструктор и деструктор. Квалификаторы прав доступа. Указатель this.
- •23) Перегрузка стандартных операций. Наследование классов.
- •24) Открытое наследование, полиморфизм классов. Виртуальные функции и абстрактные классы.
- •25) Шаблоны функций и классов.
- •26)Наследование классов. Множественное наследование. Виртуальные классы.
- •Приложение. Полный код программы по транспонированию матрицы.
16) Матрицы. Обработка матриц. Многомерные статические массивы.
Матрица — это двумерный массив, каждый элемент которого имеет два индекса: номер строки и номер столбца, поэтому для работы с элементами матрицы необходимо использовать два цикла. Если значениями параметра первого цикла будут номера строк матрицы, то значениями параметрами второго — столбцы (или наоборот). Обработка матрицы заключается в том, что вначале поочередно рассматриваются элементы первой строки (столбца), затем второй и т.д. до последней.
Матрицы, как и одномерные массивы, нужно вводить (выводить) поэлементно.
Примеры задач по обработке матриц.
1) Найти сумму элементов матрицы, лежащих выше главной диагонали.
Алгоритм решения
данной задачи построен следующим
образом: обнуляем ячейку для накапливания
суммы , затем с помощью двух циклов
(первый по строкам, второй по столбцам)
просматриваем каждый элемент матрицы,
но суммируем только в том случае, если
этот элемент находится выше главной
диагонали (при выполнении условия
).
2) Вычислить количество положительных элементов квадратной матрицы, расположенных по её периметру и на диагоналях.
Итак,
разобрав подробно постановку задачи,
рассмотрим алгоритм её
решения. Для обращения к элементам
главной диагонали вспомним, что номера
строк этих элементов всегда равны
номерам столбцов. Поэтому,
если параметр
изменяется
циклически от 0 до
,
тоA[i][i] —
элемент главной диагонали. Воспользовавшись
свойством, характерным для элементов
побочной диагонали, получим:
![]()
следовательно,
для
элементА[i][N-i-1] —
элемент побочной диагонали. Элементы,
находящиеся по периметру матрицы
записываются следующим образом: А[0][i] —
нулевая строка, А[N-1][i] —
последняя строка и соответственно А[i][0] —
нулевой столбец, А[i][N-1] —
последний столбец.
Ну а многомерный статический массив – это то же самое, что и любой другой массив, нет никакой разницы, кроме того, что мы задаём большее количество индексов. Совсем не вижу смысла в этой части вопросы.
17) Массивы указателей. Динамические массивы. Операции new, new [], delete, delete [], malloc, free.
Указатели, подобно данным других типов, могут храниться в массивах. Вот, например, как выглядит объявление 10-элементного массива указателей на int-значения.
int *ipa[10];
Здесь каждый элемент массива ipa содержит указатель на целочисленное значение.
Чтобы присвоить адрес int-переменной с именем var третьему элементу этого массива указателей, запишите следующее.
ipa[2] = &var;
Помните, что здесь ipa — массив указателей на целочисленные значения. Элементы этого массива могут содержать только значения, которые представляют собой адреса переменных целочисленного типа. Вот поэтому переменная var предваряется оператором &. Чтобы присвоить значение переменной var целочисленной переменной х с помощью массива ipa, используйте такой синтаксис.
x = *ipa[2];
Динамическое выделение памяти необходимо для эффективного использования памяти компьютера. Например, мы написали какую-то программку, которая обрабатывает массив. При написании данной программы необходимо было объявить массив, то есть задать ему фиксированный размер (к примеру, от 0 до 100 элементов). Тогда данная программа будет не универсальной, ведь может обрабатывать массив размером не более 100 элементов. А если нам понадобятся всего 20 элементов, но в памяти выделится место под 100 элементов, ведь объявление массива было статическим, а такое использование памяти крайне не эффективно.
В С++ операции new и delete предназначены для динамического распределения памяти компьютера. Операция new выделяет память из области свободной памяти, а операция delete высвобождает выделенную память. Выделяемая память, после её использования должна высвобождаться, поэтому операции new и delete используются парами. Даже если не высвобождать память явно, то она освободится ресурсами ОС по завершению работы программы.
Операция new создает объект заданного типа, выделяет ему память и возвращает указатель правильного типа на данный участок памяти. Если память невозможно выделить, например, в случае отсутствия свободных участков, то возвращается нулевой указатель, то есть указатель вернет значение 0. Выделение памяти возможно под любой тип данных: int, float,double, char и т. д.
После оператора delete ставятся квадратные скобочки, которые говорят о том, что высвобождается участок памяти, отводимый под одномерный массив(такой же принцип у скобок после оператора new)
Язык С не содержит операторов new или delete. Вместо них в С используются библиотечные функции, предназначенные для выделения и освобождения памяти. В целях совместимости C++ по-прежнему поддерживает С-систему динамического распределения памяти и не зря: в С++-программах все еще используются С-ориентированные средства динамического распределения памяти. Поэтому им стоит уделить внимание.
Ядро С-системы распределения памяти составляют функции malloc() и free(). Функция malloc() предназначена для выделения памяти, а функция frее() — для ее освобождения. Другими словами, каждый раз, когда с помощью функции malloc() делается запрос, часть свободной памяти выделяется в соответствии с этим запросом. При каждом вызове функции frее() соответствующая область памяти возвращается системе. Любая программа, которая использует эти функции, должна включать заголовок <cstdlib>.
В результате успешного вызова функция malloc() возвратит указатель на первый байт области памяти, выделенной из "кучи". Если для удовлетворения запроса свободной памяти в системе недостаточно, функция malloc() возвращает нулевой указатель.
Функция free() выполняет действие, обратное действию функции malloc() в том, что она возвращает системе ранее выделенную ею память. После освобождения память можно снова использовать последующим обращением к функции malloc().
Никогда не следует вызывать функцию free() с недействительным аргументом; это может привести к разрушению списка областей памяти, подлежащих освобождению.
Использование функций malloc() и free() иллюстрируется в следующей программе.
// Демонстрация использования функций malloc() и free().
#include <iostream>
#include <cstdlib>
using namespace std;
int main()
{
int *i;
double *j;
i = (int *) malloc(sizeof(int));
if(!i) {
cout << "Выделить память не удалось.\n";
return 1;
}
j = (double *) malloc(sizeof(double));
if(! j ) {
cout << "Выделить память не удалось.\n";
return 1;
}
*i = 10;
*j = 100.123;
cout << *i << ' ' << *j;
// Освобождение памяти.
free (i);
free (j);
return 0;
}
Несмотря на то что функции malloc() и fгее() — полностью пригодны для динамического распределения памяти, есть ряд причин, по которым в C++ определены собственные средства динамического распределения памяти. Во-первых, оператор new автоматически вычисляет размер выделяемой области памяти для заданного типа, т.е. вам не нужно использовать оператор sizeof, а значит, налицо экономия в коде и трудовых затратах программиста. Но важнее то, что автоматическое вычисление не допускает выделения неправильного объема памяти. Во-вторых, С++-оператор new автоматически возвращает корректный тип указателя, что освобождает программиста от необходимости использовать операцию приведения типов. В-третьих, используя оператор new, можно инициализировать объект, для которого выделяется память. Наконец, как будет показано ниже в этой книге, программист может создать собственные версии операторов new и delete.
