Информатика и технология программирования

       

Контекстное определение типов данных в Си


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


A.name[k]

мы несомненно имеем дело со структурированной переменной (операция "." ), элементом которой является массив name (операция [] ). Такой способ задания типа переменной в окружении (контексте) операций выделения составляющего типа будем называть контекстным определением типа. В нем могут использоваться только следующие операции:



- [] -элемент массива;



- * -косвенное обращение по указателю;



-() -вызов функции;



- () -круглые скобки, устанавливающие последовательность выполнения операций.

Заметим, что операции ("." и -&#62), соответствующие структуре, здесь не упоминаются. Это значит, что структурированный тип данных может быть определен только явно. Это связано с тем, что структура конструируется из разнородных элементов, а остальные типы данных строятся на основе однородных.

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


int *p;



Переменная, при косвенном обращении к которой получается целое -указатель на целое.


char *p[];



Переменная, которая является массивом, при косвенном обращении к элементу которого получаем указатель на символ (строку) - массив указателей на символы (строки).


char (*p)[][80];



Переменная, при косвенном обращении к которой получается двумерный массив, состоящий из массивов по 80 символов - указатель на двумерный массив строк по 80 символов в строке.



int (*p)();




Переменная, при косвенном обращении к которой получается вызов функции, возвращающей в качестве результата целое - указатель на функцию, возвращающую целое.

int (*p[10])();






Переменная, которая является массивом, при косвенном обращении к элементу которого получается вызов функции, возвращающей целое -массив указателей на функции, возвращающих целое.

char *(*(*p)()));


Переменная, при косвенном обращении к которой получается вызов функции, при косвенном обращении к ее результату получается вызов функции, которая в качестве результата возвращает переменную, при косвенном обращении к которой получается символ -указатель на функцию, возвращающую в качестве результата указатель на функцию, возвращающую указатель на строку.



Контекстный способ определения типа является универсальным и может использоваться во всех случаях, когда речь идет о типах данных:


-определение и описание переменных;


-формальные параметры функций;


-результат функции;


-определение элементов структуры (
struct);


-определение абстрактного типа данных;


-
определение типа данных (спецификатор typedef).




Содержание раздела