Архитектура Аудит Военная наука Иностранные языки Медицина Металлургия Метрология
Образование Политология Производство Психология Стандартизация Технологии


Байты после перестановки: 0000 1111 0000 0000



В этой программе целочисленной переменной sb.num присваивается число 15. Перестановка двух байтов, составляющих это значение, выполняется путем обмена двух символов, которые образуют массив ch. В результате старший и младший байты целочисленной переменной num меняются местами. Эта операция возможна лишь потому, что как переменная num, так и массив ch разделяют одну и ту же область памяти.

В следующей программе демонстрируется еще один пример использования объединения. Здесь объединения связываются с битовыми полями, используемыми для отображения в двоичной системе счисления ASCII-кода, генерируемого при нажатии любой клавиши. Эта программа также демонстрирует альтернативный способ отображения отдельных битов, составляющих байт. Объединение позволяет присвоить значение нажатой клавиши символьной переменной, а битовые поля используются для отображения отдельных битов.

// Отображение ASCII-кода символов в двоичной системе счисления.

#include < iostream>

#include < conio.h>

using namespace std;

// Битовые поля, которые будут расшифрованы.

struct byte {

  unsigned a: 1;

  unsigned b: 1;

  unsigned с: 1;

  unsigned d: 1;

  unsigned e: 1;

  unsigned f: 1;

  unsigned g: 1;

  unsigned h: 1;

};

union bits {

  char ch;

  struct byte bit;

}ascii;

void disp_bits(bits b);

Int main()

{

  do {

    cin > > ascii.ch;

    cout < < ": ";

    disp_bits(ascii);

  }while(ascii.ch! ='q'); // Выход при вводе буквы " q".

  return 0;

}

// Отображение конфигурации битов для каждого символа.

void disp_bits(bits b)

{

  if(b.bit.h) cout < < " 1";

    else cout < < " 0";

  if(b.bit.g) cout < < " 1";

    else cout < < " 0";

  if(b.bit.f) cout < < " 1";

    else cout < < " 0 ";

  if(b.bit.e) cout < < " 1";

    else cout < < " 0";

  if(b.bit.d) cout < < " 1";

    else cout < < " 0";

  if(b.bit.c) cout < < " 1";

    else cout < < " 0";

  if(b.bit.b) cout < < " 1";

    else cout < < " 0";

  if(b.bit.a) cout < < " 1";

    else cout < < " 0";

  cout < < " ";

}

Вот как выглядит один из возможных вариантов выполнения этой программы.

А: 0 1 1 0 0 0 0 1

B: 0 1 1 0 0 0 1 0

С: 0 1 1 0 0 0 1 1

D: 0 1 1 0 0 1 0 0

Е: 0 1 1 0 0 1 0 1

F: 0 1 1 0 0 1 1 0

G: 0 1 1 0 0 1 1 1

H: 0 1 1 0 1 0 0 0

I: 0 1 1 0 1 0 0 1

J: 0 1 1 0 1 0 1 0

K: 0 1 1 0 1 0 1 1

1: 0 1 1 0 1 1 0 0

M: 0 1 1 0 1 1 0 1

N: 0 1 1 0 1 1 1 0

O: 0 1 1 0 1 1 1 1

P: 0 1 1 1 0 0 0 0

Q: 0 1 1 1 0 0 0 1

Важно! Поскольку объединение предполагает, что несколько переменных разделяют одну и ту же область памяти, это средство предоставляет программисту возможность хранить информацию, которая (в зависимости от ситуации) может содержать различные типы данных, и получать доступ к этой информации. По сути, объединения обеспечивают низкоуровневую поддержку принципов полиморфизма. Другими словами, объединение обеспечивает единый интерфейс для нескольких различных типов данных, воплощая таким образом концепцию " один интерфейс — множество методов" в своей самой простой форме.

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

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

В C++ предусмотрен специальный тип объединения, который называется анонимным. Анонимное объединение не имеет наименования типа, и поэтому объект такого объединения объявить невозможно. Но анонимное объединение сообщает компилятору о том, что его члены разделяют одну и ту же область памяти. При этом обращение к самим переменным объединения происходит непосредственно, без использования оператора " точка" . Рассмотрим такой пример.

//Демонстрация использования анонимного объединения.

#include < iostream>

using namespace std;

Int main()

{

  // Это анонимное объединение.

  union {

    short int count;

    char ch[2];

  };

  // Вот как происходит непосредственное обращение к членам анонимного объединения.

  ch[0] = 'X';

  ch[1] = 'Y';

  cout < < " Объединение в виде символов: " < < ch[0] < < ch[1] < < '';

  cout < < " Объединение в виде целого значения: " < < count < < '';

  return 0;

}

Эта программа отображает следующий результат.

