Операции с разрядами (битами) в языке С
Практическая часть
Пример 1. Напишите программу по демонстрации операции поразрядного отрицания (поразрядного дополнения) числа без знака, вводимого с клавиатуры, с использованием операций побитового сдвига.
Для решения примера будем задавать какое-то число, которое представим в виде нескольких разрядов, после чего через операции побитового сдвига изменим его и выведем на консоль.
Программный код решения примера:
#include <stdio.h>
#include <conio.h>
// Прототип функции
void printBits(unsigned int var);
// Главная функция
int main (void) {
unsigned int number;
printf("\n The program on demonstration digit-by-digit operation of denying ( ~ )\n");
printf("\n\t Enter a whole number of unsigned: ");
scanf_s("%d", &number);
printf("\n\t Binary representation of the starting number and\n");
printf("\t Binary representation of bitwise negation of the initial number:\n");
printBits(number); //Исходное число
printBits(~number); // Число после поразрядного дополнения
printf("\n\n Press any key: ");
_getch();
return 0;
}
// Функция побитового представления целого числа без знака
void printBits(unsigned int var)
{
unsigned int b;
unsigned int mask = 1 << 31; // shift to 31 bit
printf("\n\t %10u = ", var);
for (b = 1; b <= 32; ++b) {
printf("%c", var & mask ? '1' : '0');
var <<= 1; // or: var = var << 1;
if (b % 8 == 0)
putchar(' ');
}
}В программе применен форматный ввод числа в виде %u и вывод числа в виде %10u, где u применяется для беззнакового типа числа, 10 – это количество позиций, отводимое для десятичного числа.
Предполагается, что заданное число может быть представлено 32 разрядами, по 4 группы с 8 разрядами (4 байта по 8 бит в каждом).
Применение оператора сдвига ( << ) позволяет все биты данного числа сдвигать на единицу (действие в цикле for) влево. При этом используется операция поразрядного И ( & ). С помощью оператора условия ( ?) выполняется замена 1 на 0 и наоборот.
Возможный результат выполнения программы показан на рис. 16.1.
Как видно из рис. 16.1, все нули или единицы исходного числа (в двоичном представлении) были инвертированы.
Задание 1
- Проверьте результат выполнения программы с помощью инженерного калькулятора calc операционной системы Windows.
- Выполните раздельное объявление переменной mask и раздельное ее определение (инициализацию с поразрядным сдвигом).
- В теле цикла for вместо функции printf() примените putchar().
- Дополните программу выводом результатов в файл compX.txt, где Х – номер компьютера, за которым выполняется лабораторная работа.
- В качестве стартового числа примите год рождения пользователя.
Пример 2. Напишите программу выполнения поразрядной операции И ( & ) над двумя целыми числами, представленными в двоичной системе счисления для 32-разрядного компьютера.
Одно из чисел будем считать маской, относительно которой "просеваются" единицы двоичного числа.
Программный код решения примера:
#include <stdio.h>
#include <conio.h>
// Прототип функции
void printBits(unsigned int var);
// Главная функция
int main (void)
{
unsigned int number, mask;
printf("\n The program on demonstration digit-by-digit operation And ( & )\n");
printf("\n\t Enter a whole number of unsigned: ");
scanf_s("%u", &number);
printf("\t Enter the number of unsigned-mask: ");
scanf_s("%u", &mask);
printf("\n\t Binary representation of the starting number and (%u) and\n", number);
printf("\t Binary representation of the number-masks (%u):\n", mask);
printBits(number);
printBits(mask);
// Число после поразрядного умножения (И)
printBits(number & mask);
printf("\n\n Press any key: ");
_getch();
return 0;
}
// Функция побитового представления целого числа без знака
void printBits(unsigned int var)
{
unsigned int b;
unsigned int mask = 1 << 31; // shift to 31 bit
printf("\n\t %10u = ", var);
for (b = 1; b <= 32; ++b)
{
printf("%c", var & mask ? '1' : '0');
var <<= 1; // or: var = var << 1;
if (b % 8 == 0)
putchar(' ');
} // End 2nd for
} // End functionВ программе операция поразрядного умножения – операция И закладывается в фактический параметр функции printBits().
Возможный результат выполнения программы показан на рис. 16.2.
Как видно из рис. 16.2, битовая единица первого числа "проходит" в результат, если в маске на этом же месте (в том же разряде) также находится битовая единица. В результате получается новое число – 32.
Задание 2
- В качестве стартового числа примите год рождения пользователя, а в качестве маски – число рождения.
- Примените операцию поразрядного умножения к введенным отрицательным числам и выведите результат на консоль. Сравните с тем, что выводит функция printBits().
- Вместо оператора условия ( ?) примените другой способ вывода 1 или 0 после применения поразрядной операции И.
- Консольный вывод запишите в текстовый файл с именем compX.txt, где Х – номер компьютера, за которым выполняется лабораторная работа.
Пример 3. Напишите программу демонстрацию поразрядной операции "ИЛИ" (включающей дизъюнкции).
Операция поразрядного логического ИЛИ ( | ) сравнивает каждый бит первого операнда с соответствующим битом второго операнда. Если любой (или оба) из сравниваемых битов равен 1, то соответствующий бит результата устанавливается в 1, в противном случае результирующий бит равен 0.
#include <stdio.h>
#include <conio.h>
// Прототип функции
void printBits(unsigned int var);
// Главная функция
int main (void)
{
unsigned int number1, number2;
printf("\n The program on demonstration digit-by-digit operator OR ( | ):\n");
printf("\n\t Enter the unsigned number of N1: ");
scanf_s("%u", &number1);
printf("\t Enter the unsigned number of N2: ");
scanf_s("%u", &number2);
printf("\n\t Binary representation of the number of N1 (%u) and\n", number1);
printf("\t Binary representation of the number of N2 (%u):\n", number2);
printBits(number1);
printBits(number2);
// Число после поразрядного сложения (ИЛИ)
printBits(number1 | number2);
printf("\n\n Press any key: ");
_getch();
return 0;
}
// Функция побитового представления целого числа без знака
void printBits(unsigned int var) {
unsigned int b;
unsigned int num = 1 << 31; // shift to 31 bit
printf("\n\t %10u = ", var);
for (b = 1; b <= 32; ++b) {
printf("%c", var & num ? '1' : '0');
var <<= 1; // or: var = var << 1;
if (b % 8 == 0)
putchar(' ');
} // End 2nd for
} // End functionВ программе использована функция printBits(), как и в предыдущем примере. Она по необходимости преобразует десятичные числа в двоичные. При этом входным параметром функции является поразрядное включающее "ИЛИ" над двумя операндами в главной функции main().
Возможный результат выполнения программы показан на рис. 16.3.
Как видно из полученного результата, поразрядная операция ИЛИ представляет собой побитовое сложение чисел при условии, что 1 + 1 = 1.
Задание 3
- В качестве исходных чисел примите год и число рождения пользователя.
- Произведите операцию включающего ИЛИ над двумя десятичными числами в соответствии с предыдущим пунктом задания. Операцию выполните в главной функции main().
- Видоизмените программу для случая, когда имеется 16-разрядный компьютер.
Пример 4. Напишите программу демонстрацию поразрядного исключающего ИЛИ ( ^ ).
Операция поразрядного исключающего ИЛИ ( ^ ) сравнивает каждый бит первого операнда (например, первого числа) с соответствующими битами второго операнда. Если один из сравниваемых битов равен 0, а второй бит равен 1, то соответствующий бит результата устанавливается в 1, в противном случае, т.е. когда оба бита равны 1 или 0, бит результата устанавливается в 0.
Программный код решения примера:
#include <stdio.h>
#include <conio.h>
// Прототип функции
void printBits(unsigned int var);
int main (void) {
unsigned int number1, number2;
printf("\n The program on demonstration digit-by-digit excluding operator OR ( ^ ):\n");
printf("\n\t Enter the unsigned number of N1: ");
scanf_s("%u", &number1);
printf("\t Enter the unsigned number of N2: ");
scanf_s("%u", &number2);
printf("\n\t Binary representation of the number of N1 (%u) and\n", number1);
printf("\t Binary representation of the number of N2 (%u):\n", number2);
printBits(number1);
printBits(number2);
printBits(number1 ^ number2); // Число после операции ^
printf("\n\n Press any key: ");
_getch();
return 0;
}
// Функция побитового представления целого числа без знака
void printBits(unsigned int var) {
unsigned int b;
unsigned int num = 1 << 31; // shift to 31 bit
printf("\n\t %10u = ", var);
for (b = 1; b <= 32; ++b) {
printf("%c", var & num ? '1' : '0');
var <<= 1; // or: var = var << 1;
if (b % 8 == 0)
putchar(' ');
} // End 2nd for
} // End functionВозможный результат выполнения программы показан на рис. 16.4.



