лекции (2010) (by Ульянов Алексей_ Лихогруд Николай_ Сергеев Николай) (1160852), страница 6
Текст из файла (страница 6)
современных языках чёткоопределены индексы массив: 0 <= i <= N-1, а основной областью применения диапазонов было именнозадание типов индекса массива.п.2.5 Указатели и ссылкиАдрес :• Указатель• Имя• МеткаУказателиСтрогиеСтандартный Паскаль, Модула-2, Ада, Оберон(со сборкой)PascalType PT = ^T;{Modula-2Type PT = pointer to T;}vari :T;Инициализировать указатель можно толькодвумя способами – либо другим указателем,либо выделением новой памяти NEW(p : PT);Не строгиеC, C++, Turbo PascalМожно получать адрес любого объекта спомощью операции взятия адреса «&»Существует абстрактный указатель «void *»T * => void * автоматическиvoid * к T * автоматически не приводитсяПроблемыстрогихинестрогихуказателей:T * p;void *pp;pp = p;p = (T *)pp;• УдалениеПоэтому все данные чётко разделяются напамятиименованные, либо не именованные.(Dispose(p : PT))Указатель служит для работы с анонимнымине вданными в динамической памяти.своёвремя,Смысл – избежание части ошибокчтоприводит к появлению «висячих ссылок» - указателей, которые должны на что-то указывать, но не указывают.• Накопление мусора – памяти, на которую не указывает ни один указатель.P,P1 : PT;New( P );New( P2 );P := P2; {порождение мусора}Dispose(P2); {P – «висячая ссылка», попытка обращения к памяти, которую она занимает, приведёт к ошибке}Различают системы с динамической сборкой мусора и без таковой.Строгий язык с динамической сборкой мусора довольно надёжен.От висячих ссылок защиты нетАдаВ чистой Аде есть только new(p).
В модуле STANDARD есть UNCHECKED_DEALLOCATION(p) – подчёркиваетсянебезопасность этой операцииПримеры ошибок:T *p;Void f(){T x;P = &x; //!!!адрес локальной переменной!!!}void Foo(){f();free(p); //!!!попытка освобождения невыделенной памяти!!! – выдастся ошибка}new(p1);p := p1;Dispose(p1); {р «висит»}Для Java, C# - указатели трансформировались в ссылкиНесколько слов о языке Small TalkПоследовательность действий при вычислении значения выражения «2+2»:1.
Посылка сообщения «+» обекту 2 с параметром 32. В классе integer ищется по таблице методов доступа обработчик сообщения «+» и вызывается3. Обработчик отрабатывает и возвращает новый объект «5»Лекция. Ульянов А.В.Указатели.В чем опасность использования: низкоуровневое программирование.Если используется динамическая сборка мусора, тогда проще.Так процедура UNCHECKED_DEALLOCATION(P) является аналогом delete(p), dispose(p) в ЯП, где используетсядинамическая сборка мусора.C#, Java - понятие указателя отсутствует (точнее в C# такое понятие есть, но только в небезопасных блокахunsafe)managed – управляемый код.Функции .net не дают все возможности по использованию ресурсов ОС, отсюда приходится обращаться квозможностям Win API.unsafe – код, где появляются новые конструкции, С RTL (как будто внутри языка С).Обращаться к ним можно тоже только из unsafe.
Функции, использующие это, тоже помечены как unsafe.unsafe {…}byte []b можно объявить как byte *b и использовать в вышеуказанном блоке.Как работает динамическая сборка мусора:Менеджер динамической сборки мусора запрашивает память, ее дают, а как только заканчивается, работаетдинамический сборщик мусора. Он-то и находит все неиспользуемые куски памяти, сводит к одному блоку.Именно поэтому ссылка на byte может плавать и нельзя рассчитывать на то, что ее адрес будет постоянным.Потому преобразование byte[] в byte * возможно только блоке (ссылка замораживается):fixed (byte* pb = b) {…}C#, Java – понятие указателя исчезло и превратилось в понятие ссылки.Типы значения,Референциальные ТД (классы, массивы, интерфейсы) – к ним обращение только по ссылке.X a; // Если в C#, Java – то объект является ссылкой и пока не существует.a = new X(); //Вызов конструктора обязателен.string[] a;string[] b = new string[N];a = b; // Присваивание ссылок, а не копирование.Понятие указателя в Ада 95(83).Ада 83:PT – указатель на тип T.type PT is access T;x: PT;x := new T;y: T; - Получить адрес у стандартными средствами нельзя.Ада 95:Если: type PT is access T;То инициализация возможна только так:x: PT;x := new T;Если же: type PTT is access all T; (на все объекты типа Т)xx: PTT;xx := new T;Однако можно ссылаться и на другие переменные:z: aliased T;zz: T;z ’access – операция взятия адреса.x := z’access; - нельзя, т.к.
без aliased.xx := z’access; -можно.xx := x; - можно.x := xx; - нельзя.В современных ЯП ссылки – это средства доступа к объекту.В C#, Java, Delphi – имеются референциальные ТД.“имена” = ссылки.В С++ добавили отдельный базисный тип - ссылочный.С точки зрения операций:Чем различаются ссылка и указатель:*(в С), ^ (M-2, P):= только к ссылкам разъименование объекта (и выполняется компилятором).. – компилятор вставляет разъименование сам.T is recordA: T1;B: T2;end recordtype PT is access T;X: Pt;X.A; X.B; //разъименование делается компилятором.X.all; // явное разъименование.В С++ к ссылкам применяется единственная операция – инициализация (путем присваивания ссылкивнешнему объекту, по сути ссылка инициализируется адресом объекта).X& t = a; // все, что можно делать с а, можно делать и с t.X* pa = new X();X& t = *pa;&t == значению указателя pa.delete(&t);Если f(X&t) – тогда инициализируется в момент вызова функции.Глава 3.
Составные ТД.П.3.1. Массивы.Последовательность однотипных элементов.D x … x DnA[i] – операция индексирования. i – индексное выражение.Атрибуты массива:1) Базовый тип (тип элементов) – D2) Тип индекса (i)3) Диапазон индекса (длина)В разных ЯП:Связывание базового типа статически (везде).Тип индекса – С/С++/С#/Java/Оберон – всегда тип int (статическое связывание).Фиксируется нижняя граница значения индекса.Длина – статическая и динамическая.Динамическая – чисто-динамическая(можно изменитьполучено динамически, но изменять нельзя).в любое время) и квазистатическая(значениеМассив всегда непрерывная последовательность байтов. Отсюда возникает проблема распределения памяти.Можно длину сделать статической (жестко), оттого сделали квазистатической.T[] a = new T[N]; //0..N-1P,i,L..R(диапазон)Стандартный Pascal:Function SCAL( A,B: Arr): real;Если диапазон для Arr от 1..N, то для массива от 0..N-1 работать будет не корректно(или вовсе не будетработать).A[i] – компилятор выполняет квазистатический контроль.
(не очень-то гибко)Модула-2:Объекты данных массива (переменные). Формальные параметры массива (открытые массивы).Понятие открытого массива: зафиксирован базовый тип.Обычный массив:TYPE Arr = ARRAY Index of D;TYPE Index = [1..N];ARRAY of D;Index = CARDINALL[0..N]; //В данном случае индекс задается статически.PROCEDURE SUM (VAR A: ARRAY OF REAL): REAL;VAR S: REAL; I: INTEGER;BEGINS:=0.0;FOR I:=0 TO HIGH(A) DOS:=S+A[I];END;RETURNSEND SUM;Открытый массив: к нему применима функция HIGH(A) – максимальная длина без единицы.Общий синтаксис объявления массива в ОберонеTYPE Arr = ARRAY N OF D;TYPE NAT IS NEW INTEGER RANGE 1..MAX_INT (NEW – означает новый тип)X: NAT;I: INTEGER;X:=I; и I:=X; - нельзя.X:=NAT(I);I:=INTEGER(X);SUBTYPE POS IS INTEGER RANGE 0..MAX_INT;X: POS; I: INTEGER;I:=X; X:=I ~ X:=POS(I);Неограниченный тип массива.D,I – зафиксированы.L..R – не фиксируемые левые и правая границы.TYPE TARR IS ARRAY INTEGER RANGE 0..N REAL;Атрибуты данных:A’LENGTH – длина массиваA’FIRST = LA’LAST = RA’RANGE RANGE A.FIRST..A.LASTУ неограниченных типов данных – атрибуты динамические, у ограниченных – статические.Зачем нужны неограниченные типы данных: они нужны для выведения из них других типов данных.X1: TARR;X2: Arr; //Нельзя.
Компилятор не может распределять память.Надо: X2: Arr range 0..N;Function SUM(A: Arr)return real isS: real := 0.0;Beginfor i in A’RANGE loop S:=S+A(i); end loop;return S;end SUM.a:=SUM(X2);C: POS;D: INTEGER;C := D; //okC: POS:D: INTEGER := -1;C := D; //ошибка.Динамический массив (квазистатический).procedure P(N: integer) isA: array(1..N) of real;C#, Java:T[] имя;new имя[len];int[] a = new int{1,2,3,4,5};Многомерные массивы.С, С++: int a[N1][N2];C#: int [,] a = new a[N1,N2];int [][] a; //ступенчатый массив, он же разрывный.Вырезка: подмножество элементов массива.Фортран:А(N1,N2)А(1,*) – 1-я строчка.А(*,1) – 1-й столбец.A(2..5,*), A(1..3,2..4) – прямоугольная вырезка.Ада поддерживает только одномерные непрерывные вырезки.П.3.2.
Записи (струтуры).struct name {поля}record последовательность полей end;Разные типы: тип класс обертка (упаковка, распаковка)С++: класс – обобщение структуры. (у структур в С собственное пространство имен)Java: отсутствует запись – она не нужна.С++: структуры – классы.Отличия:1) Имена2) struct – public, class – private.Delphi:Новое – класс.Старое – record.C#: Типы – значения.struct c {}class F{}С а = new C();Отличия от класса:1) память распределена как под типы значений2) или классы.
Есть классы-обертки.class Point { int x,y; }Point[] pointArray = new Point[1000]; //Неоправданные затраты памяти и времени. Здесь лучше использоватьструктуру.Лекция. Сергеев Николай.Регулярные комбинировнные типы-классы-множества-файлыФайлы появились вследствие нужды программистов в средствах ввода и вывода во внешниеустройства.Впервые файлы были реализованы в Паскале, где они стали частью синтаксиса языка.(writeln(i : 8 : 4) такую запись можно написать если в синтаксисе есть правила задания действительных чисел)Однако правильно ли это? Оказалось, что нет.