Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
С_глава1.doc
Скачиваний:
0
Добавлен:
16.12.2018
Размер:
548.86 Кб
Скачать

Массивы указателей

Так как указатель это переменная в которой хранится адрес ячейки памяти, то язык С++ позволяет объявить массив указателей:

тип *имя_массива[размер_массива];

Объявим массив указателей из 3 элементов на объекты типа int.

int *array [5];

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

#include <stdio.h>

void main()

{

int *array[3];

int a = 10, b = 20, c = 30;

array[0] = &a;

array[1] = &b;

array[2] = &c;

for (int i = 0; i<3; i++)

printf("%p\n", array[i]);

}

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

Занятие 5. Указатели и многомерные массивы.

Теоретическая часть

Многомерные массивы хранятся в памяти так, что самый правый индекс массива изменяется первым. Тогда для двумерного массива int A[2][3]; порядок хранения элементов такой: A[0][0], A[0][1], A[0][2], A[1][0], A[1][1], A[1][2]. Если мы введем указатель int *pA = &AA[0][0], то *pA – элемент с индексами [0][0], *(pA+3) – элемент с индексами [1][0]. Приведенная ниже программа наглядно демонстрирует это.

#include <stdio.h>

void main( )

{

int *pA;

int AA[3][2];

pA = &AA[0][0];

printf("Dostup po indexu:\n");

for (int i = 0; i<3; i++)

{

for (int j = 0; j<2; j++)

{

AA[i][j] = i + j;

printf("%p-%d\t", &AA[i][j], AA[i][j]);

}

printf("\n");

}

printf("\nDostup s ispolzovaniem ukazatelya:\n");

for (i = 0; i<2*3; i++)

printf("%p-%d\n", pA+i, *(pA+i));

printf("\n");

}

Результат работы программы:

Dostup po indexu:

0012FF64-0 0012FF68-1

0012FF6C-1 0012FF70-2

0012FF74-2 0012FF78-3

Dostup s ispolzovaniem ukazatelya:

0012FF64-0

0012FF68-1

0012FF6C-1

0012FF70-2

0012FF74-2

0012FF78-3

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

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

Допустим в программе нужно хранить список из 3 фамилий. Каждая фамилия может быть произвольной длины, но не больше, допустим, 20 символов. Данное требование можно выполнить, объявив двумерный массив символов char spisok[3][20]; т.е. 3 фамилии, по 20 символов для каждой. Тогда всего будет выделено 1байт * 20 символов * 3 фамилии = 60 байт.

Эту же задачу можно решить другим способом, а именно, объявив массив указателей char *sp [3] = {"Иванов", "Сидоров", "Козликов"}; Всего в этом массиве будет 3 элемента и каждый из них является указателем типа char *, для этого будет выделено 3*sizeof(char *) = 12 байт. Кроме того, компилятор размещает в памяти 3 строковые константы "Иванов" (7 байт), "Сидоров" (8 байт), "Козликов" (9 байт), а их адреса становятся значениями элементов sp[0], sp[1], sp[2]. Т.е. всего выделяется 12+7+8+9 = 36 байт. Выигрыш по сравнению с первым случаем очевиден.