Delphi pointer

7604 단어 Delphi
어떻게 해야만 Pointer 포인터의 모든 데이터에 접근할 수 있습니까?(여러 가지 방법이 함께 설명하는 것이 좋다) 예: varp:pointerbeginp:= 하나의 바늘 변수 p:=p+1;//왜 이렇게 사용하면 안 돼요?어떻게 해야만 다음 주소를 가리킬 수 있습니까?end;
varp: pointer;s: string;begins:= 'abc';p:= PChar(s);//포인터에 값 p:= Pointer(Integer(p)+1);//포인터를 뒤로 이동: = string(Char(p^);//뒤로 이동한 바늘 내용 end 읽기;
나는 이런 코드를 가지고 있다 varPos: Byte;PP: PByte;Pos := 1PP := PP + Pos;PP^ := 12;이 세 마디에서 델피는 항상 두 번째 문장에 오류가 있다고 말한다. 나는 이렇게 쓰면 문제가 없다는 것을 안다. PP[Pos]:=12;그런데 가끔은 C랑 달라서 익숙하지 않아요.
Delphi의 Integer 및 Pointer, 0 및 nil
엊그저께 한 동료가 나에게 델피의 Pointer에 관한 문제를 묻자 그와 함께 퇴고한 결과 재미있는 결론을 발견했다. 델피의nil=0;
생각해 보면 이것도 이해하기 쉽다. 32비트 Windows 운영체제에서 하나의 정수는 32비트이고 하나의 바늘도 32비트의 무기호 정수이다.
그러나 구체적인 프로그래밍상의 조작은 비교적 재미있습니다. 여러분, 보십시오.
var
a : Pointer;
begin
//a := nil;
ifAssigned(a)then
begin
ShowMessage('나는 뭔가')
end
else
begin
ShowMessage('나는 재주가 없어')
end
end;
결과:'나는 종류가 있다'는 것은 Pointer가 Integer와 같다는 것을 설명하고 성명한 후에 반드시 초기화해야 한다는 것이다.
다음을 살펴보십시오.
var
a : Pointer;
begin
a := 0;
ifAssigned(a)then
begin
ShowMessage('나는 뭔가')
end
else
begin
ShowMessage('나는 재주가 없어')
end
end;
결과는'나는 종류가 없다'는 것이다. 이것은 Pointer에 대해 nil은 사실 이 Pointer의 메모리 주소가 $0000000이라는 것을 설명한다.
포인터 포인터@
var p1,p2,p3:pointerS:String;I:Integer;beginp1:= Pointer(S);p2:= @S;P3:= pchar(s);//p1과 p2 p3은 어떤 차이가 있습니까?Pointer(S)^ 문자열 및 Bufferend;
Pointer는 Borland VCL의 구조 유형입니다.그래서 Ppointer 이런 것도 있어요!관리 클래스의 클래스와 같은 포인터의 포인터입니다. @주소를 찾는 작업입니다.무엇이든지 주소를 찾을 수 있습니다.그러나 빼낸 것이 반드시 내용의 방문을 할 수 있는 것은 아니다.이것은 하나의 숫자로 실제 현장을 벗어나면 의미가 없다.(한 변수가 다음에 같은 물리적 메모리를 사용할 수는 없겠지ㅋㅋ)pchar는 문자열 그룹의 첫 번째 주소를 가리킨다."/0"이 끝날 때까지 뒤에 이어지는 문자열입니다.
비록 일부 필요한 기능인델파이나 제3자는 대부분 소자나 원본 코드를 제공했지만, C++에서 자체로 코드를 바꾸어 사용하려면 정말 번거롭다. 아래를 봐라
function GetHostAddress(const hostname : string) : u_long;
var
pHostAddr : PHostEnt;
type
T = ^u_long;
begin
pHostAddr := gethostbyname(PCHAR(hostname));
if (pHostAddr = nil) then
begin
result := 0;
end
else
begin
result := T(pHostAddr^.h_addr^)^;
end;
end;

생각건대 틀림없이 C++에서 직접 범례대로 쓴 것 같은데, 무엇을 하는지 알 수 있을까요?지표는 Object Pascal Language Guide에서 언급됐고, 델파이 학습노트도 한 단락 언급됐다.그러나 나의 관념으로는 대체로 이와 같을 뿐이다
type
TStruct=record
no:integer;
name:string;
end;
PStruct=^TStruct;
var
i:integer;
pi:PInteger;
group:array[0..10] of TStruct;
PMember:PStruct;
begin
pi:=@i;
pi^:=10;
ShowMessage(IntToStr(i));
PMember:=@group[0];
PMember.no:=1;
PMember.name:=' ';
Inc(PMember);
PMember.no:=2;
PMember.name:='sunshine';
ShowMessage(group[0].name);
Dec(PMember);
PMember^.name:=' ';
ShowMessage(group[0].name);
end;

