Можно ли сдавать один и тот же тест несколько раз? |
Производные типы данных языка C++. Структуры, объединения и перечисления
Выделение памяти
При создании переменной типа структуры:
- память под все элементы структуры выделяется последовательно для каждого элемента;
- для битовых полей память выделяется, начиная с младших разрядов;
- память, выделяемая под битовые поля, кратна байту;
- общая выделяемая память может быть больше, чем сумма размеров полей структуры.
Рассмотрим пример выделения памяти под структуру
struct structA { char cA; char sA[2]; float fA;};
При создании переменной структурного типа:
structA s1;
будет выделено 7 байтов. Элементы структуры будут размещены в памяти в следующем порядке:
Рассмотрим пример выделения памяти под структуру
struct structB { int i1:2; int i2:3; int :6; unsigned int i3:4;};
При создании переменной структурного типа:
structB s2;
будет выделено 2 байта. Элементы структуры будут размещены в памяти в следующем порядке:
Для целочисленных значений, предусматривающих наличие знакового разряда (например, int ), старший левый бит из общего числа битов, выделяемых под данное битовое поле, интерпретируется как знак. Например, битовое значение 1 для поля i1 будет восприниматься как -1, а значение 11 для поля i3 - как 3.
Доступ к элементам структуры
Элементы структуры могут иметь модификаторы доступа: public, private и protected. По умолчанию все элементы структуры объявляются как общедоступные ( public ). Забегая вперед, следует сказать, что все члены класса по умолчанию объявляются как защищенные ( private ).
Для обращения к отдельным элементам структуры используются операторы: . и ->.
Доступ к элементам структуры может иметь следующее формальное описание:
переменная_структурного_типа.элемент_структуры=значение; имя_структурного_типа *указатель_структуры= & переменная_структурного_типа; указатель_структуры->элемент_структуры=значение;
Например:
struct structA { char c1; char s1[4]; float f1;} aS1, // aS1 - переменная структурного типа *prtaS1=&aS1; // prtaS1 - указатель на структуру aS1 struct structB { struct structA aS2; // Вложенная структура } bS1,*prtbS1=&bS1; aS1.c1= 'Е'; // Доступ к элементу c1 структуры aS1 prtaS1->c1= 'Е'; // Доступ к элементу c1 через // указатель prtaS1 (*prtaS1).c1= 'Е'; // Доступ к элементу c1 (prtbS1->aS2).c1='Е'; // Доступ к элементу вложенной структуры
Доступ к элементу массива структурного типа имеет следующий формальный синтаксис:
имя_массива[индекс_элемента_массива].элемент_структуры
При использовании указателей на массив структур следует сначала присвоить указателю адрес первого элемента массива, а затем реализовывать доступ к элементам массива, изменяя этот указатель адреса.
Например:
struct structA { int i; char c;} sA[4], *psA; psA=&sA[0]; … cout<<psA->i; // Доступ к первому элементу массива // структур // Переход ко второму элементу массива psA++; // Эквивалентно записи: psA=&sA[1]; cout<<psA->i;
Передача структур в качестве параметров
Переменные структурного типа и элементы структуры можно передавать в функции в качестве параметров.
Передача параметров может выполняться:
- по ссылке или указателю;
- по значению.
При передаче параметра по указателю передается только указатель на структуру, при передаче по значению в стек копируется все содержание структуры.
Например:
struct structA { int i; char c;} sA, *psA=&sA; void F1(struct structA sA); // Передача параметров по значению void F2(struct structA *psA); // Передача параметров по указателю void F3(struct structA &sA); // Передача параметров по ссылке … void F2(struct structA *psA) { psA->i =10; } // Доступ к элементу структуры
При большой вложенности вызовов и использовании большого числа структур или их значительных размерах вызов по значению может привести к переполнению стека.
Функция может возвращать значение структурного типа или типа указателя на структуру.
Например:
struct structA { int i; char с;}; struct structA Function3(void); // Функция возвращает значение // структурного типа struct structA *Function4(void); // Функция возвращает указатель // на структуру