Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
ЗФ_ОАиП / Лекции ГГУ Скорины - Программирование.doc
Скачиваний:
179
Добавлен:
21.03.2016
Размер:
2.27 Mб
Скачать

29.4. Структурные переменные в памяти компьютера

Поля структурной переменной располагаются в оперативной памяти последовательно в том порядке, в котором они объявляются: первому элементу соответствует меньший адрес памяти, а последнему – больший. Адрес переменной (поля структуры) – адрес младшего байта этой переменной. Адрес самой структурной переменной совпадает с адресом первого поля.

Обратить внимание! Поля структурной переменной хранятся в памяти друг за другом, между ними нет никаких других данных. Две структурные переменные необязательно расположены в памяти рядом.

При выделении памяти под структурную переменную учитывается такой параметр, как выравнивание структуры. Выравнивание задается опцией компилятора (Options→Compiler→Code generation...→Word alignment). Может быть задано выравнивание структуры или на границе байта, или на границе слова.

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

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

  1. отдельная структурная переменная (элемент массива) начинается на границе слова (с четного адреса);

  2. любое поле не типа char начинается с четного адреса (имеет четное смещение от начала самой переменной);

  3. при необходимости в конце структурной переменной добавляется еще один байт, чтобы общее число байтов для переменной было четным.

struct AAA {

int a;

char c[3];

int b;

};

int x = sizeof(AAA); // x = 8 при выравнивании на границу слова

// x = 7 при выравнивании на границу байта

29.5. Доступ к полям структуры

Для доступа к отдельным полям структурной переменной используется операция '.', а доступ к отдельному полю структуры осуществляется посредством конструкции вида:

имя_структурной_переменной.имя_поля

Сначала мы указываем имя структурной переменной, затем ставим точку и в конце указываем имя поля структуры.

Так как структура – это новый тип, можно описывать указатели на этот тип. Для доступа к полям структуры через указатель (через адрес структуры) используется операция '->' вместо операции '.'.

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

Пример:

struct Point {

int x;

int y;

};

struct Point pnt1, pnt2 = {5, 7};

pnt1.x = 1;

pnt1.y = 10;

printf(“Точка 2: x=%d y=%d”, pnt2.x, pnt2.y);

float dist; // расстояние между точками 1 и 2

dist = sqrt((pnt1.x - pnt2.x) * (pnt1.x - pnt2.x)+

(pnt1.y - pnt2.y) * (pnt1.y - pnt2.y));

struct Point *ptr = &pnt2;

ptr->x = 0; // (*ptr).x = 0; pnt2.x = 0; (&pnt2)->x = 0;

ptr->y = 0; // (*ptr).y = 0; pnt2.y = 0; (&pnt2)->y = 0;

dist = sqrt((pnt1.x - ptr->x) * (pnt1.x - pnt2.x)+

(pnt1.y - ptr->y) * (pnt1.y - pnt2.y));

Поля структуры могут иметь любой тип, в том числе и быть другой структурой. Другими словами, структуры могут быть вложены друг в друга. Понятно, что шаблон вкладываемой структуры должен быть уже известен компилятору. Ссылка на поле вложенной структуры формируется из имени структурной переменной, имени структурного поля и имени поля вложенной структуры.

Пример (прямоугольник как пара точек на углах одной из его диагоналей):

struct Point {

int x;

int y;

};

struct Rect {

struct Point pnt1;

struct Point pnt2;

int color;

};

struct Rect t1, t2 = {{0,0}, {5,5}, 2};

struct Rect *p_rect;

struct Point *p_point;

t1.pnt1 = t2.pnt2;

t1.pnt2.x = 11;

t1.pnt2.y = t2.pnt1.y + 10;

t1.color = 4; // t1 = {{5,5}, {11,10}, 4};

p_rect = &t2;

p_point = &t2.pnt2;

p_rect->pnt1 = t1.pnt2;

p_rect->pnt2.x = 55;

p_point->y = 77;

t2.color = 1; // t2 = {{11,10}, {55,77}, 1};

Структура типа S не может содержать элемент, являющийся структурой типа S (структура не может вкладываться сама в себя). Однако структура типа S может содержать элемент, указывающий на структуру типа S. Это позволяет использовать структуры для построения сложных динамических структур данных – стеков, списков, деревьев и т.п.

struct Node {

int data;

struct Node *next; // указатель на объект типа Node

};