같이 연구해보자...>대부분의 사람들이delphi로 자료 라이브러리를 개발하고 >Pointer를 사용하는 것은 정말 많지 않다고 생각합니다. 많은 일들을델파이가 당신을 위해 잘 해 주었습니다(예를 들어 동적 진열)>C++처럼 스스로 컨트롤해야 하지 않습니다.So...적어도 지금까지 나는 그가 동적 Record에서 > 낮은 단계의 제어를 하지 않는 한 delphi로 하지는 않았을 것이다. >anyway 매뉴얼에 있는 Pascal에 대한 설명이 매우 상세하다 >>Sample 코드가 Pointer에 사용되는 것을 자주 보았다.그러나 중국어나 영어책을 막론하고 >>Pointer는 언급하지 마십시오.설령 페이지 수가 있다 하더라도 매우 적다.Delphi에Pointer가 있다는 것을 잊어버렸습니다.Delphi에서 바늘 파라미터를 사용하면 c 언어에서function(int ^par)을 사용하면 매우 편리하다. 많은 자료를 찾아보았지만델피의 사용법을 찾지 못했다. 오늘 밤은 별일 없이델피의 만능 바늘pointer(무유형 바늘)로 대체할 수 있을 것이라는 생각이 떠올랐다.테스트 통과.procedure xx(a:pchar); [확장 정보:Javascript로 구현된 "Dua] vartm:^tadodataset;begintm:=pointer(a);end;procedure bb;vartm:tadodataset;begintm...xx(@tm);
end;
모두가 C언어가 강한 이유와 그 자유성은 대부분이 유연한 지침 운용에 나타난다고 생각한다.따라서 지침은 C 언어의 영혼이라고 해도 과언이 아니다.아울러 이런 주장은 C 언어의 지침만 지침을 계산할 수 있는 것처럼 오해를 낳기도 한다.Basic에서는 포인터를 지원하지 않습니다.사실 Pascal 언어 자체도 포인터를 지원합니다.최초의 Pascal에서 지금까지 발전한 Object Pascal은 포인터 운용에서 C 언어의 포인터에 손색이 없다고 할 수 있다.다음 내용은 8부분으로 나뉘는데 각각 1, 유형 지침의 정의 2, 무유형 지침의 정의 3, 지침의 인용 해제 4, 주소 찾기(지침 부여) 5, 지침 연산 6, 동적 메모리 분배 7, 문자 수조의 연산 8, 함수 지침 1, 유형 지침의 정의이다.특정 유형을 가리키는 바늘에 대해 C에서 이렇게 정의합니다: int *ptr;char *ptr; 그와 동등한 Object Pascal은 어떻게 정의합니까?var ptr : ^Integer; ptr : ^char; 사실은 기호의 차이일 뿐이다.2. 유형 포인터의 정의가 없습니다.C에는 모든 유형의 데이터를 가리키는 포인터인 void * 형식이 있습니다.Object Pascal은 Pointer라는 특수 유형을 정의합니다.그래서 ptr: Pointer;C의 void *ptr와;등가했어.3. 지침의 인용 해제.포인터 참조를 해제하려면 C의 구문은 (*ptr)이고 Object Pascal은 ptr^입니다.4. 주소를 얻는다.대상의 주소를 취하고 포인터 변수에 값을 부여합니다. C의 문법은 ptr = & Object입니다.Object Pascal은 ptr: = @Object입니다.기호의 차이일 뿐이다.5. 지침 연산.C에서 바늘을 이동하는 연산을 할 수 있다. 예를 들어chara[20].char *ptr=a; ptr++; ptr+=2; ptr++ 실행하기;컴파일러는 ptr를 sizeof(char) 보폭으로 전진시키는 코드를 생성하고 그 다음에 ptr는 a[1]를 가리킨다.ptr+=2;이 구절은 ptr로 하여금 두 개의 sizeof (char) 크기의 보폭을 앞으로 가게 한다.마찬가지로 Object Pascal에서 var a:array[1.20] of Char를 어떻게 구현하는지 살펴보겠습니다.ptr : PChar;//PChar는 ^Char begin ptr: = @a로 볼 수 있습니다.Inc(ptr);//이 문장은 C의 ptr++와 같다.Inc(ptr, 2);//이 문장은 C의 ptr+=2와 같다.end; 다만, 패스컬에서는 유형이 있는 포인터에 대해서만 이러한 연산이 허용되며, 유형이 없는 포인터에 대해서는 안 된다.6. 동적 메모리 분배.C에서malloc() 라이브러리 함수를 사용하여 메모리를 분배하고free() 함수로 메모리를 방출합니다.이와 같은 코드: int *ptr, *ptr2;int i; ptr = (int*) malloc(sizeof(int) * 20); ptr2 = ptr; for (i=0; i<20; i++){ *ptr = i; ptr++; } free(ptr2); Object Pascal에서 메모리를 동적으로 할당하는 함수는 GetMem()이고, 이에 대응하는 방출 함수는 FreeMem()(기존 Pascal에서 메모리를 가져오는 함수는 New()와 Dispose()이지만 New()는 객체의 단일 엔티티의 메모리 크기만 얻을 수 있고 여러 객체가 연속적으로 저장되는 메모리 블록은 얻을 수 없습니다).따라서 위의 C 코드와 동일한 Object Pascal 코드는 var ptr, ptr2:^integer입니다.i : integer; begin GetMem(ptr, sizeof(integer) * 20);//이 문장은 C와 같은 ptr=(int*)malloc(sizeof(int)*20);ptr2 := ptr;//원래 포인터 위치 for i: = 0 to 19 do begin ptr^: = i;Inc(ptr); end; FreeMem(ptr2); end; 상기 이 예(C 버전이든 Object Pascal 버전이든)에 대해 주의해야 할 문제는 메모리를 분배하는 단위가 바이트(BYTE)이기 때문에 GetMem을 사용할 때 두 번째 파라미터가 당연하게 20으로 쓰려면 문제가 생긴다는 것이다(메모리 접근이 경계를 넘는다).GetMem(ptr, 20) 때문에;실제적으로 20바이트의 메모리 공간만 분배되고 한 성형의 크기는 4바이트이면 다섯 번째 다음에 접근한 모든 요소는 불법이다. (malloc () 파라미터에 대해서도 마찬가지다.7. 문자수 그룹의 연산.C 언어에는 문자열 형식이 없기 때문에 문자열은 모두 문자열 그룹으로 이루어진다. 그래서str 헤더의 라이브러리 함수도 문자열 그룹의 연산을 진행한다. 예를 들어 다음과 같은 코드:charstr[15].char *pstr; strcpy(str, "teststr"); strcat(str, "_testok"); pstr = (char*) malloc(sizeof(char) * 15); strcpy(pstr, str); printf(pstr); free(pstr); Object Pascal에는 String 유형이 있어 다양한 문자열을 쉽게 연산할 수 있습니다.그러나 때때로 우리 Pascal 코드는 C의 코드와 상호작용을 해야 한다(예를 들어 Object Pascal 코드로 C가 쓴 DLL을 호출하거나 Object Pascal이 쓴 DLL로 C가 클라이언트의 코드를 쓸 수 있도록 준비한다). 그러면 String 형식을 사용할 수 없고 두 언어가 통용하는 문자 그룹을 사용해야 한다.사실, Object Pascal은 C와 완전히 비슷한 일련의 문자 배열의 연산 함수를 제공합니다. 상기 코드의 Object Pascal 버전은 다음과 같습니다. var str:array[1.15] of char;pstr : PChar;//Pchar 즉 ^Char begin Stropy (@str,'teststr');//C에서 수조의 이름은 수조의 첫 번째 주소 포인터로 직접 사용할 수 있지만//Pascal은 그렇지 않기 때문에str 앞에 주소를 얻는 연산자 StrCat(@str, 'testok')를 추가해야 한다.GetMem(pstr, sizeof(char) * 15); StrCopy(pstr, @str); Write(pstr); FreeMem(pstr); end; 8. 함수 지침.DLL에서 함수를 동적으로 호출할 때 함수 포인터가 사용됩니다.C로 작성된 코드는 다음과 같습니다. typedef int(*PVFN)(int);//함수 포인터 유형 int main() {HMODULE hModule = LoadLibrary("test.dll"), PVFN pvfn = NULL, pvfn = (PVFN) GetProcAddress(hModule, "Function1"), pvfn(2), FreeLibrary(hModule),개인적으로 C 언어에서 함수 포인터 유형을 정의하는 typedef 코드의 문법은 좀 난해하지만 같은 코드는 Object Pascal에서 매우 이해하기 쉽다. type PVFN = Function(para: Integer): Integer;var fn : PVFN;//fn:function(para:Integer):Integer,hm : HMODULE; begin hm := LoadLibrary('test.dll'); fn := GetProcAddress(hm, 'Function1'); fn(2); FreeLibrary(hm); end;

좋은 웹페이지 즐겨찾기