Редактирование: Сравнение Языков Программирования
Материал из eSyr's wiki.
Внимание: Вы не представились системе. Ваш IP-адрес будет записан в историю изменений этой страницы.
ПРЕДУПРЕЖДЕНИЕ: Длина этой страницы составляет 130 килобайт. Страницы, размер которых приближается к 32 КБ или превышает это значение, могут неверно отображаться в некоторых браузерах. Пожалуйста, рассмотрите вариант разбиения страницы на меньшие части.
Правка может быть отменена. Пожалуйста, просмотрите сравнение версий, чтобы убедиться, что это именно те изменения, которые вас интересуют, и нажмите «Записать страницу», чтобы изменения вступили в силу.
Текущая версия | Ваш текст | ||
Строка 1: | Строка 1: | ||
На этой страничке собираются материалы, которые могут помочь при подготовке к экзамену по языкам программирования. | На этой страничке собираются материалы, которые могут помочь при подготовке к экзамену по языкам программирования. | ||
- | ЯП из курса: C, C++, Java, C#, Pascal, Delphi, Оберон-2, Модула-2, Ада (83 и 95 стандарты) | + | ЯП из курса: C, C++, Java, C#, Pascal, Delphi, Оберон-2, Модула-2, Ада (83 и 95 стандарты) |
Полезные ссылки: | Полезные ссылки: | ||
- | * [[w:Сравнение языков программирования|Сравнение ЯП в википедии]] | ||
- | * [http://progopedia.ru/ Энциклопедия языков программирования] | ||
- | * [http://citforum.ru/programming/cpp/aglav.shtml Книжка Страуструпа] | ||
- | * [https://habrahabr.ru/post/161205/ Ликбез по типизации в языках программирования / Хабрахабр] | ||
- | План (краткий, взят из методички Головина, подробный см. в самой [ | + | [http://ru.wikipedia.org/wiki/%D1%F0%E0%E2%ED%E5%ED%E8%E5_%FF%E7%FB%EA%EE%E2_%EF%F0%EE%E3%F0%E0%EC%EC%E8%F0%EE%E2%E0%ED%E8%FF Сравнение ЯП в википедии] |
+ | |||
+ | [http://progopedia.ru/ Энциклопедия языков программирования] | ||
+ | |||
+ | [http://home.perm.ru/strannik/st_txt_prog_02.html/ Немножно рекламное сравнения большинства языков] | ||
+ | |||
+ | [http://citforum.ru/programming/cpp/aglav.shtml Книжка Страуструпа] | ||
+ | |||
+ | План (краткий, взят из методички Головина, подробный см. в самой [http://cmcmsu.no-ip.info/download/pl.exam.variants.pdf методичке]): | ||
== Базисные типы данных в языках программирования: простые и составные типы данных, операции над ними == | == Базисные типы данных в языках программирования: простые и составные типы данных, операции над ними == | ||
Строка 18: | Строка 22: | ||
; Character: Как я понял, существует несколько разновидностей (зависит от размера) и является особым перечислимым типом (Enumeration) | ; Character: Как я понял, существует несколько разновидностей (зависит от размера) и является особым перечислимым типом (Enumeration) | ||
; String: Массив '''Character''' фиксированной длины. Так же есть стандартные пакеты, реализующие строки квазистатической и динамической длины. | ; String: Массив '''Character''' фиксированной длины. Так же есть стандартные пакеты, реализующие строки квазистатической и динамической длины. | ||
- | ; Floating point: Эти типы обычно определяются вручную в виде конструкции, где Num_Digits указывает | + | ; Floating point: Эти типы обычно определяются вручную в виде конструкции, где Num_Digits указывает минимальную (минимально допустимую?) погрешность: |
'''digits''' Num_Digits | '''digits''' Num_Digits | ||
Строка 58: | Строка 62: | ||
Mother: Person_Access := '''new''' Person'(Mothers_First_Name, Mothers_Last_Name); ''-- инициализованно'' | Mother: Person_Access := '''new''' Person'(Mothers_First_Name, Mothers_Last_Name); ''-- инициализованно'' | ||
- | Тип Access - это высокоуровневый указатель, представленный записью с полями. Например, | + | Тип Access - это высокоуровневый указатель, представленный записью с полями. Например, разименовать указатель можно следующим образом: |
Mother.'''all'''.Last_Name = Father.'''all'''.Last_Name ''-- здесь, Mother.'''all''' имеет тип Person; | Mother.'''all'''.Last_Name = Father.'''all'''.Last_Name ''-- здесь, Mother.'''all''' имеет тип Person; | ||
Строка 71: | Строка 75: | ||
Есть еще очень много интересного по этой теме. Все было взято [http://en.wikibooks.org/wiki/Ada_Programming/Types/access тут]. | Есть еще очень много интересного по этой теме. Все было взято [http://en.wikibooks.org/wiki/Ada_Programming/Types/access тут]. | ||
- | === ОБЕРОН и ОБЕРОН-2 === | + | === ОБЕРОН и ОБЕРОН-2: === |
; Отличия: | ; Отличия: | ||
Строка 131: | Строка 135: | ||
** Целые числа: | ** Целые числа: | ||
*** Знаковые: byte, short, int, long (8-, 16-, 32-, 64-битные). | *** Знаковые: byte, short, int, long (8-, 16-, 32-, 64-битные). | ||
- | *** Беззнаковый 16-битный: char (код символа в UTF-16 | + | *** Беззнаковый 16-битный: char (код символа в UTF-16). |
** Числа с плавающей точкой: float, double (32-, 64-битные; IEEE 754). | ** Числа с плавающей точкой: float, double (32-, 64-битные; IEEE 754). | ||
Строка 139: | Строка 143: | ||
Также существует специальный тип null. | Также существует специальный тип null. | ||
- | Объектом в Java считается экземпляр класса или массив. Значением ссылочного типа является ссылка на объект (или специальное значение null). | + | Объектом в Java считается экземпляр класса или массив. Значением ссылочного типа является ссылка на объект (или специальное значение null). Все объекты (включая массивы) обладают методами класса Object (java.lang.Object) (иначе говоря, с т.з. Java-программиста все объекты *наследуют* методы класса Object). Строковые литералы (например, "Hello world!") являются объектами типа String (== экземплярами класса String). |
- | + | ||
- | Все объекты (включая массивы) обладают методами класса Object (java.lang.Object) (иначе говоря, с т. з. Java-программиста все объекты *наследуют* методы класса Object). Строковые литералы (например, "Hello world!") являются объектами типа String ( | + | |
Операции над простыми типами почти идентичны C/C++, однако могут выбрасывать исключения. Конкатенация строк: "Hello " + "world!" (может принимать в качестве одного из аргументов не только строку, но и любой из целых типов). | Операции над простыми типами почти идентичны C/C++, однако могут выбрасывать исключения. Конкатенация строк: "Hello " + "world!" (может принимать в качестве одного из аргументов не только строку, но и любой из целых типов). | ||
Строка 148: | Строка 150: | ||
=== C++ === | === C++ === | ||
- | |||
; Целые типы: | ; Целые типы: | ||
: char - размер как для хранения символа, определяется машиной (обычно байт) | : char - размер как для хранения символа, определяется машиной (обычно байт) | ||
Строка 164: | Строка 165: | ||
sizeof(float) <= sizeof(double) <= sizeof(long double) | sizeof(float) <= sizeof(double) <= sizeof(long double) | ||
- | + | <b>const</b> <тип> <имя_переменной> = <значение>; | |
// Значение переменной не может изменяться после инициализации (инициализация обязательна). | // Значение переменной не может изменяться после инициализации (инициализация обязательна). | ||
Строка 229: | Строка 230: | ||
== Массивы == | == Массивы == | ||
- | === Длина массива | + | === Длина массива - статический или динамический атрибут. === |
- | + | <b>Си++</b>: длина массива - только статический атрибут. <br> | |
- | + | <b>Оберон</b>, <b>Модула-2</b>: динамический атрибут только для формальных параметров, в остальных случаях - статический. <br> | |
- | + | <b>Ада</b>, <b>Java</b>, <b>C#</b>: может быть и тем и другим. <br> | |
<br> | <br> | ||
- | + | <b>Замечание из методички</b>: <br> | |
в языках Оберон и Модула-2 длина формальных параметров — открытых массивов является динамическим атрибутом. <br> | в языках Оберон и Модула-2 длина формальных параметров — открытых массивов является динамическим атрибутом. <br> | ||
В других случаях длина массива — статический атрибут. <br> | В других случаях длина массива — статический атрибут. <br> | ||
В Аде формальные параметры неограниченных типов-массивов также имеют динамический атрибут-длину (равно как и динамические массивы-локальные переменные). <br> | В Аде формальные параметры неограниченных типов-массивов также имеют динамический атрибут-длину (равно как и динамические массивы-локальные переменные). <br> | ||
<br> | <br> | ||
- | + | <b>Пример</b> динамического массива в языке Java (или C#): | |
void f(int N) { | void f(int N) { | ||
byte [] dynArray = new byte [N]; | byte [] dynArray = new byte [N]; | ||
Строка 322: | Строка 323: | ||
== Преобразование типов == | == Преобразование типов == | ||
=== Явное преобразование типов === | === Явное преобразование типов === | ||
- | Преобразование типов называется | + | Преобразование типов называется <i>явным,</i> если оно указано программистом в исходном коде. |
=== Неявное преобразование типов === | === Неявное преобразование типов === | ||
+ | Преобразование типов называется <i>неявным,</i> если оно не указывается программистом, но, тем не менее, выполняется (в языках со статической типизацией — подставляется на этапе компиляции). В языках <b>C#</b> и <b>Java</b> неявными могут быть только расширяющие преобразования; в <b>С++</b> — любые преобразования. | ||
- | + | === Понятия <i>conversion</i> и <i>casting</i> === | |
- | + | В большинстве языков, основанных на базе <b>Algol</b> и обладающих механизмом вложенных функций - например, в <b>Ada, Delphi, Modula 2</b> и <b>Pascal,</b> понятия <i>conversion</i> и <i>casting</i> принципиально различны. Понятие <i>conversion</i> относится к явному или неявному изменению значения одного типа данных на значение другого типа данных (например, расширение 16-битного целого до 32-битного). В этом случае, могут измениться требования к объёму выделенной памяти; могут возникнуть потери точности или округления. Понятие <i>casting,</i> напротив, обозначает <i>явное</i> изменение интерпретации <i>последовательности бит.</i> Например, последовательность из 32 бит может быть интерпретирована как целое без знака, как массив из 32 значений типа boolean или как вещественное число c одинарной точностью, соответствующее стандарту IEEE. | |
- | + | В <b>C-подобных</b> языках, понятием <i>casting</i> обозначается явное приведение типа в независимости от того, является ли оно изменением интерпретации последовательности бит, либо же настоящим преобразованием типа. | |
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | В большинстве языков, основанных на базе | + | |
- | В | + | |
=== Упаковка и распаковка === | === Упаковка и распаковка === | ||
- | Данные понятия определены для языков | + | Данные понятия определены для языков <b>C#</b> и <b>Java.</b> |
- | : | + | : <i>Упаковкой (boxing)</i> называется процесс преобразования значения простого типа значения в экземпляр соответствующего класса-оболочки. |
- | : | + | : <i>Распаковкой (unboxing)</i> называется, очевидно, процесс преобразования экземпляра класса-оболочки в значение соответствующего простого типа. |
- | + | ||
==== C# ==== | ==== C# ==== | ||
- | В | + | В <b>C#</b> упаковка и распаковка выполняются автоматически. |
Пример упаковки и распаковки: | Пример упаковки и распаковки: | ||
Строка 412: | Строка 346: | ||
==== Java ==== | ==== Java ==== | ||
- | В | + | В <b>Java</b> автоупаковка и автораспаковка поддерживаются начиная с J2SE 5.0 (сентябрь 2004 года). |
Пример упаковки и распаковки: | Пример упаковки и распаковки: | ||
Строка 423: | Строка 357: | ||
==== Другие языки ==== | ==== Другие языки ==== | ||
- | В некоторых языках упаковка и распаковка отсутствуют. Например, в | + | В некоторых языках упаковка и распаковка отсутствуют. Например, в <b>Smalltalk</b> любое значение принадлежит некоторому классу (т.е. даже значения простых типов являются экземплярами классов). Немного по другой причине этих операций нет и в <b>JavaScript</b>: в этом языке отсутствует понятие "класс", т.к. он является прототипным. |
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
== Операторный базис языков программирования. Управление последовательностью вычислений == | == Операторный базис языков программирования. Управление последовательностью вычислений == | ||
=== ADA === | === ADA === | ||
- | + | Джентльменский набор: | |
+ | |||
'''if''' condition '''then''' | '''if''' condition '''then''' | ||
statement; | statement; | ||
Строка 496: | Строка 422: | ||
=== ОБЕРОН И ОБЕРОН-2 === | === ОБЕРОН И ОБЕРОН-2 === | ||
- | + | ОператорIf = | |
- | + | ||
- | + | ||
IF Выражение THEN ПоследовательностьОператоров | IF Выражение THEN ПоследовательностьОператоров | ||
{ELSIF Выражение THEN ПоследовательностьОператоров} | {ELSIF Выражение THEN ПоследовательностьОператоров} | ||
Строка 505: | Строка 429: | ||
CASE ch OF | CASE ch OF | ||
- | "A" .. "Z": ReadIdentifier | + | "A" .. "Z": ReadIdentifier |
- | "0" .. "9": ReadNumber | + | | "0" .. "9": ReadNumber |
- | "'", '"': ReadString | + | | "'", '"' : ReadString |
ELSE SpecialCharacter | ELSE SpecialCharacter | ||
- | END | + | END |
WHILE Выражение DO | WHILE Выражение DO | ||
Строка 519: | Строка 443: | ||
UNTIL Выражение. | UNTIL Выражение. | ||
- | FOR v := | + | FOR v := beg TO end BY step DO statements END (В Оберон-2) |
- | + | ||
- | + | ||
- | + | ||
- | LOOP | + | LOOP ПоследовательностьОператоров END. |
- | + | ||
- | + | ||
- | + | ||
- | WITH | + | WITH v: T1 DO S1 | v: T2 DO S2 ELSE S3 END (В Оберон-2) |
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
=== for в C# и Java === | === for в C# и Java === | ||
Строка 711: | Строка 477: | ||
== Процедурные абстракции == | == Процедурные абстракции == | ||
- | |||
- | === Передача параметров в подпрограммы === | ||
- | |||
- | Для каждой подпрограммы указывается набор формальных параметров. Можно рассматривать формальные параметры как локальные переменные тела подпрограммы. При вызове подпрограммы указывается список фактических параметров. Соответствие между фактическими и формальными параметрами выполняется по позиции в списке: первый фактический параметр соответствует первому формальному параметру и т. д. Такой способ называется ''позиционным''. Язык С#, начиная с версии 4, предусматривает альтернативный — ''ключевой'' способ отождествления, в котором используются имена формальных параметров, но мы не будем его рассматривать. Существует три вида формальных параметров: | ||
- | * входные параметры (параметры, от которых требуется только значение). Мы используем только значения фактических параметров, которые не меняются при выходе из тела функции; | ||
- | * выходные параметры (эти параметры не обязаны иметь начальное значение, но могут быть изменены в теле функции); | ||
- | * изменяемые параметры (требуется и исходное значение, и возможность его изменения). | ||
- | |||
- | С входным параметром может связываться произвольное выражение, а выходным или изменяемым — только объекты, которые могут стоять в левой части оператора присваивания. В большинстве языков программирования вместо указания вида параметра указывается способ (механизм) связывания параметра, называемый способом передачи параметра. | ||
- | |||
- | Существует два основных способа передачи параметров: ''по значению'' и ''по ссылке''. | ||
- | |||
- | ==== Передача параметров по значению ==== | ||
- | |||
- | Формальный параметр есть некоторая локальная переменная. Место для локальных переменных отводится в стеке. При вызове подпрограммы значение фактического параметра копируется в соответствующий формальный параметр. Все изменения формального параметра связаны с изменением локальной переменной и не сказываются на фактическом параметре. Перед копированием может потребоваться приведение типа, если типы фактического и формального параметров не совпадают. | ||
- | |||
- | ==== Передача параметров по ссылке ==== | ||
- | |||
- | Фактически этот способ есть передача ссылки по значению. Формальный параметр — это ссылка на объект. (Существует мнение, что данное «определение» не только не отражает сути явления, но и неверно в корне. В дискуссии вокруг передачи аргументов в Java Dale King [http://www.yoda.arachsys.com/java/passing.html дал] следующее определение. ''Передача по ссылке — это когда lvalue формального параметра устанавливается в lvalue фактического параметра.'') В момент вызова происходит инициализация ссылки фактическим параметром. Преобразования типов в этот момент не происходит: типы формального и фактического параметров должны совпадать. Поскольку ссылка после инициализации отождествляется с объектом, то любые изменения формального параметра подразумевают изменения фактического параметра. Очевидно, что способ передачи по значению соответствует семантике входных формальных параметров. По ссылке можно передавать выходные и изменяемые параметры. | ||
- | |||
- | ==== Аргументы в C/C++ всегда передаются по значению ==== | ||
- | |||
- | В C++ есть ссылочный тип. Переменная ссылочного типа может ссылаться на значение любого типа, должна быть инициализирована и не может менять значения. С помощью передачи переменной ссылочного типа можно имитировать все возможности контрукции var из '''Pascal'''. Но можно действовать в стиле C — передавать указатель. В свою очередь, чтобы менять указатель, можно передавать в функцию/метод указатель или ссылку на него. | ||
- | |||
- | ==== Аргументы в Java всегда передаются по значению ==== | ||
- | |||
- | Существует распространённое '''заблуждение''' о том, что «объекты передаются по ссылке, а примитивные типы — по значению». | ||
- | '''На самом деле''' ситуация иная: | ||
- | # Аргументы любого типа передаются по значению. Объекты, однако, не передаются вообще. | ||
- | # Значения переменных всегда примитивы или ссылки (или null), но никак не объекты. | ||
- | Подробнее см. http://www.yoda.arachsys.com/java/passing.html . | ||
- | |||
- | В соответствии с изложенным выше, метод может изменить объект через аргумент-ссылку. С примитивным типом это не пройдёт, так как в Java нет ссылок на значения примитивных типов. Чтобы иметь возможность изменить из метода значение некоторой внешней переменной примитивного типа, нужно чтобы эта переменная была полем некоторого объекта. | ||
- | |||
- | В связи с этим для примитивных типов были введены классы-обёртки. Объект такого класса содержит в себе значение примитивного типа, которое можно как прочитать, так и поменять. См. также [[Сравнение_Языков_Программирования#.D0.A3.D0.BF.D0.B0.D0.BA.D0.BE.D0.B2.D0.BA.D0.B0_.D0.B8_.D1.80.D0.B0.D1.81.D0.BF.D0.B0.D0.BA.D0.BE.D0.B2.D0.BA.D0.B0|Упаковка и распаковка]] | ||
=== Перегрузка операций === | === Перегрузка операций === | ||
Строка 752: | Строка 483: | ||
Понятие «перегрузка» (англ. overloading) означает, что одному имени в одной области видимости может соответствовать несколько определений. В современных языках программирования перегружаться могут только имена подпрограмм, но не типов, переменных, модулей. | Понятие «перегрузка» (англ. overloading) означает, что одному имени в одной области видимости может соответствовать несколько определений. В современных языках программирования перегружаться могут только имена подпрограмм, но не типов, переменных, модулей. | ||
- | Пример на языке | + | Пример на языке Си++: |
class X { | class X { | ||
public: | public: | ||
Строка 861: | Строка 592: | ||
При подключении потомка родитель-пакет подключается автоматически. | При подключении потомка родитель-пакет подключается автоматически. | ||
- | + | О подключениях. Подключить пакет можно с помощью конструкции '''with'''. | |
'''with''' Points.RandomDistributions; | '''with''' Points.RandomDistributions; | ||
После этого можно будет пользоваться ввсем, что в пакете лежит, через точечную нотацию. Если же вызовов слишком много, то можно влить содержимое пакета в текущую область видимости с помощью '''use''' (только после подключения!). | После этого можно будет пользоваться ввсем, что в пакете лежит, через точечную нотацию. Если же вызовов слишком много, то можно влить содержимое пакета в текущую область видимости с помощью '''use''' (только после подключения!). | ||
Строка 925: | Строка 656: | ||
==== Конструкторы ==== | ==== Конструкторы ==== | ||
- | Обычно выделяют следующие типы конструкторов: конструктор по умолчанию, конструктор копирования и конструктор преобразования | + | Обычно выделяют следующие типы конструкторов: конструктор по умолчанию, конструктор копирования и конструктор преобразования. |
- | ==== Деструкторы | + | ==== Деструкторы ==== |
- | Деструкторы | + | Деструкторы в C++ отличаются от деструкторов в Java и C# тем, что в C++ примерно установлено место в программе, в котором будет вызван деструктор (для объектов, выделенных в статической или квазистатической памяти) или он будет вызван вручную. В Java и C# время вызова деструктора не определено из-за наличия сборщика мусора. |
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | В | + | |
- | + | ||
==== Неявные контрукторы/деструкторы/операции в C++ ==== | ==== Неявные контрукторы/деструкторы/операции в C++ ==== | ||
Следующие элементы класса могут быть определены неявно: | Следующие элементы класса могут быть определены неявно: | ||
- | * | + | * Контруктор по умолчанию (если нет ни одного явно определённого конструктора). |
* Конструктор копирования (если конструктор копирования не описан явно). Осуществляет т.н. поверхностное копирование полей класса (бит в бит). | * Конструктор копирования (если конструктор копирования не описан явно). Осуществляет т.н. поверхностное копирование полей класса (бит в бит). | ||
* Деструктор (если деструктор не описан явно). Вызывает деструкторы объектов-полей (не полей-указателей!). | * Деструктор (если деструктор не описан явно). Вызывает деструкторы объектов-полей (не полей-указателей!). | ||
Строка 998: | Строка 720: | ||
FMyField := Value; | FMyField := Value; | ||
end; | end; | ||
- | |||
==== Статические классы ==== | ==== Статические классы ==== | ||
- | + | Под <i>статическим классом</i> понимается разновидность класса, все члены которого объявлены статическими. Как правило, у таких классов не описаны конструктор и деструктор. Использовать статические члены класса можно не создавая самого экземпляра класса. Понятие статического класса чаще всего используется в языках <b>C#</b> и <b>Java.</b> В этих языках невозможно создать экземпляр статического класса; также статический класс не может реализовывать интерфейсы. В <b>C#</b> любой статический класс наследуется от типа object. В <b>С++</b> понятие статического класса как таковое отсутствует. Имитировать статический класс можно либо создав класс, все члены которого объявлены статическими, и запретив создание его экземпляров с помощью модификатора доступа private перед конструктором; либо используя шаблон проектирования singleton - в таком случае, будет существовать <i>ровно один</i> экземпляр данного класса, и будет предоставлена глобальная точка доступа к данному экземпляру. | |
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
=== Объединение типов (запись с вариантами) === | === Объединение типов (запись с вариантами) === | ||
Строка 1067: | Строка 727: | ||
Объединение типов (или запись с вариантами) — это конструкция, объединяющая в один тип несколько различных структур (вариантов). Все варианты в объединении начинаются с одного адрес и занимают одну и ту же память. | Объединение типов (или запись с вариантами) — это конструкция, объединяющая в один тип несколько различных структур (вариантов). Все варианты в объединении начинаются с одного адрес и занимают одну и ту же память. | ||
- | Размеченное объединение типов содержит одно выделенное поле (дискретного типа данных) — общее для всех вариантов. Такое поле называется дискриминантом. Значение дискриминанта определяет, по какому варианту выделена память в переменной-экземпляре размеченного объединения | + | Размеченное объединение типов содержит одно выделенное поле (дискретного типа данных) — общее для всех вариантов. Такое поле называется дискриминантом (А не детерминантом? И ещё тут слово selector подсказывают.). Значение дискриминанта определяет, по какому варианту выделена память в переменной-экземпляре размеченного объединения. |
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
== Модульность и раздельная трансляция == | == Модульность и раздельная трансляция == | ||
Строка 1242: | Строка 878: | ||
== Исключительные ситуации и обработка ошибок == | == Исключительные ситуации и обработка ошибок == | ||
- | + | Исключения есть в Си++, Ада 83, Ада 95, Visual Basic, C#, Java, Delphi | |
- | + | ||
=== Исключения и блоки try {} catch {} finally {}. Семантика возобновления и семантика завершения. === | === Исключения и блоки try {} catch {} finally {}. Семантика возобновления и семантика завершения. === | ||
Строка 1304: | Строка 939: | ||
// Может выбрасывать любые исключения. | // Может выбрасывать любые исключения. | ||
- | Данные конструкции служат для того, чтобы показать программисту и компилятору, что данный метод (или, в случае C++, метод или функция) может выбрасывать исключения соответствующих типов. Насколько [[Участник:Totktonada|я]] понимаю, всё это влияет только на статические проверки компилятора и эстетические чувства программиста. В runtime эти декларации никак себя не проявляют, поэтому употребляемые здесь «может / не может выбрасывать исключение данного типа» и тому подобные обороты следует понимать в контексте статических проверок. | + | Данные конструкции служат для того, чтобы показать программисту и компилятору, что данный метод (или, в случае C++, метод или функция) может выбрасывать исключения соответствующих типов. Насколько [[Участник:Totktonada|я]] понимаю, всё это влияет только на статические проверки компилятора и эстетические чувства программиста. В runtime эти декларации никак себя не проявляют, поэтому употребляемые здесь «может / не может выбрасывать исключение данного типа» и тому подобные обороты следует понимать в контексте статических проверок. |
В Java считается, что метод, выбрасывающий исключение должен обозначить это с помощью конструкции throws. Иначе говоря, считается, что если директивы throws нет, то метод не выбрасывает исключений. Компилятор делает некоторые статические проверки, по крайней мере, запрещает выбрасывать исключения, не перечисленные в throws, явно — с помощью оператора throw. | В Java считается, что метод, выбрасывающий исключение должен обозначить это с помощью конструкции throws. Иначе говоря, считается, что если директивы throws нет, то метод не выбрасывает исключений. Компилятор делает некоторые статические проверки, по крайней мере, запрещает выбрасывать исключения, не перечисленные в throws, явно — с помощью оператора throw. | ||
В C++, в отличие от Java, если директива throw не задана, то считается, что данный метод или функция может выбрасывать любые исключения. Статические (времени компиляции) проверки делаются только для тех методов/функций, для которых указан (возможно пустой) список исключений. | В C++, в отличие от Java, если директива throw не задана, то считается, что данный метод или функция может выбрасывать любые исключения. Статические (времени компиляции) проверки делаются только для тех методов/функций, для которых указан (возможно пустой) список исключений. | ||
+ | |||
+ | |||
=== Одно из заданий экзамена по ЯПам === | === Одно из заданий экзамена по ЯПам === | ||
Строка 1349: | Строка 986: | ||
Do_Smth; | Do_Smth; | ||
'''end'''; | '''end'''; | ||
+ | |||
+ | '''finally-блока в Аде таки нету.''' Однако он [http://stackoverflow.com/questions/4804135/best-practice-for-implementing-in-ada-2005-or-2012-an-equivalent-of-the-java-f имитируется]. | ||
Отлов исключения так же может иметь такой вид: | Отлов исключения так же может иметь такой вид: | ||
Строка 1401: | Строка 1040: | ||
=== C# === | === C# === | ||
- | В | + | В <b>C#</b> к динамическому полиморфизму имеют отношение 3 важных ключевых слова (модификатора): |
- | : 1. | + | : 1. <b>virtual</b> |
- | : 2. | + | : 2. <b>override</b> |
- | : 3. | + | : 3. <b>new</b> |
==== virtual ==== | ==== virtual ==== | ||
- | Ключевое слово | + | Ключевое слово <b>virtual</b> используется для изменения объявлений методов, свойств, индексаторов и событий и разрешения их переопределения в производном классе. Например, этот метод может быть переопределен любым производным классом. Модификатор <b>virtual</b> нельзя использовать с модификаторами <b>static, abstract, private</b> или <b>override.</b> |
public virtual double Area() | public virtual double Area() | ||
Строка 1415: | Строка 1054: | ||
==== override ==== | ==== override ==== | ||
- | Модификатор | + | Модификатор <b>override</b> требуется для расширения или изменения абстрактной или виртуальной реализации унаследованного метода, свойства, индексатора или события. Иными словами, модификатор <b>override</b> <i>расширяет</i> метод базового класса. Метод, переопределенный c использованием <b>override,</b> называется переопределенным базовым методом. Переопределенный базовый метод должен иметь ту же сигнатуру, что и метод <b>override.</b> Невиртуальный или статический метод нельзя переопределить. Переопределенный базовый метод должен иметь тип <b>virtual, abstract</b> или <b>override.</b> Объявление <b>override</b> не может изменить уровень доступа метода <b>virtual.</b> Методы <b>override</b> и <b>virtual</b> должны иметь одинаковый модификатор уровня доступа. |
- | Модификаторы | + | Модификаторы <b>new, static</b> и <b>virtual</b> нельзя использовать для изменения метода <b>override.</b> |
- | Переопределяющее объявление свойства должно задавать такие же модификаторы уровня доступа, тип и имя, как и имеющиеся у унаследованного свойства, а переопределенное свойство должно иметь тип | + | Переопределяющее объявление свойства должно задавать такие же модификаторы уровня доступа, тип и имя, как и имеющиеся у унаследованного свойства, а переопределенное свойство должно иметь тип <b>virtual, abstract</b> или <b>override.</b> |
class BaseClass | class BaseClass | ||
Строка 1460: | Строка 1099: | ||
==== new ==== | ==== new ==== | ||
- | Модификатор | + | Модификатор <b>new</b> <i>скрывает</i> члены, унаследованные от базового класса. При сокрытии унаследованного члена его производная версия заменяет версию базового класса. (На самом деле, члены можно скрыть и без модификатора <b>new,</b> но в результате возникнет предупреждение. Если же для явного скрытия члена используется <b>new,</b> то модификатор отключает вывод предупреждений и документирует тот факт, что производная версия предназначена для замены. |
class BaseClass | class BaseClass | ||
Строка 1520: | Строка 1159: | ||
abstract int Length { get;} | abstract int Length { get;} | ||
- | Пример абстрактного класса ( | + | Пример абстрактного класса (<b>Java</b> или <b>C#</b>): |
abstract class ShapesClass | abstract class ShapesClass | ||
{ | { | ||
Строка 1532: | Строка 1171: | ||
В большинстве языков абстрактный тип данных реализуется с помощью интерфейсов. См. пример в соответствующем разделе. | В большинстве языков абстрактный тип данных реализуется с помощью интерфейсов. См. пример в соответствующем разделе. | ||
- | В Ада используется ключевое слово '''limited:''' | ||
- | type Stack is limited private; | ||
В ОБЕРОН И ОБЕРОН-2 АТД позволяют открывать поля структуры. | В ОБЕРОН И ОБЕРОН-2 АТД позволяют открывать поля структуры. | ||
Строка 1599: | Строка 1236: | ||
class CoClass: ISomeInterface | class CoClass: ISomeInterface | ||
{ | { | ||
- | + | ISomeInterface.F() { //в случае неявного интерфейса, здесь стояло бы F() { | |
System.Console.WriteLine(“Явно реализованный метод”); | System.Console.WriteLine(“Явно реализованный метод”); | ||
} | } | ||
Строка 1610: | Строка 1247: | ||
// интерфейса через ссылку на объект | // интерфейса через ссылку на объект | ||
- | + | (ISomeInterface)c.F(); // все нормально | |
== Множественное наследование == | == Множественное наследование == | ||
Строка 1672: | Строка 1309: | ||
== Понятие о родовых объектах. Обобщенное программирование == | == Понятие о родовых объектах. Обобщенное программирование == | ||
=== ADA === | === ADA === | ||
- | Note to C++ programmers: generic units are similar to C++ templates. | + | Note to C++ programmers: generic units are similar to C++ templates. [http://www.example.com Ada Programming] |
Объявляем шаблон: | Объявляем шаблон: | ||
Строка 1711: | Строка 1348: | ||
: new() - означает, что параметр-тип должен иметь конструктор умолчания (без параметров). | : new() - означает, что параметр-тип должен иметь конструктор умолчания (без параметров). | ||
- | |||
- | Пример универсального шаблона (generic), реализующего односвязный список. | ||
- | // type parameter T in angle brackets | ||
- | public class GenericList<T> | ||
- | { | ||
- | // The nested class is also generic on T. | ||
- | private class Node | ||
- | { | ||
- | // T used in non-generic constructor. | ||
- | public Node(T t) | ||
- | { | ||
- | next = null; | ||
- | data = t; | ||
- | } | ||
- | private Node next; | ||
- | public Node Next | ||
- | { | ||
- | get { return next; } | ||
- | set { next = value; } | ||
- | } | ||
- | // T as private member data type. | ||
- | private T data; | ||
- | // T as return type of property. | ||
- | public T Data | ||
- | { | ||
- | get { return data; } | ||
- | set { data = value; } | ||
- | } | ||
- | } | ||
- | private Node head; | ||
- | // constructor | ||
- | public GenericList() | ||
- | { | ||
- | head = null; | ||
- | } | ||
- | // T as method parameter type: | ||
- | public void AddHead(T t) | ||
- | { | ||
- | Node n = new Node(t); | ||
- | n.Next = head; | ||
- | head = n; | ||
- | } | ||
- | public IEnumerator<T> GetEnumerator() | ||
- | { | ||
- | Node current = head; | ||
- | while (current != null) | ||
- | { | ||
- | yield return current.Data; | ||
- | current = current.Next; | ||
- | } | ||
- | } | ||
- | } | ||
== Параллельное программирование == | == Параллельное программирование == | ||
- | |||
=== ADA === | === ADA === | ||
Ада реализует концепцию так называемых задач ('''task'''), что по сути является синонимом потока. Задача оформляется совершенно аналогично модулю, но может быть объявлена и описана где угодно, даже в теле подпрограммы: | Ада реализует концепцию так называемых задач ('''task'''), что по сути является синонимом потока. Задача оформляется совершенно аналогично модулю, но может быть объявлена и описана где угодно, даже в теле подпрограммы: | ||
Строка 1837: | Строка 1421: | ||
В этом примере, естественно лучше было все 3 '''accept''' запихнуть в '''select''' - было бы меньше простоев, но для примера я оставил так. | В этом примере, естественно лучше было все 3 '''accept''' запихнуть в '''select''' - было бы меньше простоев, но для примера я оставил так. | ||
- | |||
- | === Modula-2 === | ||
- | |||
- | В языке Modula-2 есть низкоуровневый механизм ''сопрограмм''. | ||
- | |||
- | Отличия сопрограммы от процесса: | ||
- | # Известно, что сопрограммы выполняются квазипараллельно. Следовательно, их использование исключает трудную проблему взаимодействия истинно параллельных процессов. | ||
- | # Переключение процессора от одной сопрограммы к другой осществляется явным ''оператором передачи управления''. Выполнение сопрограммы, которой передаётся управление, возобновляется с той точки, где она была приостановлена последним таким оператором. | ||
== Примеры кода == | == Примеры кода == | ||
Строка 2302: | Строка 1878: | ||
function G_MatMult(A,B: Matrix) return Matrix; | function G_MatMult(A,B: Matrix) return Matrix; | ||
- | === | + | === Пример кода на С# === |
- | Пример обработки исключений в | + | Пример обработки исключений в <b>C#.</b> |
class NegativeValueException : Exception | class NegativeValueException : Exception | ||
Строка 2350: | Строка 1926: | ||
} | } | ||
} | } | ||
- | |||
- | Ключевое слово ''event'' в '''C#''' позволяет уменьшить объём кода, необходимого для реализации событийной модели взаимодействия на делегатах. Иначе говоря, это такой синтаксический сахар для упрощения работы с обратными вызовами. | ||
- | |||
- | using System; | ||
- | namespace wildert | ||
- | { | ||
- | public class Metronome | ||
- | { | ||
- | public event TickHandler Tick; // объявляем событие Tick | ||
- | public EventArgs e = null; | ||
- | public delegate void TickHandler(Metronome m, EventArgs e); | ||
- | public void Start() | ||
- | { | ||
- | while (true) | ||
- | { | ||
- | System.Threading.Thread.Sleep(3000); | ||
- | if (Tick != null) | ||
- | { | ||
- | Tick(this, e); // генерируем событие Tick | ||
- | } | ||
- | } | ||
- | } | ||
- | } | ||
- | public class Listener | ||
- | { | ||
- | public void Subscribe(Metronome m) | ||
- | { | ||
- | // регистрируем обработчик события Tick | ||
- | m.Tick += new Metronome.TickHandler(HeardIt); | ||
- | } | ||
- | private void HeardIt(Metronome m, EventArgs e) | ||
- | { | ||
- | System.Console.WriteLine("HEARD IT"); | ||
- | } | ||
- | |||
- | } | ||
- | class Test | ||
- | { | ||
- | static void Main() | ||
- | { | ||
- | Metronome m = new Metronome(); | ||
- | Listener l = new Listener(); | ||
- | l.Subscribe(m); | ||
- | m.Start(); | ||
- | } | ||
- | } | ||
- | } | ||
- | |||
- | ; Замечание | ||
- | : Делегат — это тип, который определяет сигнатуру метода. При создании экземпляра делегата можно связать этот экземпляр с любым методом с совместимой сигнатурой. Метод можно запустить (или вызвать) с помощью экземпляра делегата. Делегаты похожи на указатели на функции в C++.<ref>Процитировано из [http://msdn.microsoft.com/ru-ru/library/ms173171.aspx msdn].</ref> | ||
=== Моделирование приватных типов данных из Ады в C++ === | === Моделирование приватных типов данных из Ады в C++ === | ||
Строка 2468: | Строка 1994: | ||
|есть | |есть | ||
|есть | |есть | ||
- | |нет<ref>Есть break | + | |нет<ref>Есть break ''label'', где ''label'' ставится с двоеточием перед началом цикла.</ref> |
|есть | |есть | ||
|есть | |есть | ||
Строка 2503: | Строка 2029: | ||
|есть | |есть | ||
|- | |- | ||
- | !Виртуальные методы | + | !Виртуальные методы |
- | |нет | + | |нет |
|есть | |есть | ||
|есть | |есть | ||
Строка 2512: | Строка 2038: | ||
|нет | |нет | ||
|есть | |есть | ||
- | | | + | |есть<ref>Причём, каждый метод виртуален; взято [http://computer-programming-forum.com/27-modula2/2a715a4b1cce6ba6.htm отсюда].</ref> |
|нет | |нет | ||
|есть | |есть | ||
Строка 2554: | Строка 2080: | ||
|нет | |нет | ||
|нет | |нет | ||
+ | |- | ||
+ | !Понятие связывания подпрограмм (методов класса) на этапе выполнения (динамическое связывание) | ||
+ | |нет<ref>Обычно реализуется через указатели на функции и указатели на структуры с указателями на функции.</ref> | ||
+ | |есть | ||
+ | |есть | ||
+ | |есть | ||
+ | |нет | ||
+ | |есть | ||
+ | |нет | ||
+ | |есть | ||
+ | |нет | ||
+ | |нет | ||
+ | |есть | ||
|- | |- | ||
!Раздельная независимая трансляция | !Раздельная независимая трансляция | ||
Строка 2591: | Строка 2130: | ||
|нет<ref>Нет в Оберон; учитывая характер изменений, внесённых в Оберон-2, делаем вывод о том, что размеченных объединений в нём нет. </ref> | |нет<ref>Нет в Оберон; учитывая характер изменений, внесённых в Оберон-2, делаем вывод о том, что размеченных объединений в нём нет. </ref> | ||
|есть | |есть | ||
- | |есть<ref | + | |есть<ref>Есть в Ада; вероятно, есть и в конкретной реализации.</ref> |
- | |есть<ref | + | |есть<ref>См. предыдущее примечание.</ref> |
|- | |- | ||
!Перечисления | !Перечисления | ||
Строка 2606: | Строка 2145: | ||
|есть | |есть | ||
|есть | |есть | ||
+ | |- | ||
+ | !Оператор loop | ||
+ | | | ||
+ | | | ||
+ | | | ||
+ | | | ||
+ | | | ||
+ | | | ||
+ | |есть | ||
+ | |есть | ||
+ | |есть | ||
+ | |есть | ||
+ | |есть | ||
+ | |- | ||
+ | !Оператор with | ||
+ | |нет | ||
+ | |нет | ||
+ | |нет | ||
+ | |нет | ||
+ | |есть | ||
+ | |есть | ||
+ | |нет | ||
+ | |есть | ||
+ | |есть | ||
+ | |нет<ref>Ключевое слово '''with''' означает импортирование классов в текущую область видимости.</ref> | ||
+ | |нет | ||
|- | |- | ||
!Запрещение замещения метода в произвольных классах или наследования класса | !Запрещение замещения метода в произвольных классах или наследования класса | ||
|нет | |нет | ||
|нет | |нет | ||
- | |есть<ref>Используется ключевое слово | + | |есть<ref>Используется ключевое слово <b>sealed</b>.</ref> |
- | |есть<ref>Используется ключевое слово | + | |есть<ref>Используется ключевое слово <b>final</b>.</ref> |
|нет | |нет | ||
|нет | |нет | ||
Строка 2647: | Строка 2212: | ||
|- | |- | ||
!Вложенные модули | !Вложенные модули | ||
- | | | + | | |
- | | | + | | |
- | | | + | | |
- | | | + | | |
- | |нет<ref | + | | |
- | |нет<ref | + | |нет<ref>Вложенными могут быть только подпрограммы, которые не являются библиотечными модулями.</ref> |
- | |нет<ref | + | |нет<ref>См. предыдущее примечание.</ref> |
- | + | |нет<ref>См. предыдущее примечание.</ref> | |
|есть | |есть | ||
|есть | |есть | ||
Строка 2665: | Строка 2230: | ||
|есть | |есть | ||
|есть | |есть | ||
- | | | + | | |
|есть | |есть | ||
|есть | |есть | ||
|есть | |есть | ||
|ч/и<ref>Делаем структуру, скрыто экспортируем указатель на неё в другой модуль.</ref> | |ч/и<ref>Делаем структуру, скрыто экспортируем указатель на неё в другой модуль.</ref> | ||
- | | | + | | |
- | | | + | | |
|- | |- | ||
!Расширяющее программирование | !Расширяющее программирование | ||
Строка 2678: | Строка 2243: | ||
|и | |и | ||
|и | |и | ||
- | | | + | | |
|и | |и | ||
|есть | |есть | ||
Строка 2691: | Строка 2256: | ||
|есть | |есть | ||
|есть | |есть | ||
- | | | + | | |
|есть | |есть | ||
|и | |и | ||
Строка 2704: | Строка 2269: | ||
|и | |и | ||
|и | |и | ||
- | | | + | | |
|и | |и | ||
|и | |и | ||
Строка 2717: | Строка 2282: | ||
|нет | |нет | ||
|нет | |нет | ||
- | | | + | | |
|нет | |нет | ||
|ч/и | |ч/и | ||
Строка 2743: | Строка 2308: | ||
|есть | |есть | ||
|есть | |есть | ||
- | | | + | | |
|нет | |нет | ||
|нет | |нет | ||
Строка 2751: | Строка 2316: | ||
|есть | |есть | ||
|- | |- | ||
- | ! | + | !Рефлективное программирование |
|нет | |нет | ||
|и | |и | ||
|есть | |есть | ||
|и | |и | ||
- | | | + | | |
|и | |и | ||
|и | |и | ||
|и | |и | ||
- | | | + | | |
- | | | + | | |
- | | | + | | |
|- | |- | ||
!Передача параметров по значению | !Передача параметров по значению | ||
Строка 2768: | Строка 2333: | ||
|есть | |есть | ||
|есть<ref>cм. [http://msdn.microsoft.com/en-us/library/0f66670z(v=vs.71).aspx#vclrfpassingmethodparameters_valuetypes MSDN].</ref> | |есть<ref>cм. [http://msdn.microsoft.com/en-us/library/0f66670z(v=vs.71).aspx#vclrfpassingmethodparameters_valuetypes MSDN].</ref> | ||
+ | |есть<ref>Только для простых типов (см. примечание для ячейки ниже).</ref> | ||
|есть | |есть | ||
|есть | |есть | ||
- | | | + | | |
- | | | + | | |
- | | | + | | |
- | | | + | | |
- | | | + | | |
- | + | ||
|- | |- | ||
!Передача параметров по ссылке | !Передача параметров по ссылке | ||
|и<ref>Моделируется с помощью указателей.</ref> | |и<ref>Моделируется с помощью указателей.</ref> | ||
- | | | + | |есть<ref>Но можно действовать в стиле C — передавать по указателю.</ref> |
|есть<ref>Модификаторы '''ref''' и '''out''', также см. [http://msdn.microsoft.com/en-us/library/0f66670z(v=vs.71).aspx#vclrfpassingmethodparameters_referencetypes MSDN].</ref> | |есть<ref>Модификаторы '''ref''' и '''out''', также см. [http://msdn.microsoft.com/en-us/library/0f66670z(v=vs.71).aspx#vclrfpassingmethodparameters_referencetypes MSDN].</ref> | ||
- | + | |есть<ref>Только для ссылочных типов (точнее, значений, на которые они ссылаются). По ссылке передаётся объект, ссылочная переменная передаётся по значению.</ref> | |
- | |есть<ref | + | |есть |
- | |есть | + | |есть |
- | |есть | + | | |
- | | | + | | |
- | | | + | | |
- | | | + | | |
- | | | + | | |
|} | |} | ||
:ч/и - частично имитируется | :ч/и - частично имитируется |