Языки программирования, 07 лекция (от 26 сентября)
Материал из ESyr's Wiki pages.
Предыдущая лекция | Следующая лекция
Содержание |
Часть 1. Основные понятия традиционных процедурных ЯП
Глава 1. Скалярный базис.
Пункт 5. Символьные типы данных
В любой программе фигурирует 2 алфавита:
- символы для ввода/вывода (char)
- символы для записи самой программы (триграфы)
Начало стандартизации
Вначале был хаос, но уже в 1970-х был создан 7-битовый стандарт ASCII-7, в котором и писались сами программы. С тех пор проблемы остались только с 1 символьным типом.
(Pascal) a^ - так в ASCII-7 записовалось адресное выражение Pascal
Тогда же - ANSI ISO 10646 на отображение символьного типа данных.
Языки бывают двух видов:
- символьный ТД совместим с целочисленным
(C) c++; c+=1;
- символьный ТД не совместим с целочисленным
(Pascal) c=chr(ord(c)+1); c=succ(c);
Еще один стандарт тех времен - ISO 8809 "Latin 1". Он позволял преобразовыть текс на языках с расширенной латиницей в тект на латинице. Но таких языков было мало, да и кириллические языки никак не учитывались. Результат - в большинстве стран свои раскладки, где 0-127 из ASCII-7, 128-255 специфично для страны.
(Флуд от ZOK'a) А в России одну такую раскладку придумать не смогли. Результат - полный хаос кодировок, с которыми приходится мириться для обратной совместимости и по сей день.
Дальнейшие развитие
1980-е ознаменовались огромным экономическим подъемом Японии. Тогда-то и встал острый вопрос о кодировании их языка. Родилась новая концепция.
CS (Character Set) - Таблица соответствий названий символов (не изображений!) и их кодов.
- SBCS (Single Byte CS) - устарела, ее не хватает даже для Европы
- MBCS (Multi Byte CS) - для Японии, переменная байтовая длина
- DBCS (Double Byte CS) - 2 или 4 байта
- UCS-2, она же UNICODE
- UCS-4
Сейчас UNICODE поддерживается на уровне операционных систем. Это вызывает сложности с поддержкой устаревших программ, обращающихся к прежним системным вызовам. Для них строки перекодируются на лету.
Также UNICODE реализован в родных типах данных новых языков программирования C# и Java, разработанных в 1990-х с нуля.
Сейчас в обществе остро стоит проблема интернационализации (жаргон - i18n). ПО, написанное для одной страны должно быть пригодным к использованию в других странах. Для этого есть 2 пути
- локализация (фактически, переписывание отдельных частей кода для конкретной страны)
- глобализация (учитывание интернациональных факторов сразу)
Факторов много. В .NET и Java даже введено специальное понятие culture, включающее в себя язык, формат представления дат и многое другое.
Как это было в Ada
В Ada это было криво, но интересно. Существовал базовый набор CHARACTER, но можно было создавать и свои символьные типы, просто перечисляя значения.
(Ada) Type MyChar is (' ', '0', '1', ... , '9', 'A', ...);
Трасформационные форматы
UNICODE всем хорош, но как правило пересылая по сети символы ASCII-7, мы очень много теряем в производительности. Для борьбы с этим был разработан UTF (UCS Transformation Format).
UTF-7 представяет Unicode через серию 0-127.
UTF-8
- значения 0-127 (7 значащих бит)
- преобразуется в 1 байт
- [0][7 бит]
- значения 128-2047 (11 значащих бит)
- преобразуется в 2 байта
- [110][5 бит] [10][6 бит]
- значения 2048-65535 (16 значащих бит)
- преобразуется в 3 байта
- [1110][4 бит] [10][6 бит] [10][6 бит]
Также существует UTF-16 для представления UCS.
Все это - вопрос окружения, а не языка. Отличный пример этому - взаимодействие Motif—Xt—Xlib. Cтрока создается, пересылается, обрабатывается, не задумываясь о Transformation Format.
(C) XmCreateString("String", ...);
Пункт 6. Порядковые (ограниченные) типы данных
Порядковые типы данных (также называются ограниченными) бывают двух видов:
- перечислимые типы (будут рассмотрены в этой лекции)
- диапозоны (будут рассмотрены в следующей лекции)
Перечислимые типы
Множество абстрактных именованных значений, упорядоченных слева направо.
(Pascal) type DOW = (Monday, Tuesday, …);
(Ada) type Color is (Red,Green, …);
Операции:
- Переход к предыдущему/следующему элементу
(Pascal) v = pred(v); v = suxx(v);
- Преобразование в целый тип и обратно
(Modula-2) T v; i = ord(v); v = val(T,i);
В Ada реализовано как статическое, так и квазистатическое преобразование.
Перечеслимые типы появились впервые вроде бы в Pascal. После этого так или иначе реализовано почти во всех языках. В том числе и в C.
(C) enum DOW {MONDAY, TUESDAY, …};
Это почти то же самое, что и:
(C) #define DOW int #define MONDAY 0 #define TUESDAY 1 …
При этом разрешены неявные преобразования (будет warning)
(C) DOW d; int i; d = i; i = d;
И даже так:
(C) d = -1;
Вот это уже возмутительно и для программирования не пригодно. Потому и не принято пользовать. Впрочем C за это ругать не стоит. Зачем ассемблеру ограничивать программиста? Впрочем, в C++ этот опыт учли:
- Перегрузка имен работает
(C++) void f(); void f(T1); void f(T2); void f(int);
- Неявное преобразование из int запретили
(C++) i = e; e = (T)i;
- Плюс была внедрена очень полезная вещь:
(C++) enum Color { RED = 0xFF0000; GREEN = 0x00FF00; BLUE = 0x0000FF; … }
Поэтому в C++ перечислимый тип пользуют куда чаще, чем в C.
Впрочем, не везде все так радужно.
- В Modula-2 возможен конфликт имен, т.к. при импортировании типа мы импортируем еще и константы.
(Modula-2) FROM M IMPORT T;
- Oberon — язык системного программирования, там баги и конфликты не нужны. Потому там от перечислимого типа отказались.
- В Ada эти конфликты просто разрешили, что тоже до добра не доводит.
Помимо конфликта имен есть еще один сурьезный минус: перечислимый тип наследуется, но не расширяется, что не соответствует концепции ООП.
(С++) class X { enum T { … }; virtual T f(); }
Поэтому в Java перечислимого типа нет. Но в C# от него не отказались. Более того, придумали замечательную аргументацию, зачем же он нужен. В современном программировании язык и среда разработки бывают тесно связаны. Компонентный подход, при котором на формочку размещают кнопочки, выбирают в меню их свойства и автоматически генерят большую часть кода, весьма популярен.
(параметры среды разработки) OpenMode OM_READ OM_WRITE OM_RW
В 1980-х наметилась тенденция разделения реализации и определения.
(Eiffel) class X { void f(); } void x::f(){ … }
В соответствиии с этими условиями в C# найдено решение проблемы конфликта имен.
(C#) enum C {C1,C2,C3}; C x; x=C.C1; /* по-другому никак */
(C#) [flags] enum Mode { R=1, W=2, RW=R or W }
Языки Программирования
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
Календарь
чт | вт | чт | вт | чт | вт | чт | вт | чт | вт | |
Сентябрь
| 05 | 07 | 12 | 14 | 19 | 21 | 26 | 28 | ||
Октябрь
| 03 | 05 | 10 | 12 | 17 | 19 | 24 | 26 | 31 | |
Ноябрь
| 02 | 14 | 16 | 21 | 23 | 28 | 30 | |||
Декабрь
| 05 | 07 | 12 | 14 | 19 |