sdt-book-2006 (1133574), страница 42
Текст из файла (страница 42)
Таковы 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. В первомслучае компилятор считает, что строка,следующая после строки с этой директивой,имеет указанный номер, во втором — помимономера строки в сообщениях изменяется имяфайла, в третьем компилятор переключается врежим по умолчанию, забывая об измененныхномерах строк.Директива #pragma warning, добавленная вC# 2.0, служит для включения или отключенияпредупреждений определенного вида прикомпиляции. Она используется в виде#pragma warning disable n_1, …, n_k#pragma warning restore n_1, …, n_kгде n_1, … , n_k — номера отключаемых/включаемых предупреждений.Общая структура программыПрограмма на любом из двух рассматриваемых языков представляет собой наборпользовательских типов данных — в основном, классов и интерфейсов, с их методами.
Призапуске программы выполняется определенный метод некоторого типа. В ходе работы программы143создаются объекты различных типов и выполняются их методы (операции над ними). Объектамиособого типа представляются различные потоки выполнения, которые могут быть запущеныпараллельно.Во избежание конфликтов по именам и для лучшей структуризации программпользовательские типы размещаются в специальных пространствах имен, которые в Javaназываются пакетами (packages), а в C# пространствами имен (namespaces). Имена пакетов ипространств имен могут состоять из нескольких идентификаторов, разделенных точками.
Излюбого места можно сослаться на некоторый тип, используя его длинное имя, состоящее из именисодержащего его пространства имен или пакета, точки и имени самого типа.В обоих случаях программный код компилируется в бинарный код, исполняемый виртуальноймашиной. Правила размещения исходного кода по файлам несколько отличаются.Код пользовательских типов Java размещается вфайлах с расширением .java.При этом каждый файл относится к томупакету, чье имя указывается в самом началефайла с помощью декларации packagemypackage;При отсутствии этой декларации код такогофайла попадает в пакет с пустым именем.Код пользовательских типов C# размещается вфайлах с расширением .cs.Декларация пространства имен начинается сконструкции namespace mynamespace { изаканчивается закрывающей фигурной скобкой.Все типы, описанные в этих фигурных скобках,попадают в это пространство имен. Типы,описанные вне декларации пространства имен,попадают в пространство имен с пустымименем.Пространства имен могут быть вложены вдругие пространства имен.
При этомследующие декларации дают эквивалентныерезультаты.namespace A.B { … }namespace A{namespace B { … }}В одном файле может быть описан только одинобщедоступный (public) пользовательский типверхнего уровня (т.е. не вложенный в описаниедругого типа), причем имя этого типа должносовпадать с именем файла без расширения.В том же файле может быть декларированосколько угодно необщедоступных типов.Пользовательский тип описывается полностьюв одном файле.В одном файле можно декларировать многотипов, относящихся к разным пространствамимен, элементы одних и тех же пространствимен могут описываться в разных файлах.Чтобы ссылаться на типы, декларированные вдругих пакетах, по их коротким именам, можновоспользоваться директивами импорта.Если в начале файла после декларации пакетаприсутствует директиваПользовательский тип описывается целиком водном файле, за исключением частичных типов(введены в C# 2.0), помеченных модификаторомpartial — их элементы можно описывать вразных файлах, и эти описания объединяются,если не противоречат друг другу.Чтобы ссылаться на типы, декларированные вдругих пространствах имен, по их короткимименам, можно воспользоваться директивамииспользования.Директиваimport java.util.ArrayList;using System.Collections;то всюду в рамках этого файла можноссылаться на тип ArrayList по его короткомуделает возможным ссылки с помощьюкороткого имени на любой тип (или вложенное144имени.Если же присутствует директиваimport java.util.*;то в данном файле можно ссылаться на любойтип пакета java.util по его короткому имени.Директиваimport static java.lang.Math.cos;(введена в Java 5) позволяет в рамках файлавызывать статический метод cos() классаjava.lang.Math просто по его имени, безуказания имени объемлющего типа.Во всех файлах по умолчанию присутствуетдирективапространство имен) пространства именSystem.Collections в рамках кодапространства имен или типа, содержащего этудирективу или в рамках всего файла, еслидиректива не вложена ни в какое пространствоимен.Можно определять новые имена (синонимы илиалиасы) для декларированных извне типов ипространств имен.
Например, директиваusing Z=System.Collections.ArrayList;позволяет затем ссылаться на типSystem.Collections.ArrayList по имени Z.import java.lang.*;Таким образом, на типы из пакета java.langможно ссылаться по их коротким именам (если,конечно, в файле не декларированы типы стакими же именами — локальнодекларированные типы всегда имеютпреимущество перед внешними).Файлы должны располагаться в файловойсистеме определенным образом.Выделяется одна или несколько корневыхдиректорий, которые при компиляцииуказываются в опции -sourcepathкомпилятора. Файлы из пакета без именидолжны лежать в одной из корневыхдиректорий.
Все остальные должны находитьсяв поддиректориях этих корневых директорийтак, чтобы имя содержащего пакета, к которомуфайл относится, совпадало бы с именемсодержащей сам файл директории относительновключающей ее корневой (с заменой точки наразделитель имен директорий).Результаты компиляции располагаются вфайлах с расширением .class, по одному типу нафайл. Хранящие их директории организуютсяпо тому же принципу, что и исходный код, — всоответствии с именами пакетов, начиная отнекоторого (возможно другого) наборакорневых директорий. Указать компиляторукорневую директорию, в которую нужноскладывать результаты компиляции, можно спомощью опции -d.Чтобы эти типы были доступны прикомпиляции других, корневые директории,содержащие соответвующие им .class файлы,должны быть указаны в опции компилятора classpath.В этой же опции могут быть указаны архивныефайлы с расширением .jar, в которых многоНет никаких ограничений на именованиефайлов и содержащихся в них типов, а также нарасположение файлов в файловой системе иимена декларированных в них пространствимен.Результат компиляции C# программы —динамически загружаемая библиотека (срасширением .dll в системе Windows) илиисполняемый файл (.exe), имеющие особуюструктуру.