Как вызвать процедуру, когда внутри другой процедуры в Pascal
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;
сложение, умножение, вычитание и деление-это все процедуры. Если я помещу это в основную программу, она будет работать нормально, но когда я сделаю это как процедуру, я получу ошибку необъявленный идентификатор. Я смотрел на многих сайтах, например вот такой, но я не могу найти.
Как сделать сложение, умножение, вычитание, деление перейти к их процедурам изнутри этого?
3 ответов
вы должны объявить процедуры до процедуры, называть их. Хотя вы не показали, как определяются другие процедуры, я делаю вывод, что они объявляются после процедуры, которую вы показали.
таким образом, вы можете просто переупорядочить свой код, чтобы добавить, умножить, вычитание и деление определялись перед процедурой, которая их вызывает.
Так что это будет работать:
procedure add;
begin
//do something;
end;
procedure questiontype;
begin
add;
end;
но это не будет компилироваться:
procedure questiontype;
begin
add;
end;
procedure add;
begin
//do something;
end;
Pascal и его варианты компилируются за один проход, и если компилятор не знает о подпрограмме в точке, в которой она упоминается, она не может продолжаться.
Pascal поддерживает подпрограммы, в которых a вызывает B и B вызывает A, с помощью a *forward declaration`. Например:
procedure B; forward;
procedure A;
begin
B;
end;
procedure B;
begin
A;
end;
естественно, это бесконечный цикл, как написано, который завершится переполнением стека (как уместно!) но есть, конечно, реальные примеры, когда это необходимо.
, прямые объявления редко необходимы, и их следует избегать, если это возможно, поскольку они усложняют работу. Неизменно решение можно найти, просто переупорядочив ваши объявления.в качестве окончательного в сторону, ограничение порядка, которое происходит перед использованием, явно упоминается в известной статье Брайана Кернигана,почему Паскаль не мой любимый язык программирования.
я вижу, вы пометили свой вопрос [delphi]
а также [pascal]
, поэтому я думаю, что вы на самом деле пишете код Delphi. Тогда у вас есть еще несколько вариантов, помимо заботы о порядке процедур и forward
директива обсуждается Дэвидом.
чаще всего a Delphi
проект (GUI или консоль) делится на"единицы". Типичная единица выглядит так:
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;
вы заметите, что блок разделен на две части:interface
часть, и implementation
часть. The interface
часть содержит только объявления (функций, процедур, типов, констант и переменных); функции и процедуры, объявленные здесь, определены (то есть реализованы) в . Обратите внимание, что могут быть функции и процедуры, определенные в implementation
раздел, который не имеет деклараций в .
грандиозная идея заключается в том, что содержание interface
раздел виден всем другим блокам в вашей программе, тогда как содержание implementation
раздел виден только внутри этого самого блока. Таким образом, любой другой блок в вашей программе может использовать RANDOM_NUMBER
константа,PrintExtraNiceMessage
переменная и две процедуры DoThis
и DoThat
. Но вы можете использовать только InitFunction
в этом блоке (например, внутри DoThis
или DoThat
). Кроме того, константа BUFFER_SIZE
также не видно за пределами этого самого устройства.
это очень элегантный подход. The описывается эта единица используется в других единицах (например, какие функции есть и как они используются), и детали реализации скрыты в .
преимущество этого подхода заключается в том, что он решает вашу проблему, по крайней мере, возможно. если the add
, multiply
, subtract
и divide
процедуры должны быть видны другим единицам, затем они должны быть объявлены в . Но тогда они действительно известны компилятору, когда дело доходит до ваш questiontype
процедура, и поэтому вы можете использовать их, даже если они определены (реализованы) ниже questiontype
процедура внутри . Но, с другой стороны, если нет никакого смысла позволять другим единицам использовать эти процедуры, то они не должны быть объявлены в interface
раздел, и вам нужно сделать, как предлагает Дэвид. Это также применимо, если у вас нет нормальных единиц в вашем проекте, то есть если у вас есть только program
файл, который не имеет разделения на interface
и implementation
запасные части.
обратите внимание, что пример OP имеет еще, который применяется только к последнему "если". Предположительно, если они вводят 1, 2 или 3, соответствующая процедура срабатывает, возвращается, а затем они видят "выбрать снова". Если они входят в 4, они этого не делают. Этому хорошо послужило бы дело или каскадное "если"..иначе, если структура, где окончательное еще срабатывает только "когда все остальное терпит неудачу", что похоже на то, что предназначалось OP.