Difference between revisions of "Record"

From Lazarus wiki
Jump to navigationJump to search
(Tell the reader that the word "record" is a reserved word.)
 
(3 intermediate revisions by 3 users not shown)
Line 1: Line 1:
 
{{Record}}
 
{{Record}}
  
A <syntaxhighlight lang="pascal" enclose="none">record</syntaxhighlight> is a highly structured data [[Type|<syntaxhighlight lang="pascal" enclose="none">type</syntaxhighlight>]] in [[Pascal]].
+
A <syntaxhighlight lang="pascal" inline>record</syntaxhighlight> is a highly structured data [[Type|<syntaxhighlight lang="pascal" inline>type</syntaxhighlight>]] in [[Pascal]].
 
They are widely used in Pascal, to group data items together logically.
 
They are widely used in Pascal, to group data items together logically.
  
While simple data structures such as [[Array|<syntaxhighlight lang="pascal" enclose="none">array</syntaxhighlight>s]] or sets consist of elements all of the same type, a record can consist of a number of elements of different types, and can take on a huge complexity.
+
While simple data structures such as [[Array|<syntaxhighlight lang="pascal" inline>array</syntaxhighlight>s]] or sets consist of elements all of the same type, a record can consist of a number of elements of different types, and can take on a huge complexity.
 
Each separate part of a record is referred to as a field.
 
Each separate part of a record is referred to as a field.
  
Line 10: Line 10:
  
 
== Declaration ==
 
== Declaration ==
 +
 
=== Fixed structure ===
 
=== Fixed structure ===
 +
 
<syntaxhighlight lang="pascal">
 
<syntaxhighlight lang="pascal">
 
type
 
type
Line 23: Line 25:
 
 
 
=== Variable structure ===
 
=== Variable structure ===
 +
 
And even more complex structures are possible, e.g.:
 
And even more complex structures are possible, e.g.:
 +
 
<syntaxhighlight lang="pascal" highlight="12-13">
 
<syntaxhighlight lang="pascal" highlight="12-13">
 
type
 
type
Line 44: Line 48:
 
end;
 
end;
 
</syntaxhighlight>
 
</syntaxhighlight>
 +
 
Note that fields of the variable part have to be in parentheses. You cannot use the same identifier multiple times, so a slightly different name has to be used for the <code>marriageDate</code> in case of ''divorced''.
 
Note that fields of the variable part have to be in parentheses. You cannot use the same identifier multiple times, so a slightly different name has to be used for the <code>marriageDate</code> in case of ''divorced''.
  
 
The variable part shares the same memory. So <code>marriageDate</code> and <code>marriageDateDivorced</code> will have the same value regardless of <code>maritalState</code>. This behaviour is particularly practical as the following example shows:
 
The variable part shares the same memory. So <code>marriageDate</code> and <code>marriageDateDivorced</code> will have the same value regardless of <code>maritalState</code>. This behaviour is particularly practical as the following example shows:
 +
 
<syntaxhighlight lang="pascal" highlight="3">
 
<syntaxhighlight lang="pascal" highlight="3">
 
type
 
type
Line 56: Line 62:
 
   end;
 
   end;
 
</syntaxhighlight>
 
</syntaxhighlight>
 +
 
This record has only a variable part and enables access to the value of the word, the individual bytes and even to the bits. An identifier is not necessarily required in the <code>case</code> clause, so this does not occupy any memory. The size of this record is two bytes. In the case of <code>Bits</code>, this is only possible if <code>bitpacked</code> is used. Note the order of the bytes, with the less significant byte (LSB) coming first.
 
This record has only a variable part and enables access to the value of the word, the individual bytes and even to the bits. An identifier is not necessarily required in the <code>case</code> clause, so this does not occupy any memory. The size of this record is two bytes. In the case of <code>Bits</code>, this is only possible if <code>bitpacked</code> is used. Note the order of the bytes, with the less significant byte (LSB) coming first.
  
 
=== Advanced record ===
 
=== Advanced record ===
An “advanced record” is a record with [[Method|methods]] and [[Property|properties]].
 
  
{{Note|Remember to add a compiler directive <syntaxhighlight lang="pascal" enclose="none">{$modeSwitch advancedRecords}</syntaxhighlight> (after you have set the mode).}}
+
An “advanced record” is a record with [[Method|methods]], [[Property|properties]] and [[management_operators]]
 +
 
 +
{{Note|Remember to add a compiler directive <syntaxhighlight lang="pascal" inline>{$modeSwitch advancedRecords}</syntaxhighlight> (after you have set the mode).}}
  
 
== Addressing ==
 
== Addressing ==
 +
 
=== Fields ===
 
=== Fields ===
 +
 
Individual fields are accessed by placing a dot between the record name and the field name thus:
 
Individual fields are accessed by placing a dot between the record name and the field name thus:
 +
 
<syntaxhighlight lang="pascal">
 
<syntaxhighlight lang="pascal">
 
a.firstname := 'George';
 
a.firstname := 'George';
Line 73: Line 84:
 
</syntaxhighlight>
 
</syntaxhighlight>
  
Alternatively, the whole series of fields can be made available together using the [[With|<syntaxhighlight lang="pascal" enclose="none">with</syntaxhighlight>-construct]]:
+
Alternatively, the whole series of fields can be made available together using the [[With|<syntaxhighlight lang="pascal" inline>with</syntaxhighlight>-construct]]:
 +
 
 
<syntaxhighlight lang="pascal">
 
<syntaxhighlight lang="pascal">
 
with a do
 
with a do
Line 85: Line 97:
  
 
=== Instances ===
 
=== Instances ===
 +
 
A record is treated by the program as a single entity, and for example a whole record can be copied (provided the copy is of the same type) thus:
 
A record is treated by the program as a single entity, and for example a whole record can be copied (provided the copy is of the same type) thus:
 
<syntaxhighlight lang="pascal" highlight="7-10">
 
<syntaxhighlight lang="pascal" highlight="7-10">
Line 99: Line 112:
 
end.
 
end.
 
</syntaxhighlight>
 
</syntaxhighlight>
 
  
 
== Constant record ==
 
== Constant record ==
Line 129: Line 141:
  
 
== Records compared to other structured types ==
 
== Records compared to other structured types ==
 +
 
{{Template:Object Types}}
 
{{Template:Object Types}}
  
 
== See also ==
 
== See also ==
* [[Records]], tutorial that covers records
+
 
