Мова C забезпечує шістьма операторами для обробки бітів; їх можна застосовувати лише з цілочисельними операндами, тобто char, short, int і long, як зі знаком, так і беззнаковими.
&
| розрядний І
|
|
| розрядний включний АБО
|
^
| розрядний виключний АБО
|
<<
| ліве зміщення
|
>>
| праве зміщення
|
~
| доповнення (унарний оператор)
|
Розрядний І (оператор &) часто використовується для того, щоб приховати набір бітів, наприклад
n = n & 0177;
обнулить усі біти n крім молодших 7-и.
Розрядний АБО (оператор |) використовується для ввімкнення бітів:
x = x | SET_ON;
встановлює в одиницю всі біти x, що дорівнюють одному в SET_ON. Розрядний виключний АБО (оператор ^) встановлює в одиницю кожну позицію, де операнди мають відмінні біти, і в нуль там де вони збігаються.
Не слід плутати розрядні оператори & та | з логічними операторами && та ||, в яких ідеться про з ліва на право оцінку істинного значення. Наприклад, якщо x дорівнює 1 а y дорівнює 2, тоді x & y оцінюється як нуль, зате x && y — як один.
Оператори зміщення << й >> здійснюють ліве та праве зміщення лівого операнда на кількість бітів, вказаних правим операндом; останній має бути додатнім числом. Таким чином, x << 2зміщає значення x на два положення, заповнюючи вакантні біти нулями; це рівнозначно множенню на 4. Праве зміщення беззнакової величини завжди заповнюватиме звільнені біти нулями. Праве зміщення величини зі знаком заповнюватиме бітами знака («арифметичне зміщення») на деяких машинах і 0-бітами («логічне зміщення») на інших.
Унарний оператор ~ видає протилежне значення вказаного цілого; тобто, він перетворює кожний 1-біт на 0-біт, і навпаки. Наприклад
x = x & ~077
встановлює останні шість бітів x у нуль. Зауважте, що x & ~077 не залежить від довжини «слова», тому йому надається перевага над, скажімо, x & 0177700, яке припускає, що x — 16-бітна величина. Портабельна форма не забирає додаткових ресурсів оскільки ~077 — це сталий вираз, який оцінюється під час компіляції.
Як ілюстрація деяких розрядних операторів розглянемо функцію getbits(x,p,n), яка повертає (вирівнянe з правого боку) n-бітне поле x, починаючи з положення p. Ми припустимо, що бітове положення 0 знаходиться з крайнього правого боку і, що n із p — це чинні додаткові значення. Так, наприклад, getbits(x,4,3) повертає три біти, що знаходяться у 4-ій, 3-ій і 2-ій позиції, вирівнені зправа.
/* getbits: добуває n бітів, починаючи з положення p */
unsigned getbits(unsigned x, int p, int n)
{
return (x >> (p+1-n)) & ~(~0 << n);
}
Вираз x >> (p+1-n) переміщує потрібне нам поле на правий край слова. ~0 складається з одних 1-бітів; зміщення його ліворуч на n позицій за допомогою ~0<<n розмістить нулі в n бітів з правого боку; додання до цього ~ створює маску з одиниць для n бітів зправа.
Вправа 2-6. Напишіть функцію setbits(x,p,n,y), яка би повертала x, в якому n бітів, починаючи з положення p, дорівнюють крайнім правим n бітам y, залишаючи решту бітів незмінними.
Вправа 2-7. Напишіть функцію invert(x,p,n), яка би повертала x, в якому порядок n бітів, починаючи з положення p, було би обернено на протилежний (тобто 1 замінено на 0 і навпаки), залишаючи решту бітів незмінними.
Вправа 2-8. Напишіть функцію rightrot(x,n), яка повертає значення цілого x, оберненого в правий бік на n позицій.