C++Builder  |  Delphi  |  FireMonkey  |  C/C++  |  Free Pascal  |  Firebird
볼랜드포럼 BorlandForum
 경고! 게시물 작성자의 사전 허락없는 메일주소 추출행위 절대 금지
분야별 포럼
C++빌더
델파이
파이어몽키
C/C++
프리파스칼
파이어버드
볼랜드포럼 홈
헤드라인 뉴스
IT 뉴스
공지사항
자유게시판
해피 브레이크
공동 프로젝트
구인/구직
회원 장터
건의사항
운영진 게시판
회원 메뉴
북마크
볼랜드포럼 광고 모집

자유게시판
세상 살아가는 이야기들을 나누는 사랑방입니다.
[25873] 델파이 레코드 가변부분에 대하여
델마를 향하여 [skygarden100] 6078 읽음    2016-03-30 23:45
델파이 가변부분이 왜 필요한지 모르겠어여

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;

구체적으로 레코드 가변부분이 필요한 이유와 예를 하나 들어주시면 감사하겠습니다.
양병규 [bkyang]   2016-03-31 11:35 X

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;와 같이 써야 하죠.

이게 익숙하지 않으면 오히려 헷갈릴 수도 있습니다.
저처럼 자주 쓰는 사람에게는 굉장히 좋은 방법이지만요.

+ -

관련 글 리스트
25873 델파이 레코드 가변부분에 대하여 델마를 향하여 6078 2016/03/30
25874     Re:델파이 레코드 가변부분에 대하여 kylix 5657 2016/03/31
Google
Copyright © 1999-2015, borlandforum.com. All right reserved.