В.В. Кулямин - Технологии программирования. Компонентный подход (1134162), страница 43
Текст из файла (страница 43)
Оба языка достаточносложны, и всем их деталям просто невозможно уделить внимание в рамках двух лекций. Для болееглубокого изучения этих языков (особенно необходимого при разработке инструментов дляработы с ними) рекомендуется обратиться к соответствующим стандартам [7] и [8] (ссылкиприведены на последние версии стандартов на момент написания этой лекции, кроме тогонекоторые элементы C# 2.0 не вошли в [8], они описываются согласно [9]).Оба языка имеют мощные выразительные возможности объектно-ориентированных языковпоследнего поколения, поддерживающих автоматическое управление памятью и работу вмногопоточном режиме.
Они весьма похожи, но имеют большое число мелких отличий в деталях.Наиболее существенны для построения программ различия, касающиеся наличия в C#невиртуальных методов, возможности объявления и использования пользовательских типовзначений и делегатных типов в C# и возможности передачи значений параметров в C# по ссылке.Обсуждение и одновременно сравнение характеристик языков мы будем проводить последующему плану.1. Лексика2.
Общая структура программ3. Базовые типы и операции над ними4. Инструкции и выражения5. Пользовательские типы6. Средства создания многопоточных программОбщие черты Java и C# описываются далее обычным текстом, а особенности — в колонках.В левой колонке будут описыватьсяособенности Java.В правой колонке будут описыватьсяособенности C#.ЛексикаПрограммы на обоих рассматриваемых языках, C# и Java, могут быть написаны сиспользованием набора символов Unicode, каждый символ в котором представляется при помощи16-ти бит. Поскольку последние версии стандарта Unicode [10] определяют более широкоемножество символов, включая символы от U+10000 до U+10FFFF (т.е. имеющие коды от 216 до220+216-1), такие символы представляются в кодировке UTF-16, т.е. двумя 16-битными символами,первый в интервале U+D800–U+DBFF, второй — U+DC00–U+DFFF.Лексически программы состоят из разделителей строк (символы возврата каретки, переводастроки или их комбинация), комментариев, пустых символов (пробелы и табуляции),идентификаторов, ключевых слов, литералов, операторов и разделительных символов.В обоих языках можно использовать как однострочный комментарий, начинающийся ссимволов // и продолжающийся до конца строки, так и выделительный, открывающийсясимволами /* и заканчивающийся при помощи */.Идентификаторы должны начинаться с буквы (символа, который считается буквой в Unicode,или символа _) и продолжаться буквами или цифрами.
В качестве символа идентификатора можетиспользоваться последовательность \uxxxx, где x — символы 0-9, a-f или A-F, обозначающаясимвол Unicode c шестнадцатеричным кодом xxxx. Корректными идентификаторами являются,например, myIdentifier123, αρετη_µυσ, идентификатор765 (если последние два представлены вUnicode). Ключевые слова устроены также (без возможности использовать Unicode140последовательности в C#), но используются для построения деклараций, инструкций и выраженийязыка или для обозначения специальных констант.В Java ключевые слова не могут использоватьсяв качестве идентификаторов.Добавив в начало ключевого слова символ @, вC# можно получить идентификатор,посимвольно совпадающий с этим ключевымсловом.
Этот механизм используется дляобращения к элементам библиотек .NET,написанным на других языках, в которых могутиспользоваться такие идентификаторы —@class, @int, @public и пр.Можно получать идентификаторы, добавляя @ ив начало идентификатора, но делать это нерекомендуется стандартом языка.Другой способ получить идентификатор,совпадающий по символам с ключевым словом,— использовать в нем Unicodeпоследовательность вместо соответствующегосимвола ASCII.Кроме того, в C# есть специальныеидентификаторы, которые только в некоторомконтексте используются в качестве ключевыхслов. Таковы add, alias, get, global, partial,remove, set, value, where, yield.В обоих языках имеется литерал null для обозначения пустой ссылки на объект, булевскиелитералы true и false, символьные и строковые литералы, целочисленные литералы и литералы,представляющие числа с плавающей точкой.Символьный литерал, обозначающий отдельный символ, представляется как этот символ,заключенный в одинарные кавычки (или апострофы).
Так, например, можно представить символы'a', '#', 'Ы'. Чтобы представить символы одинарной кавычки, обратного слэша и некоторыедругие используются так называемые ESC-последовательности, начинающиеся с обратного слэша— '\'' (одинарная кавычка), '\\' (обратный слэш), '\"' (обычная кавычка), '\n' (переводстроки), '\r' (возврат каретки), '\t' (табуляция). Внутри одинарных кавычек можноиспользовать и Unicode-последовательности, но осторожно — если попытаться представить так,например, символ перевода строки \u000a, то, поскольку такие последовательности заменяютсясоответствующими символами в самом начале лексического анализа, кавычки будут разделеныпереводом строки, что вызовет ошибку.В Java можно строить символьные литералы ввиде восьмеричных ESC-последовательностейиз не более чем трех цифр — '\010', '\142','\377'.
Такая последовательность можетпредставлять только символы из интервалаU+0000–U+00FF.В C# можно использовать шестнадцатеричныеESC-последовательности из не более чемчетырех цифр для построения символьныхлитералов. Такая последовательностьобозначает Unicode-символ с соответствующимкодом.Строковые литералы представляются последовательностями символов (за исключениемпереводов строк) в кавычках. В качестве символов могут использоваться и ESCпоследовательности, разрешенные в данном языке. Строковый литерал может быть разбит нанесколько частей, между которыми стоят знаки +.
Значения литералов "Hello, world" и "Hello,"+ " world" совпадают.В C# можно строить буквальные строковыелитералы (verbatim string literals), в которыхESC-последовательности и Unicode141последовательности не преобразуются в ихзначения. Для этого нужно перед открывающейкавычкой поставить знак @. В такой строкемогут встречаться любые символы, кроме ".Чтобы поместить туда и кавычку, надоповторить ее два раза.Например, "Hello \t world" отличается от@"Hello \t world", а "\"" совпадает с @"""".Целочисленные литералы представляют собой последовательности цифр, быть может, сознаком — 1234, -7654.
Имеются обычные десятичные литералы и шестнадцатеричные,начинающиеся с 0x или 0X. По умолчанию целочисленные литералы относятся к типу int.Целочисленные литералы, имеющие тип длинного целого числа long, оканчиваются на букву lили L.В Java имеются также восьмеричныецелочисленные литералы, которые начинаютсяс цифры 0.В C#, в отличие от Java, имеются беззнаковыецелочисленные типы uint и ulong. Литералыэтих типов оканчиваются на буквы u или U, и налюбую комбинацию букв u/U и l/L,соответственно.Литералы, представляющие числа с плавающей точкой, могут быть представлены в обычнойзаписи (3.1415926) или экспоненциальной (314.15926e-2 и 0.31415926e1).
По умолчанию такиелитералы относятся к типу double, и могут иметь в конце символ d или D. Литералы типа floatоканчиваются буквами f или F.В Java литералы с плавающей точкой могутиметь шестнадцатеричное представление сдвоичной экспонентой. При этом литералначинается с 0x или 0X, экспонента должнабыть обязательно и должна начинаться с буквыp или P.В C# есть тип с плавающей точкой decimal дляболее точного представления чисел прифинансовых расчетах.
Литералы этого типаоканчиваются на букву m или M.Операторы и разделители обоих языков:(===&&)<<=||{>>=++}!!=--Дополнительные операторы Java:>>>>>>=[++=<<]-=>>;**=<<=,//=>>=.%%=:&&=?||=~^^=Дополнительные операторы C#:->::??В C#, помимо ранее перечисленныхлексических конструкций, имеются директивыпрепроцессора, служащие для управлениякомпиляцией. Директивы препроцессора немогут находиться внутри кавычек, начинаютсясо знака # и пишутся в отдельной строке, эта жестрока может заканчиваться комментарием.Директивы #define и #undef служат для того,чтобы определять и удалять опции дляусловной компиляции (такая опция может бытьпроизвольным идентификатором, отличным отtrue и false).Директивы #if, #elif, #else и #endif служат142для того, чтобы вставлять в код и выбрасыватьиз него некоторые части в зависимости отдекларированных с помощью предыдущихдиректив опций.
В качестве условий,проверяемых директивами #if и #elif, могутиспользоваться выражения, составленные изопций и констант true и false при помощискобок и операций &&, ||, ==, !=.Напримерusing System;#define Debugpublic class Assert{public void Assert (bool x){#if Debugif(!x) thrownew Exception("Assert failed");#endif}}Директивы #error и #warning служат длягенерации сообщений об ошибках ипредупреждениях, аналогичных таким жесообщениям об ошибках компиляции. Вкачестве сообщения выдается весь текст,следующий в строке за такой директивой.Директива #line служит для управлениямеханизмом сообщений об ошибках с учетомстрок. Вслед за такой директивой в той жестроке может следовать число, число и имяфайла в кавычках или слово default.