Структуры:

Структуры - это объединенная в единое целое множество компонентов данных.

В отличие от массива, всегда состоящего из однотипных элементов, компоненты структуры могут быть разных типов и все должны иметь различные имена. Например:


//Структура, описывающая товары на складе.

struct goods {
	char* name; //наименование
	long price;
	float percent; //наименование в %
	int voL;
	char date[9]; //дата поставки
	};

Комментарий:struct - спецификатор структурного типа, служебное слово goods - имя структурного типа(тег).

В фигурных скобках размещаются описания элементов, которые входят в каждый объект типа goods, ';' обязательна.

    С помощью struct goods можно:
  1. определить конкретную структуру struct goods flood; //структура с именем food
  2. указатель на структуры такого типа: struct point goods*point_to;

Есть и другие способы определения структур:


	=typedef struct
	=#define goods struct
	=struct - направленная структура безъимянного типа.

struct
	{
	char processor[10];
	int frequency;
	int memory;
	int disk;
	} PIV_asus,Nvidia,Compaq;

Комментарий: введены три структуры(три обьекта) с именами PIV_asus,Nvidia,Compaq в каждую из которых входят элементы, в которые можно будет занести сведения о характеристиках конкретных ПК.

Выделение памяти для структур:

Определение структурного типа не связано с выделением памяти, а при каждом определении структуры(объекта), ей выделяется память в таком количестве, чтобы могли разместиться данные всех элементов.

! влиять на размещение структур можно с помощью процессорной директивы #pragma (выравнивание данных).

Инициализация и присваивание:

Инициализация структур похожа на инициализацию массивов.Непосредственно в определении конкретной структуры после ее имени и знак = в фигурных скобках размещается список начальных значений элементов.


struct goods coat={"пиджак черный",400000,7.5,200,"12.06.01"};

! в отличие от массивов допускается присваивание структур присваивание структур следующим образом: tea=coat;

Доступ к элементам структур:

С помощью уточненых имен:


имя_структуры.имя_элемента

coat.name - указатель типа char* на строку "пиджак черный"
coat.price - переменная типа long 400000

Перед точкой стоит не название структурного типа, а имя конкретной структуры, для которой ее определение выделила память.

Уточненное имя - это выражение с двумя операндами и операцией '.' между ними - операцией доступа к элементу структуры.У нее самый высокий ранг, на ряду со скобками и операцией 'стрелка' для доступа к элементам структуры, через адресующий ее указатель.




Еще немного о структурах:

Вектор есть совокупность элементов одного типа; 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 не является достаточным для работы с полным почтовым адресом, но в качестве примера достаточен). Обратите внимание на точку с запятой в конце; это одно из очень немногих мест в C++, где необходимо ставить точку с запятой после фигурной скобки, поэтому люди склонны забывать об этом.

Переменные типа address могут описываться точно также, как другие переменные, а доступ к отдельным членам получается с помощью операции . (точка). Например:


address jd;
jd.name = "Jim Dandy";
jd.number = 61;

Запись, которая использовалась для инициализации векторов, можно применять и к переменным структурных типов. Например:


address jd = {
    "Jim Dandy",
    61, "South Street",
    "New Providence", {'N','J'}, 7974
};

Однако обычно лучше использовать конструктор . Заметьте, что нельзя было бы инициализировать 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;
}

Остальные осмысленные операции, такие как сравнение (== и !=) не определены. Однако пользователь может определить эти операции; Размер объекта структурного типа нельзя вычислить просто как сумму его членов. Причина этого состоит в том, что многие машины требуют, чтобы объекты определенных типов выравнивались в памяти только по некоторым зависящим от архитектуры границам (типичный пример: целое должно быть выравнено по границе слова) или просто гораздо более эффективно обрабатывают такие объекты, если они выравнены в машине. Это приводит к "дырам" в структуре. Например, (на моей машине) 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 вызвало бы к синтаксическую ошибку.