Опубликован: 14.12.2010 | Уровень: для всех | Доступ: свободно
Лекция 17:

Операции с разрядами (битами) в языке С

< Лекция 16 || Лекция 17: 1234 || Лекция 18 >

Практическая часть

Пример 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. Поразрядное инвертирование целого числа

Как видно из рис. 16.1, все нули или единицы исходного числа (в двоичном представлении) были инвертированы.

Задание 1

  1. Проверьте результат выполнения программы с помощью инженерного калькулятора calc операционной системы Windows.
  2. Выполните раздельное объявление переменной mask и раздельное ее определение (инициализацию с поразрядным сдвигом).
  3. В теле цикла for вместо функции printf() примените putchar().
  4. Дополните программу выводом результатов в файл compX.txt, где Х – номер компьютера, за которым выполняется лабораторная работа.
  5. В качестве стартового числа примите год рождения пользователя.

Пример 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.

Как видно из рис. 16.2, битовая единица первого числа "проходит" в результат, если в маске на этом же месте (в том же разряде) также находится битовая единица. В результате получается новое число – 32.

Задание 2

  1. В качестве стартового числа примите год рождения пользователя, а в качестве маски – число рождения.
  2. Примените операцию поразрядного умножения к введенным отрицательным числам и выведите результат на консоль. Сравните с тем, что выводит функция printBits().
  3. Вместо оператора условия ( ?) примените другой способ вывода 1 или 0 после применения поразрядной операции И.
  4. Консольный вывод запишите в текстовый файл с именем 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.


Рис. 16.3.

Как видно из полученного результата, поразрядная операция ИЛИ представляет собой побитовое сложение чисел при условии, что 1 + 1 = 1.

Задание 3

  1. В качестве исходных чисел примите год и число рождения пользователя.
  2. Произведите операцию включающего ИЛИ над двумя десятичными числами в соответствии с предыдущим пунктом задания. Операцию выполните в главной функции main().
  3. Видоизмените программу для случая, когда имеется 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.


Рис. 16.4.
< Лекция 16 || Лекция 17: 1234 || Лекция 18 >
Мухаммадюсуф Курбонов
Мухаммадюсуф Курбонов