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

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

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

float *mas[6];

Это соответствует массиву из шести элементов, являющихся адресами объектов типа float.

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

Многоуровневые указатели

Рассмотрим определение переменной:

double **pp;

В соответствии принципом контекстного определения pp нужно интерпретировать как переменную, при косвенном обращении к которой получается указатель на переменную типа double, то есть как указатель на указатель или адрес указателя. Но поскольку любой указатель в Си может ссылаться как на отдельную переменную, так и на область памяти (массив), то в применении к двойному указателю получаются 4 варианта структур данных, а именно:

· указатель на одиночный указатель на переменную типа double;

· указатель на одиночный указатель на массив переменных типа double;

· указатель на массив, содержащий указатели на одиночные переменные типа double;

· указатель на массив, содержащий указатели на массивы переменных типа double.

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

double **pp, *pd[20];

pp = pd; // или pp = &pd[0];

*(pp+i) // или pp[i]

**(pp+i) // или *pp[i]

Здесь повторяется та же самая система эквивалентности обычных массивов и указателей - типов double* и double[], но применительно не к массивам обычных переменных, а к массивам указателей. Иначе, типы double** и double *[] различаются так же, как указатель-переменная и указатель-константа. Массив указателей типа double *[] является статической структурой данных, размерность которой определяется при компиляции. Двойной указатель типа double** может ссылаться и на динамический массив указателей, который создается во время работы программы под заданную размерность:

double **create(int n,int m)

{ double **pp,*q; // создать динамический массив

int i,j; // указателей размерностью sz+1

pp = (double**)malloc(sizeof(double *)*n);

if(pp)

for (i=0; i<n; i+)

{ *(pp+i) = (double*)malloc(sizeof(double)*m);

if(!*(pp+i))

{ for(j=0; j<i; j+ ) free(*(pp+j));

free(pp);

}

}

// работа с динамическим массивом

return(pp); // возврат указателя на динамический массив указателей

}