Here's a very simple program which will do what you want. Maintaining a 'tail' pointer means that you don't have to traverse the list every time that you want to add a value. If this were your code, then you would be missing the 'tail:= tmp' line in Insert: without this, Display prints the first and last entries, but not those in the middle.
type
node = ^MyRec;
MyRec = record
value: integer;
next: node
end;
var
head, tail: node;
Procedure Insert (v: integer);
var
tmp: node;
begin
new (tmp);
tmp^.value:= v;
tmp^.next:= nil;
if head = nil
then head:= tmp
else tail^.next:= tmp;
tail:= tmp;
end;
Procedure Display;
var
tmp: node;
begin
tmp:= head;
while tmp <> nil do
begin
writeln (tmp^.value);
tmp:= tmp^.next
end;
end;
begin
head:= nil;
Insert (5);
Insert (10);
Display;
Insert (15);
Display;
readln
end.
[Edit]
Judging by your comments, some further explanation is required. [Professorial mode on] When I started programming some thirty years ago (OMSI Pascal on a PDP 11/70), linked lists and pointers appeared in every self-respecting program, but since the rise of Delphi in 1990, such complexities have been hidden and most programmers now never see a naked pointer.
Linked lists come in different formats: the simple and the complex. The simple types differ at the points of insertion and deletion: a stack inserts and deletes at the same end, a queue inserts at one end and deletes at the other, a list allows insertion and deletion at any place. More complex types are trees and graphs. Your question is asking about the implementation of a queue - insertion is always at the rear, deletion is at the front.
In order to implement this properly, we need two variables: 'head' points to the head of the queue and 'tail' points to the end of the queue. These variables are normal global variables; memory is allocated for them in the data segment of the program. A pointer is a simple variable whose value is the memory address of another variable. Initially, 'head' does not point to anything so its value is nil (think of this as 0).
Normally in textbooks, the construction of a queue is accompanied by little boxes showing how memory is allocated, but I don't know how to do that here and so the explanation will be a little wordy.
When the first insertion occurs, the memory manager in the run time system allocates 12 bytes from the heap and sets the value of the local variable 'tmp' to be the address of the first of those 12 bytes (this is 'new (tmp)'). Of those 12 bytes, the 'value' part is set to 5 and the 'next' part is set to nil. Then the program checks what the value of 'head' is: if it is nil, then the value (ie address of the memory block allocated above) is copied from 'tmp' to 'head'. If 'head' already points to something, then the value of 'tmp' is copied to 'tail^.next' (which previously would have been nil). Then the value of 'tmp' is copied to the tail variable. Thus 'head' always points to the beginning of the queue and does not change whereas 'tail' points to the end of the queue and changes every time a new node is inserted.
Let's do some debugging:
When the program starts, head = nil, tail is undefined
After 'insert (5)', head = $870874, tail = $870874
After 'insert (10)', head = $870874, tail = $870880
After 'insert (15)', head = $870874, tail = $87088C
When displaying,
tmp:= head ......... tmp = $870874 (ie head)
tmp:= tmp^.next .... tmp = $870880
tmp:= tmp^.next .... tmp = $87088C
tmp:= tmp^.next .... tmp = nil
If your program has more than one queue, then you will need two variables for each queue, and 'Insert' will have to be changed in order to accept two parameters (which will be the head and tail of the given queue).
There is no need to write 'new (head)' and 'new (tail)' - doing so will cause the original pointers to the beginning and end of the queue to be lost.
[Professorial mode off] I hope that this explanation helps.