Структуры и объединения

В языках Си/Си++ понятие структуры аналогично понятию записи (record) в Паскале. Это структурированный тип данных, представляющий собой поименованную совокупность разнотипных элементов. Тип структура обычно используется при разработке информационных систем, баз данных.

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

Элементы такой структуры (фамилия, курс, группа, стипендия) называются полями. Каждому полю должно быть поставлено в соответствие имя и тип. Формат описания структурного типа следующий: struct имя_типа {определения_элементов};

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

struct student {char fam[30];

i n t kurs;

char grup[3];

f l o a t s t i p;

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

struct student studl, stud2;

Правила Си++ разрешают в этом случае служебное слово s t r u c t опускать и писать student studl, stud2;

Здесь studl и stud2 — переменные структурного типа.

Допускаются и другие варианты описания структурных переменных. Можно вообще не задавать имя типа, а описывать сразу переменные:

struct {char fam[30];

int kurs;

char grup[3];

float stip;

} studl, stud2, *pst;

B этом примере кроме двух переменных структурного типа объявлен указатель p s t на такую структуру. В данном описании можно было сохранить имя структурного типа student.

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

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

Снова все похоже на Паскаль. Примеры уточненных имен для описанных выше переменных:

studl.fam; studl.stip

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

student studl={"Кротов", 3, "Ф32", 350};

Пусть в программе определен указатель на структуру student *pst, studl;

Тогда после выполнения оператора присваивания pst=&studl;

к каждому элементу структурной переменной studl можно обращаться тремя способами. Например, для поля fam studl.fam или (*pst).fam или pst->fam

В последнем варианте используется знак операции доступа к элементу структуры: —>. Аналогично можно обращаться и к другим элементам этой переменной:

pst->FIO, pst->grup, pst->stip.

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

о 100 студентах могут храниться в массиве, описанном следующим образом:

student stud[100];

Тогда сведения об отдельных студентах будут обозначаться, например, так: s t u d f i ].fam, stud[5].kurs и т.п. Если нужно взять первую букву фамилии 25-го студента, то следует писать:

stud[25].fam[0].

Пример 1. Ввести сведения об N студентах. Определить фамилии студентов, получающих самую высокую стипендию.

•include <stdio.h>

•include <conio.h>

void main (}

{

const N=30; int i; float maxs;

struct student {char fam[15];

int kurs;

char grup[3];

float stip;

};

student stud[N];

clrscr();

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

{ printf("%d-n студент",i);

printf("\п"Фамилия:");scanf("%s",&stud[i].fam);

printf("Курс:"); scanf("%d", &stud[i].kurs);

printf("Группа:"); scanf("%s",&stud[i].grup);

printf("Стипендия:"); scanf("%f",&stud[i].stip);

}

maxs=0;

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

if (stud[i].stip>maxs) maxs=stud[i].stip;

printf("\n Студенты,получающие максимальную

стипендию %f руб.", maxs);

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

if(stud[i].stip==maxs) printf("\n%s",stud[i].fam);

}

Элемент структуры типа поля битов. Использование структуры в программе на Си позволяет работать с отдельными битами, т.е. с разрядами двоичного кода. Для этого используются элементы структуры типа поля битов. Формат структуры, содержащий поля битов, следующий:

struct имя_структуры

{ тип имя_поля 1: длина_в_битах;

тип имя поля 2: длина в битах;

тип имя_поля_Ы: длина_в_битах;

};

В качестве типа полей могут использоваться спецификаторы: int, unsigned, signed. Минимальной величиной такого типа может быть структура, состоящая всего из одного битового поля. Пример описания такой структуры:

struct onebit

{ unsigned bit:1;

} cod;

Конечно, для переменной cod в памяти будет выделено 8 бит (1 байт), но использоваться будет только один первый бит.

Объединение. Объединение — это еще один структурированный тип данных. Объединение похоже на структуру и в своем описании отличается от структуры тем, что вместо ключевого слова s t r u c t используется слово union.

union имя_типа

{определения_элементов};

Объединение отличается от структуры способом организации во внутренней памяти. Все элементы объединения в памяти начинаются с одного байта.

Пусть в программе описана структура:

struct S

{ int i;

char ch;

long int L;

};

Расположение ее элементов в памяти будет следующим:

байт байт

i

байт

ch

байт байт байт байт

L

Элементы структуры занимают последовательные ячейки памяти с размером, соответствующим типу. Общий размер структуры равен сумме длин полей. А теперь рассмотрим объединение со следующим описанием:

union s

{ int i;

char ch;

long int L;

};

Величина с таким типом в памяти будет расположена следующим образом:

байт

ch

байт

L

байт

L

байт

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

Пример 2. Составим программу решения следующей задачи: с клавиатуры вводится символ. Вывести на экран двоичный код этого символа.

//Получение двоичного кода символа

•include <stdio.h>

•include <conio.h>

//Структура битовых полей

struct byte{int bl:l;

Int

int

int

int

int

int

int

};

//Объединение -

union bits

{char ch;

byte cod

b2:l

b3:l

b4:l

b5:l

b6:l

b7:l

b8:l

переменная

} u;

//Прототип функции декодирования

void decode(bits x);

//Основная программа

void main()

{ do{u.ch=getche(); //Ввод символа с клавиатуры

printf(":");

decode(u);

} while (u.ch! = 'q'); //Символ q- признак

// ввода

конца

//Функция декодирования

void decode(bits u)

{ if

if

if

if

if

if

if

if

(u.cod.b8) printf("l")

(u

(u

(u

(u

(u

(u

(u

,cod.b7)

,cod.b6)

cod.

cod.

cod.

cod.

b5)

b4)

b3)

b2)

cod.bl)

printf("1")

printf("1")

printf("1")

printf("1")

printf("1")

printf ("1")

printf ("1")

else printf ("0")

else printf ("0")

else printf ("0")

else printf ("0")

else printf ("0")

else printf ("0")

else printf ("0")

else printf ("0")

printf("\n");

В этой программе переменная-объединение и содержит два элемента: символьное поле ch и битовую структуру cod, которые накладываются друг на друга. Таким образом, оказывается возможным получить доступ к каждому биту кода символа. Работа программы заканчивается после ввода символа q. Вот вариант результатов работы данной программы:

s:01110011

d:01100100

J:01101010

а:01100001

b:01100010

с:01100011

d:01100100

q:01110001

 

 


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



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