델파이 포인터 (Pointer) 11편
데이터 좌표에 의한 수정
포인터
C/C++
int* pNum; // integer pointer
char* pText; // char pointer ..
*pNum = 123456;
*pText = 'C';
Delphi
pNum: ^integer; // integer pointer
pText: ^Char; // char pointer ...
pNum^ := 123456;
pText^ := 'C';
델파이와 포인터
델파이에선 C/C++ 과 달리 포인터 타입에 주의 하여야 합니다.
C/C++ : 어떤 타입의 포인터이든 대입 가능
int* pNum;
char* pText;
...
pNum = pText;
pText = pNum;
Delphi : 다른 타입의 포인터를 대입 하면 에러 간주
pNum: PInteger;
pText: PChar;
...
pNum := pText; // 에러.
Pointer Type 이 다름
char* vs PChar
C/C++ 의 char* 과 Delphi PChar 는 완전히 같다.
포인터 타입 에러 처리
포인터를 사용하면 자유롭게 데이터를 사용 할 수 있는데,
타입 에러가 나면 불편함.
Pointer type으로 wrapping 하면 됩니다.
Pointer type 은 타입 없는 포인터 입니다.
pNum: PInteger;
pText: PChar;
...
pNum := Pointer(pText); // Pointer Type 에러 안남
String 과 PChar
String 에 대해서 인덱스로 접근 하는 방법( sTemp[n] ) 과
포인터로 접근 하는 방법( PChar )이 있습니다.
Delphi 에서는 String 을 인덱스로 접근 하는
내부 함수가 최적화 되어 있어서,
sTemp[n] 방법이 pTemp^ 방법 보다 조금 빠르거나
비슷하다고 합니다.
예) String 의 "," 를 "=" 로 변경
(내용 중에 " ' "이 들어가면 올라가지 않아서 " " " 로 변경)
sTemp: string;
pTemp: PChar;
i: integer;
...
for i := 1 to Length(sTemp) do // 인덱스로 접근 방법
begin
if sTemp[i] = "," then
sTemp[i] := "=";
...
end;
...
pTemp := PChar(sTemp); // 포인터로 접근 하는 방법
for i := 1 to Length(sTemp) do
begin
if pTemp^ = "," then
pTemp^ := "=";
pTemp := pTemp + 1;
...
end;
Delphi 에서 포인터를 사용을 대신 할 수 있는 기능이 있다.
Call by Reference
C/C++
void Swap(int* ANum1, int* ANum2) {
int nTemp = 0;
nTemp = *ANum1;
*ANum1 = *ANum2;
*ANum2 = nTemp;
}
...
int nNum1, nNum2;
Swap(&nNum1, &nNum2);
Delphi
procedure Swap(var ANum1: integer; var ANum2: integer);
var
nTemp: integer;
begin
nTemp := ANum1;
ANum1 := ANum2;
ANum2 := nTemp;
end;
...
nNum1, nNum2: integer;
Swap(nNum1, nNum2);
char*
C/C++
char* pTemp;
char* pText = "This is sample"; // 메모리 할당 1
pText += 3;
*pText = 'e'; // 데이터 수정
pTemp = (char*)malloc(15); // 메모리 할당 2
memcpy(pText, pTemp, 15); // 데이터 복사
pTemp += 4;
*pTemp = 'n'; // 데이터 수정
Delphi
pTemp, pText: string;
pText := 'This is sample'; // 메모리 할당 1
pText[4] := 'e'; // 데이터 수정
pTemp := pText;
pTemp[5] := 'n'; // 메모리 할당 2, 데이터 복사, 데이터 수정
Structure
C/C++ 에서는 Structure 의 멤버 변수 일일이 대입하는게 힘들어서,
포인터로 클래스나 함수에 넘긴다.
Delphi 에서는 멤버 변수 일괄 대입해 준다.
C/C**
Struct tagTest {
int nAttack, nDefend, nStr, nInt, nDex, nVal; }
...
tagTest Test1, Test2; ...
Test2->nAttack = Test1->nAttack;
Test2->nDefend = Test1->nDefend;
Test2->nStr = Test1->nStr;
Test2->nInt = Test1->nInt;
Test2->nDex = Test1->nDex;
Test2->nVal = Test1->nVal;
Delphi
tagTest = record
nAttack, nDefend, nStr, nInt, nDex, nVal: integer;
end;
...
Test1, Test2: tagTest; ...
Test2 := Test1;
void *
C/C** void* MyFunc(void* SumType, int Size) {
char* pBuf;
pBuf = SumType;
...
}
...
MyFunc(&sText, 10);
MyFunc(&Test1, sizeof(tagTest));
MyFunc(&nNum1, sizeof(integer));
Delphi
procedure MyFunc(const SumType; Size: integer); // 변수 타입이 없슴
var
pBuf: PChar;
begin
pBuf := PChar(@SumType);
...
end;
...
MyFunc(sText[1], 10);
MyFunc(Test1, sizeof(tagTest));
MyFunc(nNum1, sizeof(integer));
String
C/C++
char* pTest = (char*)malloc(100); // 메모리 할당
memset(pTest, 100) ; // 초기화
Delphi
pTest: PChar; ...
SetLength(pTest, 100); // 메모리 할당
FillChar(pTest, 0, 100); // 초기화
멤버 변수
Delphi 는 포인터 변수를 포인터 안쓰고
처리 할수 있게 서비스 하고 있습니다.
Window API 를 쓰는 경우 와 같이 포인터 사용이 불가피한 경우에도
포인터 사용하지 않아도 되도록 한 것 같습니다.
PTestData = ^TTestData;
TTestData = record
'Delphi > 문법' 카테고리의 다른 글
델파이 Self (0) | 2023.09.20 |
---|---|
델파이 Owner 와 Parent (0) | 2023.09.13 |
델파이 포인터 (Pointer) 10편 (0) | 2023.08.23 |
델파이 포인터 (Pointer) 9편 (0) | 2023.08.22 |
델파이 포인터 (Pointer) 8편 (0) | 2023.08.21 |
댓글