Чтение онлайн

ЖАНРЫ

Программирование. Принципы и практика использования C++ Исправленное издание
Шрифт:

Причина популярности шестнадцатеричной системы кроется в том, что шестнадцатеричные цифры позволяют точно представить четырехбитовые значения. Таким образом, две шестнадцатеричные цифры можно использовать для представления восьмибитового байта, четыре шестнадцатеричные цифры представляют два байта (которые часто являются полусловом), восемь шестнадцатеричных цифр могут представить четыре байта (что часто соответствует размеру слова или регистра).

Когда был разработан язык С — предшественник языка С++ (в 1970-х годах), не менее популярной была восьмеричная система, но сейчас она используется редко. Мы можем указать, что (десятичное число)

1234
при выводе должно трактоваться как десятичное, шестнадцатеричное или восьмеричное.

cout << 1234 << "\t(decimal)\n"

<< hex << 1234 << "\t(hexadecimal)\n"

<< oct << 1234 << "\t(octal)\n";

Символ

'\t'
означает “символ табуляции”. Он обеспечивает следующее представление выходной информации:

1234 (decimal)

4d2 (hexadecimal)

2322 (octal)

Обозначения

<< hex
и
<< oct
не являются значениями, предназначенными для вывода. Выражение
<< hex
сообщает потоку, что любое целое число в дальнейшем должно быть представлено как шестнадцатеричное, а выражение
<< oc
t означает, что любое целое число в дальнейшем должно быть представлено как восьмеричное. Рассмотрим пример.

cout << 1234 << '\t' << hex << 1234 << '\t' << oct << 1234 << '\n';

cout << 1234 << '\n'; // восьмеричная основа продолжает действовать

В итоге получаем следующий вывод:

1234 4d2 2322

2322 // целые числа продолжают трактоваться как восьмеричные

Обратите внимание на то, что последнее число выведено как восьмеричное; иначе говоря, термины

oct
,
hex
и
dec
(для десятичных чисел) являются персистентными (инертными) — они применяются к каждому целому числу, пока мы не дадим потоку другое указание. Термины
hex
и
oct
используются для изменения поведения потока и называются манипуляторами (manipulators).

ПОПРОБУЙТЕ

Выведите ваш день рождения в десятичном, восьмеричном и шестнадцатеричном форматах. Обозначьте каждое из этих значений. Выровняйте ваш вывод по столбцам, используя символ табуляции, и выведите свой возраст.

Представление чисел в системе счисления, отличной от десятичной, может ввести читателя в заблуждение. Например, если заранее не знать, в какой системе представлено число, то строка 11 может означать десятичное число 11, а не восьмеричное число 9 (т.е. 11 в восьмеричной системе) или шестнадцатеричное число 17 (т.е. 11 в шестнадцатеричной системе). Для того чтобы избежать таких проблем, можно попросить поток показать базу, в которой представлено целое число. Рассмотрим пример.

cout << 1234 << '\t' << hex << 1234 << '\t' << oct << 1234 << '\n';

cout << showbase << dec; // показывать базы

cout << 1234 << '\t' << hex << 1234 << '\t' << oct << 1234 << '\n';

В результате получим следующий вывод:

1234 4d2 2322

1234 0x4d2 02322

Итак, десятичные числа не имеют префиксов, восьмеричные числа имеют префикс 0,

а шестнадцатеричные числа имеют префикс
0x
(или
0X
). Именно так обозначаются целочисленные литералы в языке С++. Рассмотрим пример.

cout << 1234 << '\t' << 0x4d2 << '\t' << 02322 << '\n';

В десятичном виде эти числа выглядели бы так:

1234 1234 1234

Как вы могли заметить, манипулятор

showbase
является персистентным, как и манипуляторы
oct
и
hex
. Манипулятор
noshowbase
отменяет действие манипулятора
showbase
, возвращая поток в состояние по умолчанию, в котором любое число выводится без указания его базы счисления.

Итак, существует несколько манипуляторов вывода.

11.2.2. Ввод целых чисел

По умолчанию оператор

>>
предполагает, что числа используются в десятичной системе счисления, но его можно заставить вводить целые числа как шестнадцатеричные или восьмеричные.

int a;

int b;

int c;

int d;

cin >> a >> hex >> b >> oct >> c >> d;

cout << a << '\t' << b << '\t' << c << '\t' << d << '\n';

Если набрать на клавиатуре числа

1234 4d2 2322 2322

то программа выведет их так:

1234 1234 1234 1234

Обратите внимание на то, что при вводе манипуляторы

oct
,
dec
и
hex
являются персистентными, как и при выводе.

ПОПРОБУЙТЕ

Завершите фрагмент кода, приведенный выше, и преобразуйте его в программу. Попробуйте ввести предлагаемые числа; затем введите числа

1234 1234 1234 1234

Объясните результат. Попробуйте ввести другие числа, чтобы увидеть, что произойдет.

Для того чтобы принять и правильно интерпретировать префиксы

0
и
0x
, можно использовать оператор
>>
. Для этого необходимо отменить установки, принятые по умолчанию. Рассмотрим пример.

cin.unsetf(ios::dec); // не считать десятичным

// (т.е. 0x может означать

// шестнадцатеричное число)

cin.unsetf(ios::oct); // не считать восьмеричным

// (т.е. 12 может означать двенадцать)

cin.unsetf(ios::hex); // не считать шестнадцатеричным

// (т.е. 12 может означать двенадцать)

Функция-член потока

unsetf
сбрасывает флаг (или флаги), указанный как аргумент. Итак, если вы напишете

cin >>a >> b >> c >> d;

Поделиться с друзьями: