лекции (2009), страница 7
Описание файла
Текстовый-файл из архива "лекции (2009)", который расположен в категории "". Всё это находится в предмете "языки программирования" из 7 семестр, которые можно найти в файловом архиве МГУ им. Ломоносова. Не смотря на прямую связь этого архива с МГУ им. Ломоносова, его также можно найти и в других разделах. .
Просмотр 7 страницы текстового-файла онлайн
End P;
….
P(a,a);
Предположим, что оно не обрабатывается. Тогда запись активации пропадает. Значит, если была передача по
ссылке, то значение «а» изменится, а если по значению и результату, то не изменится, т.к. копировать в «а»
будет нечего.
Энтропия – явление, при котором программа может выдавать различные результаты при одних и тех же
исходных данных. Если в программе есть энтропия, то это очень плохо. Очевидно, что при программировании
на Ада риск энтропии значительно повышается, т.к. не известно какой способ передачи выберет в этот раз
компилятор.
• В Ада-95 – по значению, по ссылке
• В Си – не определяется семантика использования. Способ передачи только по значению
• В Си++ – по значению, по адресу (ссылке). Контроль семантики: in – ссылка константная, out, inout – не
константная
void f( T &); //Компилятор считает, что f будет менять значение => константный объект
//передавать нельзя
Это указание для компилятора, чтобы он следил за соблюдением семантики
class X
{
void f(); //неконстантная функция;
}
……..
const X a;// X * const this; внутри методов
a.f();// ошибка!!
class X
{
void f() const; //константная функция;
}
……..
const X a;// X * const this; внутри методов
a.f();// Правильно!!
• С#, Java
void f( T x) {….;}
……
T a; // a – ссылка, если Т – объект
f(a); // передаётся ссылка
Оба языка поддерживают идею примитивных типов (которые в C# являются подмножеством типов-значений
— value types), и оба для трансляции примитивных типов в объектные обеспечивают их автоматическое
«заворачивание» в объекты (boxing) и «разворачивание» (unboxing) (в Java — начиная с версии 1.5).
object – предок всех классов. => Объект любого класса неявно приводится к типу object.
object o;
int i;
o = i;
i = o; // ошибка!
Автоупаковка, Автораспаковка:
o = i; // o = new Integer(i) – Java
// o = new Int32(i) – C#
Так что если функция объявляется как void f(object o), то в неё можно передавать любой объект( для
примитивных типов будет производится автоупраковка\распаковка)
• Java:
В Java параметры метода передаются только по значению, но поскольку для экземпляров классов передаётся
ссылка, ничто не мешает изменить в методе экземпляр, переданный через параметр. Структур в Java нет.
Передача объектов примитивных типов в методы «как по ссылке» выполняется через классы-обёртки:
void f(Integer X){…X = ….; }
…..
int i = 1;
Integer px = new Integer(i);
f(px);
i = px;
Integer – класс-обёртка для примитивного типа «int». Суть способа – преобразовать объект примитивного
типа в объект класса и работать внутри функции с объектом класса.
• C#
для C# создана более развитая терминология:
Тип-значение(value type) – тип, объекты которого передаются по значению. Если где-то нужен объект такого
типа, то отводится место под сам объект. типами-значениями являются простые(примитивные) типы данных и
структуры
Референциальный тип – тип, объекты которого передаются по ссылке. Если где-то нужен объект такого типа,
то отводится место под адрес. Референциальными типами являются классы(любой массив – наследник
класса Array, строка это объект класса String, и т.д.)
В принципе, в C# можно передавать объекты простых типов в функции с помощью классов-обрёток, но C#
также поддерживает явное описание передачи параметров по ссылке – ключевые слова ref и out. «ref»
реализует семантику inout, а «out» реализует семантику out. При использовании out компилятор вставляет
квазистатический контроль на наличие в методе присваивания значения, зато не требует
инициализированность фактического параметра перед вызовом метода.
void f(ref int x){x = -3;}
….
int a = 0;
f( ref a); // а будет передано по ссылке, если бы объект «а» был структурой, то он так же //
передался бы по ссылке
Разрешать или не разрешать функции с переменным количеством параметров?
Си
В Си можно было создавать функции с переменным количеством параметров при помощи библиотеки
«stdargs»: va_list, va_start, va_end, va_next и т.д
Си#
void f(param object [] args){…. args [0] = …; }
void g(object [] args){…. args [0] = …; }
….
f(a , b);
f();
f(1);
f(new X[]{new X(). new X()});// Ошибка!!
f(new X(), new X()); // Правильно!
g(new X[]{new X(). new X()});// Правильно!!
java
void func(Object a[])
{
for(int i = 0;i < a.length; i++)
System.out.println(a[i]);
}
Для java 1.5 – func(1,2,3, new Object(), "word");
Для java 1.4 – func(new Object[] {1, 2, "some string"});
Передача параметров по имени
Алгол-60
Передаём сам объект «как он есть» . Фактически передаётся его идентификатор как строчка. Далее в теле
процедуры идентификатор формального параметра заменяется на идентификатор фактического
Обоснование невозможности написание процедруры swap на Algol-60:
procedure Swap(a,b); //a, b передаются по имени
Begin
T tmp;
tmp := a; a:= b; b := tmp;
End;
….
swap(i, A[i]);
T tmp;
tmp := i;
i := A[i];
A[i] := tmp;// A [ A[i] ] := i; неправильно!!!
swap(A[i], i);
T tmp;
tmp := A[i];
A[i] := i;
i:= tmp;// i := A[i] – всё правильно
Решение проблемы: С каждым параметром передавалась процедура thunk, которая выполнялась при каждом
обращении к фактическому параметру.
Параметры по умолчанию
В С++ можно задавать параметры по умолчанию: void f(int a = 4){ …;}
В C# эту возможность убрали. Вместо этого предлагается использовать перегрузку:
f(){ f(1, 2); }
f(int i ){ f(i , 2) ;}
f(int i, int j ) { … ; }
Лекция. Ульянов А.В.
Подпрограммы. Типы данных.
Ада 83, Java – нет.
П.1. Передача подпрограмм, как параметров.
Присваивание [:=]
Вычисление [()]
Ада 83: generic не только для ТД, но и для процедур, функций.
//generic – параметризация.
с/с++: typedef void (*f)(int);
Отсюда, процедурный тип – указатель.
Проблема в том, что в Ада 83 и Java отказались от указателей, т.е. и от П/П ТД.
//В Java целиком, в Ада частично.
Ада 95:
type Func_Pointer is access function (L,R: float) return Boolean;
function Compare (X,Y: float) return Boolean … end Compare;
F: Func_Pointer
F:=Compare’access
Модула-2, Оберон:
TYPE FUNC_INT = PROCEDURE (L,R: REAL): BOOLEAN;
PROCEDURE COMPARE (X,Y: REAL): BOOLEAN;
VAR F: FUNC_INT;
F:=COMPARE;
П.2. Функции обратного вызова.
Для реализации ООП(динамическое связывание), например, в xlib xt Motif;
События Реакция.
Чистые ООЯП: Любой ОД принадлежит классу.
//Автоупаковка, автораспаковка => Простой ТД объект.