Читаем C++ полностью

Одно из стандартных применений побитовых логических опраций – реализация маленького множества (вектор битов). В этом случае каждый бит беззнакового целого представляет один член множества, а число членов ограничено числом битов. Бнарная операция amp; интерпретируется как пересечение, ! как объединение, а ^ как разность. Для наименования членов такого множества можно использовать перечисление. Вот маленький прмер, заимствованный из реализации (не пользовательского итерфейса) «stream.h»:

enum state_value (* _good=0, _eof=1, _fail=2, _bad=4 *); // хорошо, конец файла, ошибка, плохо

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

cout.state = _good;

Например, так можно проверить, не был ли испорчен поток или допущена операционная ошибка:

if (cout.state amp;(_bad!_fail)) // не good

Еще одни скобки необходимы, поскольку amp; имеет более всокий приоритет, чем !.

Функция, достигающая конца ввода, может сообщать об этом так:

cin.state != _eof;

Операция != используется потому, что поток уже может быть испорчен (то есть, state==_bad), поэтому

cin.state = _eof;

очистило бы этот признак. Различие двух потоков можно находить так:

state_value diff = cin.state^cout.state;

В случае типа stream_state (состояние потока) такая раность не очень нужна, но для других похожих типов она оказвается самой полезной. Например, при сравнении вектора бит, представляющего множество прерываний, которые обрабатываются, с другим, представляющим прерывания, ждущие обработки.

Следует заметить, что использование полей (#2.5.1) в действительности является сокращенной записью сдвига и маскрования для извлечения полей бит из слова. Это, конечно, моно сделать и с помощью побитовых логических операций, Например, извлечь средние 16 бит из 32-битового int можно следующим образом:

unsigned short middle(int a) (* return (a»»8) amp;0xffff; *)

Не путайте побитовые логические операции с логическими операциями:

amp; amp; !! !

Последние возвращают 0 или 1, и они главным образом ипользуются для записи проверки в операторах if, while или for (#3.3.1). Например, !0 (не ноль) есть значение 1, тогда как ~ 0 (дополнение нуля) есть набор битов все-единицы, который обычно является значением -1.

<p>3.2.5 Преобразование типа</p>

Бывает необходимо явно преобразовать значение одного тпа в значение другого. Явное преобразование типа дает значние одного типа для данного значения другого типа. Например:

float r = float(1);

перед присваиванием преобразует целое значение 1 к знчению с плавающей точкой 1.0. Результат преобразования типа не является lvalue, поэтому ему нельзя присваивать (если только тип не является ссылочным типом).

Есть два способа записи явного преобразования типа: трдиционная в C запись приведения к типу (double)a и функцинальная запись double(a). Функциональная запись не может прменяться для типов, которые не имеют простого имени. Например, чтобы преобразовать значение к указательному типу надо или использовать запись преобразования типа

char* p = (char*)0777;

или определить новое имя типа:

typedef char* Pchar; char* p = Pchar(0777);

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

Pname n2 = Pbase(n1-»tp)-»b_name; //функциональная запись Pname n3 = ((Pbase)n2-»tp)-»b_name; // запись приведения // к типу Поскольку операция -» имеет больший приоритет, чем прведение, последнее выражение интерпретируется как

((Pbase)(n2-»tp))-»b_name

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

any_type* p = (any_type*) amp;some_object;

позволит работать посредством p с некоторым объектом some_object как с любым типом any_type.

Когда преобразование типа не необходимо, его следует ибегать. Программы, в которых используется много явных преоразований типов, труднее понимать, чем те, в которых это не делается. Однако такие программы легче понимать, чем программы, просто не использующие типы для представления понятий блее высокого уровня (например, программу, которая оперирует регистром устройства с помощью сдвига и маскирования, вместо того, чтобы определить подходящую struct и оперировать ею, см. #2.5.2). Кроме того, правильность явного преобразования типа часто критическим образом зависит от понимания програмистом того, каким образом объекты различных типов обрабатваются в языке, и очень часто от подробностей реализации. Например:

int i = 1; char* pc = «asdf»; int* pi = amp;i;

i = (int)pc; pc = (char*)i; // остерегайтесь! значение pc может изм//ниться // на некоторых машинах // sizeof(int)«sizeof(char*) pi = (int*)pc; pc = (char*)pi; // остерегайтесь! значение pc может изм// ниться // на некоторых машинах char* // представляется иначе, чем int*

Перейти на страницу:

Похожие книги

1С: Бухгалтерия 8 с нуля
1С: Бухгалтерия 8 с нуля

Книга содержит полное описание приемов и методов работы с программой 1С:Бухгалтерия 8. Рассматривается автоматизация всех основных участков бухгалтерии: учет наличных и безналичных денежных средств, основных средств и НМА, прихода и расхода товарно-материальных ценностей, зарплаты, производства. Описано, как вводить исходные данные, заполнять справочники и каталоги, работать с первичными документами, проводить их по учету, формировать разнообразные отчеты, выводить данные на печать, настраивать программу и использовать ее сервисные функции. Каждый урок содержит подробное описание рассматриваемой темы с детальным разбором и иллюстрированием всех этапов.Для широкого круга пользователей.

Алексей Анатольевич Гладкий

Программирование, программы, базы данных / Программное обеспечение / Бухучет и аудит / Финансы и бизнес / Книги по IT / Словари и Энциклопедии
1С: Управление торговлей 8.2
1С: Управление торговлей 8.2

Современные торговые предприятия предлагают своим клиентам широчайший ассортимент товаров, который исчисляется тысячами и десятками тысяч наименований. Причем многие позиции могут реализовываться на разных условиях: предоплата, отсрочка платежи, скидка, наценка, объем партии, и т.д. Клиенты зачастую делятся на категории – VIP-клиент, обычный клиент, постоянный клиент, мелкооптовый клиент, и т.д. Товарные позиции могут комплектоваться и разукомплектовываться, многие товары подлежат обязательной сертификации и гигиеническим исследованиям, некондиционные позиции необходимо списывать, на складах периодически должна проводиться инвентаризация, каждая компания должна иметь свою маркетинговую политику и т.д., вообщем – современное торговое предприятие представляет живой организм, находящийся в постоянном движении.Очевидно, что вся эта кипучая деятельность требует автоматизации. Для решения этой задачи существуют специальные программные средства, и в этой книге мы познакомим вам с самым популярным продуктом, предназначенным для автоматизации деятельности торгового предприятия – «1С Управление торговлей», которое реализовано на новейшей технологической платформе версии 1С 8.2.

Алексей Анатольевич Гладкий

Финансы / Программирование, программы, базы данных