Студопедия

КАТЕГОРИИ:


Архитектура-(3434)Астрономия-(809)Биология-(7483)Биотехнологии-(1457)Военное дело-(14632)Высокие технологии-(1363)География-(913)Геология-(1438)Государство-(451)Демография-(1065)Дом-(47672)Журналистика и СМИ-(912)Изобретательство-(14524)Иностранные языки-(4268)Информатика-(17799)Искусство-(1338)История-(13644)Компьютеры-(11121)Косметика-(55)Кулинария-(373)Культура-(8427)Лингвистика-(374)Литература-(1642)Маркетинг-(23702)Математика-(16968)Машиностроение-(1700)Медицина-(12668)Менеджмент-(24684)Механика-(15423)Науковедение-(506)Образование-(11852)Охрана труда-(3308)Педагогика-(5571)Полиграфия-(1312)Политика-(7869)Право-(5454)Приборостроение-(1369)Программирование-(2801)Производство-(97182)Промышленность-(8706)Психология-(18388)Религия-(3217)Связь-(10668)Сельское хозяйство-(299)Социология-(6455)Спорт-(42831)Строительство-(4793)Торговля-(5050)Транспорт-(2929)Туризм-(1568)Физика-(3942)Философия-(17015)Финансы-(26596)Химия-(22929)Экология-(12095)Экономика-(9961)Электроника-(8441)Электротехника-(4623)Энергетика-(12629)Юриспруденция-(1492)Ядерная техника-(1748)

Лекция № 6. Кодирование текста: ASCII и Unicode (UTF-16)




 

Кодирование текста: ASCII и Unicode (UTF-16)

 

Человек легко воспринимает текст. Наш мозг ежедневно обрабатывает огромные объёмы текста. В отличие от нас, процессор компьютера может работать только с числами. Поэтому все текстовые данные в памяти компьютера представляются числами. Но перед подробным обсуждением этого момента, давайте вспомним, как организована память компьютера.

 

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

 

Бит слишком малая единица. Поэтому биты объединяются в байты. В одном байте восемь бит. Каждый байт имеет свой адрес. Именно байт является минимальной единицей, к которой может обратиться процессор - процессор не может обращаться к отдельным битам, только через соответствующие байты. Давайте посмотрим на небольшой участок памяти компьютера:

 

1 2 3 4 5 6

01001000 01000101 01001011 01001011 01001111 00100001

 

 

Сверху показаны адреса байтов, а снизу - значения, хранящиеся в данных адресах. В реальности не существует таких адресов, так как современные компьютеры работают с огромными адресными пространствами. Адреса в современных компьютерах записываются вот так: 0x01328921. Адреса записываются в шестнадцатеричном формате.

 

В одном байте может храниться 256 значений - 28 = 256. Диапазон значений: от нуля до 255 (для беззнаковых чисел), или от -128 до 127 (для чисел со знаком). В шестнадцатеричной форме максимальное значение байта - 0xff. Обратите внимание на удобство использования шестнадцатеричной системы счисления: для записи любого однобайтного значения требуется две цифры. Посмотрим на диапазоны однобайтного числа во всех трёх системах счисления:

 

00000000... 11111111

0... 255

0x00... 0xff

 

 

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

 

1 2 3 4 5 6

01001000 01000101 01001011 01001011 01001111 00100001 // двоичная (бинарная) форма

72 69 76 76 79 33 // десятичная форма

0x48 0x45 0x4b 0x4b 0x4f 0x21 // шестнадцатеричная форма

Компьютеру удобнее использовать бинарную форму, а нам - шестнадцатеричную, или десятичную.

Кодировка ASCII

 

Чтобы представить текст числами, каждой букве присваивают числовое значение - кодируют значения букв. Присвоив всем буквам уникальное значение, мы получим кодировку (character set, endoding). Но использовать свою кодировку нет никакого смысла - вы сможете использовать её только в своей программе. На данный момент наибольшее распространение получила кодировка ASCII.

 

Первоначально один символ в кодировке ASCII занимал 7 бит. Но когда распространение получил 8-битный байт (да, существовали байты разных размеров), то ASCII была расширена до восьми бит. 7-битная кодировка в два раза меньше восьмибитной: 27=128 < 28=256.

 

Итак, первоначально в кодировке ASCII было 128 значений: от 0 до 127 (0x00 до 0x7f). Этого достаточно чтобы закодировать все буквы латинского алфавита, арабские цифры и ещё ряд знаков.

 

