Файл: Pobegaylo_A._C_Cplus_dlya_studenta.pdf

ВУЗ: Не указан

Категория: Не указан

Дисциплина: Не указана

Добавлен: 13.12.2020

Просмотров: 4116

Скачиваний: 28

ВНИМАНИЕ! Если данный файл нарушает Ваши авторские права, то обязательно сообщите нам.
background image

Часть I. Язык программирования С 

106 


  int a; 
  struct inside 
  { 
    int b; 
    int c; 
  } b; 
}; 
int main(void) 

  struct demo c = {1, {2, 3}}; 
  printf("%d %d %d\n", c.a, c.b.b, c.b.c);  /* 1 2 3 */ 
  return 0; 

Так как компилятору должна быть известна длина поля структу-
ры, то в структуре нельзя объявлять член, тип которого совпадает 
с  типом  объявляемой  структуры.  Однако  возможно  объявление 
члена структуры, тип которого является указателем на тип объяв-
ляемой структуры. Например: 

  struct node    /* вершина двоичного дерева */ 

  struct node *left;   /* левый потомок */ 
  struct node *right;  /* правый потомок */ 
}; 

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

  struct demo 
  { 
    double d; 
    int a[]; 
  }; 

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


background image

Глава 8. Типы данных, определяемые программистом 

107 

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

  struct emp boss; 
  boss = director; 

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

  адрес_поля_структуры % длина_поля_структуры == 0 

Если поле структуры является массивом, то в этом выражении в 
качестве  длины  поля  структуры  берут  длину  элемента  массива.  
В этом случае говорят, что адреса полей структуры выровнены по 
границам  соответствующего  типа  данных.  Начальный  адрес  са-
мой  структуры  выровнен  на  границу,  кратную  наибольшей  из 
длин полей структуры. Такое выравнивание необходимо для пра-
вильной  работы  микропроцессора.  Отсюда  следует,  что  в  струк-
туре  могут  быть  пропущенные  байты  с  неопределенным  содер-
жанием. Поэтому работать с полями структуры нужно, используя 
их имена. 
Отметим,  что  выравнивание  адресов  структуры  зависит  от  мик-
ропроцессора,  на  котором  будет  работать  программа,  и  поэтому 
может  отличаться  от  рассмотренного  выше  подхода.  Обычно  
каждый компилятор содержит директиву для управления вырав-
ниванием адресов данных в зависимости от их типа. 

8.4. Объединения 

Объединением

 называется область памяти, используемая для хра-

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

членами  объеди-

нения

. Как и в случае структуры, члены объединения могут иметь 

любой тип, исключая типы 

void

 и функцию, при условии, что из-


background image

Часть I. Язык программирования С 

108 

вестна  длина  этого  типа  данных.  Тип,  описывающий  объедине-
ние,  также  называется 

объединением

.  Объявляются  объединения 

следующим образом: 

  union имя_объединения 
  { 
    /* объявления членов объединения */ 
  }; 

Здесь 

union

 —  ключевое  слово,  а 

имя_объединения

  служит  для 

именования типа объединения и называется 

тегом

 

объединения

а  члены  объединения  перечисляются  в  блоке.  Объявление  объ- 
единения должно заканчиваться символом 

;

. Например: 

  union num 
  { 
    int n; 
    double f; 
  }; 

Не допускается объявление 

анонимных

 объединений. 

Тип  объединения  определяется  ключевым  словом 

union

  и  тегом 

объединения. Поэтому переменная типа объединения объявляет-
ся как: 

  union имя_объединения имя_переменной; 

Например: 

  union num d;  /* d – переменная типа union num */ 

 

В  языке  программирования  С++  тип  объединения  также  опреде-
ляется только именем объединения. 

Учитывая  это  замечание,  в  языке  программирования  С++  пере-
менную  типа  объединения  можно  также  объявить  следующим 
образом: 

  num d;  /* d – переменная типа num */ 

Объявление типа объединения и переменной, которая имеет этот 
тип, может быть объединено в одну инструкцию.  


background image

Глава 8. Типы данных, определяемые программистом 

109 

Например: 

  union num 
  { 
    int n; 
    double f; 
  } d;  /* d – переменная типа union num */ 

Допускается  объявление  переменных,  которые  имеют  тип  ано-
нимного объединения. Например: 

  union 
  { 
    int n; 
    double f; 
  } d;  /* d – переменная типа анонимного объединения */ 

При  объявлении  переменной  типа  объединения  ее  можно  ини-
циализировать значением, которое имеет тип первого члена объ-
единения. Например: 

  union num d = {10}; 

Обычно переменные, типом которых является объединение, так-
же называются 

объединениями

Как и в случае со структурами, для доступа к члену объединения 
используется оператор 

.

 (точка). Например: 

  union num e; 
  e.n = 1; 
  e.f = 1.1; 

Объединения одного типа можно присваивать друг другу. В этом 
случае  оператор  присваивания  выполняет  почленное  копирова-
ние объединений. Например: 

  union num g; 
  g = e; 

Длина  памяти,  распределяемой  компилятором  под  объединения, 
равна  наибольшей  из  длин  членов  объединения.  Адрес  этой  па-
мяти  выравнивается  на  границу,  кратную  наибольшей  из  длин 
членов объединения. 


background image

Часть I. Язык программирования С 

110 

8.5. Битовые поля 

Битовым полем

 называется элемент структуры или объединения, 

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

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

где 

тип

  может  принимать  одно  из  следующих  значений: 

int

unsigned

  или 

signed

, а 

длина_в_битах

  должна  быть  неотрицатель-

ным  целым  числом.  Причем  эта  длина  не  должна  превышать 
длины базового типа данных битового поля. Например: 

  struct demo 
  { 
    int count; 
    unsigned b1 : 1; 
    unsigned b2 : 1; 
    double d; 
  }; 

Если длина битового поля равна нулю, то адрес следующего поля 
структуры будет выровнен на границу типа 

int

Запрещается  использовать  спецификаторы  доступа 

const

  и 

volatile

 при определении битового поля. 

Инициализируются битовые поля, как и обычные члены структу-
ры, например: 

  struct demo d = {10, 1, 0, 10.5}; 

Используются  битовые  поля  для  установки  различных  флагов. 
Если в программе нужно обрабатывать только некоторые биты из 
поля, то остальные биты можно не именовать. В этом случае со-
держимое неименованных битов не определено. Например: 

  struct  demo 
  { 
    unsigned b1: 1; 
    unsigned   : 2; 
    unsigned b2: 1; 
  }; 


Смотрите также файлы