* [[Object|<syntaxhighlight lang="pascal" enclose="none">object</syntaxhighlight>]]
+
* [[Basic Pascal Tutorial/Chapter 5/Records|Records]], tutorial that covers records
* [[Class|<syntaxhighlight lang="pascal" enclose="none">class</syntaxhighlight>]]
+
* [[Object|<syntaxhighlight lang="pascal" inline>object</syntaxhighlight>]]
* [[FPC_New_Features_3.2.0#Dynamic_Array_constants_and_variable_initialization|FPC New Features 3.2.0 - Dynamic Array constants and variable initialization]]
+
* [[Class|<syntaxhighlight lang="pascal" inline>class</syntaxhighlight>]]
  
 
{{Data types}}
 
{{Data types}}
  
 
[[Category:Code]]
 
[[Category:Code]]

Latest revision as of 05:13, 28 November 2022

Deutsch (de) English (en) español (es) suomi (fi) français (fr) magyar (hu) polski (pl) português (pt) русский (ru)

A record is a highly structured data type in Pascal. They are widely used in Pascal, to group data items together logically.

While simple data structures such as arrays or sets consist of elements all of the same type, a record can consist of a number of elements of different types, and can take on a huge complexity. Each separate part of a record is referred to as a field.

The word record is a reserved word.

Declaration

Fixed structure

type
	TMember = record
		firstname, surname : string;
		address: array [1..3] of string;
		phone: string;
		birthdate: TDateTime;
		paidCurrentSubscription: boolean
	end;

Variable structure

And even more complex structures are possible, e.g.:

type
	TMaritalState = (unmarried, married, widowed, divorced);
	TPerson = record
		// CONSTANT PART
		// of course records may be nested
		name: record
			first, middle, last: string;
		end;
		sex: (male, female);
		// date of birth
		dob: TDateTime;
		// VARIABLE PART
		case maritalState: TMaritalState of
			unmarried: ( );
			married, widowed: (marriageDate: TDateTime);
			divorced: (marriageDateDivorced, divorceDate: TDateTime;
				isFirstDivorce: boolean)			
	end;

Note that fields of the variable part have to be in parentheses. You cannot use the same identifier multiple times, so a slightly different name has to be used for the marriageDate in case of divorced.

The variable part shares the same memory. So marriageDate and marriageDateDivorced will have the same value regardless of maritalState. This behaviour is particularly practical as the following example shows:

type
  TSpecialWord = record
    case Byte of
      0: (Word_value: Word);                      // 7
      1: (Byte_low, Byte_high: Byte);             // 7, 0
      2: (Bits: bitpacked array [0..15] of 0..1); // 1, 1, 1, 0, 0, ...
  end;

This record has only a variable part and enables access to the value of the word, the individual bytes and even to the bits. An identifier is not necessarily required in the case clause, so this does not occupy any memory. The size of this record is two bytes. In the case of Bits, this is only possible if bitpacked is used. Note the order of the bytes, with the less significant byte (LSB) coming first.

Advanced record

An “advanced record” is a record with methods, properties and management_operators

Light bulb  Note: Remember to add a compiler directive {$modeSwitch advancedRecords} (after you have set the mode).

Addressing

Fields

Individual fields are accessed by placing a dot between the record name and the field name thus:

	a.firstname := 'George';
	a.surname := 'Petersen';
	a.phone := '789534';
	a.paidCurrentSubscription := true;

Alternatively, the whole series of fields can be made available together using the with-construct:

with a do
begin
	firstname := 'George';
	surname := 'Petersen';
	phone := '789534';
	paidCurrentSubscription := true
end;

Instances

A record is treated by the program as a single entity, and for example a whole record can be copied (provided the copy is of the same type) thus:

var
	a, b: TMember;

(* main program *)
begin
	// ... assign values to the fields in record a
	b := a
	// Now b holds a _copy_ of a.
	// Do not get confused with references:
	// a and b still point to _different_ _entities_ of TMember.
end.

Constant record

type
	// record definition
	TSpecialDay = record
		dayName: string;
		month: integer;
		day: integer;
	end;

const
	// TSpecialDay constant
	christmasDay: TSpecialDay = (
		dayName: 'Christmas Day';
		month: 12;
		day: 25;
	);

// since FPC 3.2.0 you may define an constant array of records like this
const
   SpecialDays: array of TSpecialDay = (
     ( dayName: 'Christmas Day' ; month: 12; day: 25),
     ( dayName: 'New Year''s Day'; month:  1; day:  1)
   );

Records compared to other structured types

Feature Record Adv Record Object Class
Encapsulation (combining data and methods + hiding visibility) No Yes Yes Yes
Inheritance No No Yes Yes
Class constructor and destructor No Yes Yes Yes
Polymorphism (virtual methods) No No Yes Yes
Memory allocation Stack Stack Stack Heap (Only)
Setting fields to zero on allocation
Managed Types only Managed Types only Managed Types only All fields
Default() function returns a constant with
all fields zeros all fields zeros all fields zeros returns nil
Operator overload (global) Yes Yes Yes Yes
Operator overload (in type only) No Yes No No
Type helpers No Yes No Yes
Virtual constructors, class reference No No No Yes
Variant part (case) as c/c++ union Yes Yes No No
Bitpacked (really packing) Yes Yes No No

Modified from https://forum.lazarus.freepascal.org/index.php/topic,30686.30.html (original author: ASerge).

See also


navigation bar: data types
simple data types

boolean byte cardinal char currency double dword extended int8 int16 int32 int64 integer longint real shortint single smallint pointer qword word

complex data types

array class object record set string shortstring