Язык программирования Си. Издание 3-е, исправленное
Шрифт:
Если функции передается большая структура, то, чем копировать ее целиком, эффективнее передать указатель на нее. Указатели на структуры
сообщает, что pp– это указатель на структуру типа struct point. Если pp указывает на структуру point, то *pp– это сама структура, а (*pp).x и (*pp).y– ее элементы. Используя указатель pp, мы могли бы написать
Скобки в (*pp).x необходимы, поскольку приоритет оператора . выше, чем приоритет *. Выражение *pp.x будет проинтерпретировано как *(pp.x), что неверно, поскольку pp.x не является указателем.
Указатели на структуры используются весьма часто, поэтому для доступа к ее элементам была придумана еще одна, более короткая форма записи. Если p– указатель на структуру, то
р-›
есть ее отдельный элемент. (Оператор – › состоит из знака -, за которым сразу следует знак ›.) Поэтому printf можно переписать в виде
printf("origin: (%d,%d)\n", pp-›х, pp-›y);
Операторы. и -› выполняются слева направо. Таким образом, при наличии объявления
следующие четыре выражения будут эквивалентны:
Операторы доступа к элементам структуры . и – › вместе с операторами вызова функции и индексации массива [] занимают самое высокое положение в иерархии приоритетов и выполняются раньше любых других операторов. Например, если задано объявление
то
увеличит на 1 значение элемента структуры len, а не указатель p, поскольку в этом выражении как бы неявно присутствуют скобки: ++(p-›len). Чтобы изменить порядок выполнения операций, нужны явные скобки. Так, в (++р)-›len, прежде чем взять значение len, программа прирастит указатель p. В (р++)-›len указатель p увеличится после того, как будет взято значение len (в последнем случае скобки не обязательны).
По
6.3 Массивы структур
Рассмотрим программу, определяющую число вхождений каждого ключевого слова в текст Си-программы. Нам нужно уметь хранить ключевые слова в виде массива строк и счетчики ключевых слов в виде массива целых. Один из возможных вариантов - это иметь два параллельных массива:
Однако именно тот факт, что они параллельны, подсказывает нам другую организацию хранения - через массив структур. Каждое ключевое слово можно описать парой характеристик
Такие пары составляют массив. Объявление
объявляет структуру типа key и определяет массив keytab, каждый элемент которого является структурой этого типа и которому где-то будет выделена память. Это же можно записать и по-другому:
Так как keytab содержит постоянный набор имен, его легче всего сделать внешним массивом и инициализировать один раз в момент определения. Инициализация структур аналогична ранее демонстрировавшимся инициализациям - за определением следует список инициализаторов, заключенный в фигурные скобки:
Инициализаторы задаются парами, чтобы соответствовать конфигурации структуры. Строго говоря, пару инициализаторов для каждой отдельной структуры следовало бы заключить в фигурные скобки, как, например, в