Структуры. Перечисления. Объединения. Битовые поля.
1.1. Перечисления.
Перечислением называется тип данных, который включает множество именованных целочисленных констант. Именованные константы, принадлежащие перечислению, называются перечислимыми константами.
Объявляются перечисления следующим образом:
enum color { r, g, b }; // объявление типа
где enum – ключевое слово, color – имя типа перечисления, r, g, b – сами перечислимые константы. При объявлении типа перечисления его значения могут инициализироваться произвольными целочисленными константами или константным выражением. Например,
enum color { r = 2, g = r = 2, b = 6 }; // объявление типа
Если инициализация отсутствует, то перечислимым константам присваиваются последовательные значения: 0, 1, 2, … Например,
enum color { r, g, b }; // r = 0, g = 1, b = 2
Переменная типа перечисление объявляется следующим образом:
enum color c; // объявление переменной c, которая имеет тип color (язык С)
color d; // объявление переменной d, которая имеет тип color (язык С++)
и также называется перечислением. Объявление типа перечисления и переменной, которая имеет этот тип, может быть объединено в одну инструкцию. Например,
enum turn { off, on } a; // а – переменная типа turn
Переменным перечислимого типа можно присваивать только именованные значения перечислимых констант. Например,
color c = r; // правильно
color c = 0; // ошибка
Целочисленным переменным можно присваивать значения перечислимых констант. Например,
int e = r; // правильно
1.2. Структуры.
Тип структура описывает упорядоченный набор данных, которые называются полями или членами структуры. Каждое поле структуры имеет имя и тип, который должен отличаться от типов void и функция. При этом следует учитывать, что структура может включать только такие поля, длина которых известна компилятору в момент определения структуры.
Объявляются структуры следующим образом:
struct emp
{
int empno;
char name[20];
double salary;
};
где struct – ключевое слово, emp – имя типа структуры, empno, name, salary – члены структуры.
Переменная типа структура объявляется следующим образом:
struct emp e; // объявление переменной e, которая имеет тип emp (язык С)
emp d; // объявление переменной d, которая имеет тип emp (язык С++)
и также называется структурой. Объявление типа структуры и переменной, которая имеет этот тип, может быть объединено в одну инструкцию. Например,
struct emp
{
int empno;
char name[20];
double salary;
} director; // director – переменная типа emp
Инициализируются структуры также как и массивы. Например,
struct emp a = { 10, “Paul”, 2000 };
Так как члены структуры описываются в блоке, то их имена принадлежат локальной области видимости внутри этого блока. Для доступа к элементу структуры используется оператор точка ‘.’. Например,
director.empno = 20;
strcpy(director.name, “John”); // нельзя выполнить присваивание, так как director.name – константа
director.salary = 3000;
Членами структуры могут быть массивы и другие структуры. Для доступа к членам вложенной структуры оператор ‘.’ используется столько раз, какова вложенность структуры. Например,
#include <stdio.h>
struct demo
{
int a;
struct inside
{
int b;
int c;
} b;
};
int main ()
{
struct demo c = { 1, {2, 3} };
printf(“%d %d %d\n”, c.a, c.b.b, c.b.c ); // печатает: 1 2 3
return 1;
}
При объявлении структура может содержать поля, тип которых является указателем на тип объявляемой структуры. Например,
struct node /* вершина двоичного дерева */
{
struct node *left; /* левый потомок */
struct node *right; /* правый потомок */
};
Структуры одного типа можно присваивать друг другу. В этом случае оператор присваивания выполняет по членное копирование структур. Например,
struct emp boss;
boss = director;
Отметим, что структуры даже одного типа нельзя сравнивать между собой.
1.3. Объединения.
Тип объединение описывает набор данных, которые называются элементами или членами объединения. Объединение позволяет хранить в одной и той же области памяти значения различных типов, которые соответствуют типам элементов объединения. Но в каждый данный момент времени в этой области памяти может храниться только одно значение. Отсюда следует, что длина памяти, распределяемой компилятором под объединение, равна наибольшей из длин членов этого объединения. Как и в случае структуры, члены объединения могут иметь любой тип за исключением типов void и функция.
Объявляются объединения следующим образом:
union num
{
int n;
double f;
};
где union – это ключевое слово, num – имя типа объединения, n, f – члены объединения.
Переменная типа объединение объявляется следующим образом:
union num d; // объявление переменной d, которая имеет тип num (язык С)
num d; // объявление переменной d, которая имеет тип num (язык С++)
и также называется объединением. Объявление типа объединения и переменной, которая имеет этот тип, может быть объединено в одну инструкцию. Например,
union num
{
int n;
double f;
} d; // d – переменная типа num
При объявлении переменной типа объединение её можно инициализировать значением, которое должно иметь тип первого члена объединения. Например,
union num d = { 1 }; // правильно, d = 1
union num d = { 1.0 }; // ошибка
Как и в случае со структурами, для доступа к элементу объединения используется оператор точка ‘.’. Например,
union num e, g;
e.n = 1;
e.f = 1.1;
Объединения одного типа можно присваивать друг другу. В этом случае оператор присваивания выполняет по членное копирование объединений. Например,
union num e, g;
e = g;
Также как и структуры объединения нельзя сравнивать.
1.4. Битовые поля.
Битовым полем называется член структуры или объединения, который определяет последовательность бит. Битовое поле может иметь один из следующих типов: int, unsigned или signed. При объявлении битового поля после его имени указывается длина поля в битах. Например,
struct demo
{
unsigned a1: 1; // 1 бит
signed b1: 3; // 3 бита
int c1: 6; // 6 бит
};
Длина битового поля должна быть неотрицательным целым числом и не должна превышать длины базового типа данных битового поля.
Инициализируются битовые поля так же, как и обычные элементы структуры. Например,
struct demo
{
unsigned a1: 1;
unsigned a2: 2;
} s = { 0, 1 }; // a1 = 0, a2 = 1
Доступ к элементам битового поля осуществляется так же, как и доступ к обычным членам структуры. Например,
#include <stdio.h>
struct demo
{
unsigned a: 1;
signed b: 3;
int c: 6;
};
int main ()
{
struct demo s;
s.a = 1;
s.b = -1;
s.c = -4;
printf(“s.a = %u\n”, s.a); // печать: s.a = 1
printf(“s.b = %d\n”, s.b); // печать: s.b = -1
printf(“s.c = %d\n”, s.c); // печать: s.c = -4
return 1;
}
Битовые поля могут использоваться в выражениях точно так же, как и переменные базового типа битового поля. Обычно битовые поля используются для установки различных флагов.
1.5. Передача структур в функции.
Когда структура используется как параметр функции, то она передается в функцию по значению, как и принято в языке программирования С. Например,
struct emp
{
int empno;
char name[20];
double salary;
};
void print(struct emp s) // или просто: void print(emp s)
{
printf(“%d %s %f\n”, s.empno, s.name, s.salary);
}
Для того чтобы функция могла изменить значения членов структуры, она должна получить указатель на эту структуру. Для доступа к членам структуры через указатели используется оператор ‘->’. Например,
void init_emp(emp *ps, int en, char *nm, double sal)
{
ps->empno = en;
strcpy(ps->name, nm);
ps->salary = sal;
}
Аналогично передаются в функции и объединения. Например, передадим в функцию указатель на объединение.
union num
{
int n;
double f;
} d;
void print(char c, num *n)
{
switch(c)
{
case ‘i’:
printf(“n = %d\n”, n->n);
break;
case’f’:
printf(“f = %f\n”, n->f);
break;
default:
printf(“Unknown type.\n”);
}
enum color { r, g, b }; // r = 0, g = 1, g = 2
Не g 3 символ, а b
спасибо, исправил
Желательно больше примеров использования
битовых полей,объединений и перечислений.
Здесь указаны не все случаи использования структур,
битовых полей,объединений и перечислений.