Strings in Delphi
- "Delphi6 Developer Guide" Reading Notes
SpaceSoft [Dark Night Sand]
Delphi supports the structure of this structure is very rich, not only the String type supported by Delphi itself, but also supports a string array of C language compatible. So what is the difference between them? This article tries to make a detailed analysis of this and try to answer several problems in the forum.
First of all, we have to discuss the String in delphi in the end, because we know on the OP's grammatical reference manual, Delphi has three string: shortstring, Ansistring (is the kind of bcb's ANSISTRING) and WiDestring To support Unicode, other and ANSISTRING are exactly the same. In the default, the compiler will interpret the String as ansistring, and when needed, you can set the compiler to interpret String as ShortString (of course, we have to do this very little, because Ansistring is very good, SHORTString only supports 255 characters and is not compatible with the string array of C language. This will be mentioned later), the corresponding compiler indicator is the default {$ h } and {$ h-}.
So, what is the difference between these three String? The difference is their different structures.
For ShortString, it can be represented in memory in memory:
STRSHORT = Record WLENGTH: WORD; SZBUF: Array of Char; End;
That is, each operation of ShortString does not need to traverse this string, you can get the size of this string. In addition, this string array is finally no # 0 character as the end. So shortstring array and C language strings are incompatible.
For Ansistring, according to the Description of the Delphi6 Developer Guide, its structure can be represented as follows:
STRANSI = Record nsize: Integer; NREF: Integer; NLENGTH: Integer; SZBUF: Array of Char; End;
That is to say, Ansistring not only saves the length of this string, but also saves the number of references to this string. Therefore, different Ansistring actually may have the same physical address, so Delphi's string copy is often an efficient. However, what should I do when a string changes? Delphi will release references to this string (drop NREFCOUNT 1), then create a string to load new content.
In addition, unlike ShortString, Ansistring's character array is ended in # 0, so SZBUF can be used as an array of characters in C. It is estimated that such a design is for compatible Win32 API.
WideString and Ansistring are basically the same, so when we discuss, only Ansistring and Shortstring are discussed.
Then we want to explain that String has the management characteristics of survival. That is, after the String exceeds the scope, the resource occupied by the string is automatically released. How is this mechanism implementation? For global variables, of course its scope is the Unit's living cycle, then it is of course released in the Finalization section. What about the variables in the function? The compiler automatically puts a try ... finally processing outside the entire function. In this way, in any case, these variables can always be released. The following question is: If there is a pointer now, it is pointed to a string, then what is it pointing?
The answer is: pointing to the beginning of SZBUF, and shortstring does not support such a forced conversion (this is natural, because the purpose of doing this transformation is purely to be compatible with C language). So String [1] is the first character of this string. So, "looks" this string only there are those characters. So, we can convert a String into a PCHAR with PCHAR () to force type transformation, and then transmit it to the Win32 API that requires the character array as the parameter, because "looks" this string is indeed a standard C language. String. Even, we can use the string like this:
Procedure test (); var strbuf: string; begin setlength (strbuf, 255); // Don't forget to apply for enough space for your string, otherwise ... Hey, wait for the box ^ _ ^ GetModuleFileName (0, Pchar (Strbuf), 255); ShowMessage (strbuf);
We know that this API prototype is like this:
DWORD getModuleFileName (HModule HModule, // Handle To Module LPTSTR LPFILENAME, / / POINTER TO A Buffer That Receiver DWORD NSIZE / / SIZE OF BUFFER);
This API actually thought that we really passed an Array of CHAR according to its request!
By similar to this mechanism, Delphi makes it free to walk in the API prototype written in the C language, and there is no feeling of "second-class citizens", and can enjoy the convenience of Delphi itself. amazing!
Now let's summarize the characteristics of the string type in Delphi:
1. Different from the C language, not relying on the # 0 characters to make a string end flag, but through the numbers in front of the string (although in order to compatibility with C language, the string of ANSISUSTRING is indeed at the end. A # 0 character) 2, String is a survival management feature, and the resource occupied by the string is automatically released when the String exceeds the scope. 3. Forced the string to PCHAR, it will get a string pointer, which is the same as the usage of the string pointer and the array in the C language. For Strbuf: string;
SETLENGTH (Strbuf, 255); When you are in use, you can think of pchar (strbuf) as a C language:
CHAR STRBUF [255];
Remember, in the last statement, Strbuf is a pointer, pointing to the address of the first character of the pointer, and the pointer you do Pchar (strbuf) is this thing. In the end, explain a sentence in the "Developer's Guide":
"Be careful when practicing a string is converted to a PCHAR type, because the string has the function of automatic recycling when it exceeds its scope of action, so when the value of P: = PCHAR (STR) is performed, the P 's scope (survival The period is longer than STR. "
The meaning of this sentence is that the string type is automatically reclaimed, but the string pointer is not. P: = PCHAR (STR) The pointer returned to the scope may be used outside the action domain, so the Licheng cycle of the P should be longer than the STR. For example, explain:
Procedure getpchar (p: pchar); var strtmp: string; begin stramp: = 'asasses'; p: = pchar (strtmp);
At this time, the scope of this pointer P returned is greater than STRTMP, and the startMP has been released automatically when this process ends. The function that calls this process is that the P is actually a hanging pointer, meaningless. The author's intention is to remind the reader to take care of such a situation.
references:
1. "Delphi6 Developer Guide", Steve Teixeira Waiting, Longjin Song and other translation, Machinery Industry Press, Beijing, January 2003
2, "Object Pascal Language Reference Manual"
Welcome to the author's personal homepage: http://www.mrspace.net/