Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2007.08.26;
Скачать: CL | DM;

Вниз

Как узнать какой пункт из case в record выбран?   Найти похожие ветки 

 
Зет   (2007-07-26 05:47) [0]

Я смотрю, что-то во многих учебниках этот элемент вообще не освещён.


 
wicked ©   (2007-07-26 06:08) [1]

никак, поэтому и не освещен


 
Зет   (2007-07-26 06:24) [2]

Удалено модератором
Примечание: Выражения выбираем


 
Зет   (2007-07-27 04:44) [3]


> Удалено модератором
> Примечание: Выражения выбираем


Но он врёт. Вводит людей в заблуждение.


 
Sergey Masloff   (2007-07-27 06:00) [4]

Никто не врет. Просто нужно прочитать не много учебников а один. Но прочитать а не просмотреть.
 "поля" записи это просто понятные компилятору псевдонимы адресов. Поэтому выбора там реально никакого нет. Просто записываешь и читаешь по адресу. Можешь записать по одному адресу а прочитать по другому.

TMyRec = packed record
   case integer of
   0: (a : dword);
   1: (b : word; c : word);
 end;

var rec :TMyRec;
begin
 rec.a := 65537;  // 10000000000000001 в двоичном
 ShowMessage(Format("%d %d",[rec.b,rec.c]));
end;


идея понятна? перед wicked ©   извинишься?


 
Зет   (2007-07-27 07:20) [5]


> Sergey Masloff   (27.07.07 06:00) [4]
>
> Никто не врет. Просто нужно прочитать не много учебников
> а один.


Сакчай учебник delphi7_self-tuition_beg.zip и пойди найди там эту тему.


 
Alex Konshin ©   (2007-07-27 09:05) [6]

В поваренной книге об этом тоже ничего нет.


 
ya00011   (2007-07-27 09:51) [7]


> Sergey Masloff   (27.07.07 06:00) [4]

Я никогда не понимал смысла в этом case integer of. Зачем указывать тип, когда он ни на что не влияет. Можно было бы просто разработать другой синтаксис. Объясните это?


 
Однокамушкин   (2007-07-27 10:32) [8]


> Я никогда не понимал смысла в этом case integer of. Зачем
> указывать тип, когда он ни на что не влияет. Можно было
> бы просто разработать другой синтаксис. Объясните это?

Исторически так сложилось... В классическом Паскале синтаксис предусматривал наличие селектора - специального поля, которое переключало альтернативы, что-то типа такого:

TSomeType = record
 case S: Integer of
   0: (X: Single;);
   1: (A: array[0..3] of Byte);
end;


Подразумевалась проверка значяения селектора в run-time, т.е., например, к полю X можно было обратиться только тогда, когда поле S было равно 0, иначе - run-time error... аналогично к полю A обращаться можно было только когда S = 1 и т.п. Но это не прижилось из-за больших накладных расходов на проверку, на старых компьютерах это было критично, поэтому многие реализации компиляторов отказывались от проверки значения селектора... В такой ситуации сам селектор стал ненужным, поле выкинули, оставили только тип (точнее - произвольный идентификатор), который ни на что не влияет... Если не ошибаюсь, такое упрощение синтаксиса - это изобретение Borland


 
MBo ©   (2007-07-27 10:53) [9]

>поле выкинули, оставили только тип
есть два вида синтаксиса, один с полем селектора, под него даже место  в записи отводится, только оно не заполняется ;)


 
Жирный   (2007-07-28 07:50) [10]


> Однокамушкин   (27.07.07 10:32) [8]
> TSomeType = record
>  case S: Integer of
>    0: (X: Single;);
>    1: (A: array[0..3] of Byte);
> end;
> В такой ситуации сам селектор стал ненужным, поле выкинули,
>  оставили только тип (точнее - произвольный идентификатор),
>  который ни на что не влияет... Если не ошибаюсь, такое
> упрощение синтаксиса - это изобретение Borland


Нет не выкинули. S можно проверить и в зависимости от него самому обращаться к нужному полю.


 
MBo ©   (2007-07-28 10:36) [11]

>Жирный   (28.07.07 07:50) [10]
> S можно проверить и в зависимости от него самому обращаться к нужному полю.

сам пробовал?

procedure TForm1.Button1Click(Sender: TObject);
type
 TRec = packed record
   case Selector: Byte of
     0: (i: Integer);
     1: (s: Single);
   end;
