Главная страница

Задание 1 Массив одномерный. Отчет по выполнению заданий 1 и 2 по статическому и динамическому массивам. По заданию 3 в отчет включить код, комментируя функции. 2


Скачать 116.17 Kb.
НазваниеОтчет по выполнению заданий 1 и 2 по статическому и динамическому массивам. По заданию 3 в отчет включить код, комментируя функции. 2
Дата19.02.2022
Размер116.17 Kb.
Формат файлаdocx
Имя файлаЗадание 1 Массив одномерный.docx
ТипОтчет
#366770
страница5 из 6
1   2   3   4   5   6

Динамический массив


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

Примечание. Как же писать код программы и обращаться к ячейкам массива, если он еще не создан, т.е. нет переменной и соответственно память не выделена? Для этого в программе разработан тип данных – указатель. Это переменная, значением которой может быть адрес.

Динамический массив в языке Си определяется через указатель. Количество элементов в массиве может быть определено перед созданием массива.

Индексация элементов динамического массива начинается с нуля.
Функции языка Си по управлению динамическим массивом из модуля malloc.h:

  1. Выделение памяти под переменную в динамической памяти (создание динамической переменной)

void* malloc(выражение);

Выражение определяет объем памяти в байтах.

Функция запрашивает у диспетчера динамической памяти (ДП) необходимое количество последовательно расположенных байтов, заданное выражением, если такой участок есть, то результат функции – адрес первого байта выделенной области, если такого свободного объема нет, то результат функции NULL.

Так как результат функции не типизированный указатель, то результат нужно привести к базовому типу массива (или типу переменной, под которую выделяется память).

Пример создания динамического массива

int mai()

{

int n;

cout<<”Введите количество элементов массива”;

int *x=(int *)malloc(n);

double *y=( double *)malloc(n);

}

  1. Удаление динамического массива

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

void free(указатель на динамическую память);

Пример удаления динамического массива после использования

int mai()

{

int n;

cout<<”Введите количество элементов массива”;

int *x=(int *)malloc(n);

double *y=( double *)malloc(n);

for(i=0;i
cin>>x[i];

for(i=0;i
cout<
free(x);

}

  1. Изменение размера динамического массива

void* realloc(указатель, выражение);

где

указатель – это указатель на массив, размер которого надо изменить;

выражение – определяет новый размер массива в байтах.

Функция изменяет размер массива, добавляя новые байты в конец массива или удаляя последнее байты, сохраняя при этом значения остальных элементов массива.
Пример применения realloc для увеличения и уменьшения размера массива

int main()

{

int n=5;

int *x=(int *) malloc(n);

x[0]=1; x[1]=2;x[2]=3; x[3]=4; x[4]=5;

//увеличить массив на один элемент

realloc(x,sizeof(int)*(n+1)); n++;

x[5]=6;

//увеличить массив на два элемента

realloc(x,sizeof(int)*(n+2));

x[6]=7; x[7]=8;

//уменьшить массив на один элемент

n--;

realloc(x,sizeof(int)*n);

free(x);

}

Контейнер - современная реализация динамических массивов


Векторы - это реализация динамического массива в C++, т.е. такого массива, чья длина меняется в ходе программы. Называется вектор, потому что добавлять и удалять элементы можно только с одного конца.

Стандартный шаблон обобщённого программирования языка C++ std::vector — реализация динамического массива.

Объём вектора и изменение размера

Типичная реализация вектора — это указатель на динамический массив. Размер вектора — это фактическое число элементов, а объём — количество используемой им памяти.

Если при вставке в вектор новых элементов, его размер становится больше его объёма, происходит перераспределение памяти. Как правило, это приводит к тому, что вектор выделяет новую область хранения, перемещая элементы и свободные старые области в новый участок памяти.

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

Метод reserve() используется для предотвращения ненужного перераспределения памяти. После вызова reserve(n), объём вектора гарантированно будет не меньше n.

  1. Формат определения вектора в программе: vector<Т>. Где Т тип элемента вектора

Примеры создания вектора его конструкторами

vector myVector; // Пустой вектор из элементов типа int

vector myVector(10); // Вектор из 10-и элементов типа float

vector myVector(5, ' '); // Вектор, состоящий из 5-и пробелов

class myType {

...

};

int n = 10;

vector< myType > myVector(n); // Вектор из 10-и элементов пользовательского типа T

  1. Доступ к элементам вектора

По соглашению C и C++, первый элемент имеет индекс 0, последний  size() – 1.

  1. Применение операции индексирования.

vector myVector(10);

cin>>myVector[0];

i=0;

myVector[i]*=2;

myVector[1]=5;

Примечание. Если i>=myVector.size() то результат операции не определен

  1. Применение методов

а) Метод at - доступ к любому элементу по индексу

Формат метода at

[const] T& at(int i); где Т тип элемента вектора

Примечание. Может вернуть исключение out_of_range

б) Метод v.front() - доступ к первому элементу вектора