7-битная кодировка ASCII является основой для всех распространённых сейчас кодировок и чрезвычайно важна в программировании. Поэтому мы познакомимся с конкретными значениями:

 

0 - ноль. Это не цифра в выводимом тексте. К данному коду не привязан никакой символ. Т.е. вы никогда не увидите на экране представление нуля. Тем не менее, ноль очень важен в программировании и хранении текста. Для чего используется этот код, мы узнаем позже.

32 - пробел.

48 - код нуля. Когда мы видим на экране монитора ноль, в памяти компьютера этот символ представлен числом 48.

49 - единица. Далее идут остальные арабские цифры.

57 - девятка.

65 - прописная буква A (английский алфавит).

90 - прописная буква Z.

97 - строчная буква a.

122 - строчная буква z.

 

Давайте вернёмся к рассмотренной ранее последовательности байтов, и попробуем значению каждого поставить в соответствие код из ASCII:

 

1 2 3 4 5 6

01001000 01000101 01001011 01001011 01001111 00100001 // двоичная (бинарная) форма

72 69 76 76 79 33 // десятичная форма

H E L L O! // символы ASCII

 

 

О, чудо! У нас получился текст "HELLO!"

 

Компьютер видит всего лишь последовательность байт, к которым он может обратиться по их адресам. Мы можем видеть как простые числа, так и текст, если смотреть на эти числа в кодировке ASCII.

Расширенная кодировка ASCII (extended ASCII)

 

С появлением восьмибитной кодировки, в ASCII смогли закодировать и другие алфавиты. Расширенных кодировок ASCII много - существуют версии для многих национальных алфавитов. При этом первая половина кодировки (значения от нуля до 127) везде одинаковая.

 

Русский алфавит (кириллица) закодирован в кодировке с названием windows-1251. Ещё одна популярная версия ASCII - windows-1252 - это кодировка для западноевропейских языков (в ней закодированы буквы специфические для французского и немецкого алфавитов). Кстати, текст, который вы сейчас читаете, закодирован в windows-1251.

 

Нам не важно, как закодированы русские буквы (да и английские тоже) в windows-1251 - не нужно знать конкретные значения. Если необходимо, можете найти полный список значений символов для windows-1251 в поисковиках.

Кодирование цифр в тексте

 

На практике не нужно знать закодированные значения букв. Но в то же время нужно обязательно запомнить закодированные значения цифр. В ASCII цифры имеют коды с 48 до 57. 48 - ноль, 49 - единица... 57 - девять. Напоминаю, что первые 128 значений одинаковы во всех кодировках, поэтому и коды цифр везде совпадают. И это, скажу я вам, очень здорово. Для чего нужно знать коды цифр, и как это связано с созданием игр?

 

Допустим, в нашей игре нужно выводить на экран значений юнитов пользователя. Внутри программы это простое число, представленное переменной. Но чтобы пользователь увидел это число, его нужно превратить в текст, который и будет отображён на экране. Поэтому при создании игры, нужно обязательно написать код, который занимается преобразованием чисел в текст.

 

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

 

Сначала пользователю нужно вывести символ 0. Для этого потребуется использовать закодированное значение этого символа - 48. Затем пользователю нужно вывести символ 5, код которого - 53. Здесь видна интересная особенность: код символа цифры отличается от фактического значения на 48. Поэтому для однозначных (и только для однозначных) чисел мы можем использовать вот такой код:

 

int var = GetUnitNumber(); // узнать количество юнитов

char output = var+48;

 

Теперь можно вывести переменную output на экран. Только осталось решить одну проблему: в реальных ситуациях очень редко используются однозначные числа. Например, в Company of heroes у игрока в подчинении находятся в среднем больше 15 отрядов, в Age of Empires - больше 50. В других играх ситуация аналогичная. В шутерах может потребоваться выводить количество патронов и здоровья (значения которых практически всегда больше 9). Конечно же, и при создании своей игры нам нужно будет выводить многозначные числа. Вывод многозначных чисел мы рассмотрим в следующем уроке, а сейчас вернёмся к рассмотрению кодировок.

Кодировка (encoding) Юникод - Unicode

 

Один байт может иметь только 256 значений. Это значит, что в кодировке ASCII можно закодировать 256символов: цифр, букв, пиктограмм, знаков пунктуации и других различных символов. В то же время существуют письменности, в которых гораздо больше символов, например, китайские или японские иероглифы.

 

