Особенности языка С. Учебное пособие Для освоения темы этого урока вам потребуются знания о системах счисления (двоичной, восьмеричной и др.), навыки перевода чисел из одной системы счисления в другую, а также вы должны иметь представление о том, что такое битовые (они же поразрядные) операции. С последним можно познакомиться по вот этой лекции. В языке программирования C существуют следующие поразрядные операции: & (И), | (ИЛИ), ^ (исключающее ИЛИ), << (сдвиг влево), >> (сдвиг вправо), ~ (поразрядное дополнение до единицы). Рассмотрим на примерах, как они работают, но перед этим уделим внимание выводу в языке C чисел в отличных от десятичной системах счисления. В С можно присваивать целочисленные значения в десятичной, восьмеричной и шестнадцатеричной системах счисления. Для того, чтобы присвоить переменной число в восьмеричной системе счисления, перед ним надо написать 0 (ноль), в шестнадцатеричной — 0x (ноль и икс), например: int a, b; a = 077; // записано восьмеричное число b = 0x1F; // присвоено шестнадцатеричное число Любые целые числа можно выводить на экран в десятичном, восьмеричном и шестнадцатеричном представлении. Пример кода для вывода определенных ранее двух переменных в различных системаъ счисления: printf("%d %o %x %X\n", a,a,a,a); printf("%d %o %x %X\n", b,b,b,b); В результате на экране вы увидите: 63 77 3f 3F 31 37 1f 1F Восьмеричные и шестнадцатеричные числа используются из-за удобства при работе с двоичной системой счисления. Каждая цифра восьмеричного числа может быть заменена тремя цифрами двоичного. И каждая цифра шестнадцатеричного числа легко заменяет четыре разряда двоичного числа. Вот таблица соответствия цифр восьмеричной системы счисления числам двоичной системы:
Теперь допустим, что у нас есть восьмеричное число 037. По таблице легко понять, что в двоичном выражении оно будет выглядеть как 011 111. Задание
Итак, если бы мы при работе с поразрядными операциями использовали десятичные числа, то чтобы оценить результат нам бы каждый раз приходилось переводить десятичное число в двоичную систему счисления, что относительно трудоемко. Если же человек видит, например, восьмеричное число, то он может представить как оно выглядит в двоичном представлении, помня или держа перед глазами таблицу соответствия чисел. Например, как только мы видим 017, то можем представить в уме, как последние четыре бита ячейки памяти забиты единицами. Теперь вернемся к поразрядным операциям и протестируем каждую из них. Для этого напишем небольшую программу: int a, b; a = 017; b = 036; printf("0%o & 0%o = 0%o\n", a, b, a & b); printf("0%o | 0%o = 0%o\n", a, b, a | b); printf("0%o ^ 0%o = 0%o\n", a, b, a ^ b); printf("0%o << 2 = 0%o\n", a, a << 2); printf("0%o >> 2 = 0%o\n", a, a >> 2); printf("~0%o = 0%o\n", a, ~a); Результат ее работы будет выглядеть так: 017 & 036 = 016 017 | 036 = 037 017 ^ 036 = 021 017 << 2 = 074 017 >> 2 = 03 ~017 = 037777777760 Этот результат будет проще понять с помощью рисунка: В последнем случае получилось такое большое число потому, что под форматы вывода целых чисел ( Задание
Теперь рассмотрим пример использования битовых операций. Допустим, у нас есть массив, требуется снять с него "маску", которая бы отражала, в какой позиции стоят отрицательные, а в какой положительные элементы. Пусть единица в бите обозначает соответствующий ей положительный элемент массива, а ноль — отрицательный. Другими словами, если у нас есть массив {4, -3, 2, 2, 8, -1}, то его "битовая маска" будет выглядеть как 101110, или в восьмеричном представлении как 056. Составим алгоритм решения этой задачи:
Вроде бы все просто, но как установить в единицу определенный бит числа? Существует закономерность соответствия степеней двойки и двоичного представления числа: При переборе первый элемент массива имеет индекс 0, но соответствующий ему бит в mask должен стоять впереди остальных. Если известно общее количество элементов массива (N), то можно определить степень двойки по формуле Другая проблема — как в языке C возвести число в степень. Понятно, что можно написать свой код, но скорее всего в стандартной библиотеке уже есть подобная функция. С помощью заголовочного файла math.h можно подключить библиотеку с математическими функциями. Среди них есть функция #include <stdio.h> #include <math.h> #define N 12 main () { int nums[N] = {7, 3, 9, -5, -3, 2, 1, 0, 16, -4, 2, 0}; int mask = 0, i; for (i=0; i < N; i++) if (nums[i] >= 0) mask = mask | (int)pow(2,N-i-1); printf("%o\n", mask); } Задание |
|||||||||||||||||||



Последние комментарии
4 дня 16 часов назад
4 дня 17 часов назад
4 дня 17 часов назад
4 дня 17 часов назад
1 неделя 4 дня назад
1 неделя 4 дня назад
1 неделя 5 дней назад
1 неделя 6 дней назад
1 неделя 6 дней назад
2 недели 6 дней назад