Правило интерпретации составных описателей может быть названо чтением «изнутри – наружу». Начать интерпретацию нужно с идентификатора и проверить, есть ли справа от него открывающие скобки, квадратные [ или круглые (. Если да – то рассматривается правая часть описателя. Затем следует проверить, есть ли слева от идентификатора символ *, если да – то рассматривается левая часть. Если на каком либо шаге интерпретации справа встретится закрывающая круглая скобка ), которая используется для изменения порядка интерпретации, то необходимо сначала закончить интерпретацию внутри данной пары круглых скобок ( ), а затем продолжит интерпретацию справа от закрывающей круглой скобки. На последнем шаге интерпретируется спецификация типа. После этого тип объявленного объекта полностью известен.
char *(*(*var)())[10];
7 6 4 2 1 3 5
1. Идентификатор var – это
2. Указатель на
3. Функцию без аргументов, возвращающую
4. Указатель на
5. Массив из 10 элементов, являющихся
6. Указателями на
7. Значения типа char.
Рассмотрим примеры:
1. int *var[5]; // var – массив указателей на значения типа int;
2. int (*var)[5]; // var – указатель на массив значений типа int;
3. long *var(); // var – функция, возвращающая указатель на значения типа long;
4. long (*var)(); // var – указатель на функцию, возвращающую значение типа long;
5. struct both {
int a;
char b; } (*var[5])(); // var – массив указателей на функции, возвращающие структуры типа both.
Чаще определения структурных типов и их использование в программах оказывается разнесенным по исходному тексту. В таком случае этот пример будет выглядеть следующим образом (на языке C++):
struct both {
int a;
char b; };
both (*var[5])();
6. double (*var())[3]; // var – функция, возвращающая указатель на массив из 3-х значений типа double;
7. union sign {
int x;
char y; } **var[5][5]; // var – массив из 5-ти элементов, являющихся массивами указателей на указатели на объединения типа sign (двумерный массив указателей на указатели).
Ситуация, аналогичная примеру 5. С учетом раздельного определения объединения и переменной var, последнее будет выглядеть следующим образом:
sign **var[5][5];
8. sign *(*var[5])[5]; // var – массив из 5-ти элементов, являющихся указателями на массив указателей на объединения типа sign.
Алгоритмы обработки статических линейных струткур чаще всего также носят линейный характер и представляют собой циклы, подобные циклам создания и удаления двумерного динамического массива (§3.3). Наряду с операциями, используемыми для простых структур данных – просмотр, модификация, ввод и вывод, – к массивам и другим линенйным структрурам (не только статическим) применяются более сложные операции, например, поиск, реверсирование (обращение).
Алгоритмы поиска, в том числе, в линейных структурах, будут рассмотрены позднее.
Операция реверсирования представляет собой перестановку элементов структуры данных, например, массива, в обратном порядке. Реверсирование может оказаться полезным в случае, когда массив упорядочен, например, по убыванию, и требуется переупорядочить его по возрастанию.
Часто требуется скопировать содержимое одного массива в другой. Наиболее просто такая операция выполняется, если массив-приёмник по размерам не превосходит массив-источник. Удобно оформить эту операцию в виде отдельной процедуры.