[const] T& front() (int i); где Т тип элемента вектора

Примечание. Результат не определен если вектор пуст

в) Метод back() - доступ к последнему элементу вектора

[const] T& back () (int i); где Т тип элемента вектора

Примечание. Результат не определен если вектор пуст

Пример применения методов доступа

int main()

{

vector myVector{ 1, 2, 3, 4, 5, 6 };

cout<
cout << myVector.front() << endl;

cout << myVector.back() << endl;

std::cout << "Hello World!\n";

}

Некоторые методы управления

Класс vector — это контейнер. Согласно стандарту C++, любой контейнер должен содержать методы begin(), end(), size(), max_size(), empty(), и swap().

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




Метод

Описание

Сложность

Операторы

vector::operator=

Копирует значение одного вектора в другой.

O(n)

vector::operator==

Сравнение двух векторов

O(n)

Доступ
к элементам

vector::at

Доступ к элементу с проверкой выхода за границу

O(1)

vector::operator[]

Доступ к определённому элементу

O(1)

vector::front

Доступ к первому элементу

O(1)

vector::back

Доступ к последнему элементу

O(1)

Итераторы

vector::begin

Возвращает итератор на первый элемент вектора

O(1)

vector::end

Возвращает итератор на место после последнего элемента вектора

O(1)

vector::rbegin

Возвращает reverse_iterator на конец текущего вектора.

O(1)

vector::rend

Возвращает reverse_iterator на начало вектора.

O(1)

Работа с
размером вектора

vector::empty

Возвращает true, если вектор пуст

O(1)

vector::size

Возвращает количество элементов в векторе

O(1)

vector::max_size

Возвращает максимально возможное количество элементов в векторе

O(1)

vector::reserve

Устанавливает минимально возможное количество элементов в векторе

O(n)

vector::capacity

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

O(1)

vector::shrink_to_fit

Уменьшает количество используемой памяти за счёт освобождения неиспользованной (C++11)

O(1)

Модификаторы

vector::clear

Удаляет все элементы вектора

O(n)

vector::insert

Вставка элементов в вектор

Вставка в конец, при условии, что память не будет перераспределяться — O(1), в произвольное место — O(n)

vector::erase

Удаляет указанные элементы вектора (один или несколько)

O(n)

vector::push_back

Вставка элемента в конец вектора

O(1)

vector::pop_back

Удалить последний элемент вектора

O(1)

vector::resize

Изменяет размер вектора на заданную величину

O(n)

vector::swap

Обменять содержимое двух векторов

O(1)

Другие методы

vector::assign

Ассоциирует с вектором поданные значения

O(n), если установлен нужный размер вектора, O(n*log(n)) при перераспределении памяти

vector::get_allocator

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

O(1)

Пример вставки нового элемента в вектор в первую, последнюю и внутреннюю позицию (по индексу 3)

vector price = { 78.56, 34.07, 23,45, 61.08, 29.3 };

//вставка значения как первого элемента вектора и запоминание итератора на него

auto iterator = price.insert(price.begin(), 42.67);

//результат: 42.67,78.56, 34.07, 23,45, 61.08, 29.3 

//вставка с использованием итератора

price.insert(iterator, 30.76);

//результат: 30.76, 42.67,78.56, 34.07, 23,45, 61.08, 29.3 

//Initialize an integer variable

int position = 3;

//Insert the number at the particular position

iterator = price.insert(price.begin() + position, 52.56);

//результат: 30.76, 42.67,78.56, 52.56, 34.07, 23,45, 61.08, 29.3 
Пример передачи вектора в качестве параметра

Вывод значений вектора на экран

void print(vector X){

for(int i=0;i

cout<<X[i]<<” “;

}

Пример функции, которая создает вектор из определенного количества элементов и возвращает его в качестве результата

vector createVector(int n){

vector Х(n);

return X;

}

int main(){

vector B = createVector(2);

B[0] = 5; B[1] = 6;

}
1   2   3   4   5   6


написать администратору сайта