
- •Н. А. Аленский основы программирования
- •§ 1. Структура простой программы. Ввод, вывод
- •1.1. Пример первой программы
- •1.2. Директива препроцессора #include
- •1.3. Структура программы
- •1.4. Комментарии
- •1.5. Ключевые слова и идентификаторы
- •1.6. Простой ввод, вывод
- •§ 2. Оператор if
- •2.1. Полная форма
- •2.2. Сокращённая форма
- •2.3. Особенности оператора
- •Задачи и упражнения
- •§ 3. Выражения
- •3.1. Константы
- •Непосредственно записать в выражении;
- •3.2. Операции и их приоритет
- •3.3. Операции отношения и логические операции
- •3.4. Особенности операции присваивания
- •3.5. Тернарная операция (?)
- •Задачи и упражнения
- •§ 4. Оператор выбора switch
- •Задачи и упражнения
- •§ 5. Операторы цикла
- •5.1. Оператор while c предусловием
- •Правила использования и особенности оператора while
- •5.2. Оператор цикла do … while c постусловием
- •5.3. Оператор for
- •5.4. Операторы continue и break
- •Задачи и упражнения
- •§ 6. Введение в одномерные массивы
- •6.1. Что такое массив. Объявление одномерного массива
- •6.2. Способы определения массивов
- •6.3. Вывод одномерного массива. Функции printf и сprintf
- •6.4. Некоторые типы простых задач при работе с массивами
- •Задачи и упражнения
- •§ 1. Функции без результатов. Передача параметров по значению
- •1.1. Примеры. Правила оформления и вызова функций
- •Void line2(int Len, y, char ch) // ошибка,
- •1.2. Формальные и фактические параметры
- •1.3. Передача параметров по значению
- •§ 2. Функции типа void с несколькими результатами
- •2.1. Пример
- •2.2. Что такое ссылочный тип
- •2.3. Возврат значений из функции с помощью ссылочного типа
- •Задачи и упражнения
- •§ 3. Функции с одним результатом. Оператор return
- •Задачи и упражнения
- •§ 4. Одномерные массивы в функциях. Сортировка массива
- •Задачи и упражнения.
- •§ 5. Область действия имён. Локальные и глобальные имена
- •§ 6. Дополнительные возможности функций
- •Встраиваемые функции (inlineфункции)
- •6.2. Параметры по умолчанию
- •6.3. Перегрузка функций
- •§ 1. Примеры
- •§ 2. Класс. Поля и методы класса
- •§ 3. Создание объектов. Конструктор
- •Задачи и упражнения.
- •Глава 4 простые типы данных § 1. Целый тип
- •1.1. Битовые операции
- •1.2. Использование битовых операций
- •1.3. Упаковка и распаковка информации
- •Задачи и упражнения.
- •§ 2. Логический тип
- •§ 3. Символьный тип
- •Глава 5 матрицы (двухмерные массивы) § 1. Объявление, способы определения
- •§ 2. Вывод матриц
- •§ 3. Типы алгоритмов на обработку матриц
- •3.1. Построчная обработка
- •3.2. Обработка матрицы по столбцам
- •3.3. Обработка всей матрицы
- •3.4. Обработка части матрицы
- •3.5. Преобразование матрицы
- •Упражнения.
- •3.6. Построение матриц
- •§ 4. Передача матрицы в качестве параметра функции
- •Задачи и упражнения.
- •Б. Обработка матрицы по столбцам.
- •Даны две матрицы a и b одинаковой размерности. Построить матрицу с, каждый элемент которой определяется по правилу:
- •Список рекомендуемой литературы
- •Сборники задач по программированию
- •Оглавление
- •Задачи и упражнения …….……………………………………...12
- •3.1. Константы ………………………………………………...…14
1.2. Использование битовых операций
Упражнение 1. Включить отмеченный символом * бит, то есть в нём получить единицу. Значения остальных бит должны остаться без изменения.
Условно это обозначим так:
*
?
? ? ? ? ? ? ? ?
1
Здесь символом отмечен бит со значением нуль или единица, значение которого не должно меняться, символом * указан изменяемый бит. Символы ? означают, какую операцию (& или | или ^), с каким числом (00010000 или 11101111) надо выполнить для решения задачи. Проанализировав все шесть вариантов или некоторые из них, получаем
*
|
0 0 0 10 0 0 0
1
Операция битовое или с нулём не меняет значения бита (0 | 0 = 0; 1 | 0 = 1). В результате операции или с единицей всегда получится единица независимо от того, что было на месте символа “звёздочка”. А что запишем в программе? Так как работаем с одним байтом, то объявление будет таким: char c=5 (произвольное значение с 0 значением отмеченного “звёздочкой” бита). Операцию записываем следующим образом: с=с | 16 или с | =16, или с | = 0x10, где 0x10 — шестнадцатеричная константа 1016=1*16=1610. Получаем 000101012=1516=21 и, если выполнить
printf ("%5d" ,c);
выведем число 21.
Упражнение 2. Выключить отмеченный символом * бит, то есть в этом разряде получить 0. Значения остальных бит должны остаться без изменения.
Проанализировав, как и в упражнении 1, шесть вариантов или некоторые из них, получаем
*
&
1 1 1 0 1 1 1 1
0
Операция битовое и с единицей не меняет значения бита (0&1=0; 1&1=1), а с нулём всегда даст нуль независимо от того, что было на месте символа “звёздочка”. В программе пусть char c=0x32 (произвольное значение с 0 значением отмеченного “звёздочкой” бита). Выполним
с & = – 17; printf (“ %5d”, c);
Здесь 1 1 1 0 1 1 1 1 — это представление отрицательного числа –17.
0 0 1 1 0 0 1 0
&
1 1 1 0 1 1 1 1
0 0 1 0 0 0 1 0
Получим 2216=2*16+2=3410. Будет выведено число 34.
Упражнение 3. Заменить указанный бит (например, 5–й справа) на противоположный, не меняя значения остальных бит.
Ответ: с=с ^ 0x10. Самостоятельно объяснить результат.
Упражнение 4. Проверить, что находится в 4–м справа бите, нуль или единица.
Ответ: if (c & 8 = = 8) cout<< “единица”; else cout<<”нуль”;
Упражнение 5. Используя битовые операции, вывести двоичное представление двухбайтного целого числа.
Для получения двоичного представления выполняем следующее:
1–й ш а г. Выделяем (получаем) значение последнего (правого) бита:
с=number & 1.
2–й ш а г. Для получения значения предпоследнего бита сдвигаем число на один разряд вправо и используем ту же битовую операцию & c единицей.
3–й шаг. Если результат сдвига не запоминали, то сдвигаем число на два разряда вправо и применяем операцию & c единицей.
4–й шаг. Сдвигаем число на три разряда вправо и применяем ту же операцию.
…
16–й шаг. Сдвигаем число на пятнадцать разрядов вправо и применяем операцию & c единицей.
Предложенный алгоритм программируем так:
int main()
{ short number, c; // int по умолчанию
cin>>number;
int x=20; // текстовая координата x экрана
for (int j=0; j<16; j++) /* j<16, так как тип unsigned short определяет целое число с объёмом памяти 2 байта или 16 бит.*/
{ c=((number>>j) & 1); // Получаем нуль или один.
gotoxy(x--, wherey()); // Вывод справа налево
cout<<c;
}
getch(); return 0;
}
Замечания.
-
В приведенном варианте значение переменной number не изменилось. Если бы результат сдвига запоминали, то на каждом шаге надо сдвигать всегда на один разряд:
number= number>> 1; или number >>= 1; а затем c=number & 1.
-
Но в этом варианте значение number изменится.
-
Можно усложнить программу таким образом, чтобы незначащие нули слева не выводились. Один из возможных вариантов решения следующий. Формируем массив a [16] из нулей и единиц в том же порядке, что и в приведенной программе, т. е. a[0] — значение последнего (правого) бита, a[1] — значение предпоследнего бита и так далее, a[15] — значение первого (левого) бита. Находим последний ненулевой элемент этого массива и, начиная с него, выводим массив в обратном порядке.
-
С помощью приведенной программы можно выводить и двоичное представление отрицательных чисел. Поэтому этот вариант получения двоичного представления лучше алгоритма деления на два (см. функцию SUMDIG в § 2 гл. 1).