Тема Структуры Лекция 14. 10. 13 г. 1
Основные понятия Структура – это набор нескольких именованных переменных, объединённых в единое целое под общим именем. Входящие в структуру переменные называются элементами, полями или членами структуры. Члены структуры имеют произвольные типы и уникальные в пределах структуры имена. Доступ к членам структуры производится по составному имени, включающему имя структуры и имя члена структуры. Пример: struct {int x; int y; } pt 1, pt 2; pt 1. x = 3; pt 1. y = 6; pt 2 = pt 1; Синтаксис языка С позволяет отделить описание «внутреннего устройства» структуры от определения конкретных переменных, имеющих это внутреннее устройство: struct point {int x; int y; }; struct point pt 1, pt 2; Такой подход позволяет рассматривать первое объявление как новый, структурный тип данных, а второе – как определение переменных этого типа. Замечание. Допускается совмещать объявление структурного типа и объявление переменных этого типа: struct point {int x; int y; } pt 1, pt 2; Лекция 14. 10. 13 г. 2
Основные понятия Элементы структуры могут иметь произвольный тип, в том числе, они сами могут быть структурами. Рассмотрим два примера структур (структурных типов), подходящих для работы с графикой: «точка» и «прямоугольник» : point y struct point { int x, y; }; (4, 3) x p 2 y p 1 struct rect { struct point p 1, p 2; }; x int y rect p 1 int x int y p 2 int x int y Лекция 14. 10. 13 г. 3
Структуры и функции Приведенная ниже программа проверяет принадлежность произвольной точки прямоугольнику. //Ex 056. с - структуры #include
Структуры и функции Как видно из предыдущей программы, структуры могут использоваться в качестве аргументов функций. Следующая программа демонстрирует, что структура может быть и возвращаемым из функции значением. Решить задачу: найти прямоугольник, вмещающий два заданных прямоугольника. Пусть первый прямоугольник имеет координаты: {1, 1}, {4, 5}, а второй - {2, 0}, {6, 6} Очевидно, что решением будет прямоугольник с координатами: {1, 0}, {6, 6} Лекция 14. 10. 13 г. 5
Структуры и функции //Ex 057. с #include
Указатели на структуры и массивы структур Структурные типы данных также как и обычные типы данных могут использоваться для конструирования указателей и массивов. Пусть struct T – структурный тип данных, тогда: struct T x – описывает переменную типа struct T, или просто структуру x, struct T *p – описывает указатель на структуру типа struct T, struct T m[5] – описывает массив из пяти структур типа struct T, struct T *pm[] – описывает массив неопределенного размера из указателей на структуры типа struct T, struct T (*pm)[] – описывает указатель на массив неопределенного размера из структур типа struct T и т. д. Указатели на структуры особенно полезны при передаче аргументов-структур в функции, т. к. приводят к экономии памяти при передаче громоздких структур. Даны описания: struct point { int x, y; }; (*pp). x эквивалентно pp->x struct point pt, *pp = &pt; (*pp). x = 3; (*pp). y = 5; Скобки нужны потому, что приоритет операции. выше, чем у операции * операции наивысшего приоритета () [] ->. Лекция 14. 10. 13 г. 7
Массивы структур Для заданного множества прямоугольников найти минимальный покрывающий их прямоугольник. //Ex 058. с #include
Определение новых типов с помощью typedef Синтаксис определения новых типов в языке С достаточно громоздкий, что приводит к снижению «читабельности» (наглядности) исходного текста программы. Этот недостаток устраняется с помощью специального оператора typedef (Type Definition), который позволяет вводить синонимы (упрощённую запись) для громоздких определений типов. Полное название Например: typedef unsigned char Uchar; typedef int Boolean; Синоним typedef char* String; typedef struct point { int x, y; } Point; typedef Point* Ppoint; typedef struct rect {Point pt 1, pt 2; } Rect; typedef int (*F) (int); Синоним Лекция 14. 10. 13 г. 9
Модификация программы //Ex 058 -1. с #include
Битовые поля в структурах Как уже отмечалось ранее, членами одной структуры могут быть данные совершенно разных типов. В языке С есть возможность включать в состав структуры «нестандартные» элементы, размер которых исчисляется не в байтах, а в битах. В качестве имени типа для таких элементов обычно используется unsigned int, а размер в битах указывается после имени элемента через двоеточие: struct { unsigned int is_keyword : 1; unsigned int is_extern : 1; unsigned int is_static : 1; } flags; В этом примере определяется переменная flags, которая содержит три однобитовых поля. На отдельные поля ссылаются так же, как и на элементы обычных структур: flags. is_keyword, flags. is_extern и т. д. Поля "ведут себя" как малые целые и могут участвовать в арифметических выражениях точно так же, как и другие целые. Замечание. Невозможно определить адрес битового поля структуры, поэтому операция &flags. is_keyword вызовет появление сообщения об ошибке при компиляции. Лекция 14. 10. 13 г. 11
Объединения (union) Помимо структур в языке С имеется еще одна конструкция, позволяющая собрать под одним именем разнотипные элементы – объединения. Синтаксически объединения практически ничем не отличаются от структур, кроме использования ключевого слова union вместо ключевого слова struct. Принципиальное отличие объединений от структур – все элементы объединения размещаются в памяти с одного адреса и перекрывают друга. Вследствие этого в каждый момент времени объединение может хранить только одно поле: union u_tag { int ival; float fval; char *sval; } u; Очевидно, что получить значение поля объединения можно лишь того типа, какой был ранее записан в это объединение: u. ival = 10; … x = u. fval; // err! Лекция 14. 10. 13 г. 12