Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Высокоуровневые методы информатики и программир...docx
Скачиваний:
25
Добавлен:
12.11.2019
Размер:
6.53 Mб
Скачать

6.3. Указатели

Указатель - это адрес памяти. Значение указателя сообщает, где раз­­ме­щен объект, но не говорит о самом объекте. Пере­мен­­ная типа ука­за­­тель описывается так: <тип> *<переменная-указатель>. Данная запись означает, что переменная-указатель является указателем на любую переменную указанного типа.

Символ операции “*” (звез­дочка) используется для задания указателя на объект.

Пример: int *х; // указатель на любую переменную типа int. Указатель на тип void совместим с любым указателем.

Пример: void *х; int *y; // допустимо присваивание: y = x.

Двумя наиболее важными операциями, связанными с указателями, являются операция обращения по адресу (разадре­сации) и операция опре­де­ления адреса. Операция обращения по адресу (*) служит для прис­ваива­ния или счи­тывания значения переменной, размещенной по адресу “переменная‑ ука­затель” (*ptr_var = value).

Пример. Предложение *х=16 означает, что по адресу, зада­ваемому в х, помещается значение 16.

Операция определения адреса возвращает адрес памяти своего опе­ранда. Операндом должна быть переменная. Операция определения ад­реса выполняется следующим образом:

<указатель-переменная>=&<переменная>;

Пример. Запись a=*&b равносильна записи a=b.

Для определения адреса массива операцию & можно не указывать перед его именем.

Если переменная, например, ptr определена как указатель на струк­ту­ру, то для дос­тупа к полю структуры (field); можно ис­пользовать опера­цию -> в виде: ptr->field, которая эквивалентна выражению (*ptr).field.

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

• описать указатель вне любой функции или снабдить его предписанием static. Начальным значением явля­ется нулевой адрес памяти ‑ 0;

• присвоить указателю адрес переменной;

• присвоить указателю значение другого указателя;

• использовать операторы распределения памяти new и delete.

Операция динамического выделения памяти имеет вид:

<указатель-переменная>=new [<имя переменной>] [<тип переменной>];

Операция возвращает нулевое значение, если не может выделить па­мять.

Операция освобождения выделенной памяти имеет вид:

delete <указатель-переменная>.

Примеры:

ptr=new int [3];// выделение памяти для массива из трех элементов типа int

ptrf=new float[3][5];// выделение памяти для массива 3 на 5 чисел типа float

ptrstack=new stack; //выделение памяти для структуры (записи) stack

delete ptrstack; // освобождается память выделенная ранее по адресу ptrstack

Пример динамического формирования и вывода стека (п. 1.9.3):

int main(int argc, char **argv) { // создание и вывод стека из чисел 1,2,3,4,5

struct stack { int inf; stack* next;}; // объявление структуры (записи) stack

stack *top=0,*kon,*del;//объявление переменных-указателей на запись stack

for (int i=1;i<=5;i++) // цикл формирования стека из пяти записей

{ kon=new stack; // выделение памяти для новой записи

kon->next=top; kon->inf=i; //запоминание адреса предыдущей записи

top=kon; // запоминание адреса последней записи (вершины стека)

} // конец цикла формирования стека

kon=top; // установка адреса вершины стека (последней записи стека)

while (kon!=0) // цикл вывода записей стека на экран (cout << ) (п. 6.5.2)

{cout<<kon->inf<<endl;del=kon;kon=kon->next;delete del;}//вывод 5,4,3,2,1

getch(); return 0; } // задержка и завершение работы функции