Описанный процесс можно продолжить, т.е. многоуровневая адресация может иметь сколько угодно уровней. Однако уровни глубже второго, т.е. указатели более «глубокие», чем указатели на указатели, применяются крайне редко: избежать ошибки при их использовании можно только, хорошо представив их смысл. Например, в данном случае операторы
*A_sim = ‘R’; ** AA_sim = ‘R’; ***ptr = ‘R’; эквивалентны и не меняют содержимого участка памяти с адресом 32000, т.е. значения переменной sim.
5.2. МАССИВЫ УКАЗАТЕЛЕЙ
Указатели, как и объекты любых других типов, могут быть собраны в массив. Для оператора объявления массива указателей можно использовать синтаксические формы по аналогии с формами операторов объявления массивов других объектов: символов, чисел, структур и т.д. Рассмотрим форму объявления массивов указателей для случая, когда количество элементов в массиве указателей заранее не известно. Память под этот массив будет выделяться динамически, следовательно, необходимо объявить переменную-указатель, используя многоуровневую адресацию.
В операторе объявления такой переменной-указателя
<спецификация типа > * <имя переменной>; –
в качестве <спецификации типа> следует использовать производный тип данных, соответствующий типу указателя на объект, адрес которого может быть значением каждого элемента массива указателей.
* PP; объявляется переменная с
именем PP, которая является
указателем на
переменную-указатель типа
После объявления переменной PP: float * * PP; –
можно с использованием функции malloc() динамически выделить память для массива указателей, значением каждого элемента которого является адрес переменной типа float.
В примере 5.1 применение переменной-указателя PP демонстрируется при выделении динамической памяти для массива указателей, настраиваемого на элементы статического массива с именем pr. Значения элементов задаются с использованием разыменования переменной PP. При этом
*PP[j] ** (PP + j) pr[j].
Пример 5.1.
#include <stdio.h>
#include <stdlib.h>
int main (void)
{ int j, i,n; float ** PP; float pr[3];
printf("\nVvod n = "); scanf("%d",&n);
if ((PP=(float**)malloc(n*sizeof(float*)))== NULL)
{printf("\nError: Out of memory: PP=NULL");exit(1);}
for (j=0;j<n;j++) *(PP+j)= pr+j;
**PP=2.5; i=0;
do { **(PP+i+1)=**(PP+i)+ 2.7; i++; } while (i<n-1);
printf("\n New massiv Sposop_1:");
for(i=0;i<n;i++) printf("\n pr[%d] = %f",i,**(PP+i));
printf("\n New massiv Sposop_2:");
for(i=0;i<n;i++) printf("\n pr[%d] = %f",i,pr[i]);
return 0;
}
Замечание. Здесь использовалась двухуровневая адресация. Аналогично можно использовать адресацию и большей «глубины».
В примере 5.2 демонстрируется полезность приема настройки массива указателей на одномерный массив для одновременного упорядочения элементов одномерного массива и по возрастанию, и по убыванию без перестановки его элементов [1]. pmin (pmax) – адрес массива указателей, предназначенного для хранения адресов элементов массива с адресом arr, расположенных в порядке убывания (возрастания) их значений.
Пример 5.2.
#include <stdio.h>
#include <stdio.h>
#define N 6
void main (void)
{ int j, i, * buf; int arr[] = {5,2,3, 1, 6, 4}; int * pmin[N], * pmax[N];
for (j=0;j<N;j++) pmin[j]=pmax[j]=&arr[j];
for(i=0;i<N - 1;i++)
for(j=i + 1; j<N; j++)
Уважаемый посетитель!
Чтобы распечатать файл, скачайте его (в формате Word).
Ссылка на скачивание - внизу страницы.