Урок 40. Управление битами с помощью BitArray C#
В этой части уроков по C# для начинающих рассматривается использование класса BitArray. Данный тип коллекции может использоваться для хранения очень больших серий битов, которыми можно манипулировать как независимо, так и коллективно, как целой группой.
Коллекция BitArray
Коллекция BitArray может содержать большие группы логических значений или битовых полей. Она похожа на другие коллекции, которые уже нами, но здесь содержимое - это не объекты, а логические значения. Это означает, что поведение класса немного отличается.
Реализованные интерфейсы коллекции
Коллекция BitArray реализует свойства и методы интерфейса ICollection. Это поведение уже описано. В оставшейся части этой статьи описываются дополнительные функции, предоставляемые BitArrays.
Конструкторы BitArray
Класс BitArray необычен тем, что не предоставляет конструктор без параметров. Коллекция BitArrays должна быть полностью инициализирована при создании экземпляра с использованием одного из шести конструкторов. Каждый заполняет содержимое коллекции по-своему. Простейший конструктор создает BitArray, содержащий несколько логических значений, которые являются ложными. Требуемое количество битов передается как целочисленный аргумент.
Класс BitArray находится в пространстве имен System.Collections, поэтому для выполнения примеров добавьте с помощью System.Collections; к исходному коду.
BitArray flags = new BitArray (16);Этот конструктор может быть расширен путем передачи второго логического значения. В этом случае размер созданного BitArray определяется в соответствии с целочисленным параметром, а каждому элементу в коллекции присваивается логическое значение.
BitArray flags = new BitArray (16, true);Оставшиеся четыре конструктора позволяют создавать BitArray с полным содержимым, инициализированным из существующих значений. Первый из них позволяет скопировать массив булевых значений в коллекцию.
bool[] bits = new bool[] { true, false, false, true }; BitArray flags = new BitArray(bits); foreach (bool flag in flags) { Console.WriteLine(flag); } /* True False False True */Вместо использования массива логических значений для инициализации BitArray, существующий BitArray может использоваться для исходных данных для создания копии.
bool[] bits = new bool[] { true, false, false, true }; BitArray flags = new BitArray(bits); BitArray copy = new BitArray(flags); foreach (bool flag in copy) { Console.WriteLine(flag); } /* True False False True */Пятый конструктор генерирует содержимое BitArray из массива байтов. Каждый байт разделен на восемь битов в созданной коллекции. Первый байт копируется в первые восемь битов BitArray с наименее значимым битом в качестве первого элемента в коллекции. Второй байт копируется в индексы с восьми по пятнадцать и так далее.
byte[] bytes = new byte[] { 1, 170 }; BitArray flags = new BitArray(bytes); foreach (bool flag in flags) { Console.WriteLine(flag); } /* True False False False False False False False False True False True False True False True */Последний конструктор инициализирует содержимое BitArray из массива целых чисел. Целочисленные значения - это 32-битные значения, поэтому первое целое число копируется в записи от нуля до тридцати одного, второе - в биты от тридцати двух до шестидесяти трех и так далее. Для каждого целого числа младший значащий бит добавляется первым.
int[] values = new int[] { 1, 32767 }; BitArray flags = new BitArray(values); foreach (bool flag in flags) { Console.WriteLine(flag); } /* True False False False ... */Чтение и запись содержимого BitArray
Чтение отдельных битов
Отдельные биты могут быть извлечены из BitArray с использованием номера индекса, добавленного к имени коллекции в квадратных скобках. Класс также предоставляет метод Get, который принимает индекс в качестве параметра и возвращает значение бита в указанной позиции. Каждый метод продемонстрирован ниже:
BitArray flags = new BitArray(new bool[] { true, false, false, true }); Console.WriteLine(flags[0]); // "True" Console.WriteLine(flags.Get(1)); // "False"Установка отдельных битов
Вы можете установить и очистить отдельные биты в BitArray. Как и при чтении отдельных битов, есть два способа сделать это. Во-первых, значение индекса может быть добавлено к имени коллекции, а значение бита назначено напрямую. Во-вторых, вы можете использовать метод Set. Этот метод принимает целочисленный параметр для индекса изменяемого элемента и логическое значение, указывающее новое значение. В следующем примере показаны оба метода:
BitArray flags = new BitArray(16, false); flags[0] = true; flags.Set(1, true);Запись нескольких битов
Часто вам захочется установить или очистить все биты внутри BitArray. Это может быть достигнуто с помощью метода SetAll. Метод требует один аргумент, содержащий новое значение для каждого бита в коллекции.
BitArray flags = new BitArray (16); flags.SetAll (true);Длина битового массива
Поскольку класс BitArray реализует ICollection, он включает свойство Count, которое возвращает количество битов в коллекции. В дополнение к этому свойству только для чтения, BitArray предоставляет свойство Length, которое можно использовать как для запроса количества элементов в коллекции, так и для изменения длины.
Когда свойство Length установлено, размер BitArray может увеличиваться или уменьшаться. Если новая длина меньше существующего числа элементов, коллекция усекается, и все записи с индексами, равными или превышающими новую длину, удаляются навсегда. Если новая длина больше текущего количества элементов, то новые элементы добавляются в BitArray. Каждый дополнительный бит изначально false.
BitArray flags = new BitArray(new bool[] { true, false, false, true }); Console.WriteLine(flags.Count); // 4 Console.WriteLine(flags.Length); // 4 flags.Length = 8; Console.WriteLine(flags.Length); // 8Побитовые операции
Основной причиной создания BitArrays является набор доступных побитовых операций. Четыре метода обеспечивают логическую функциональность NOT, AND, OR и XOR (исключающее ИЛИ). В последних разделах статьи описывается использование этих функций.
Not
Метод NOT выполняет операцию обратного кода BitArray. Каждый бит в коллекции инвертирован. то есть все true значения - false и наоборот.
BitArray flags = new BitArray(new bool[] { true, false, false, true }); flags.Not(); foreach (bool flag in flags) { Console.Write("{0}\t", flag); } /* OUTPUT False True True False */And
Метод And выполняет логическую операцию AND. Требуются два BitArrays одинакового размера, один из которых передается методу в качестве параметра. Содержимое коллекции, используемой в качестве параметра, не изменяется.
BitArray flags = new BitArray(new bool[] { true, false, false, true }); BitArray andFlags = new BitArray(new bool[] { false, true, false, true }); flags.And(andFlags); foreach (bool flag in flags) { Console.Write("{0}\t", flag); } /* OUTPUT False False False True */Or
Метод Or выполняет логическую операцию OR.
BitArray orFlags = new BitArray(new bool[] { false, true, false, true }); flags.Or(orFlags); foreach (bool flag in flags) { Console.Write("{0}\t", flag); } /* True True False True */Xor
Последний метод обеспечивает логическую исключающую OR побитовую операцию.
BitArray flags = new BitArray(new bool[] { true, false, false, true }); BitArray xorFlags = new BitArray(new bool[] { false, true, false, true }); flags.Xor(xorFlags); foreach (bool flag in flags) { Console.Write("{0}\t", flag); } /* True True False False */
Автор этого материала - я - Пахолков Юрий. Я оказываю услуги по написанию программ на языках Java, C++, C# (а также консультирую по ним) и созданию сайтов. Работаю с сайтами на CMS OpenCart, WordPress, ModX и самописными. Кроме этого, работаю напрямую с JavaScript, PHP, CSS, HTML - то есть могу доработать ваш сайт или помочь с веб-программированием. Пишите сюда.
Читайте также:
Отправляя сообщение я подтверждаю, что ознакомлен и согласен с политикой конфиденциальности данного сайта.