Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Лекции / lezione6

.html
Скачиваний:
10
Добавлен:
28.06.2014
Размер:
16.73 Кб
Скачать

Перечислимый тип. Структуры. Объединения Лекция 6. Перечислимый тип. Структуры. Объединения 1. Перечислимый тип Перечислимый тип задаёт тип, который является подмножеством целого типа. Объявление переменной перечислимого типа задаёт имя переменной и определяет список именованных констант, называемый списком перечисления:

enum [<тег>] {<список перечисления>} <описатель> [, <описатель> ...];

enum  <тег>   <описатель> [, <описатель> ...];

<Тег> предназначен для различения нескольких перечислимых типов, объявленных в одной программе. <Список перечисления> содержит одну или более конструкций вида:

<идентификатор> [= <константное выражение>] Конструкции в списке разделяются запятыми. Каждый <идентификатор> именует элемент списка перечисления. По умолчанию, если не задано <константное выражение>, первому элементу присваивается значение 0, следующему элементу – значение 1 и т.д. Запись = <константное выражение> изменяет умалчиваемую последовательность значений. Элемент, идентификатор которого предшествует записи = <константное выражение>, принимает значение, задаваемое этим константным выражением. Константное выражение должно иметь тип int и может быть как положительным, так и отрицательным. Следующий элемент списка получает значение, равное <константное выражение> + 1, если только его значение не задаётся явно другим константным выражением. В списке перечисления могут содержаться элементы, которым сопоставлены одинаковые значения, однако каждый идентификатор в списке должен быть уникальным. Кроме того, идентификатор элемента списка перечисления должен быть отличным от идентификаторов элементов всех остальных списков перечислений, а также от других идентификаторов. enum Weekdays {SA, SU,     MO, TU, WE, TH, FR};   enum Weekdays {SA, SU = 0, MO, TU, WE, TH, FR}; // SA и SU имеют одинаковое значение