var
 r: TRec;
begin
 FillChar(r, SizeOf(r), 0);
 r.s := Pi;
 Caption := Format("%d  %d",[SizeOf(r), r.Selector])
end;


 
Жирный   (2007-07-29 07:51) [12]


> MBo ©   (28.07.07 10:36) [11]
>
> >Жирный   (28.07.07 07:50) [10]
> > S можно проверить и в зависимости от него самому обращаться
> к нужному полю.
>
> сам пробовал?


Само собой.
Только Дельфи не выдаёт ошибки если обращаешься не туда. Селектор для человека, а не для неё.


 
Однокамушкин   (2007-07-29 17:32) [13]


> Жирный   (28.07.07 07:50) [10]
> Нет не выкинули. S можно проверить и в зависимости от него
> самому обращаться к нужному полю.

Это всё равно не селектор... В чём разница между

TSomeType1 = record
 case S: Integer of
   0: (X: Single;);
   1: (A: array[0..3] of Byte);
end;

и
TSomeType2 = record
 S: Integer;
 case Integer of
   0: (X: Single;);
   1: (A: array[0..3] of Byte);
end;


А ни в чём! И там, и там для компилятора S - просто поле в записи, никак не связанное с вариантной частью... А то, что человек может придать этому полю смысл селектора - так он его чему угодно придать может... Весь смысл был именно в том, что проверка является обязательной и неявной... Если бы это сохранилось, то даже финализируемые типы вроде string и Variant можно было бы вставлять в вариантную часть - тогда компилятор мог бы при изменении значения селектора финализировать и инициализировать соответствующие альтернативы в вариантной части... А сейчас - не может, и вручную сделать не даёт...


 
TStas ©   (2007-07-29 22:50) [14]

С Сях это, вроде, union называется. Там даже пример есть, как на этом преобразуются типы


 
Жирный   (2007-07-30 01:22) [15]


> Однокамушкин   (29.07.07 17:32) [13]
> А то, что человек может придать этому полю смысл селектора
> - так он его чему угодно придать может...


Только как читающий код об этом догадается? Телепаты вышли из отпуска?


 
TUser ©   (2007-07-31 01:55) [16]

Это рудимент. Кто-нибудь видел код, где record case реально нужен и сипользован?


 
Жирный   (2007-07-31 02:12) [17]


> TUser ©   (31.07.07 01:55) [16]
>
> Это рудимент. Кто-нибудь видел код, где record case реально
> нужен и сипользован?


Конечно.

 TVarData = packed record
   case Integer of
     0: (VType: TVarType;
         case Integer of
           0: (Reserved1: Word;
               case Integer of
                 0: (Reserved2, Reserved3: Word;
                     case Integer of
                       varSmallInt: (VSmallInt: SmallInt);
                       varInteger:  (VInteger: Integer);
                       varSingle:   (VSingle: Single);
                       varDouble:   (VDouble: Double);
                       varCurrency: (VCurrency: Currency);
                       varDate:     (VDate: TDateTime);
                       varOleStr:   (VOleStr: PWideChar);
                       varDispatch: (VDispatch: Pointer);
                       varError:    (VError: HRESULT);
                       varBoolean:  (VBoolean: WordBool);
                       varUnknown:  (VUnknown: Pointer);
                       varShortInt: (VShortInt: ShortInt);
                       varByte:     (VByte: Byte);
                       varWord:     (VWord: Word);
                       varLongWord: (VLongWord: LongWord);
                       varInt64:    (VInt64: Int64);
                       varString:   (VString: Pointer);
                       varAny:      (VAny: Pointer);
                       varArray:    (VArray: PVarArray);
                       varByRef:    (VPointer: Pointer);
                    );
                 1: (VLongs: array[0..2] of LongInt);
              );
           2: (VWords: array [0..6] of Word);
           3: (VBytes: array [0..13] of Byte);
         );
     1: (RawData: array [0..3] of LongInt);
 end;



Если это рудимент, то как ты объявишь TVarData тогда?


 
Жирный   (2007-07-31 02:21) [18]

Или вот ещё:

 TRect = packed record
   case Integer of
     0: (Left, Top, Right, Bottom: Longint);
     1: (TopLeft, BottomRight: TPoint);
 end;


Можно задавать TRect четырьмя числами или двумя точками.


 
ferr ©   (2007-07-31 02:23) [19]