Для решения этой (и некоторых других) проблемы в начале девяностых была создана кодировка Юникод(Unicode). Первоначально все символы юникода занимали два байта. Соответственно, в unicode можно было закодировать 216 = 65536 значений. Затем кодовое пространство было расширено до более чем миллиона символов. В результате этого появилось несколько представлений юникода.

 

Наиболее популярными представлениями юникода являются два: UTF-8 - используется в интернете и UTF-16 - используется в Windows (Windows XP, Windows Vista, Windows 7).

 

В контексте создания игр не важно, как кодируются все символы в различных представлениях Unicode. Но важно то, что во всех представлениях арабские цифры кодируются так же, как и в ASCII.

 

Существует две версии UTF-16: UTF-16LE (little-endian) - кодировка с обратным порядком байтов и UTF-16BE (big-endian) - кодировка с прямым порядком байтов. В Windows, конечно же, используется UTF16-LE.

 

Код символов в юникоде обозначается так: U+hhhh (четыре шестнадцатеричных цифры, h - от hexadecimal - шестнадцатеричный). Например, U+221A - символ квадратного корня - √.

 

Часть символов в UTF-16 кодируются двумя байтами (первые 63 тысячи). Остальные символы кодируются суррогатными парами. Так как это не слишком важно для создания игр, то я не буду останавливаться на суррогатных парах подробно.

 

В UTF-8 первые 128 символов кодируются одним байтом. Остальные символы могут кодироваться несколькими байтами (от двух до четырёх).

 

И ещё один момент (самый важный): в юникод закодированы все символы всех современных и многих мёртвых письменностей плюс знаки из различных областей науки и культуры (математические и экономически символы, нотные знаки и многое другое). Именно по этой причине и нужно использовать юникод.

 

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

Кодирование текста в Microsoft Windows (Windows XP, Windows Vista, Windows 7)

 

В современных версиях Windows существует два способа представления текста: UTF-16 и кодовые страницы (в основном это восьмибитные кодировки). Основной способ - юникод. Кодовые страницы нужны для совместимости со старыми приложениями (в Windows 95, Windows 98 - в основном использовалась ASCII). Кроме того, юникод не понимает одна очень важная программа - консоль.

 

Пусть вас не смущает новый термин - кодовая страница (code page). В windows так называются все кодировки (character sets или encodings). Т.е. понятие кодировка равнозначно кодовой странице.

 

Сразу сделаю замечание, которое лучше запомнить. В Windows есть чёткое разделение: вот юникод (UTF-16LE), а вот все остальные кодировки. И юникод, и остальные кодировки в Windows называются кодовыми страницами, но этот термин (кодовые страницы) я буду применять ко всем кодировкам за исключением юникода.

 

Когда мы писали консольные программы, вывод текста осуществлялся с помощью кодовой страницы windows-1252. Именно поэтому нам приходилось вызывать setlocale (она меняет кодовую страницу на windows-1251):

 

setlocale(LC_CTYPE,"Russian");

 

Эта функция меняет локальность.

Locale (местная специфика) - локальность

 

В Windows есть такое понятие как Locale. Здесь я не совсем верно использую кальку этого слова - локальность, но, на мой взгляд, она довольно ёмкая, чтобы вместить весь смысл понятия Locale. Locale переводится как местные особенности. Т.е. это какие-то параметры используемы в данном конкретном месте (регионе, стране). setlocale как раз и меняет эти особенности:

 

setlocale(LC_CTYPE,"Russian");

 

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

 

Первый параметр этой функции говорит, какие категории местных особенностей можно изменить. Можно изменить только кодовую страницу (LC_CTYPE), можно формат представления даты и времени (LC_TIME), а можно изменить и все категории (LC_ALL, all - всё).

 

Возвращаемся к кодировкам.

 

Одновременно может использоваться только одна кодовая страница, при этом с символами кодовой страницы в программе можно использовать и юникод, так как юникод стоит особняком от всех остальных кодовых страниц. Старайтесь в своих программах всегда использовать юникод. Кодовые страницы имеет смысл использовать только в консоли.

 




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


Дата добавления: 2014-01-06; Просмотров: 5358; Нарушение авторских прав?; Мы поможем в написании вашей работы!


Нам важно ваше мнение! Был ли полезен опубликованный материал? Да | Нет



studopedia.su - Студопедия (2013 - 2024) год. Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав! Последнее добавление




Генерация страницы за: 0.045 сек.