Здравствуйте, AndrewVK, Вы писали:
AVK>Здравствуйте, Сергей Губанов, Вы писали:
СГ>>Java и C# как раз и используют то что в терминологии оберонов называется POINTER TO RECORD, то есть refernce-type.
AVK>Тогда что такое в твоем понимании указатель?
видимо это такая бяка, которая указывает на область памяти. и, видимо, эта бяка нифига не типизированная
... << RSDN@Home 1.1.4 beta 3 rev. 185>>
— сколько программистов надо чтобы заменить сгоревшую лампочку?
— сколько не бери, а лампочку не поменять — проблема аппаратная, программным путем не решается...
Здравствуйте, Сергей Губанов, Вы писали:
СГ>Есть еще парочка уточнений.
СГ>Например, в Component Pascal указатели могут быть не на любые типы, а только на RECORD или на ARRAY (Кстати, просто обычный ARRAY — это value-type, динамический ARRAY уже reference-type, но на обычный ARRAY можно объявить указатель и получить pointer-type).
Вот это, имхо, не есть очень хорошо: оно только усложняет боксинг (приходится специально заворачивать примитивные типы в pointer to record).
СГ>Что касается рассширения типов (то бишь, наследования), то тут квалификатор "POINTER TO", как бы, игнорируются, то есть то что базовый тип был ссылочным не мешает рассширение типа сделать типом-значением СГ>"POINTER TO" — для расширения типов не имеет значения.
Ну это уже особенности (бонусные фичи) языка... С равным успехом можно потребовать, что наследование происходит только от исходных, value-типов, а POINTER TO создаёт производный тип. Просто — больше писанины будет.
Кстати говоря, конструкция "POINTER TO" — по смыслу неграмотная, так как рассказывает о внутреннем представлении!
Да и без внутреннего представления:
Либо мы должны синтаксически по-разному работать с переменными типов T и pointer to T (например, явно разыменовывать указатели, в отличие от значений/ссылок),
Либо, если синтаксис одинаков (а семантика различается лишь в инициализации/копировании) — называть типы схожим образом. Что-то в стиле "shared record..." Здесь спецификатор "shared" выглядит как определение, а не как самостоятельная сущность.
Здравствуйте, AndrewVK, Вы писали:
AVK>Здравствуйте, Сергей Губанов, Вы писали:
СГ>>Java и C# как раз и используют то что в терминологии оберонов называется POINTER TO RECORD, то есть refernce-type.
AVK>Тогда что такое в твоем понимании указатель?
Сказка про белого бычка. Серия восемьдесят восьмая.
Указатель — это такая специальная переменная, которая может быть связана с объектом размещенным в динамической памяти, а может быть и не связана ни с каким объектом, в этом случае ее значение равно константе называемой NIL (или null). Если эта переменная, все таки связана с объектом размещенным в динамической памяти, то доступ к этому объекту можно получить разыменовывая указатель (причем, операция разыменования практически всегда прозрачна для программиста, то есть выражения p.f() и v.f() выглядят одинаково не смотря на то что p — переменная указательного или ссылочного типа, а v — переменная value-типа).
Кроме того, указательными и ссылочными переменными управляет сборщик мусора и может менять их фактическое значение, но так как для программы их фактическое значение не доступно (а доступен лишь объект с которыми они связаны), то эта деятельность сборщика мусора для программы не заметна.
Здравствуйте, Кодт, Вы писали:
К>Кстати говоря, конструкция "POINTER TO" — по смыслу неграмотная, так как рассказывает о внутреннем представлении!
Почему рассказывает о внутреннем представлении? Она говорит лишь о том где размещается объект: на стеке или в динамической памяти. И в том и в другом случае объект одинаково внутри устроен.
Дисклаймеры:
1. Прости за оффтопик.
2. Это не наезд.
У меня сложилось впечатление, что ты во что бы ни стало хочешь научить людей языку Оберон. Особенно — апологетов С++, C#, Java.
Причём не просто пацанов, которые от a^=b^=a^=b кипятком писают. А людей, практикующих за деньги и достаточно долго.
Соответственно, глубина практических и философских знаний о предмете (как языке, так и программировании в целом) у них достаточно велика.
Поэтому битва "фанатизм против фанатизма" обречена на провал.
Оберон не настолько имеет преимущества перед другими языками, что ради него все всё бросят. Да ещё и закидают...
Форум же не зря называется "Философия программирования". Здесь есть смысл исследовать парадигмы.
Если какой-то язык хорошо приспособлен для некоей парадигмы или паттерна — это замечательно. Если на другом языке то же самое делается с бОльшими усилиями — ну по крайней мере понятна цена.
Говорить же "X крут, а Y,Z,T перед ним сынки" это несерьёзно. Просто ты наживаешь себе врагов на ровном месте.
Здравствуйте, Сергей Губанов, Вы писали:
СГ>Указатель — это такая специальная переменная, которая может быть связана с объектом размещенным в динамической памяти, а может быть и не связана ни с каким объектом, в этом случае ее значение равно константе называемой NIL (или null). Если эта переменная, все таки связана с объектом размещенным в динамической памяти, то доступ к этому объекту можно получить разыменовывая указатель (причем, операция разыменования практически всегда прозрачна для программиста, то есть выражения p.f() и v.f() выглядят одинаково не смотря на то что p — переменная указательного или ссылочного типа, а v — переменная value-типа).
Тогда чем переменная указательного типа отличается от переменной ссылочного типа?
Здравствуйте, AndrewVK, Вы писали:
AVK>Здравствуйте, Сергей Губанов, Вы писали:
СГ>>Указатель — это такая специальная переменная, которая может быть связана с объектом размещенным в динамической памяти, а может быть и не связана ни с каким объектом, в этом случае ее значение равно константе называемой NIL (или null). Если эта переменная, все таки связана с объектом размещенным в динамической памяти, то доступ к этому объекту можно получить разыменовывая указатель (причем, операция разыменования практически всегда прозрачна для программиста, то есть выражения p.f() и v.f() выглядят одинаково не смотря на то что p — переменная указательного или ссылочного типа, а v — переменная value-типа).
AVK>Тогда чем переменная указательного типа отличается от переменной ссылочного типа?
Эти переменные функционально ничем не отличаются. Вот только одновременно их быть не может, ведь тип может быть либо указательным либо ссылочным, но не может быть и тем и тем одновременно. То есть либо мы пишем так:
TYPE
Gadget = POINTER TO GadgetDesc; (* pointer-type *)
GadgetDesc = RECORD(* value-type *)
(* ... *)END;
Либо мы сразу пишем так:
TYPE
Gadget = POINTER TO RECORD(* reference-type *)
(* ... *)END;
Но мы не можем написать и так и сяк одновременно. Первый случай отличается от второго тем, что мы можем размещать переменные GadgetDesc на стеке или в массиве-значений (в том случае если нам это вдруг зачем-то надо, конечно).
Здравствуйте, Сергей Губанов, Вы писали:
К>>Кстати говоря, конструкция "POINTER TO" — по смыслу неграмотная, так как рассказывает о внутреннем представлении!
СГ>Почему рассказывает о внутреннем представлении? Она говорит лишь о том где размещается объект: на стеке или в динамической памяти. И в том и в другом случае объект одинаково внутри устроен.
Потому что она говорит ясным английским языком: "это не сам объект, это указатель на запись". А то, что и к записи, и к указателю на запись применяются одинаковые синтаксические конструкции (например, доступ к членам — var.field, ptr.field) — только привносит бардак в голову.
Вот если бы мы говорили о "personal record" vs "shared record", то внутреннее представление действительно было бы убрано с глаз долой.
Наконец, есть ещё один хитрый момент — это передача указателя в процедуру по ссылке. Как ни крути, а здесь разница бросится в глаза.
type
Rec = record x:integer end;
Ptr = pointer to Rec; {если Оберон это не позволяет - унаследуем от Rec}procedure Change0( v: Rec) begin v.x := 0 end;
procedure Change1(var v: Rec) begin v.x := 1 end;
procedure Change2( v: Ptr) begin v.x := 2 end;
procedure Change3(var v: Ptr) begin v.x := 3 end;
procedure Change4(var v: Ptr) begin v := new Ptr; v.x := 4 end;
var
r: Rec;
p,q: Ptr;
begin
r.x := -1;
Change0(r); {r.x = -1}
Change1(r); {r.x = 1}
p := new Ptr; p.x := -1;
q := p;
Change0(p); {p.x = -1}
Change1(p); {p.x = 1}
Change2(p); {p.x = 2}
Change3(p); {p.x = 3}
Change4(p); {p.x = 4, q.x=3}end;
Таки да, это был указатель, то есть нечто вторичное по отношению к самому объекту.
Как элемент не тождественен списку элементов, так и объект не тождественен паре указатель-объект. И никакие заклинания не спасают.
Здравствуйте, Сергей Губанов, Вы писали:
СГ>Эти переменные функционально ничем не отличаются.
Значит получается что в СР есть две сущности с одинаковыми функциями?
СГ> Вот только одновременно их быть не может, ведь тип может быть либо указательным либо ссылочным, но не может быть и тем и тем одновременно. То есть либо мы пишем так: СГ>
СГ>Но мы не можем написать и так и сяк одновременно. Первый случай отличается от второго тем, что мы можем размещать переменные GadgetDesc на стеке или в массиве-значений (в том случае если нам это вдруг зачем-то надо, конечно).
Понятно. Но не думаю что это намного логичнее и проще боксинга.
Здравствуйте, Кодт, Вы писали:
К>Потому что она говорит ясным английским языком: "это не сам объект, это указатель на запись". А то, что и к записи, и к указателю на запись применяются одинаковые синтаксические конструкции (например, доступ к членам — var.field, ptr.field) — только привносит бардак в голову.
Это из-за того что var.field — безопасная операция, а ptr.field — потенциально опасная операция, т.к. ptr может быть равен NIL? В этом смысле, действительно, не помешало бы эту потенциальную опасность как-то выразить синтаксически чтобы лишний раз напоминать программисту о том что он делает.
К>Наконец, есть ещё один хитрый момент — это передача указателя в процедуру по ссылке. Как ни крути, а здесь разница бросится в глаза.
Здравствуйте, AndrewVK, Вы писали:
AVK>Здравствуйте, Сергей Губанов, Вы писали:
СГ>>Эти переменные функционально ничем не отличаются.
AVK>Значит получается что в СР есть две сущности с одинаковыми функциями?
С точки зрения CP есть только одна сущность — "POINTER TO".
Здравствуйте, Сергей Губанов, Вы писали:
СГ>Здравствуйте, Кодт, Вы писали:
К>> хочешь научить людей языку Оберон
СГ>Прошу рассматривать мои сообщения как: "Обзор философии программирования на языках Oberon-family".
Но ты не даешь обзор. Ты не производишь сравнений с другими языками. Ты только показываешь примеры из Оберона, и не говоришь больше ничего. Приходится все доделывать другим товарищам... Исправляйся.
Здравствуйте, buriy, Вы писали:
B>Здравствуйте, Сергей Губанов, Вы писали:
СГ>>Здравствуйте, Кодт, Вы писали:
К>>> хочешь научить людей языку Оберон
СГ>>Прошу рассматривать мои сообщения как: "Обзор философии программирования на языках Oberon-family".
B>Но ты не даешь обзор. Ты не производишь сравнений с другими языками. Ты только показываешь примеры из Оберона, и не говоришь больше ничего. Приходится все доделывать другим товарищам... Исправляйся.
Да, у меня закралась идейка написать что-то вроде обзорной статьи, сейчас ее обдумываю...
Здравствуйте, AndrewVK, Вы писали:
AVK>Я же написал — ПСЕВДОКОД, а не С/С++. Воспринимай эту операцию как операцию получения указателя по значению. Никакой адресной арифметики.
А в С++, кстати, тоже не будет адресов. Тоже типа "безопасный" поинтер.
... << RSDN@Home 1.1.4 beta 3 rev. 207>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, Сергей Губанов, Вы писали:
СГ>Кстати, просто обычный ARRAY — это value-type, динамический ARRAY уже reference-type, но на обычный ARRAY можно объявить указатель и получить pointer-type).
О! То что нужно. Тогда объяви, плиз, обычный ARRAY как локальную переменную функции, получи указатель, и возврати его из функции.
Кстати, pointer-type можно инкрементить?
... << RSDN@Home 1.1.4 beta 3 rev. 207>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, VladD2, Вы писали:
VD>Здравствуйте, AndrewVK, Вы писали:
AVK>>Я же написал — ПСЕВДОКОД, а не С/С++. Воспринимай эту операцию как операцию получения указателя по значению. Никакой адресной арифметики.
VD>А в С++, кстати, тоже не будет адресов. Тоже типа "безопасный" поинтер.
int* p = &a[5];
if ( *(p - 1) == a[4] ) Console::WriteLine(S"Vlad2 не прав");
"p — 1" — это адресная арифметика, в Си/Си++ указатели и адреса есть одно и тоже.