Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: Общие вопросы > Записи


Автор: Marlin 15.9.2005, 09:10
Довольно стыдно задавать такой вопрос, но лучше спросить чем быть в неведении.

Чем отличается такой вид записи:


Код

in_addr=record
case Integer of
      0:(S_un_b:SunB);
      1:(S_un_w:SunW);
      2:(S_addr:u_long);
end;
TInAddr=in_addr;


От такого вида:

Код

in_addr=record
   S_un_b:SunB;
   S_un_w:SunW;
   S_addr:u_long;
end;
TInAddr=in_addr;


Меня интересует "case Integer of" зачем мне выбор значения в структуре?
Допустим мне нужно передать указатель на структуру данных, которую я заполнил, ведь я ничего не выбирал не указывал никакого значения.

И еще вопрос?

Запись:

Код

MyRecord = Record
    pole1: integer;  
    Pole2: integer;
    Pole3: integer;
end;


А теперь запись

Код

MyRecord =Packed Record
    pole1: integer;  
    Pole2: integer;
    Pole3: integer;
end;


В данном случае меня интересует служебное слово Packed (Упакованный). Для чего его нужно писать?

В книгах ничего об этом не говориться, Растолкуйте пожалуйста.

Автор: ~FoX~ 15.9.2005, 09:22
Цитата

By default, the values in a structured type are aligned on word or double-word boundaries for faster access. When you declare a structured type, you can include the reserved word packed to implement compressed data storage. For example,

type TNumbers = packed array[1..100] of Real;

Using packed slows data access and, in the case of a character array, affects type compatibility

Добавлено @ 09:27
Цитата(Marlin @ 15.9.2005, 10:10)
Меня интересует "case Integer of" зачем мне выбор значения в структуре?

Кажись перечелсяемы тип просто.

Автор: Snowy 15.9.2005, 10:43
Цитата(Marlin @ 15.9.2005, 09:10)
Чем отличается такой вид записи:

В случае case память на все записи одна, просто доступ к ней может осуществляться, как к разным полям.
То есть, записывая в третье поле - меняются первые два.
Во втором случае каждое поле имеет свою собственную память.


Цитата(Marlin @ 15.9.2005, 09:10)
слово Packed (Упакованный). Для чего его нужно писать?

По умолчанию компилятор оптимизирует запись в памяти для наиболее быстрого доступа к полям. Но, если мы хотим создать точную структуру, без оптимизации, то нужно использовать слово packed, чтобы компилятор собрал запись строго так, как мы ему указали, без выравнивания.

Автор: StayAtHome 15.9.2005, 11:03
Запись с case (вариантная запись) используется в типе Rect (реализация прямоугольника в Delphi). Там хорошо видно, для чего она может быть нужна:
Код

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

Т. е. можно обращатся и к X,Y-координатам как
Код

aRectangle.Left, Rec.Top
, и сразу к целым углам прямоугольника:
Код

aRectangle.TopLeft
или даже так
Код

aRectangle.TopLeft.X, aRectangle.TopLeft.Y

Довольно остроумно, ИМХО.

Автор: Петрович 15.9.2005, 11:10
По поводу packed.
Испльзуется если описываемая запись отражает какую-либо внешнюю структуру. Если оно указано, то поля располагаются в памяти плотно. Размер такой записи равен сумме размеров каждого поля. Если-же packed не указано, то между полями могут быть добавлены лишние (не используемые) байты, предназначенные для выравнивания отдельных полей на границу машинного слова. Это для ускорения доступа к ним.
Например, структура:
Код

MyRecord1 = Record
    Pole1: Char;  
    Pole2: integer;
end;
будет занимать в памяти 8 байт.
А структура:
Код

MyRecord2 = packed Record
    Pole1: Char;  
    Pole2: integer;
end;
будет занимать в памяти 5 байт.
Зато обращение к MyRecord2.Pole1 будет требовать немножко больше времени. Хотя, для современных процессоров, эта разница может быть несущественной, либо вообще отсутствовать.

Теперь, вкратце о case в record'ах.

Такая конструкция называется вариантной записью. Используется тогда, когда один и тот-же record предназначен для размещения данных либо одного, либо другого типа.
Например:
Код

tNameType = (ntFirstName,ntLastName);
tPersone = record
  case NameType :tNameType of
    ntFirstName: (FirstName:String);
    ntLastName: (LastName:String);
end;

Эта запись может хранить либо фамилию, либо имя персонажа. Что именно в ней хранится в данный момент, определяется значением поля NameType.
Это классическое применение вариантной записи. Есть еще одно применение, используемое для обхода механизма жесткой проверки типов. Оно как раз самое частое. В твоем примере:
Код

in_addr=record
case Integer of
      0:(S_un_b:SunB);
      1:(S_un_w:SunW);
      2:(S_addr:u_long);
end;

где:
Код

  SunB = array[0..3] of byte;
  SunW = array[0..1] of word;
  u_long = dword;

переменная типа in_addr занимает 4 байта (dword). Но, можно обратиться например к младшему слову как v.SunW[2], или к старшему байту как v.SunB[3].

Более подробно, можно прочитать в книжках. smile


Автор: Romikgy 15.9.2005, 13:37
Цитата
case Integer of

аналог сишного union !!!

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)