Размещение структурных переменных в памяти

Массивы структур

Использование typedef

Вложенные структуры

Обращение к полям структур

Обращение к элементам структур производится посредством:

а) операции принадлежности (.) в виде:

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

или

(*указатель_структуры_или_объединения).имя_элемента

б) операции косвенной адресации (->) в виде:

указатель_структуры_или_объединения -> имя_элемента

Например:

Объявляем переменную и указатель на переменные структуры

Stud_Type s1, *s2;

обращаемся к полям структуры:

s1. Number;

s1. Fio;

s1. S_b;

или

s2 -> Number,

s2 -> Fio;

s2 -> S_b;

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

Например, в структуре person, содержащей Ф.И.О. и дату рождения, сделать дату рождения внутренней структурой date по отношению к структуре person. Шаблон такой конструкции будет выглядеть следующим образом:

struct date

{

int day, month, year;

};

struct person

{

char fio[40];

struct date f1;

};

Объявляем переменную и указатель на переменные такой структуры:

struct person a, *p;

Инициализируем указатель p адресом переменной а:

p = &a;

Тогда обращение к полям структурной переменной a будет следующим:

a.fio

a.f1.day

a.f1.month

a.f1.year

или

p -> fio

p -> f1.day

p -> f1.month

p -> f1.year

Использование typedef упрощает определение структурных переменных, например:

typedef struct person

{

char fio[40];

int day, month, year;

} W;

здесь W - созданный пользователем тип данных - структура с указанными полями, и для нашего примера:

W t1, t2; - декларация двух переменных t1, t2 типа W.

Структурный тип может быть использован для декларации массивов, элементами которых являются структурные переменные, например:

struct person spisok[100]; - spisok - массив структур;

или

struct person

{

char fio[40];

int day, month, year;

} spisok[100];

В данном случае обращение к полю, например, day i -й записи может быть выполнено одним из следующих способов:

spisok[i].day *(spisok+i).day (spisok+i) -> day.

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

­ структурные переменные, являющиеся элементами массива, начинаются на границе слова, т.е. с четного адреса;

­ любое поле структурной переменной начинается на границе слова, т.е. с четного адреса и имеет четное смещение по отношению к началу переменной;

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

Некоторые особенности:

1. поля структуры, как правило, имеют разный тип, кроме функций, файлов и самой этой структуры;

2. поля не могут иметь атрибут класс памяти, данный атрибут можно определить только для всей структуры;

3. идентификаторы как самой структуры, так и ее полей могут совпадать с идентификатарами других объектов программы, т.к. шаблон структуры обладает собственным пространством имен;

4. при наличии в программе функций пользователя шаблон структуры рекомендуется поместить глобально перед определениями всех функций, в этом случае он будет доступен всем функциям.

5. Элементы структур в общем случае размещаются в памяти последовательно с учетом выравнивания начальных адресов. Выравнивание - установка значения адреса, кратного некоторой величине, определяемой собенностями адресации данных на аппаратном уровне.

Пример на использование структур

Вести сведения о студентах учебной группы (не более 50):

а) фамилию и имя;

в) итоги сдачи экзаменов – три оценки.

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

Текст программы может иметь вид:

#include <iostream.h>

#include <stdio.h>

#include <string.h>

#include <conio.h>

struct Spisok {

char Fio[20];

int Ot[3];

float S_Bal;

} *sved;

void Vvod(int nom,struct Spisok *sved)

{ cout << "\n Vvedi svedenia " << (nom+1);

cout << "\n FIO - "; gets(sved->Fio);

float s=0;

for(int i=0;i<3;i++) {

cout << "\n Otcenki - "; cin >> sved->Ot[i];

s+=sved->Ot[i];

}

sved->S_Bal=s/3.;

return; }

void main(void)

{ struct Spisok Stud[50]; int i,N; char Bukva;

clrscr();

cout << "\n Vvedi kol-vo < 50 "; cin >> N;

for(i=0;i<N;i++) Vvod(i,&Stud[i]);

cout << "\n Spisok Students";

for(i=0;i<N;i++)

printf("\n %20s %4.2f",Stud[i].Fio,Stud[i].S_Bal);

cout << "\n Poisk FIO (bukva) "; cin >> Bukva;

cout << "\n Sveden Students";

int kod_p=0;

for(i=0;i<N;i++)

if(Stud[i].Fio[0]==Bukva){ kod_p=1;

printf("\n %20s %4.2f",Stud[i].Fio,Stud[i].S_Bal); }

if(kod_p==0) cout << " Takix HET!";

cout << "\n Poisk zapisi";

Vvod(-1,sved);

kod_p=0;

for(i=0;i<N;i++)

if(memcmp(sved,&Stud[i],sizeof(sved))==0)

{ kod_p=1;

printf("\n %20s %4.2f",Stud[i].Fio,Stud[i].S_Bal);

}

if(kod_p==0) cout << " Takix HET!";

getch();

}


Понравилась статья? Добавь ее в закладку (CTRL+D) и не забудь поделиться с друзьями:  



double arrow
Сейчас читают про: