Указатели на структуры описываются точно так же, как и указатели на другие типы данных. Существуют, по крайней мере, три причины использования указателей на структуры:
1) указателями проще управлять (например, при сортировке), чем самими структурами;
2) в некоторых версиях языка структура не может передаваться функции в качестве аргумента, но это возможно для указателя на структуру;
3) во многих эффективных представлениях данных используются структуры, которые содержат указатели на другие структуры данных.
Указатели на структуры используются при создании различных динамических структур данных, связанных списков, элементами которых, в свою очередь, являются структуры данных и т.д. Например, пусть необходимо создать объект, описывающий информацию о звезде: ее имя, спектральный класс, координаты, расстояние. Можно создать тип данных пользователя следующим образом:
struct star
{
char name[25];
char clas;
short subclass;
float decl,RA,dist;
} ;
Затем можно использовать созданный тип пользователя в программе:
#include <stdlib.h>
#include<string.h>
void main(void)
{
star *mystar; // создан указатель на структуру star
mystar = (star *) malloc(sizeof(star)); // выполняется инициализация указателя
strcpy(mystar -> name,"Эпсилон Лебедя");
mystar -> clas = ‘N‘;
mystar -> subclass = 2;
mystar -> decl = 3.5167;
mystar -> RA = -9.633;
mystar -> dist = 0.303;
….
free (mystar);
}
В этом варианте mystar объявлен как указатель типа star, а не как переменная типа star. Память для mystar резервируется путем обращения к функции malloc(). Для ссылки на элементы структуры mystar вместо прямого метода доступа (.) использован косвенный метод доступа, т.е. символ ->. Обе операции, "->" и ".", ассоциируются слева направо, так что эти конструкции эквивалентны.
Операции работы со структурами "->" и "." наряду с круглыми скобками () для списка аргументов и квадратными скобками [ ] для индексов находятся на самом верху иерархии старшинства операций и, следовательно, связываются очень крепко. Если, например, имеется описание
struct {
int x;
int *y;
} *p;
то выражение ++p->x увеличивает х, а не р до доступа к х, так как оно эквивалентно выражению ++(p->х).
Для изменения порядка выполнения операций можно использовать круглые скобки: выражение (++p)->х увеличивает p до доступа к х, а выражение (p++)->x увеличивает p после доступа к х (круглые скобки в последнем случае необязательны). Аналогично выражение *p->y извлекает то, на что указывает y; выражение *p->y++ увеличивает y после того, на что он указывал.