It is thought that the reason why C is strong, and its freedom, is largely reflected in its flexible use of pointers. Therefore, it is not too important to say that the pointer is the soul of C language. At the same time, this argument also makes a lot of people misunderstanding, it seems that only the C language pointer can be counted. Basic does not support pointers, regardless. In fact, the Pascal language itself also supports pointers. The Object Pascal, from the very beginning of Pascal's development, can be said to be in the hands of the pointer, not inferior to the C language pointer.
The following sections are divided into eight parts, namely
Definition of a type pointer
Ii. definition of an untyped pointer
Iii. dereferencing A pointer
Iv. Fetch Address (pointer assignment value)
Five, pointer arithmetic
VI. Dynamic Memory allocation
Vii. Arithmetic of character array
Eight, function pointers
The definition of a type pointer. For pointers to specific types, this is defined in C:
int *ptr;
Char *ptr;
How is the equivalent of the object Pascal defined?
Var
PTR: ^integer;
PTR: ^char;
In fact, the difference between the symbols.
Second, the definition of the untyped pointer. There is a void * type in C, which is a pointer to any type of data. Object Pascal defines a specific type for it: Pointer. So
Ptr:pointer;
As in C.
void *ptr;
Equivalent.
Third, dereference the pointer. To remove a pointer reference (that is, the value of the area to which the pointer refers), the syntax for C is (*ptr), and Object Pascal is ptr^.
Four, take the address (pointer assignment value). Takes an address of an object and assigns it to a pointer variable, the syntax of C is
PTR = &Object;
The Object Pascal is
PTR: = @Object;
It's just a sign of the difference.
Five, the pointer operation. In C, you can move a pointer to an operation, such as:
Char a[20];
Char *ptr=a;
ptr++;
ptr+=2;
When the ptr++ is executed, the compiler generates code that lets PTR advance the sizeof (char) step, and then ptr points to a[1]. ptr+=2, which makes the PTR advance two sizeof (char) size step. Again, let's take a look at how Object Pascal is implemented:
Var
A:array [1..20] of Char;
Ptr:pchar; PChar can be seen as ^char
Begin
PTR: = @a;
INC (PTR); This sentence is equivalent to the ptr++ of C;
Inc (PTR, 2); This sentence is equivalent to the ptr+=2 of C;
End
Only, in Pascal, such an operation is allowed on a pointer of a type, which is not possible for an untyped pointer.
Six, dynamic memory allocation. C, using the malloc () library function to allocate memory, the free () function frees memory. Code like this:
int *ptr, *PTR2;
int i;
ptr = (int*) malloc (sizeof (int) * 20);
PTR2 = ptr;
for (i=0; i<20; i++) {
*ptr = i;
ptr++;
}
Free (PTR2);
In Object Pascal, the function that allocates memory dynamically is GETMEM (), the corresponding deallocation function is Freemem () (the function that acquires memory in traditional Pascal is new () and Dispose (), but new () can only get the memory size of a single entity of an object. Cannot get contiguous blocks of memory that hold multiple objects). Therefore, the code of Object Pascal, which is equivalent to the code of the preceding section C, is:
var ptr, ptr2: ^integer;
I:integer;
Begin
Getmem (PTR, sizeof (integer) * 20);
This sentence is equivalent to C's ptr = (int*) malloc (sizeof (int) * 20);
PTR2: = ptr; Keep the original pointer position
For I: = 0 To
Begin
ptr^: = i;
INC (PTR);
End
Freemem (PTR2);
End
For this example (either the C version or the Object Pascal version), it is important to note that the allocation of memory is in bytes (byte), so when using Getmem, its second parameter if it is assumed to be 20, then there will be a problem (memory access out of bounds). Since Getmem (PTR, 20) is actually allocated only 20 bytes of memory, and the size of an integer is four bytes, then all elements after the fifth access are illegal (for malloc () parameters as well).
Seven, the operation of the character array. In the C language, there is no string type, so the string is implemented with a character array, so there is a set of STR-preceded library functions for the operation of the character array, such as the following code:
Char str[15];
Char *pstr;
strcpy (str, "teststr");
strcat (str, "_testok");
Pstr = (char*) malloc (sizeof (char) * 15);
strcpy (PSTR, str);
printf (PSTR);
Free (PSTR);
In Object Pascal, there is a string type, which makes it easy to perform various operations on the string. However, sometimes our Pascal code needs to interact with C's code (e.g., a DLL written in C with Object Pascal, or a DLL written in Object Pascal to allow the code to write the client in C), you cannot use the string type. Instead, you must use a character array that is common to both languages. In fact, Object Pascal provides an arithmetic function that exactly resembles the whole set of character arrays of C, which is the object Pascal version of the above code:
var Str:array [1..15] of char;
Pstr:pchar; Pchar is ^char.
Begin
Strcopy (@str, ' teststr '); In C, the name of the array can be used directly as a pointer to the array's first address
But Pascal is not like this, so add an operator to the address before Str
StrCat (@str, ' _testok ');
Getmem (pstr, sizeof (char) * 15);
Strcopy (Pstr, @str);
Write (PSTR);
Freemem (PSTR);
End
Eight, function pointers. A function pointer is used when a function in a DLL is called dynamically. Let's say that a section of code written in C is as follows:
typedef int (*PVFN) (int); Defining function pointer types
int main ()
{
hmodule hmodule = LoadLibrary ("Test.dll");
PVFN PVFN = NULL;
PVFN = (PVFN) GetProcAddress (hmodule, "Function1");
PVFN (2);
FreeLibrary (hmodule);
}
In my personal sense, the syntax of a typedef code that defines a function pointer type in C is somewhat obscure, and the same code is quite understandable in Object Pascal:
Type PVFN = Function (Para:integer): Integer;
Var
FN:PVFN;
can also be defined directly here, such as: Fn:function (Para:integer): Integer;
Hm:hmodule;
Begin
HM: = LoadLibrary (' Test.dll ');
fn: = GetProcAddress (hm, ' Function1 ');
FN (2);
FreeLibrary (HM);
End
Simple Introduction to Delphi pointers:
See an example of a pointer usage:
1 var
2 X, Y:integer; X and Y integer types
3 P: ^integer; P pointer to integer type
4 begin
5 X: = 17; Assign a value to X
6 P: = @X; Assign the address of X to P
7 Y: = p^; Remove the value pointed to by P to assign Y
8 End;
The second row defines x, Y, two variables. The third line declares that p is a pointer to an integer type, which means that p can point to the address of X or Y. The fifth line assigns the X value, and the sixth line assigns the address of X to P.
Value to Y after the variable p is pointed to. At this point, X and Y have the same value.
The operator @ is used to take out the address of the variable, or the address of the procedure and function.
and the symbol ^ has two goals,
When it appears in front of a type definition, such as ^typename indicates pointers to this type;
When it appears behind a pointer variable, such as point^ returns the value of the variable pointed to by the pointer;
Understanding pointers makes it easier to understand the object-oriented Pascal language, because pointers are often manipulated behind the scenes. Any type that requires dynamic allocation of large memory spaces can be used with pointer types. For example,
, the long-string variable is actually manipulated using pointers. Other advanced programming techniques require the use of pointer types.
Sometimes pointers are the only way to adapt to the strict type restriction of Object Pascal. A generic pointer type, converted to a different pointer type by type, as in the following example:
Type
Pinteger = ^integer;
Var
R:single;
I:integer;
P:pointer; Generic pointers
Pi:pinteger;
Begin
P: = @R; Remove the memory address of R
PI: = Pinteger (P); Converts a generic type to a pointer to an integer type
I: = pi^;
End
Of course, real numbers and integers are stored in different formats. This assignment is to copy the original binary data from R to I without converting it.
The reserved word nil is a special constant that can be assigned to any pointer type, and when nil assigns a pointer, the pointer does not point to anything, it is a null pointer.
The @ operator returns the stored address of the variable in memory, or the procedure \ function \ method;
1. If the variable, @x returns the address of X. If the compile option {$T-} is not open, the return thing is a generic pointer, if the compile option is turned on, the return is the type of x corresponding to the reference
Needle.
2. If it is a routine (procedure \ Function), @f returns the entry point of F, and the type of @f is a pointer.
3. When @ is used in a method of a class, the name of the method must have a class name, such as @tmyclass.dosomething
The pointer points to the DoSomething method of the Tmyclass.
When a process variable is on the left side of an assignment statement, the compiler expects a procedure value to the right of the assignment statement. This assignment allows the left-hand variable to point to the procedure or function defined on the right.
Entry point. In other words, the variable can be used to refer to a declared procedure or function, and you can directly use a reference to the argument.
Var
F:function (X:integer): Integer;
I:integer;
function SomeFunction (X:integer): Integer;
...
F: = SomeFunction; Assign a value to F
I: = F (4); Call the function you are pointing to
In an assignment statement, the type of the left variable determines the interpretation of the procedure or method pointer on the right.
Var
F, G:function:integer;
I:integer;
function Somefunction:integer;
...
F: = SomeFunction; Assign a value to F
G: = F; Copy the value of F to G
I: = G; Calling functions
The first sentence gets the entry of the function, the second sentence copies the pointer, and the third sentence gets the return value of the function.
Sometimes it's possible to use
If F = MyFunction then ...;
Here, the presence of f causes a function call; The compiler calls the function f points to, and then calls MyFunction, comparing the results. This rule is whenever a process variable (
Procedural variable) appears in an expression that represents the function or procedure to which the call is directed. Sometimes f points to a process (no return value), or F points to a
Number of functions, the preceding statement produces a compilation error. To compare F and myfunction, you need to use
If @F = @MyFunction then ...;
@f converts f to an untyped pointer variable that contains an address, @myfunction returns the address of the myfunction.
Get the memory address of a process variable using @@. For example, @@f returns the address of F.
The @ operator usually assigns an untyped pointer value to a procedure variable, for example:
var strcomp:function (STR1, Str2:pchar): Integer;
...
@StrComp: = GetProcAddress (Kernelhandle, ' lstrcmpi ');
Call the Getprocaddres function, and use StrComp to point to the value
Any process variable can be assigned nil, indicating that nothing is pointed. However, a procedure variable that attempts to invoke a nil value causes an error in order to test whether a procedure variable can be assigned a value
, using the standard assignment function assigned
If Assigned (onclick) then OnClick (X);
First come here, I am also looking for help while translating, no reference to what books, so there are some nouns may not be too accurate, I hope you can forgive me, after all, my English proficiency is limited AH
Delphi Pointer Encyclopedia (the light does not practice is not learning)