Процедурное программирование на языке С. Часть 2. Указатели на объекты. Многоуровневая адресация: Методические указания к лабораторным работам по курсам «Алгоритмические языки и программирование» и «Процедурное программирование», страница 11

Описанный процесс можно продолжить, т.е. многоуровневая адресация может иметь сколько угодно уровней. Однако уровни глубже второго, т.е. указатели более «глубокие», чем указатели на указатели, применяются крайне редко: избежать ошибки при их использовании можно только, хорошо представив их смысл. Например, в данном случае  операторы 

*A_sim = ‘R’;     ** AA_sim = ‘R’;    ***ptr = R’;   эквивалентны  и не меняют содержимого участка памяти с адресом 32000, т.е. значения переменной    sim.

5.2.  МАССИВЫ УКАЗАТЕЛЕЙ

Указатели, как и  объекты любых других типов, могут быть собраны в массив. Для  оператора объявления массива указателей можно использовать  синтаксические формы по аналогии с формами операторов объявления массивов других объектов: символов, чисел, структур и т.д. Рассмотрим  форму объявления массивов указателей для случая, когда количество элементов в массиве указателей заранее не известно. Память под этот массив будет выделяться динамически, следовательно, необходимо объявить переменную-указатель, используя многоуровневую адресацию.

В операторе объявления такой переменной-указателя

<спецификация типа >  * <имя переменной>;   –

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

Овал: float *
 


                                  * PP;                объявляется переменная с

                                                                                  именем PP, которая является

                                                                                    указателем на

                                                                                      переменную-указатель типа

 


После объявления переменной PP:    float * * PP

можно с использованием функции malloc() динамически выделить память для массива указателей, значением каждого элемента которого является адрес переменной типа float.

В примере 5.1 применение переменной-указателя PP демонстрируется при выделении динамической памяти для массива указателей, настраиваемого на элементы статического массива с именем pr. Значения элементов задаются с использованием разыменования переменной PP. При этом 

*PP[j]     ** (PP + jpr[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++)