델파이 가변부분이 왜 필요한지 모르겠어여
type
TRecord5 = record
case yes : boolean of
True: (tel : integer);
False: (phone:integer;
address : String[20]);
end;
이렇게 선언하고 인스턴스 생성하면 sizeof(record5) ===>32byte나옵니다.
이걸로 봐서 메모리는 선언한 변수만큼 전부 할당되는것으로 보여집니다. (메모리효율적인 부분도 아니고)
case문에 의해 접근을 여부가 결정되는것도 아닙니다. case 값이 True여도 False쪽 변수에 값넣고 showMessage로
찍어보면 찍힙니다.
즉 , 아래 일반적인 레코드랑 사용하는데 별 차이가 없는듯합니다. 책에 나온 내용도 딱히 이해가 안가고요.
type
TRecord5 = record
tel : integer;
phone:integer;
address : String[20];
end;
구체적으로 레코드 가변부분이 필요한 이유와 예를 하나 들어주시면 감사하겠습니다.
|
kylix님이 설명 잘 해주셨는데.. 좀 보충을 하자면...
type
TRecord2 = record
A: Ineger;
case B: Ineger of
1: ( C: Byte; D: Byte );
2: ( E: Word );
end;
var
Rec: TRecord2;
이렇게 있을 때,
Rec.C의 주소와 Rec.E의 주소는 같습니다.
그러니까 Rec.E := $ABCD;라고 할당하고 Rec.C와 Rec.D의 값을 확인해 보면 $ABCD가 반으로 나누어져서 들어가 있음을 확인할 수 있습니다.
Kylix님이 올리신 도움말의 예제처럼 헤더부분은 같은데 바디부분이나 혹은 풋터부분이 다른 여러 형태의 데이터를 하나로 선언할때에도 쓰이구요.
저같은 경우는 레코드를 비교할 때나 한 번에 값을 할당할 때에도 꽤 자주 사용하고 있습니다.
예컨데...
type
TRectangle = record
case Boolean of
True: ( Left: Word;
Top: Word;
Width: Word;
Height: Word );
False: ( Value: Int64 );
end;
이렇게 선언하구요.
( 저는 주로 case Yes: Boolean of 하지 않고, case Boolean of 이렇게 합니다. 그러면 그만큼 사이즈도 빠집니다.)
이 경우, Left, Top, Width, Height 네 멤버를 합친 메모리 공간이 Value 멤버 하나의 메모리 공간과 같은 주소, 같은 사이즈입니다. 아래처럼 두 개의 TRectangle이 완전히 일치하는지 확인하려면 네 멤버를 모두 비교해야 하는데요.
var
R1: TRecord;
R2: TRecord;
begin
...
if R1.Value = R2.Value then
...
이렇게 하면 두 레코드의 멤버들 (Left, Top, Width, Height) 값을 한 라인으로 모두 비교할 수 있습니다. Word형 네 번을 비교하는 것보다 당연히 Int64로 한 번에 비교하는 게 빠르겠죠.(물론, 속도때문이라기 보다는 코드를 간결하게 하기 위해서 저는 이렇게 씁니다.)
Left, Top, Width, Height 멤버들을 잠시 백업한다거나 복구하거나 그럴 때도
var
R1: TRecord;
Temp: Int64;
begin
...
Temp := R1.Value;
이런 식으로 하면 간편하구요.
초기화 할 때도, R1.Value := 0;하면 되니까 FillChar나 ZeroMemory같은 거 안 써도 되구요.
특히, 멤버가 더 많이 있을 때, 다른 멤버들은 놔두고 딱 그 네 개의 멤버가 초기화할 때에는 이런 초기화가 유용합니다.
물론 그 네 멤버만 따로 레코드로 선언해도 되지만 그러면 R1.Bound.Left := 12;와 같이 써야 하죠.
이게 익숙하지 않으면 오히려 헷갈릴 수도 있습니다.
저처럼 자주 쓰는 사람에게는 굉장히 좋은 방법이지만요.