procedure questiontype;
begin
writeln ('Enter the type of question you would like...');
writeln ('1. Add');
writeln ('2. Multiply');
writeln ('3. Subtraction');
writeln ('4. Division');
readln (typeofquestion);
case typeofquestion of
1: add;
2: multiply;
3: subraction;
4: division
else writeln ('Choose again');
end;
end;
The add, multiply, subtraction and division are all procedures. If i put this in the main program, it will work fine, but when i make this as a procedure itself, i get the error undeclared identifier. I've looked on many websites for an example that is like this but i can't find any.
How do make add, multiply, subtraction, division go to their procedures from inside this one?
You have to declare procedures before routines that call them. Although you haven't shown how the other routines are defined, I deduce that they are declared after the routine you have shown.
So you can simply re-order your code so that add, multiply, subtraction and division are defined before they procedure that calls them.
So this will work:
procedure add;
begin
//do something;
end;
procedure questiontype;
begin
add;
end;
But this will not compile:
procedure questiontype;
begin
add;
end;
procedure add;
begin
//do something;
end;
Pascal and its variants are compiled in a single pass and if the compiler does not know about a routine at the point at which it is mentioned, it cannot continue.
Pascal does support co-routines where A calls B and B calls A, by the use of a *forward declaration`. For example:
procedure B; forward;
procedure A;
begin
B;
end;
procedure B;
begin
A;
end;
Naturally this is an infinite loop as written which will terminate with a stack overflow (how appropriate!) but there are of course real examples where this is necessary.
However, forward declarations are rarely needed and should be avoided if possible since they increase complexity. Invariably a solution can be found by simply re-ordering your declarations.
As a final aside, the ordering constraint that declaration occurs before use is explicitly mentioned in Brian Kernighan famous article, Why Pascal is Not My Favorite Programming Language.
I see you have tagged your question [delphi]
as well as [pascal]
, so I guess you are in fact writing Delphi code. Then you got a few more options, besides caring about the order of the procedures and the forward
directive discussed by David.
Most often a Delphi
project (GUI or console) is divided into "units". A typical unit looks like this:
unit MyUnit;
interface
const
RANDOM_NUMBER = 17;
var
PrintExtraNiceMessage: boolean;
procedure DoThis;
procedure DoThat;
implementation
const
BUFFER_SIZE = 256;
procedure InitSomething;
begin
// TODO: do some internal work...
end;
procedure DoThis;
begin
// TODO: do something
end;
procedure DoThat;
begin
// TODO: do something else
end;
You will notice that the unit is divided in two parts: the interface
part, and the implementation
part. The interface
part contains only declarations (of functions, procedures, types, constants, and variables); the functions and procedures declared here are defined (that is, implemented) in the implementation
section. Notice that there can be functions and procedures defined in the implementation
section that have no declarations in the interface
section.
The grand idea is that the contents of the interface
section is visible to all other units in your program, whereas the contents of the implementation
section is only visible inside this very unit. So any other unit in your program can use the RANDOM_NUMBER
constant, the PrintExtraNiceMessage
variable and the two procedures DoThis
and DoThat
. But you can only use InitFunction
in this very unit (for instance, inside DoThis
or DoThat
). In addition, the constant BUFFER_SIZE
is not visible outside this very unit, either.
This is a very elegant approach. The interface
section describes how this unit is used in other units (e.g., what functions there are and how they are used), and the implementation details are "hidden" in the implementation
section.
A benefit of this approach is that it solves your problem, at least possibly. If the add
, multiply
, subtract
, and divide
procedures should be visible to other units, then they should be declared in the interface
section. But then they are indeed known to the compiler by the time it comes to your questiontype
procedure, and so you can use call these even if they are defined (implemented) below the questiontype
procedure inside the implementation
section. But, on the other hand, if it makes no sense at all to let other units use these procedures, then they should not be declared in the interface
section, and you need to do as David suggests. This also applies if you have no normal units at all in your project, that is, if you only have the program
file, which has no division into interface
and implementation
parts.
Notice that the OP's example has an else that only applies to the last "if". Presumably, if they enter 1, 2, or 3, the corresponding procedure fires, returns, and then they see 'Choose again'. If they enter 4, they do not. This would be well served by a Case or cascading if..else if structure where the final else is only triggered "when all else fails", which is like what the OP intended.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With