The correct understanding of the Move function in Delphi (like Const and VAR, is the address, so move is the address, but not the value) is wonderful good

Source: Internet
Author: User

We can see the following code
var Psource,pdest:pchar;
Len:integer;
.....//A number of codes.//////
Move (Psource,pdest,len); Error
Move (Psource^,pdest^,len); That's right
It does look like it's a pass, not an address, but don't forget, it's not c,c++, it's Delphi.
Object Pascal, so, must not be judged from the method of the function call is a value or a string address!! Must look at the function's
Definition, only the definition can tell whether it is a value or an address, again, this is not c,c++!!
The function definitions We see are like this.
Procedure Move (const Source; var Dest; Count:integer);
From the definition, it is clear that dest is the address, not the value, then source, in fact, we are not very clear
The const modifier here has two meanings, and the first one knows that the source is a constant way in the function body,
Can not change its value, the second may know not many people, that is the way source is passed and dest,
It's an address! In other words, Const and VAR are all addresses, except one that does not allow modification within a function.
The other is the variable value that affects the call after the modification
So move is the address, but not the value!

Through a period of learning, the above understanding is not all right. In fact, the Const keyword modification of the source is a value or pass the address, to see the const modified parameter type. If the argument is a simple type, that is still a value, if the decorated parameter is not a simple type, but a string (not including a short string), is the address , is the memory address of the actual parameter, even if there is no keyword decoration, such as Procedure Proca (s: String), which is the address of the argument, is implemented by reference counting and is only written if the value of S is overwritten. the variable that the var keyword modifies is definitely a pass-through address. For the data types in Delphi, we know that declaring a variable is divided into two parts: "The variable Itself" and "the memory footprint of the variable". For a variable of a simple type, the variable itself stores the value of the variable, whereas for a complex type (constructed or string), the "variable itself" simply holds a pointer to the memory footprint of the variable, while the memory footprint of the variable has its own storage space with address value.  That is, the "variable itself" of a complex type holds a pointer to the address of the actual data, an integer value of 4 bytes in size.

Var

I:integer;

s:string;

Begin

i:=1;//in memory I address the value is 1, that is, the variable itself is stored in the variable value;

s:= ' hello,world! '; //The variable itself is stored ' hello,world! ' The address value that is stored in memory is actually its first address.

End

Let's look at the declaration of the Move function again:

Procedure Move (const Source; var Dest; count:integer);

Its internal implementation code:

Procedure Move (const Source; var Dest; count:integer);
Var
S, D:pchar;
I:integer;
Begin
S: = PChar (@Source);//Take the address of the Source variable
D: = PChar (@Dest); The address of the dest variable is taken
If S = D then Exit;
If Cardinal (D) > Cardinal (S) Then
For I: = count-1 downto 0 Do
D[i]: = S[i]
Else
For I: = 0 to Count-1 do
D[i]: = S[i];
End

Now understand why Move (Psource,pdest,len); Is wrong, and Move (Psource^,pdest^,len); Is that right? Although the Psource,pdest declaration is a pchar type, it is a pointer variable that points to a string of pointer types with a null string. If move (Psource,pdest,len) writes like this, in the implementation code of the Move (@pSource) takes the address of the pointer itself, not the address of the pointer pointing to the data. Note that it is the address of the pointer itself instead of the data store , and if so, it is obviously not possible to implement the data movement, take a pointer to the address, is not the value; and move (Psource^,pdest^,len); Correct, is the address value that is directed to the function Pchar variable. psource^, which indicates the address of the actual data that is pointing to. (@ Remove the variable address operator); pdest^, pointing to the destination memory address, move function, know which address to start, how many bytes of data moved to the destination address space, do not look at the internal implementation of the move function, it is very difficult to understand its implementation process.

From the above analysis, we now look back and see the declaration of the move process, procedure move (const Source; var Dest; count:integer); The const-Modified variable, the address value of the argument passed, is not allowed inside the function, modifies the source memory address, that is, it cannot point to a different address, the value of source is a copy of the psource^ value, which is the psource^.

Souce is a memory header address, this memory header address, of course, is a value, not the address of the real parameter. It passes a value that is the memory address of the actual data that the variable points to. Const and Var are not the same at all. For const modifier pointers, it is important to be aware of the understanding. You can refer to Http://rainux.org/delphi and http://www.cnblogs.com/sonicit/archive/2008/03/23/1118524.html, which is very detailed.

Summary: A pointer-type parameter is passed by value and is decorated with a const. The situation becomes complex and interesting, and the actual pass is a copy of the pointer, and the formal parameters and arguments are two pointers. However, the two pointers point to the same address. They can share the pointer to the data in the address, but cannot share the pointer itself. The parameters and arguments passed by the reference are the same variable.  thus fully shared. Source and dest all point to a first address, but it cannot be said that Const-decorated arguments are passed by address, which is a conceptual error.

Look at the following example:

Note the difference:

Procedure Tform1.byconstval (const obj:tedit)

Begin

Obj. text:= ' Hello world! '; /Modify the properties of obj correctly;

obj:=form1;//error, cannot point it to other objects, cannot modify the pointer itself, can modify the data pointing to the object, including properties, etc.;

End

Procedure Tform1.byval (Obj:tedit)

Begin

Obj. text:= ' Hello world! '; /Modify the properties of obj correctly;

obj:=form1;//correct, this time obj points to the other object, not the incoming object, its pointer to send a change, does not affect the direction of the external arguments;

End

Procedure Tform1.byref (Obj:tedit)

Begin

Obj. text:= ' Hello world! '; /Modify the properties of obj correctly;

obj:=form1;//correct, this time obj points to the other object, not the incoming object, its point to send a change, affecting the direction of the outside arguments, outside the argument also points to the Form1 object;

End

Some other reference examples:

Move (const Source;   var Dest; Count:integer);
Source and dest all point to a first address,
Such as
VAR first address
P:pointer; p^
P:pchar p^
As long as the pointer type is p^
S:string S[1];
Arr:array [0..10] of Char; Arr[0] or ARR
Arr:array [0..10] of Tdatarecord arr[0] or ARR
As long as the array type is arr[0] or ARR

Once you understand the first address, it's easy to understandC memcpy and Delphi move, or API Movememory/copymemory, is the memory of the mutual copy, as long as the first address on the line

Of course, the first address in the array may not start with 0, and sometimes when we assign a record or array, we assign the values to the fields as follows:
Type
Tarrchar:array [0..3] of Char;

Procedure SetValue (Arr:tarrchar);
Var
Chars:array of Char;
Begin
SetLength (Chars, 4);
Chars[0]: = Arr[0];
...
End

We can do this:
Procedure SetValue (Arr:tarrchar);
Var
Chars:array of Char;
Begin
SetLength (Chars, 4);
Move (ARR, Chars, SizeOf (Char) * 4);
End

The record type can do the same, but pay attention to the static allocation space of the String/array type; Such as
S:STRING[255];
Arr:array [0..len] of Tmytype

Sentiment: Learning to get started with Delphi is easy, but in-depth, requires a process. However, in the course of learning to pay attention to these details, thoroughly understand, in the actual development, the more effective.

http://blog.csdn.net/tjb_1216/article/details/4627346

The correct understanding of the Move function in Delphi (like Const and VAR, is the address, so move is the address, but not the value) is wonderful good

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.