1.
procedure TForm1.Button1Click(Sender: TObject);
var
i : Integer;
Addr : Pointer;
begin
i := 1234;
Addr := @i;
ShowMessage(inttostr(integer(Addr^)));
end;
2.
type
PInteger = ^Integer;
procedure TForm1.Button1Click(Sender: TObject);
var
Addr : PInteger;
begin
New(Addr);
Addr^ := 1234;
ShowMessage(inttostr(Addr^));
Dispose( Addr );
end;
1번의 경우 ShowMessage함수를 2와 같이
ShowMessage(inttostr(Addr^));
로 쓰면 에러가 납니다.
[Error] Unit1.pas(33): There is no overloaded version of 'IntToStr' that can be called with these arguments
' Addr^ '는 정수이기 때문에 integer()로 형변환(?)해줄 필요 없을 것 같은데요..
차이점인 무엇인지 알려주시면 정말 감사하겠습니다. :)
당연한 내용입니다.
포인터를 잘 쓰실려면 항상 포인터 타입에 대해 신경을 써야 합니다.
variable 은 size 와 type 에 대한 정의 입니다.
가령 integer 라면 4 바이트의 메모리 공간을 가지고 integer type 입니다.
또한 array [0..9] of char 라면 10 바이트의 메모리 size을 가지고 char type 입니다.
포인터는 size 에 대한 정보 없이 type 에 대한 정의만 가지고 있습니다.
PInteger: ^Integer;
PChar: ^Char;
와 같죠.
그럼 1번 케이스에서 포인터 컴파일러 입장에서 보죠. Addr 영역의 주소값을 읽어 해당 공간에서 값을 읽을려는데, 어떤 type 인지 몰라서 읽지 못합니다. (가령 char 타입이면 1바이트를 읽고, integer 타입이면 4바이트를 읽어야 합니다)
이 문제는 IntToStr()에 파라미터로 포인터의 값을 넘겨 주는 부분에서 발생합니다.
반면에 2번은 포인터의 타입을 알 수 있죠.
사실, C/C++ 에서는 2번의 경우도 에러가 나든가 버그가 생겨야 정상 입니다만, 델파이에선 친절(?)하게도 타입 정의가 있다면 찾아서 적용합니다.
즐푸하세여..
타락천사..
사족: 포인터 개념잡기에는 C 가 최곱니다.