Урок 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 - то есть могу доработать ваш сайт или помочь с веб-программированием. Пишите сюда.

тегистатьи IT, уроки по си шарп, си шарп, операторы




Отправляя сообщение я подтверждаю, что ознакомлен и согласен с политикой конфиденциальности данного сайта.




Обустройство крыши дома - этапы работы
Преобразование числа в римские цифры на C#
Атаки с помощью SQL-инъекции: теория, примеры, способы защиты