Тип char: символы и их коды


Один символ, Unicode, ASCII и преобразования типов

В этом уроке вы будете хранить отдельные символы в переменных char, узнаете их числовые коды и научитесь преобразовывать символ в число и обратно.

Один символ и строка

Тип char в C# хранит одну кодовую единицу UTF-16 стандарта Unicode. Для обычных латинских букв, цифр и многих других символов этого достаточно, чтобы представить один символ.

Символ записывают в одинарных кавычках ('), а строку — в двойных ("): char ch = 'b'; и string text = "b"; имеют разные типы.

char letter = 'A';
char digit = '9';
char sign = '%';
string word = "Hello";

'9' — символ цифры, а 9 — целое число. Числовой код символа '9' равен 57, а не 9.

Ввод одного символа

Console.ReadLine() возвращает строку. Чтобы получить из неё значение char, используйте char.Parse:

Console.Write("Введите одну латинскую букву: ");
char ch = char.Parse(Console.ReadLine());
Console.WriteLine("Вы ввели: " + ch);

Введите, например, A и нажмите Enter. Метод char.Parse требует строку ровно из одной кодовой единицы UTF-16: пустая строка или несколько букв вызовут ошибку. В этих упражнениях вводите один простой символ, например латинскую букву, цифру или знак.

Почему преобразование автоматически работает только в одну сторону

Представьте char как маленькую коробку, а int — как большую. Значения char находятся в диапазоне от 0 до 65 535. Тип int вмещает и отрицательные числа, и положительные до 2 147 483 647. Поэтому любой код из char помещается в int, и преобразование выполняется автоматически.

В обратном направлении целое число, например 1 000 000, может не поместиться в char. Поэтому нужно явно написать (char). Само приведение не гарантирует, что исходное число лежит в допустимом диапазоне.

Из char в int — автоматическое преобразование. Из переменной int в char — явное приведение. Перед преобразованием числа в символ убедитесь, что число находится в диапазоне 0–65 535.

Например, код символа 'c' равен 99. Запись int num = 'c'; сохранит число 99, а (char)(num + 1) даст символ 'd' с кодом 100.

Пример преобразований char и int

Фрагменты с Main в этом уроке заменяют метод Main внутри класса Program вашей консольной программы.

1
2
3
4
5
6
7
8
9
10
11
static void Main(string[] args)
{
    int num;
    char ch;
    ch = 'c';   // Сохраняем символ c
    num = ch;   // Автоматически получаем его числовой код Unicode
    Console.WriteLine("num = " + num); // 99
    Console.WriteLine("ch = " + ch);   // c
    ch = (char)(num + 1);               // Явно преобразуем код 100 в символ
    Console.WriteLine("ch = " + ch);   // d
}

Результат:

num = 99
ch = c
ch = d

ASCII и Unicode

ASCII — стандарт кодирования, в котором каждому из 128 символов соответствует число от 0 до 127. Он включает английские буквы, цифры, знаки и управляющие коды. Например:

Символ Код
'A' 65
'B' 66
'a' 97
'b' 98
'0' 48
'9' 57

Unicode охватывает гораздо больше символов. Для символов основной таблицы ASCII числовые значения совпадают с их значениями в Unicode.

При преобразовании char в int вы получаете числовое значение кодовой единицы Unicode. При явном преобразовании подходящего int в char получается кодовая единица с этим значением:

int num = 65;
char ch = (char)num;
Console.WriteLine(ch); // A
Почему некоторые символы не помещаются в один char

В C# тип char занимает 16 бит и хранит одну кодовую единицу UTF-16. В этот диапазон входят латинские и русские буквы, многие другие письменности и знаки валют, например и £.

Символы Unicode с кодовыми точками выше U+FFFF, например эмодзи 😀, представляются в UTF-16 парой кодовых единиц, которую называют суррогатной парой. Одного char для них недостаточно, зато их можно хранить в string:

// Ошибка: для этого эмодзи нужны две кодовые единицы UTF-16.
// char emoji = '😀';

// Допустимо: строка содержит последовательность кодовых единиц.
string emoji = "😀";

Поэтому утверждение «один char — всегда один видимый символ» неточно. В основных упражнениях этого урока используются простые символы ASCII.

Практика: запустите два варианта

Сначала предскажите вывод, затем запустите:

1
2
3
4
5
6
7
8
9
static void Main(string[] args)
{
    int num;
    char ch;
    ch = 'c'; // Код Unicode равен 99; он совпадает с ASCII
    num = ch; // Автоматическое преобразование char в int
    Console.WriteLine("num=" + num);
    Console.WriteLine("ch=" + ch);
}

В следующем варианте есть ошибка. Скопируйте его, попробуйте запустить и найдите причину по сообщению среды разработки:

1
2
3
4
5
6
7
8
9
static void Main(string[] args)
{
    int num;
    char ch;
    num = 99;
    ch = num;
    Console.WriteLine("num=" + num);
    Console.WriteLine("ch=" + ch);
}
Объяснение и исправление

Ошибка находится в ch = num;: значение переменной int нельзя автоматически присвоить переменной char. Для кода 99, который находится в допустимом диапазоне, используйте:

ch = (char)num;

После исправления вывод будет:

num=99
ch=c

Проверьте себя

  1. Чем отличаются char digit = '5'; и int digit = 5;?
  2. Что выведет Console.WriteLine((int)'A');?
  3. Что выведет Console.WriteLine((char)66);?
  4. Какой символ получится после char ch = 'a'; ch = (char)(ch + 2);?
Ответы
  1. Первая переменная содержит символ с кодом 53, вторая — целое число 5. Это два отдельных примера: не объявляйте обе переменные с одним именем в одном блоке.
  2. 65.
  3. B.
  4. c, потому что код 'a' равен 97, а код 'c' — 99.
Полная справочная таблица ASCII

Dec — десятичный код, Hex — шестнадцатеричный. Коды 0–31 и 127 служат для управления и обычно не отображаются как обычные печатные символы.

Dec Hex Символ Название Dec Hex Символ Название
0 0x00 NUL Нулевой символ 64 0x40 @ Знак «at»
1 0x01 SOH Начало заголовка 65 0x41 A Заглавная A
2 0x02 STX Начало текста 66 0x42 B Заглавная B
3 0x03 ETX Конец текста 67 0x43 C Заглавная C
4 0x04 EOT Конец передачи 68 0x44 D Заглавная D
5 0x05 ENQ Запрос 69 0x45 E Заглавная E
6 0x06 ACK Подтверждение 70 0x46 F Заглавная F
7 0x07 BEL Звуковой сигнал 71 0x47 G Заглавная G
8 0x08 BS Возврат на один символ 72 0x48 H Заглавная H
9 0x09 TAB Горизонтальная табуляция 73 0x49 I Заглавная I
10 0x0A LF Перевод строки 74 0x4A J Заглавная J
11 0x0B VT Вертикальная табуляция 75 0x4B K Заглавная K
12 0x0C FF Перевод страницы 76 0x4C L Заглавная L
13 0x0D CR Возврат каретки 77 0x4D M Заглавная M
14 0x0E SO Сдвиг наружу 78 0x4E N Заглавная N
15 0x0F SI Сдвиг внутрь 79 0x4F O Заглавная O
16 0x10 DLE Экранирование канала данных 80 0x50 P Заглавная P
17 0x11 DC1 Управление устройством 1 81 0x51 Q Заглавная Q
18 0x12 DC2 Управление устройством 2 82 0x52 R Заглавная R
19 0x13 DC3 Управление устройством 3 83 0x53 S Заглавная S
20 0x14 DC4 Управление устройством 4 84 0x54 T Заглавная T
21 0x15 NAK Отрицательное подтверждение 85 0x55 U Заглавная U
22 0x16 SYN Синхронизация 86 0x56 V Заглавная V
23 0x17 ETB Конец блока передачи 87 0x57 W Заглавная W
24 0x18 CAN Отмена 88 0x58 X Заглавная X
25 0x19 EM Конец носителя 89 0x59 Y Заглавная Y
26 0x1A SUB Замена 90 0x5A Z Заглавная Z
27 0x1B ESC Экранирование 91 0x5B [ Открывающая квадратная скобка
28 0x1C FS Разделитель файлов 92 0x5C \ Обратная косая черта
29 0x1D GS Разделитель групп 93 0x5D ] Закрывающая квадратная скобка
30 0x1E RS Разделитель записей 94 0x5E ^ Знак циркумфлекса
31 0x1F US Разделитель единиц 95 0x5F _ Подчёркивание
32 0x20 (пробел) Пробел 96 0x60 ` Обратная кавычка
33 0x21 ! Восклицательный знак 97 0x61 a Строчная a
34 0x22 " Двойная кавычка 98 0x62 b Строчная b
35 0x23 # Решётка 99 0x63 c Строчная c
36 0x24 $ Знак доллара 100 0x64 d Строчная d
37 0x25 % Процент 101 0x65 e Строчная e
38 0x26 & Амперсанд 102 0x66 f Строчная f
39 0x27 Одинарная кавычка 103 0x67 g Строчная g
40 0x28 ( Открывающая круглая скобка 104 0x68 h Строчная h
41 0x29 ) Закрывающая круглая скобка 105 0x69 i Строчная i
42 0x2A * Звёздочка 106 0x6A j Строчная j
43 0x2B + Плюс 107 0x6B k Строчная k
44 0x2C , Запятая 108 0x6C l Строчная l
45 0x2D - Дефис 109 0x6D m Строчная m
46 0x2E . Точка 110 0x6E n Строчная n
47 0x2F / Косая черта 111 0x6F o Строчная o
48 0x30 0 Цифра ноль 112 0x70 p Строчная p
49 0x31 1 Цифра один 113 0x71 q Строчная q
50 0x32 2 Цифра два 114 0x72 r Строчная r
51 0x33 3 Цифра три 115 0x73 s Строчная s
52 0x34 4 Цифра четыре 116 0x74 t Строчная t
53 0x35 5 Цифра пять 117 0x75 u Строчная u
54 0x36 6 Цифра шесть 118 0x76 v Строчная v
55 0x37 7 Цифра семь 119 0x77 w Строчная w
56 0x38 8 Цифра восемь 120 0x78 x Строчная x
57 0x39 9 Цифра девять 121 0x79 y Строчная y
58 0x3A : Двоеточие 122 0x7A z Строчная z
59 0x3B ; Точка с запятой 123 0x7B { Открывающая фигурная скобка
60 0x3C < Знак «меньше» 124 0x7C | Вертикальная черта
61 0x3D = Знак равенства 125 0x7D } Закрывающая фигурная скобка
62 0x3E > Знак «больше» 126 0x7E ~ Тильда
63 0x3F ? Вопросительный знак 127 0x7F DEL Удаление

Содержание курса