Объединение в виде символов: XY

Объединение в виде целого значения: 22872


Число 22872 получено в результате помещения символов X и Y в младший и старший байты переменной count соответственно. Как видите, к обеим переменным, входящим в состав объединения, как count, так и ch, можно получить доступ так же, как к обычным переменным, а не как к составляющим объединения. Несмотря на то что они объявлены как часть анонимного объединения, их имена находятся на том же уровне области видимости, что и другие локальные переменные, объявленные на уровне объединения. Таким образом, член анонимного объединения не может иметь имя, совпадающее с именем любой другой переменной, объявленной в той же области видимости.

Анонимное объединение представляет собой средство, с помощью которого программист может сообщить компилятору о своем намерении, чтобы две (или больше) переменные разделяли одну и ту же область памяти. За исключением этого момента, члены анонимного объединения ведут себя подобно любым другим переменным.

Использование оператора sizeof для гарантии переносимости программного кода

Как было показано, структуры и объединения создают объекты различных размеров, которые зависят от размеров и количества их членов. Более того, размеры таких встроенных типов, как int, могут изменяться при переходе от одного компьютера к другому. Иногда компилятор заполняет структуру или объединение так, чтобы выровнять их по границе четного слова или абзаца. (Абзац содержит 16 байт.) Поэтому, если в программе нужно определить размер (в байтах) структуры или объединения, используйте оператор sizeof. Не пытайтесь вручную выполнять сложение отдельных членов. Из-за заполнения или иных аппаратно-зависимых факторов размер структуры или объединения может оказаться больше суммы размеров отдельных их членов.

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

union х {

  char ch;

  int i;

  double f;

} u_var;

Здесь при выполнении оператора sizeof u_var получим результат 8 (при условии, что double-значение занимает 8 байт). Во время выполнения программы не имеет значения, что реально будет храниться в переменной u_var; здесь важен размер самой большой переменной, входящей в состав объединения, поскольку объединение должно иметь размер самого большого его элемента.

Переходим к объектно-ориентированному программированию

Эта глава заключает описание не объектно-ориентированных атрибутов C++. Начиная со следующей главы, мы будем рассматривать средства, которые поддерживают объектно-ориентированное программирование (Object Oriented Programming— OOP), или ООП. Чтобы понять объектно-ориентированные средства C++ и научиться их эффективно применять, необходимо глубокое понимание материала этой и предыдущих девяти глав. Поэтому, возможно, вам стоит повторить пройденный материал. Особое внимание при повторении уделите указателям, структурам, функциям и перегрузке функций.


Глава 11: Введение в классы

В этой главе мы познакомимся с классом. Класс — это фундамент, на котором построена С++-поддержка объектно-ориентированного программирования, а также ядро многих более сложных программных средств. Класс — это базовая единица инкапсуляции, которая обеспечивает механизм создания объектов.

Основы понятия класса

Объектно-ориентированное программирование построено на понятии класса.

Начнем с определения терминов класса и объекта. Класс определяет новый тип данных, который задает формат объекта. Класс включает как данные, так и код, предназначенный для выполнения над этими данными. Следовательно, класс связывает данные с кодом. В C++ спецификация класса используется для построения объектов. Объекты — это экземпляры класса. По сути, класс представляет собой набор планов, которые определяют, как строить объект. Важно понимать, что класс — это логическая абстракция, которая реально не существует до тех пор, пока не будет создан объект этого класса, т.е. то, что станет физическим представлением этого класса в памяти компьютера.

Определяя класс, вы объявляете данные, которые он содержит, и код, который выполняется над этими данными. Хотя очень простые классы могут содержать только код или только данные, большинство реальных классов содержат оба компонента. В классе данные объявляются в виде переменных, а код оформляется в виде функций. Функции и переменные, составляющие класс, называются его членами. Таким образом, переменная, объявленная в классе, называется членом данных, а функция, объявленная в классе, называется функцией-членом. Иногда вместо термина член данных используется термин переменная экземпляра (или переменная реализации).

Объявление класса начинается с ключевого слова class.

Класс создается с помощью ключевого слова class. Объявление класса синтаксически подобно объявлению структуры. Рассмотрим пример. Следующий класс определяет тип queue, который предназначен для реализации очереди. (Под очередью понимается список с дисциплиной обслуживания в порядке поступления, т.е. " первым прибыл — первым обслужен".)

// Создание класса queue.

class queue {

    int q[100];

    int sloc, rloc;

  public:

    void init();

    void qput(int i);

    int qget();

};


Поделиться:



Популярное:

Последнее изменение этой страницы: 2016-03-17; Просмотров: 1440; Нарушение авторского права страницы


lektsia.com 2007 - 2024 год. Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав! (0.024 с.)
Главная | Случайная страница | Обратная связь