- •2. Оператор цикла while.
- •Билет 2.
- •Билет 3
- •2. Оператор цикла for
- •Билет 4
- •Билет 5
- •1. Константы
- •1.1 Целые Константы
- •1.3 Символьные Константы
- •1.4 Строки
- •2. Оператор if
- •Билет 6
- •Билет 7
- •1.1 Описания Функций
- •1.2 Определения Функций
- •1.3 Описания
- •2.1.1 Область Видимости
- •2.1.2 Объекты и Адреса (Lvalue)
- •2.1.3 Время Жизни
- •2. Логические операции.
- •Билет 8
- •1. Указатели. Использование указателей при работе с массивами
- •2. Оператор Goto
- •Билет 9
- •2. Указатели и операции над ними.
- •Билет 10
- •Билет 11
- •1. Оператор if
- •2. Строки
- •Билет 12
- •1. Увеличение и уменьшение
- •Билет 13
- •1. Побитовые логические операции
- •2. Функция scanf
- •Билет 14
- •Основные сведения о функциях
- •2. Функции operator new() и operator delete()
- •Билет 15
- •1. Объединения
- •2. Форматный вывод - функция printf
- •Билет 16
- •1. Оператор Выражение
- •2. Области видимости объектов
- •Билет 17
- •1.1 Оператор Return
- •1.2 Оператор Break
- •1.3 Оператор Continue
- •2. Ввод-вывод текстового файла: getc( ), putc( )
- •Билет 18
- •Билет 19
- •1. Аргументы функции main()
- •2. Операции Отношения
- •Билет 20
- •1. Стандартный ввод и вывод - функции getchar и putchar
- •2.1 Оператор typedef
- •Билет 21
- •1. Глобальные переменные
- •2. Открытие файла: fopen( )
- •Закрытие файла: fclose( )
- •Билет 22
- •2. Директивы Препроцессора
- •2.1. Директива #include
- •2.2. Директива #define
- •2.3. Директива #undef
- •Билет 23
- •1. Преобразование типов.
- •2. Операция Запятая
- •Билет 24
- •1. Определение
- •2. Арифметические Преобразования
- •Билет 25
- •Билет 26
- •1. Передача Параметров
- •Билет 27
- •1. Преобразования символов
- •2. Массив и константный указатель
- •Билет 28
- •2. Операции Отношения
- •Билет 29
- •1. Оператор return. Точка вызова и точка возврата
- •Билет 30
- •2. Рекурсивная функция
- •Билет 31
- •2. Функция. Прототип
- •Билет 32
- •2. Генерация случайных чисел
- •Билет 33
- •2. Шаблоны функций и шаблонные функции
Билет 13
1. Побитовые логические операции
Побитовые логические операции
& ! ^ ~ >> <<
применяются к целым, то есть к объектам типа char, short, int, long и их unsigned аналогам, результаты тоже целые.
Одно из стандартных применений побитовых логических операций - реализация маленького множества (вектор битов). В этом случае каждый бит беззнакового целого представляет один член множества, а число членов ограничено числом битов. Бинарная операция & интерпретируется как пересечение, ! как объединение, а ^ как разность. Для наименования членов такого множества можно использовать перечисление. Вот маленький пример, заимствованный из реализации (не пользовательского интерфейса) <stream.h>:
enum state_value (* _good=0, _eof=1, _fail=2, _bad=4 *);
// хорошо, конец файла, ошибка, плохо
Определение _good не является необходимым. Я просто хотел, чтобы состояние, когда все в порядке, имело подходящее имя. Состояние потока можно установить заново следующим образом:
cout.state = _good;
Например, так можно проверить, не был ли испорчен поток или допущена операционная ошибка:
if (cout.state&(_bad!_fail)) // не good
Еще одни скобки необходимы, поскольку & имеет более высокий приоритет, чем !.
Функция, достигающая конца ввода, может сообщать об этом так:
cin.state != _eof;
Операция != используется потому, что поток уже может быть испорчен (то есть, state==_bad), поэтому
cin.state = _eof;
очистило бы этот признак. Различие двух потоков можно находить так:
state_value diff = cin.state^cout.state;
В случае типа stream_state (состояние потока) такая разность не очень нужна, но для других похожих типов она оказывается самой полезной. Например, при сравнении вектора бит, представляющего множество прерываний, которые обрабатываются, с другим, представляющим прерывания, ждущие обработки.
Следует заметить, что использование полей (#2.5.1) в действительности является сокращенной записью сдвига и маскирования для извлечения полей бит из слова. Это, конечно, можно сделать и с помощью побитовых логических операций, Например, извлечь средние 16 бит из 32-битового int можно следующим образом:
unsigned short middle(int a) (* return (a>>8)&0xffff; *)
Не путайте побитовые логические операции с логическими операциями:
&& !! !
Последние возвращают 0 или 1, и они главным образом используются для записи проверки в операторах if, while или for (#3.3.1). Например, !0 (не ноль) есть значение 1, тогда как ~ 0 (дополнение нуля) есть набор битов все-единицы, который обычно является значением -1.
2. Функция scanf
Обращение к этой функции имеет вид:
scanf (Управляющая_строка,&Имя1,&Имя2,...,&ИмяN);,
где: 1) Имя1,Имя2,...,ИмяN - это имена переменных, значения которых надо ввести. Смысл символа "&" перед именем будет раскрыт ниже; 2) Управляющая_строка - это строка символов, которая задает количество и типы вводимых переменных. Делается это так: в формате указывается символ %, за которым следует буква, определяющая тип вводимой переменной.
Сочетание %буква является спецификацией преобразования. При вводе мы будем пользоваться следующими спецификациями:
%d - ввести целое число;
%c - ввести один символ;
%s - ввести строку символов.
Спецификации преобразования должны соответствовать количеству и типу вводимых переменных.
К счастью, при применении функции scanf() мы ничего не должны знать о смысле символа "&". Необходимо запомнить только два правила.
Если нужно ввести некоторое значение и присвоить его переменной одного из основных типов, то перед именем переменной требуется писать символ &.
Если требуется ввести значение строковой переменной, то использовать символ & не нужно.
Функция scanf() использует некоторые специальные знаки (пробелы, символы табуляции и символ "новая строка") для разбиения входных символов на отдельные поля. Она согласует последовательность спецификаций преобразования с последовательностью полей, опуская упомянутые специальные знаки между ними.
При обращении к функции scanf() выполнение программы приостанавливается, и нужно ввести значения для указанных переменных, после чего работа программы продолжается.
Пример 1.
#include<stdio.h>
main ()
{
int a,b,c,d,e;
/* При вводе каждое число должно */
/* отделяться от другого пробелом */
scanf ("\n %d%d%d%d%d",&a,&b,&c,&d,&e);
printf ("\n %d %d %d %d %d",a,b,c,d,e);
}
Управляющая строка может содержать:
пробелы ' ', символы табуляции '\t' и перевода строки '\n', которые просто игнорируются;
обычные символы (кроме символа "%"), которые предполагаются совпадающими с очередными (отличными от символов, перечисленных в предыдущем пункте) символами входного потока;
спецификации преобразования, состоящие из
%,
необязательного символа "подавления" присваивания "*",
необязательного числа, задающего максимальную ширину поля и
символа преобразования.
Спецификация преобразования управляет преобразованием очередного входного поля. Результат обычно помещается в переменную, на которую ссылается соответствующий параметр. Однако, если присутствует символ "*", то входное поле просто пропускается, и никакого присваивания не производится.
Перечислим основные символы преобразования:
d - десятичное число;
x - шестнадцатеричное число;
o - восьмеричное число;
c - символ;
s - строка символов.