а классом почему нельзя?


 
Жирный   (2007-07-31 02:26) [20]


> ferr ©   (31.07.07 02:23) [19]
>
> а классом почему нельзя?


Типа барон любит чтоб было посложнее?


 
Жирный   (2007-07-31 02:27) [21]

И как именно классом? Напиши такой класс.


 
ferr ©   (2007-07-31 02:35) [22]

> И как именно классом? Напиши такой класс.


public class Rectangle
{
private int _left, _top, _width, _height;

public Point TopLeft

public Point BottomRight

public int X

public int Y

public int Width

public int Height
}


Класс полностью я писать не собираюсь, но морда у него обычно примерно такая. За подробности в .net framework классы Point и PointF.

P.S. в с++ в отличии от c# можно сделать и Rectangle<double>..


 
Плохиш ©   (2007-07-31 02:51) [23]


> ferr ©   (31.07.07 02:35) [22]
> > И как именно классом? Напиши такой класс.
>
>
> public class Rectangle
> {
> private int _left, _top, _width, _height;

Осталось выяснить, какое это имеет отношение к делфи...


 
Однокамушкин   (2007-07-31 09:13) [24]


> Жирный   (31.07.07 02:12) [17]
>  TVarData = packed record
> <...>

Вообще-то этот тип является переводом на Delphi системного типа VARIANT: http://msdn2.microsoft.com/en-us/library/ms221627.aspx

Там нет селектора, сишный синтаксис его вообще не предусматривает, и ничего, всё понятно благодаря комментариям... Потому что всё-таки селектор без принудительной проверки - это не селектор, а способ написания комментария... Не самый лучший способ, кстати...


 
Жирный   (2007-08-01 01:43) [25]


> Там нет селектора, сишный синтаксис его вообще не предусматривает,
>  и ничего, всё понятно благодаря комментариям...

Типичный сишный идиотизм. Непонятный, нечитаемый код, который объясняется комментариями. Иногда на немецком или французском языке.

Пример того каким язык программирования не должен быть.


> Потому что всё-таки селектор без принудительной проверки

Какая тебе нужна проверка в вариантном типе из [17] ?
Или в [18] какая тебе проверка?


 
celades ©   (2007-08-01 02:10) [26]


> Типичный сишный идиотизм. Непонятный, нечитаемый код, который
> объясняется комментариями. Иногда на немецком или французском
> языке.
>
> Пример того каким язык программирования не должен быть.

но увы реальный мир говорит об обратном:(


 
Однокамушкин   (2007-08-01 08:52) [27]


> Жирный   (01.08.07 01:43) [25]
> Какая тебе нужна проверка в вариантном типе из [17] ?

Примерно такая, чтобы код типа
X := VarData.varInteger;
транслировался компилятором вот в такое:
if VarData.VType = varInteger then
 X := VarData.varInteger
else
 raise ... // Неверное значение селектора


Кстати, объявление, приведённое в [17], в этом смысле неправильное, потому что у вариантного типа поле VType является селектором для полей varInteger, varDouble и т.п., а из данного объявления этот вывод сделать нельзя...

> celades ©   (01.08.07 02:10) [26]
> но увы реальный мир говорит об обратном:(

Любите башорг - источник мудрости:

Паша Форкерт: вот ты мне скажи, если фряха такая классная, то почему большинство сидит на линухе?
Bobs: паша
Bobs: если смотреть шире
Bobs: то _большинство_ сидит на винде
Bobs: а если смотреть еще шире, то большинство лускает семечки и спрашивает: "слышь, лох, закурить не найдется?"


http://bash.org.ru/quote/390943

С выбором языка программирования ситуация примерно та же самая...



Страницы: 1 вся ветка

Текущий архив: 2007.08.26;
Скачать: CL | DM;

Наверх




Память: 0.55 MB
Время: 0.03 c
2-1186069152
-==\AnGnA/==-
2007-08-02 19:39
2007.08.26
Куча вопросов


2-1185955901
Glivera
2007-08-01 12:11
2007.08.26
Создание формы


2-1186103207
Adios
2007-08-03 05:06
2007.08.26
MediaPlayer


3-1178100547
dmitrigan
2007-05-02 14:09
2007.08.26
fibplus и трехзвенка


2-1185778225
snake-as
2007-07-30 10:50
2007.08.26
Помогите с освоением ООП