|
||||
|
2.3.8 Структуры Вектор есть совокупность элементов одного типа, struct является совокупностью элементов (практически) произвольных типов. Например: struct address (* // почтовый адрес char* name; // имя «Jim Dandy» long number; // номер дома 61 char* street; // улица «South Street» char* town; // город «New Providence» char* state[2]; // штат 'N' 'J' int zip; // индекс 7974 *) определяет новый тип, названный address (почтовый адрес), состоящий из пунктов, требующихся для того, чтобы послать кому-нибудь корреспонденцию (вообще говоря, address не является достаточным для работы с полным почтовым адресом, но в качестве примера достаточен). Обратите внимание на точку с запятой в конце; это одно из очень немногих мест в С++, где необходимо ставить точку с запятой после фигурной скобки, поэтому люди склонны забывать об этом. Переменные типа address могут описываться точно также, как другие переменные, а доступ к отдельным членам получается с помощью операции . (точка). Например: address jd; jd.name = «Jim Dandy»; jd.number = 61; Запись, которая использовалась для инициализации векторов, можно применять и к переменным структурных типов. Например: address jd = (* «Jim Dandy», 61, «South Street», «New Providence», (*'N','J'*), 7974 *); Однако обычно лучше использовать конструктор (#5.2.4). Заметьте, что нельзя было бы инициализировать jd.state строкой «NJ». Строки оканчиваются символом '\0', поэтому в «NJ» три символа, то есть на один больше, чем влезет в jd.state. К структурным объектам часто обращаются посредством указателей используя операцию -». Например: void print_addr(address* p) (* cout «„ p-“name „„ „\n“ „„ p-“number „„ " " „„ p-“street „« «\n“ «« p-“town «« «\n“ «« chr(p-“state[0]) «« chr(p-“state[1]) «« " " «« p-“zip «« «\n“; *) Объекты типа структура можно присваивать, передавать как параметры функции и возвращать из функции в качестве результата. Например: address current; address set_current(address next) (* address prev = current; current = next; return prev; *) Остальные осмысленные операции, такие как сравнение (== и !=) не определены. Однако пользователь может определить эти операции, см. Главу 6. Размер объекта структурного типа нельзя вычислить просто как сумму его членов. Причина этого состоит в том, что многие машины требуют, чтобы объекты определенных типов выравнивались в памяти только по некоторым зависящим от архитектуры границам (типичный пример: целое должно быть выровнено по границе слова), или просто гораздо более эффективно обрабатывают такие объекты, если они выровнены в машине. Это приводит к «дырам» в структуре. Например, (на моей машине) sizeof(address) равен 24, а не 22, как можно было ожидать. Заметьте, что имя типа становится доступным сразу после того, как оно встретилось, а не только после того, как полностью просмотрено все описание. Например: struct link(* link* previous; link* successor; *) Новые объекты структурного типа не могут быть описываться, пока все описание не просмотрено, поэтому struct no_good (* no_good member; *); является ошибочным (компилятор не может установить размер no_good). Чтобы дать возможность двум (или более) структурным типам ссылаться друг на друга, можно просто описать имя как имя структурного типа. Например: struct list; // должна быть определена позднее struct link (* link* pre; link* suc; link* member_of; *); struct list (* link* head; *) Без первого описания list описание link вызвало бы к синтаксическую ошибку. |
|
||