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

Встроенные типы данных

< Лекция 5 || Лекция 6: 123 || Лекция 7 >

Символы и байты

Символьный или байтовый тип в языке Си++ относится к целым числам, однако мы выделили их в особый раздел, потому что запись знаков имеет свои отличия.

Итак, для записи знаков в языке Си++ служат типы char и unsigned char. Первый – это целое число со знаком, хранящееся в одном байте, второй – беззнаковое байтовое число. Эти типы чаще всего используются для манипулирования символами, поскольку коды символов как раз помещаются в байт.

Пояснение. Единственное, что может хранить компьютер, это числа. Поэтому для того чтобы можно было хранить символы и манипулировать ими, символам присвоены коды – целые числа. Существует несколько стандартов, определяющих, какие коды каким символам соответствуют. Для английского алфавита и знаков препинания используется стандарт ASCII. Этот стандарт определяет коды от 0 до 127. Для представления русских букв используется стандарт КОИ-8 или CP-1251. В этих стандартах русские буквы кодируются числами от 128 до 255. Таким образом, все символы могут быть представлены в одном байте (максимальное число символов в одном байте – 255 ). Для работы с китайским, японским, корейским и рядом других алфавитов одного байта недостаточно, и используется кодировка с помощью двух байтов и, соответственно, тип wchar_t (подробнее см. ниже).

Чтобы объявить переменную байтового типа, нужно записать:

char c;                   
// байтовое число со знаком

unsigned char u;   
// байтовое число без знака

Поскольку байты – это целые числа, то все операции с целыми числами применимы и к байтам. Стандартная запись целочисленных констант тоже применима к байтам, т.е. можно записать:

c = 45;

где c — байтовая переменная. Однако для байтов существует и другая запись констант. Знак алфавита (буква, цифра, знак препинания), заключенный в апострофы, представляет собой байтовую константу, например:

'S' '&' '8' 'ф'

Числовым значением такой константы является код данного символа, принятый в Вашей операционной системе.

В кодировке ASCII два следующих оператора эквивалентны:

char c = 68;
char c = 'D';

Первый из них присваивает байтовой переменной c значение числа 68. Второй присваивает этой переменной код латинской буквы D, который в кодировке ASCII равен 68.

Для обозначения ряда непечатных символов используются так называемые экранированные последовательности – знак обратной дробной черты, после которого стоит буква. Эти последовательности стандартны и заранее предопределены в языке:

\a     звонок
\b     возврат на один символ назад
\f     перевод страницы
\n     новая строка
\r     перевод каретки
\t     горизонтальная табуляция
\v     вертикальная табуляция
\'     апостроф
\"     двойные кавычки
\\     обратная дробная черта
\?     вопросительный знак

Для того чтобы записать произвольное байтовое значение, также используется экранированная последовательность: после обратной дробной черты записывается целое число от 0 до 255.

char zero = '\0';
const unsigned char bitmask = '\0xFF';
char tab = '\010';

Следующая программа выведет все печатные символы ASCII и их коды в порядке увеличения:

for (char c = 32; c < 127; c++)
     cout << c << " " << (int)c << " ";

Однако напомним еще раз, что байтовые величины – это, прежде всего, целые числа, поэтому вполне допустимы выражения вида

'F' + 1
'a' < 23

и тому подобные. Тип char был придуман для языка Си, от которого Си++ достались все базовые типы данных. Язык Си предназначался для программирования на достаточно "низком" уровне, приближенном к тому, как работает процессор ЭВМ, именно поэтому символ в нем – это лишь число.

В языке Си++ в большинстве случаев для работы с текстом используются специально разработанные классы строк, о которых мы будем говорить позже.

Кодировка, многобайтовые символы

Мы уже упоминали о наличии разных кодировок букв, цифр, знаков препинания и т.д. Алфавит большинства европейских языков может быть представлен однобайтовыми числами (т.е. кодами в диапазоне от 0 до 255 ). В большинстве кодировок принято, что первые 127 кодов отводятся для символов, входящих в набор ASCII: ряд специальных символов, латинские заглавные и строчные буквы, арабские цифры и знаки препинания. Вторая половина кодов – от 128 до 255 отводится под буквы того или иного языка. Фактически, вторая половина кодовой таблицы интерпретируется по-разному, в зависимости от того, какой язык считается "текущим". Один и тот же код может соответствовать разным символам в зависимости от того, какой язык считается "текущим".

Однако для таких языков, как китайский, японский и некоторые другие, одного байта недостаточно – алфавиты этих языков насчитывают более 255 символов.

Перечисленные выше проблемы привели к созданию многобайтовых кодировок символов. Двухбайтовые символы в языке Си++ представляются с помощью типа wchar_t:

wchar_t wch;

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

Константы типа wchar_t записываются в виде L'ab'.

Наборы перечисляемых значений

Достаточно часто в программе вводится тип, состоящий лишь из нескольких заранее известных значений. Например, в программе используется переменная, хранящая величину, отражающую время суток, и мы решили, что будем различать ночь, утро, день и вечер. Конечно, можно договориться обозначить время суток числами от 1 до 4. Но, во-первых, это не наглядно. Во-вторых, что даже более существенно, очень легко сделать ошибку и,например, использовать число 5, которое не соответствует никакому времени дня. Гораздо удобней и надежнее определить набор значений с помощью типа enum языка Си++:

enum DayTime { morning, day, evening, night };

Теперь можно определить переменную

DayTime current;

которая хранит текущее время дня, а затем присваивать ей одно из допустимых значений типа DayTime:

current = day;

Контроль, который осуществляет компилятор при использовании в программе этой переменной, гораздо более строгий, чем при использовании целого числа.

Для наборов определены операции сравнения на равенство ( == ) и неравенство ( != ) с атрибутами этого же типа, т.е.

if (current != night)
     // выполнить работу

Вообще говоря, внутреннее представление значений набора – целые числа. По умолчанию элементам набора соответствуют последовательные целые числа, начиная с 0. Этим можно пользоваться в программе. Во-первых, можно задать, какое число какому атрибуту набора будет соответствовать:

enum { morning = 4, day = 3, evening = 2, 
            night = 1 };
     // последовательные числа начиная с 1
enum { morning = 1, day, evening, night };
     // используются числа 1, 2, 3 и 4
enum { morning, day = 2, evening, night };

Во-вторых, атрибуты наборов можно использовать в выражениях вместо целых чисел. Преобразования из набора в целое и наоборот разрешены.

Однако мы не рекомендуем так делать. Для работы с целыми константами лучше применять символические обозначения констант, а наборы использовать по их прямому назначению.

< Лекция 5 || Лекция 6: 123 || Лекция 7 >
Андрей Одегов
Андрей Одегов
Язык программирования C++
Елена Шумова
Елена Шумова

Здравствуйте! Я у Вас прошла курс Язык программировая Си++.

Заказала сертификат. Хочу изменить способ оплаты. Как это сделать?

Иван Иванов
Иван Иванов
Россия, Екатеринбург
Владимир Алемасов
Владимир Алемасов
Россия