Внутри компьютера данные и команды, хранятся в двоичном виде. У каждого компьютера есть набор символов, который он использует. Как минимум этот набор включает 26 заглавных и 26 строчных букв, цифры от 0 до 9, а также некоторые специальные символы: пробел, точка, запятая, символ возврата каретки и т.д. Для того чтобы компьютер мог использовать эти символы, каждому из них приписывается в соответствие номер [2]. Отображение символов в целые числа называется кодом символов. Важно отметить, что связанные между собой устройства и компьютеры должны иметь один и тот же код для одинаковых символов, иначе они не смогут обмениваться информацией. По этой причине были разработаны стандарты для кодирования символов. Самые важные из них – это ASCII-код и UNICODE. ASCII-код был так назван по первым буквам своего названия: американский стандартный код для обмена информацией (A merican S tandard C ode for I nformation I nterchange). Каждый символ ASCII-кода содержит 8 битов, таким способом может быть закодировано 256 символов (см. Табл. 4.1). Кодировка UNICODE содержит 16 бит.
Коды от 0 до 0x7F являются одними и теми же кодами символов для всех стран. С кода 0x80 начинаются символы национальных букв, а также псевдографические символы и некоторые специальные знаки (таблица 4.2). Эти символы могут отличаться в зависимости от национального драйвера клавиатуры.
Таблица 4.1. ASCII-коды символов (от 0x20 до 0x7F)
Код | Символ | Код | Символ | Код | Символ | Код | Символ | Код | Символ | Код | Символ |
@ | P | ` | p | ||||||||
! | A | Q | a | q | |||||||
" | B | R | b | r | |||||||
# | C | S | c | s | |||||||
$ | D | T | d | t | |||||||
% | E | U | e | u | |||||||
& | F | V | f | v | |||||||
' | G | W | g | w | |||||||
( | H | X | h | x | |||||||
) | I | Y | i | y | |||||||
2A | * | 3A | : | 4A | J | 5A | Z | 6A | j | 7A | z |
2B | + | 3B | ; | 4B | K | 5B | [ | 6B | k | 7B | { |
2C | , | 3C | < | 4C | L | 5C | \ | 6C | l | 7C | | |
2D | - | 3D | = | 4D | M | 5D | ] | 6D | m | 7D | } |
2E | . | 3E | > | 4E | N | 5E | ^ | 6E | n | 7E | ~ |
2F | / | 3F | ? | 4F | O | 5F | _ | 6F | o | 7F | ⌂ |
Таблица 4.2 ASCII-коды символов (от 0x80 до 0xFF)
Код | Символ | Код | Символ | Код | Символ | Код | Символ | Код | Символ | Код | Символ | Код | Символ | Код | Символ |
А | Р | A0 | а | B0 | ░ | C0 | └ | D0 | ╨ | E0 | р | F0 | Ё | ||
Б | С | A1 | б | B1 | ▒ | C1 | ┴ | D1 | ╤ | E1 | с | F1 | ё | ||
В | Т | A2 | в | B2 | ▓ | C2 | ┬ | D2 | ╥ | E2 | т | F2 | Є | ||
Г | У | A3 | г | B3 | │ | C3 | ├ | D3 | ╙ | E3 | у | F3 | є | ||
Д | Ф | A4 | д | B4 | ┤ | C4 | ─ | D4 | ╘ | E4 | ф | F4 | Ї | ||
Е | Х | A5 | е | B5 | ╡ | C5 | ┼ | D5 | ╒ | E5 | х | F5 | ї | ||
Ж | Ц | A6 | ж | B6 | ╢ | C6 | ╞ | D6 | ╓ | E6 | ц | F6 | Ў | ||
З | Ч | A7 | з | B7 | ╖ | C7 | ╟ | D7 | ╫ | E7 | ч | F7 | ў | ||
И | Ш | A8 | и | B8 | ╕ | C8 | ╚ | D8 | ╪ | E8 | ш | F8 | ° | ||
Й | Щ | A9 | й | B9 | ╣ | C9 | ╔ | D9 | ┘ | E9 | щ | F9 | • | ||
8A | К | 9A | Ъ | AA | к | BA | ║ | CA | ╩ | DA | ┌ | EA | ъ | FA | · |
8B | Л | 9B | Ы | AB | л | BB | ╗ | CB | ╦ | DB | █ | EB | ы | FB | √ |
8C | М | 9C | Ь | AC | м | BC | ╝ | CC | ╠ | DC | ▄ | EC | ь | FC | № |
8D | Н | 9D | Э | AD | н | BD | ╜ | CD | ═ | DD | ▌ | ED | э | FD | ¤ |
8E | О | 9E | Ю | AE | о | BE | ╛ | CE | ╬ | DE | ▐ | EE | ю | FE | ■ |
8F | П | 9F | Я | AF | п | BF | ┐ | CF | ╧ | DF | ▀ | EF | я | FF |
Вывод символов на экран. Коды от 0x0 до 0x1F соответствуют управляющим символам, которые раньше предназначались для пересылки данных. Сейчас в передаче данных по сетям и телефонным линиям используются совсем другие принципы и форматы, но некоторые символы до сих пор сохранили своё назначение – управляющие символы применяются для форматирования при выводе на стандартные устройства (см. Табл. 4.3). Такие символы нельзя ввести с клавиатуры с помощью функций ввода, обеспечивающих автоматическое эхо (getche(), scanf() и т.д.).
Таблица 4.3. Коды некоторых управляющих символов.
Код | Команда | Значение | Управляющая последовательность в Си |
0x07 | BEL | Bell (звонок) | \a |
0x08 | BS | BackSpace (отступ назад) | \b |
0x09 | HT | Horizontal Tab (горизонтальная табуляция) | \t |
0x0A | LN | Line Feed (перевод строки) | \n |
0x0B | VT | Vertical Tab (вертикальная табуляция) | \v |
0x0D | CR | Carriage Return (возврат каретки) | \r |
0x1A | SUB | Substitute (замена и конец файла) | \x1a |
0x1B | ESC | ESCape (выход) | \x1b |
Используя форматирующую строку для вывода символа – "%c", можно вывести на экран символьные отображения некоторых управляющих символов:
Пример 4.1. Вывод на экран двадцати шести управляющих символов.
char i,c;
for (i=0;i<=0x1f;i++)
printf("key %d=%c\n",i,i);
При таком способе управляющие шесть символов с кодами: 7, 8, 9, 0xA, 0xD и 0x1A - интерпретируются буквально согласно своему значению (табл. 4.3), и поэтому необходим другой способ для вывода этих символов на экран.
Пример 4.2. Вывод на экран первых тридцати двух символов ASCII.
#include <dos.h>
void main()
{unsigned int far *screen;
clrscr();
screen = (unsigned int *) MK_FP(0xB800, 0);
int i;
for (i=0; i<=0x1f; i++) screen[i] = 0x0F00 + i;}
В этом примере мы создали глобальный указатель на видеопамять текстового режима. После создания указателя мы обращаемся к видеопамяти как к одномерному массиву из i элементов, в котором каждый элемент типа unsigned int (беззнаковые два байта) соответствует символу на экране. Первый байт элемента отвечает за цветовой атрибут, а второй – за его код. Таким образом, у всех тридцати двух символов из примера 4.2 цветовой атрибут неизменен и соответствует белым символам на черном фоне.
Рис. 4.1. Выполнение программы из примера 4.2.
Если мы изменим старший байт элемента следующим образом:
for (i=0; i<=0x1f; i++) screen[i]=((i%16)<<8)+i;
то мы увидим на экране ряд из цветных символов, причем цвета начинаются заново каждые 16 символов.
Рис. 4.2. Выполнение измененной программы из примера 4.2.
Если мы изменим обращение к элементам массива так, чтобы данные заносились только в четные элементы:
for (i=0; i<=0x1f; i++) screen[i*2]=((i%16)<<8)+i;
то мы увидим, что ряд символов "разредился".
Рис. 4.3. Выполнение измененной программы из примера 4.2.
Для удобства можно вывести кроме символов и их коды. Поэтому увеличиваем цикл вывода на экран до 256 символов и добавляем цикл вывода кодов следующим образом:
Пример 4.3. Вывод на экран 256 символов и их кодов.
// вывод кодов в десятичном виде
for (int j=0;j<16;j++)
for (int i=0;i<16;i++) printf("%3d ",i*16+j);
// вывод символов
for (i=0;i<16;i++) for (j=0;j<16;j++)
screen[i*5+j*80+4] = 0x0E00 + i*16+j;
Обратите внимание на то, что в строке на экране может поместиться только 80 символов. Вывод на экран кодов с форматирующей последовательностью %3d плюс два пробела (итого, 5) дает возможность автоматического переноса на новую строку после выполнения шестнадцати команд printf ().