void main()    { enum Weekdays d1 = SA, d2 = SU, d3 = WE, d4;      d4 = 2; // Ошибка!    d4 = d1 + d2; // Ошибка!    d4 = (enum Weekdays)(d1 + d2); // Можно, но результат    d4 = (enum Weekdays)(d1 - d2); // может не попасть    d4 = (enum Weekdays)(TH * FR); // в область определения    d4 = (enum Weekdays)(WE / TU); // перечисления   }   2. Структуры Структура позволяет объединить в одном объекте совокупность значений, которые могут иметь различные типы. Однако в языке С реализован очень ограниченный набор операций над структурами как единым целым: передача функции в качестве аргумента, возврат в качестве значения функции, получение адреса. Можно присваивать одну структуру другой, если они имеют одинаковый тип. Объявление структуры задает имя структурного типа и/или последовательность объявлений переменных, называемых элементами структуры. Эти элементы могут иметь различные типы.

struct [<тег>] {<список объявлений элементов>} <описатель> [, <описатель> ...];

struct  <тег>   <описатель> [, <описатель> ...]; <Тег> предназначен для различения нескольких структур, объявленных в одной программе. Список объявлений элементов представляет собой последовательность из одного или более объявлений переменных. Каждая переменная, объявленная в этом списке, называется элементом структуры. Особенность синтаксиса объявлений элементов структуры состоит в том, что они не могут содержать спецификаций класса памяти и инициализаторов. Элементы структуры могут иметь базовый тип, либо быть массивом, указателем, объединением или структурой. struct    { char str[50];      int a, b; // Объявляем структуру, не задавая тег   } s; // и сразу же объявляем переменную

struct S    { char str[50];      int a, b;     }; // Объявляем структуру с тегом S

struct S s; // Объявляем переменную Элемент структуры не может быть структурой того же типа, в которой он содержится. Однако он может быть указателем на тип структуры, в которую он входит. Размер указателя стандартный, поэтому компилятор знает, сколько памяти потребуется под указатель. Для работы с указателем надо знать размер типа, на который он указывает, но к моменту работы с указателем структура будет полностью объявлена, и, следовательно, размер её будет известен. Идентификаторы элементов структуры должны различаться между собой. Идентификаторы элементов разных структур могут совпадать. Для инициализации структуры, как и других составных типов, надо записать список инициализаторов через запятую в фигурных скобках. struct S s = {"Str", 0, 1}; // Используем тег S, объявленный в предыдущем примере Выбор элемента структуры осуществляется с помощью одной из следующих конструкций:

<переменная> . <идентификатор элемента структуры>

<указатель> -> <идентификатор элемента структуры> Выражение выбора элемента позволяет получить доступ к элементу структуры. Выражение имеет значение и тип выбранного элемента. struct S s, *p = &s; // Объявляем переменную s и указатель p, в который заносим адрес переменной s s.a  = 10;   p->b = 20;   Две структуры являются разными типами, даже если у них одинаковые члены. 2.1. Пример Вводим массив структур и осуществляем поиск по любой совокупности параметров.

#include <stdio.h>

#include <string.h>

#include <conio.h>

struct S                         // Объявляем структуру, состоящую

{ char str[21];                  // из строки и целого числа

  int a;

 };

struct S s[10];                  // Объявляем массив структур

void main(int argc, char *argv[])

{ int n, a, i, check = 0;        // Переменная а содержит число, которое будет сравниваться с полем структуры а.

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

  char str[21] = "";             // Переменная str содержит строку, которая будет сравниваться с полем структуры str.

                                 // Если переменная str содержит пустую строку, этот параметр не используется для поиска.

  FILE *in, *out;

  char ans;

  if (argc < 3)

   { printf("Too few arguments.\n"); return; }

  if ((in = fopen(argv[1], "r")) == NULL)

   { printf("It is impossible to open file '%s'.\n", argv[1]);

     return;

    }

  if ((out = fopen(argv[2], "w")) == NULL)

   { printf("It is impossible to open file '%s'.\n", argv[2]);

     fclose(in); return;

    }

  for (n = 0; !feof(in); n++)

   fscanf(in, "%s%d", s[n].str, &s[n].a);

  fclose(in);

  printf("Use Str for search? "); ans = getche();

  if (ans == 'y' || ans == 'Y')

   { printf("\nInput string for search: "); scanf("%s",str); }

  printf("Use A for search? "); ans = getche();

  if (ans == 'y' || ans == 'Y')

   { check = 1; printf("\nInput A: "); scanf("%d", &a); }

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

                      // Следующее условие проверяет содержимое структуры на равенство параметрам поиска,

                      // учитывая необходимость сравнения с этим параметром

   if ((!*str  || strcmp(str, s[i].str) == 0) &&

       (!check || a == s[i].a))

    fprintf(out, "%-30s %3d\n", s[i].str, s[i].a);

  fclose(out);

 }

3. Объединения Объединение позволяет в разные моменты времени хранить в одном объекте значения разных типов. В процессе объявления объединения с ним ассоциируется набор типов значений, которые могут храниться в данном объединении. В каждый момент времени объединение может хранить значение только одного типа из набора. Контроль над тем, какого типа значение хранится в данный момент в объединении, возлагается на программиста.

union [<тег>] {<список объявлений элементов>} <описатель> [, <описатель> ...];

union  <тег>   <описатель> [, <описатель> ...]; <Тег> предназначен для различения нескольких объединений, объявленных в одной программе. Память, которая выделяется переменной типа объединение, определяется размером наиболее длинного элемента объединения. Все элементы объединения размещаются в одной и той же области памяти с одного и того же адреса. Значение текущего элемента объединения теряется, когда другому элементу объединения присваивается значение.

#include <stdio.h>

void main()

 { union

    { float    f;

      long int i;

     } u;

   printf("Input float number: "); scanf("%f", &u.f);

   printf("Internal: %08x\n\n", u.i);

  }

Содержание

Соседние файлы в папке Лекции