^
) can be used in combination with a letter to
specify a character with ASCII value less than 27. Thus ^G
equals
#7 (G is the seventh letter in the alphabet.)
If you want to represent the single quote character, type it two times
successively, thus '''' represents the single quote character.
ShortString
![]()
The meaning of a string declaration statement is interpreted differently depending on the {$H} switch. The above declaration can declare an ansistrng or a short string.
Whatever the actual type, ansistrings and short strings can be used interchangeably. The compile always takes care of the necessary type coversions. Note, however, that the result of an expression that contains ansstrings snd short strings will always be an ansistring.
A string declaration declares a short string in the following cases:
The predefined type ShortString is defined as a string of length 255:
ShortString = String[255];
For short strings Free Pascal reserves Size+1 bytes for the string S, and in the zeroeth element of the string (S[0]) it will store the length of the variable. If you don't specify the size of the string, 255 is taken as a default. For example in
{$H-} Type NameString = String[10]; StreetString = String;NameString can contain maximum 10 characters. While StreetString can contain 255 characters. The sizes of these variables are, respectively, 11 and 256 bytes.
If the {$H} switch is on, then a string definition that doesn't contain a length specifier, will be regarded as an ansistring.
Ansistrings are strings that have no length limit. They are reference counted. Internally, an ansistring is treated as a pointer.
If the string is empty (''), then the pointer is nil. If the string is not empty, then the pointer points to a structure in heap memory that looks as in seetansistrings.
Because of this structure, it is possible to typecast an ansistring to a pchar. If the string is empty (so the pointer is nil) then the compiler makes sure that the typecasted pchar will point to a null byte.
AnsiStrings can be unlimited in length. Since the length is stored, the length of an ansistring is available immediatly, providing for fast access.
Assigning one ansistring to another doesn't involve moving the actual string. A statement
S2:=S1;results in the reference count of S2 being decreased by one, The referece count of S1 is increased by one, and finally S1 (as a pointer) is copied to S2. This is a significant speed-up in your code.
If a reference count reaches zero, then the memory occupied by the string is deallocated automatically, so no memory leaks arise.
When an ansistring is declared, the Free Pascal compiler initially allocates just memory for a pointer, not more. This pinter is guaranteed to be nil, meaning that the string is initially empty. This is true for local, global or part of a structure (arrays, records or objects).
This does introduce an overhead. For instance, declaring
Var A : Array[1..100000] of string;Will copy 1000000 times nil into A. When A goes out of scope, then the 100000 strings will be dereferenced one by one. All this happens invisibly for the programmer, but when considering performance issues, this is important.
Memory will be allocated only when the string is assigned a value. If the string goes out of scope, then it is automatically dereferenced.
If you assign a value to a character of a string that has a reference count greater than 1, such as in the following statements:
S:=T; { reference count for S and T is now 2 } S[I]:='@';then a copy of the string is created before the assignment. This is known as copy-on-write semantics.
It is impossible to access the length of an ansistring by referring to the zeroeth character. The following statement will generate a compiler error if S is an ansistring:
Len:=S[0];Instead, you must use the Length function to get the length of a string.
To set the length of an ansistring, you can use the SetLength function. Constant ansistrings have a reference count of -1 and are treated specially.
Ansistrings are converted to short strings by the compiler if needed, this means that you can mix the use of ansistrings ans short strings without problems.
You can typecast ansistrings to PChar or Pointer types:
Var P : Pointer; PC : PChar; S : AnsiString; begin S :='This is an ansistring'; PC:=Pchar(S); P :=Pointer(S);There is a difference between the two typecasts. If you typecast an empty string to a pointer, the pointer wil be Nil. If you typecast an empty ansistring to a PChar, then the result will be a pointer to a zero byte (an empty string).
The result of such a typecast must be use with care. In general, it is best to consider the result of such a typecast as read-only, i.e. suitable for passing to a procedure that needs a constant pchar argument.
It is therefore NOT advisable to typecast one of the following:
To specify a constant string, you enclose the string in single-quotes, just as a Char type, only now you can have more than one character. Given that S is of type String, the following are valid assignments:
S := 'This is a string.'; S := 'One'+', Two'+', Three'; S := 'This isn''t difficult !'; S := 'This is a weird character : '#145' !';As you can see, the single quote character is represented by 2 single-quote characters next to each other. Strange characters can be specified by their ASCII value. The example shows also that you can add two strings. The resulting string is just the concatenation of the first with the second string, without spaces in between them. Strings can not be substracted, however.
Whether the constant string is stored as an ansistring or a short string depends on the settings of the {$H} switch.
program one; var p : PChar; begin P := 'This is a null-terminated string.'; WriteLn (P); end.Results in the same as
program two; const P : PChar = 'This is a null-terminated string.' begin WriteLn (P); end.These examples also show that it is possible to write the contents of the string to a file of type Text. The strings unit contains procedures and functions that manipulate the PChar type as you can do it in C. Since it is equivalent to a pointer to a type Char variable, it is also possible to do the following:
Program three; Var S : String[30]; P : PChar; begin S := 'This is a null-terminated string.'#0; P := @S[1]; WriteLn (P); end.This will have the same result as the previous two examples. You cannot add null-terminated strings as you can do with normal Pascal strings. If you want to concatenate two PChar strings, you will need to use the unit strings. However, it is possible to do some pointer arithmetic. You can use the operators + and - to do operations on PChar pointers. In table (PCharMath) , P and Q are of type PChar, and I is of type Longint.
Operation | Result |
P + I | Adds I to the address pointed to by P. |
I + P | Adds I to the address pointed to by P. |
P - I | Substracts I from the address pointed to by P. |
P - Q | Returns, as an integer, the distance between 2 addresses |
(or the number of characters between P and Q) |