Указатели и массивы

Массивы

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

Массив — это упорядоченная последовательность переменных одного типа. Каждому элементу массива отводится 1 ячейка памяти. Элементы одного массива занимают последовательно расположенные ячейки памяти. Все элементы имеют одно имя — имя массива и отличаются индексами — порядковыми номерами в массиве.

Описание массива в программе отличается от описания простой переменной наличием после имени квадратных скобок, в которых задается количество элементов массива (размерность).

Массив может быть одномерным или многомерным.

 Одномерные массивы

Массив в программе объявляется следующим образом:

<тип элементов массива> <имя массива> [<количество элементов массива>];

int m [25]; //описание одномерного массива из 25 целых чисел

Количество элементов массива должно быть определено до начала компиляции. Возможны несколько вариантов задания количества элементов массива:

  1. Непосредственно указать число float A[20];

  2. Объявить целочисленную константу и потом использовать ее

const int n=20;

float A[n];

                                                                   Рис.6

Элементы массива нумеруются с нуля.


A[0], A[18] — индекс задается как константа
Чтобы обратиться к элементу массива, надо указать имя массива и номер элемента в массиве (индекс):

A[i] — индекс задается как переменная

A[2*i] — индекс задается как выражение

Массивы можно поэлементно складывать, умножать, вычитать, делить, находить минимальный (максимальный) элемент массива, сумму, произведение и количество каких-либо элементов.

Все действия над массивами производятся поэлементно с использованием операторов цикла.

На рис.7 и рис.8 приведены схема алгоритмов ввода и вывода массива с клавиатуры.

Формирование массива с помощью генератора случайных чисел. В языке С++ есть встроенный генератор случайных чисел — функция rand. Она формирует целые псевдослучайные значения в диапазоне от 0 до rand_max. Константа rand_max = 32767. Формируемые значения называются псевдослучайными, так как генератор создает их по строго заданному алгоритму, неизвестному программисту, для которого эти значения кажутся случайными.

Сначала необходимо запустить датчик случайных чисел: srand(time(NULL)), где srand — это функция инициализации генератора случайных чисел, которая обязательно должна быть вызвана перед использованием генератора случайных чисел rand; time — функция работы с таймером компьютера; NULL — нулевой адрес, указывает на то, что от таймера необходимо получить машинное время в миллисекундах.

Затем для получения целого случайного числа необходимо выполнить оператор: <имя переменной> = rand ();

Если необходимо сгенерировать целое случайное число в диапазоне от 0 N, то необходимо поступить следующим образом: <имя переменной> = rand () % (N+1)

Многомерные массивы

Двумерный массив является частным случаем многомерного массива.

Двумерный массив (матрица) — это прямоугольная таблица однотипных элементов, которые имеют два индекса. Матрица имеет строки (горизонтальные ряды значений) и столбцы (вертикальные ряды значений). Нумерация строк и столбцов начинается с нуля.

В оперативной памяти двумерный массив хранится по строкам. Сначала элементы 0-строки, затем 1-ой строки и т.д.

Рис.9

Матрица в программе объявляется следующим образом:

<тип элементов массива>  <имя массива> [<число строк>] [<число столбцов>];

int m [5] [6]; //описание целочисленной матрицы m из 5 строк и 6 столбцов

Доступ к элементам матрицы осуществляется через индексы. Каждый элемент имеет два индекса: номер строки i и номер столбца j, на пересечении которых он находится.

m[2][1] // элемент, стоящий на пересечении 2-ой строки и 1-го столбца

Элементы матрицы могут быть сформированы с помощью генератора случайных чисел или введены с клавиатуры. Формирование, ввод, обработка и вывод элементов матрицы производится поэлементно с использованием вложенных циклов.

На рис.10 и рис.11 приведены схема алгоритмов ввода и вывода массива с клавиатуры.


Указатели

Указатель — это переменная или именованная константа, которая содержит адрес другой переменной, именованной константы или функции. Указатель не является самостоятельным типом данных.

Описание указателя:

<тип данных> *<имя указателя>

Например:

int *p;

переменная p — указатель на данное типа int

float *I;

переменная I — указатель на данное типа float

char *c;

переменная c — указатель на данное типа char

Если требуется объявить несколько указателей, то символ * нужно ставить перед именем каждого указателя.

Например: int *a, *b, *c;

Размер указателя зависит от модели памяти. Можно определить указатель на указатель: int **p;

Указатель на void применяется в тех случаях, когда конкретный тип объекта, адрес которого требуется хранить, не определен.

Указатель может быть константой или переменной, а также указывать на константу или переменную.

С указателями используются 2 оператора:

  • & — унарный оператор, возвращает адрес памяти, по которому расположен его операнд.

& = «адрес переменной»

  • * — унарный оператор, он обращается к значению переменной, расположенной по адресу, заданному его операндом.

* = «взять по адресу»

С указателями можно использовать 4 арифметических оператора:

  • инкремент;

  • дикремент;

  • сложение;

  • вычитание.

При этом необходимо учитывать объем памяти, выделяемый под тот или иной тип данных.

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

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

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

В таком случае приходится пользоваться динамически распределяемой памятью, а полученные таким образом массивы называются динамическими.

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

Динамические массивы объявляются следующим образом:

<тип элементов массива>  *<имя массива>;

где <тип элементов массива>  может быть любым допустимым в С++ типом, <имя массива> — является указателем.

Для выделения памяти под динамический массив используется следующий оператор:

<имя массива> = new <тип элементов массива> <количество элементов массива>

Когда память, выделенная под динамический массив больше не нужна, ее следует освободить. Делается это с помощью оператора delete:

delete {}имя динамического массива;

Лабораторная работа №12

Лабораторная работа №13

Лабораторная работа №14