Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
методичка 25.07.doc
Скачиваний:
0
Добавлен:
01.04.2025
Размер:
2.05 Mб
Скачать

Лабораторная работа №5 Программирование алгоритмов над многомерными динамическими массивами

Цель работы: закрепить практические навыки работы с системой программирования языка С++ на примере реализации алгоритмов над динамическими многомерными массивами.

Основные теоретические сведения

Указатели

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

Указатели в языке Си делятся на два вида: указатели на объекты и указатели на функции. Свойства и правила их использования различны.

Указатели, подобно любым другим переменным, перед своим использованием должны быть объявлены. Объявление указателя на объект имеет вид:

тип *имя_указателя;

где тип – один из предопределенных или определенных пользователем типов, а имя_указателя – указатель.

Например,

int *APtr;

объявляет переменную APtr типа int * (т.е указатель на целое число) и читается следующем образом: “ APtr является указателем на объект целочисленного типа”. Каждая переменная, объявляемая как указатель, должна иметь перед собой символ (*), который обозначает операцию косвенной адресации.

При объявлении указателя возможна его инициализация. Имеется две формы инициализации указателя:

1) тип *имя_указателя=инициализирующее_значение

2) тип *имя_указателя (инициализирующее_значение)

В качестве инициализирующего_значения может использоваться:

- явно заданный участок памяти

double *cc=0x1047;

- указатель, уже имеющий значение

float *ca;

float *cb=ca;

- выражение, позволяющее получить адрес объекта с помощью операции ссылки (&)

int a;

int *ce=&a;

Указатели должны инициализироваться либо при своем объявлении, либо с помощью оператора присваивания. Использовать указатель без присвоения ему какого-нибудь участка памяти нельзя. Указатель может получить в качестве начального значения 0 или NULL. Указатель с начальным значением 0 или NULL ни на что не указывает. NULL – это символическая константа, определенная специально для цели показать, что данный указатель ни на что не указывает. Пример объявления указателя с его инициализацией:

int *countPtr = NULL;

Для присваивания указателю адреса некоторой переменной используется операция адресации & (операция ссылки), которая возвращает адрес своего операнда. Например, если имеются объявления

int y = 5;

int *yPtr, x;

то оператор

yPtr = &y;

присваивает адрес переменной y указателю yPtr.

Присвоив указателю адрес конкретного участка памяти, можно с помощью операции разыменования не только получать, но и изменять содержимое этого участка памяти. Для этого используется операция разыменования * (операция косвенной адресации). Она возвращает значение объекта, на который указывает ее операнд (т.е. указатель).

Если присвоить указателю адрес конкретного объекта или значение уже инициализированного указателя, то это превратит запись *имя_указателя в синоним уже имеющегося имени объекта. Запись,

double z;

double *A=&z;

double *C, *D;

C=&z;

D=A;

превратит *A, *C, *D в синонимы переменной z. Изменяя значение, лежащее по адресу на которое указывают указатели, автоматически изменяется значение переменной, так как указатели A, C, D и переменная z связаны между собой одним участком памяти. Продолжая начатый пример

z=6;

double A1, C1, D1;

A1=*A;

C1=*C;

D1=*D;

присвоит переменным A1, C1, D1 значение 6, т.е. значение переменной z, на которую указывают указатели A, C, D.

Операции new и delete

Чтобы связать неинициализированный участок памяти, еще не занятым никаким объектом программы, используется оператор new:

указатель=new тип (инициализирующее_значение);

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

double *A=new double;

int *B;

B=new int;

объявляет указатели и выделяет им свободное место, не занятое никаким объектом.

Инициализирующее_значение задает начальные значения создаваемого объекта. Запись

double *C=new double (-1.8);

предоставляет место указателю С под объект вещественного типа и инициализирует его, т.е. записывает начальное значение -1.8.

Если операция new возвратила нулевое значение адреса – NULL, то это значит, что операционная система не может выделить память под данный объект, поэтому после использования оператора new желательно всегда проверять адрес выделенного участка памяти

double *A;

A=new double;

if (A==NULL) …

Динамически распределенную память следует освобождать, когда отпадает необходимость в размещенных в ней объектах. Освобождение памяти осуществляется с помощью операции delete, которая имеет следующий синтаксис