Struct student stud1,stud2;

Компилятор автоматически выделит память под данные переменные (непрерывный участок). Можно в одном операторе задать шаблон структуры и объявить переменные

Struct student

{

char name[30];

Int kurs;

char group[3];

Int index;

} stud1, stud2;

Доступ к конкретному элементу структуры осуществляется с помощью операции “точка” (dot). Например

strcpy(stud.name,”Иванов И.И.”);илиprintf(“%s”,stud2.group);

Структуры, как и переменные другого типа, могут объединяться в массивы структур. Например:

struct student stud1kurs[200];

Этот оператор создаст в памяти 200 переменных типа структуры с шаблоном student и именами stud1kurs[0], stud1kurs[1] и т. д.

Для доступа к полю kurs 25-го элемента массива используем конструкцию stud1kurs[24].kurs

Если объявлены две переменные типа структуры с одним шаблоном, можно сделать присваивание stud1=stud2; При этом произойдет побитовое копирование каждого поля одной переменной в соответствующее поле другой переменной. В то же время нельзя использовать операцию присваивания переменных типа структуры, шаблоны которых описаны под разными именами, пусть даже совсем идентично.

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

Пример:

func1(first.a); или func2(&second.b);

Можно в качестве формального параметра передать по значению всю структуру:

#include <stdio.h>

/* использование структуры в качестве параметра функции */

Struct stru

{

Int x;

Char y;

};

void f(struct stru param); /* прототип функции */

Main(void)

{

Struct stru arg;

arg.x=1; arg.y=’2’;

F(arg);

Return 0;

}

Void f(struct stru param)

{

printf(“%d %d \n”,param.x, param.y);

}

Можно также создать указатель на структуру и передавать аргумент типа структуры по ссылке. Объявить указатель на структуру можно следующим образом: trsuct stru *adr_pointer;

adr_pointer –переменная типа указатель на структуруstruct stru.

Если передавать структуру по значению, то все элементы структуры заносятся в стек. При использовании в качестве элемента структуры массива возможно переполнение стека. При передаче по ссылке в стек заносится только адрес структуры. При этом копирование структуры не происходит, а также появляется возможность изменять содержимое элементов структуры.

Struct complex

{

Float x;

Float y;

} c1, c2;

struct complex *a; /* объявление указателя */

a=&c1; /* указателю присваивается адрес переменнойс1 */

Получить значение элемента xпеременной c1 можно так: (*a).x;

Использование указателей на структуру встречается часто. Поэтому, кроме способа получения значения элемента структуры, используя (*a).x, применяется специальная операция -> (стрелка, arrow).

Вместо (*a).x можно использовать a -> x.

В качестве элементов структуры можно использовать массивы, структуры и массивы структур.

Пример:

Struct addr

{

char city[30],street[30];

Int house;

};

Struct fulladdr

{

Struct addr address;

Int room;

char name[30];

} f,g;

f.address.house=101; /* присвоение значения элементу house структуры address переменной f */

Доступ к отдельному биту

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

Один из методов, встроенных в язык С и позволяющих иметь доступ к биту, - это поля битов (bit-fields). В действительности поля битов – это специальный тип членов структуры, в котором определено, из скольких бит состоит каждый элемент. Основная форма объявления такой структуры следующая:

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

{

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

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

….

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

};

тип: {int, unsigned, signed}

ИмяI может быть пропущено, тогда соответствующее количество бит не используется (пропускается). Длина структуры всегда кратна 8. Так, если указать:

Struct onebit

{

unsigned one_bit: 1;

} obj;

то для переменнойobjбудет выделено 8 бит, но использоваться будет только первый.

В структуре могут быть смешаны обычные переменные и поля битов.

Объединения

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

Union u

{

Int i;

Char ch;

Long int l;

};

Таким образом задается шаблон объединения. Далее можно объявить переменные данного типа. Например:

Union u alfa, beta;

Можно объявлять переменные одновременно с заданием шаблона. В отличие от структуры для переменной типа union места в памяти выделяется ровно столько, сколько надо элементу объединения, имеющему наибольший размер в байтах. В приведенном выше примере под переменную alfa будет выделено 4 байта памяти. Все элементы располагаются в одном и том же месте памяти. Синтаксис использования элементов объединения такой же, как для структуры: u.ch=’5’;

Для объединений также разрешена операция ->, если обращение к объединению с помощью указателя.

Программа, приведенная ниже, выдает на экран двоичный код ASCII символа, вводимого с клавиатуры:

#include <stdio.h>

#include <conio.h>

/* использование полей битов и объединений */

struct byte {

int b1: 1;

int b2: 1;

int b3: 1;

int b4: 1;

int b5: 1;

int b6: 1;

int b7: 1;

int b8: 1;

}; /* определена структура – битовое поле */

union bits {

Char ch;

Struct byte b;

} u; /* определение объединения */

void decode(union bits u); /* прототип функции */

Main(void)

{

do {

u.ch=getche();

printf(“: “);

Decode(u);

} while(u.ch!=’q’);

Return 0;

}

Void decode(union bits u)

{

if (u.b.b8) printf(“1”);

else printf(“0”);

if (u.b.b7) printf(“1”);

else printf(“0”);

if (u.b.b6) printf(“1”);

else printf(“0”);

if (u.b.b5) printf(“1”);

else printf(“0”);

if (u.b.b4) printf(“1”);

else printf(“0”);

if (u.b.b3) printf(“1”);

else printf(“0”);

if (u.b.b2) printf(“1”);

else printf(“0”);

if (u.b.b1) printf(“1”);

else printf(“0”);

printf(“\n”);

}

Перечисляемый тип

Перечисляемый тип (enumeration) – это множество поименованных целых констант. Перечисляемый тип определяет все допустимые значения, которые могут иметь переменные этого типа. Основная форма объявления типа следующая: num имя_типа{список_названий} список переменных;

Список переменных может быть пустым. Пример определения перечисляемого типа и переменной данного типа: enum seasons {win, spr, sum, aut }; enum seasons s;

Ключом к пониманию сущности перечисляемого типа является то, что каждое из имен win, spr, sum, aut представляют собой целую величину. Если эти величины не определены по другому, то по умолчанию они соответственно равны 0, 1, 2. 3. Во время объявления типа можно одному или нескольким символам присвоить другие значения, например:

enum value {one=1, two, three, ten=10,thousand=1000,next);

printf(“%d %d %d %d %d\n”,one, two, ten, thousand, next);

На экране 1 2 10 1000 1001

С переменными перечисляемого типа можно производить следующие операции:

- присвоить переменную типа enum другой переменной того же типа;

- провести сравнение с целью выяснения равенства или неравенства;

- арифметические операции с константами типа enum (i=win – aut).

Переименование типов – typedef

Язык С позволяет давать новое название уже существующим типам данных. Для этого используется ключевое слово typedef.При этом не создается новый тип данных. Например: