2013-05-31

[델파이] 포인터의 이해

PAnsiChar
type PAnsiChar = ^AnsiChar;

타입을 보시면 아시겠지만 AnsiChar의 포인터 형입니다. 포인터 이므로 Inc나 Dec 같은 연산이 가능합니다. C처럼 종료 문자열은 NULL 입니다.

샘플 코드 입니다.
var
  myString  : AnsiString;
  myCharPtr : PAnsiChar;
  i : Integer;

begin
  // Create a string of AnsiChar's
  myString  := 'Hello World';

  // Point to the first character in the string
  i := 1;
  myCharPtr := Addr(myString[i]);

  // Display all characters in the string
  while i <= Length(myString) do
  begin
    ShowMessage(myCharPtr^);
    Inc(i);
    Inc(myCharPtr);
  end;
end;
   H
   e
   l
   l
   o
   
   W
   o
   r
   l
   d

PAnsiString
type PAnsiString = ^AnsiString;

AnsiString 자체가 포인터이므로 PAnsiString은 잘 이용되지 않습니다.

PChar
type PChar = ^Char;

PChar는 Char 값의 포인터 입니다. 정수연산을 하듯이 Inc나 Dec등으로 포인터를 더하거나 뺄 수 있습니다.

var
  myString  : string;
  myCharPtr : PChar;
  i : Integer;

begin
  // Create a string of Char's
  myString  := 'Hello World';

  // Point to the first character in the string
  i := 1;
  myCharPtr := Addr(myString[i]);

  // Display all characters in the string
  while i <= Length(myString) do
  begin
    ShowMessage(myCharPtr^);
    Inc(i);
    Inc(myCharPtr);
  end;
end;
   H
   e
   l
   l
   o
   
   W
   o
   r
   l
   d

PCurrency
type PCurrency = ^Currency;

var
  currPtr : PCurrency;

begin
  // Allocate storage for three currency variables
  GetMem(currPtr, 3 * SizeOf(Currency));

  // Fill out these currency variables
  currPtr^ := 123.45;
  Inc(currPtr);
  currPtr^ := 2.9;
  Inc(currPtr);
  currPtr^ := 87654321;

  // Now display these values
  Dec(currPtr, 2);
  ShowMessageFmt('Currency 1 = %m',[currPtr^]);
  Inc(currPtr);
  ShowMessageFmt('Currency 2 = %m',[currPtr^]);
  Inc(currPtr);
  ShowMessageFmt('Currency 3 = %m',[currPtr^]);
end;
Currency 1 = ?123.45
Currency 2 = ?2.90
Currency 3 = ?87,654,321.00

PDateTime
type PDateTime = ^TDateTime;

var
  dateTimePtr : PDateTime;
  a : TDateTime;

begin
  // Allocate storage for three date time variables
  GetMem(dateTimePtr, 3 * SizeOf(Extended));

  // Fill out these date time variables
  dateTimePtr^ := Yesterday;
  Inc(dateTimePtr);
  dateTimePtr^ := Date;
  Inc(dateTimePtr);
  dateTimePtr^ := Tomorrow;

  // Now display these values
  Dec(dateTimePtr, 2);
  ShowMessage('Yesterday = '+DateToStr(dateTimePtr^));
  Inc(dateTimePtr);
  ShowMessage('Today     = '+DateToStr(dateTimePtr^));
  Inc(dateTimePtr);
  ShowMessage('Tomorrow  = '+DateToStr(dateTimePtr^));
end;
Typical program output:
   
Yesterday = 10/04/2003
Today     = 11/04/2003
Tomorrow  = 12/04/2003

PExtended
type PExtended = ^Extended;

var
  extPtr : PExtended;

begin
  // Allocate storage for three extended variables
  GetMem(extPtr, 3 * SizeOf(Extended));

  // Fill out these extended variables
  extPtr^ := 123.45;
  Inc(extPtr);
  extPtr^ := 2.9;
  Inc(extPtr);
  extPtr^ := 87654321;

  // Now display these values
  Dec(extPtr, 2);
  ShowMessageFmt('Value 1 = %f',[extPtr^]);
  Inc(extPtr);
  ShowMessageFmt('Value 2 = %f',[extPtr^]);
  Inc(extPtr);
  ShowMessageFmt('Value 3 = %f',[extPtr^]);
end;
Value 1 = 123.45
Value 2 = 2.90
Value 3 = 87654321.00

PInt64
type PInt64 = ^Int64;

var
  int64Ptr : PInt64;
  a : TDateTime;

begin
  // Allocate storage for three Int64 variables
  GetMem(int64Ptr, 3 * SizeOf(Int64));

  // Fill out these Int64 variables
  int64Ptr^ := 1;
  Inc(int64Ptr);
  int64Ptr^ := 22;
  Inc(int64Ptr);
  int64Ptr^ := 333;

  // Now display these values
  Dec(int64Ptr, 2);
  ShowMessageFmt('Value 1 = %d',[int64Ptr^]);
  Inc(int64Ptr);
  ShowMessageFmt('Value 2 = %d',[int64Ptr^]);
  Inc(int64Ptr);
  ShowMessageFmt('Value 3 = %d',[int64Ptr^]);
end;
Value 1 = 1
Value 2 = 22
Value 3 = 333

Pointer
type Pointer;

포인터 변수 유형은 모든 메모리를 기반으로 일반적인 사용에 대한 포인터를 제공합니다. 즉 어떤 데이터 타입이든 넣을 수 있습니다. 예로 객체, 스트링, 배열등 어떠한 형이라도 참조가 가능합니다. 하지만 주의 할 것은 형식화되지 않은 포인터의 사용은 많은 문제를 유발할 수 있습니다. 되도록이면 형식에 맞는 포인터 유형을 사용 하는 것이 좋습니다.

var
  generalPtr : Pointer;  // A pointer to anything
  formPtr    : ^TForm;   // A pointer to a form object

begin
  // The current unit's form is addressable via the self keyword
  generalPtr := Addr(self);

  // We can assign this pointer to the form pointer
  formPtr := generalPtr;

  // And set the form caption to show this
  formPtr.Caption := 'Test program';
end;
The form is shown with caption:
   
Test program

PShortString
type PShortString = ^ShortString;

var
  myString  : shortString;
  stringPtr : PShortString;

begin
  // Set up our short string
  myString := 'Hello World';

  // Point to our string
  stringPtr := Addr(myString);

  // Display the string using the pointer
  ShowMessage(stringPtr^);
end;
Hello World

PString
type PString = ^String;

String 자체가 포인터이므로 잘 사용되지 않습니다.

PVariant
type PVariant = ^Variant;

PWideChar
PWideChar = ^WideChar;

var
  myWideString  : WideString;
  myWideCharPtr : PWideChar;
  i : Integer;

begin
  // Create a string of WideChar's
  myWideString  := 'Hello';

  // Point to the first character in the string
  myWideCharPtr := Addr(myWideString[1]);

  // Display the string
  ShowMessage(myWideCharPtr);

  // Now increment the pointer
  Inc(myWideCharPtr,2);

  // And see what is shows now
  ShowMessage(myWideCharPtr);

  // Display all characters in the string
  while i <= Length(myWideString) do
  begin
    ShowMessage(myWideCharPtr^);
    Inc(i);
    Inc(myWIdeCharPtr);
  end;
end;
Hello
llo

PWideString
type PWideString = ^WideString;

댓글 없음: