📄 pasl1005.html
字号:
writeln(a); {10}
end;
var
x : byte;
begin
x:=15;
writeln(x); {15}
foo(x);
writeln(x); {Still 15}
end.
</pre>
<hr><p>It outputs :</p><pre>
15
15
10
15
</pre><hr><p>
At first, x is 15, then passed to procedure foo as passing parameter a.
Eventhough it is legal to modify a inside foo, the value of x is unaffected
anyway. This type of passing method is called <b>PASS BY VALUE</b>.
How about this :</p><hr><pre>
procedure foo(var a : byte); { See the difference ? }
begin
writeln(a); {15}
a:=10;
writeln(a); {10}
end;
var
x : byte;
begin
x:=15;
writeln(x); {15}
foo(x);
writeln(x); {10}
end.
</pre><hr><p>It outputs :</p><pre>
15
15
10
10
</pre><hr><p>
If we add <tt>var</tt> before a as passing parameter, the value of x is changed
whenever a is changed. This type of passing method is called <b>PASS BY REFERENCE.</b></p>
<p>We must pass by value if the parameters are not necessarily be changed in
the procedure. If the parameters need changing and the change is important
to be known by the caller, use pass by reference.</p>
<p>In Borland Pascal 7.0, we could omit the return values of a function. In
our examples so far, we use <tt>readkey</tt>, right ? <tt>Readkey</tt> is actually a function
but a built-in one. Before version 7.0, we must take a return value of it
(<tt>readkey</tt>), like this : <tt>c:=readkey;</tt>. But, from version 7.0, we could omit it
by just calling <tt>readkey</tt> like this : <tt>readkey;</tt></p>
<p>You <b>CAN</b> call another procedure inside a procedure or function as long as
the caller procedure/function lies below it. Example :</p><hr><pre>
procedure a;
begin
:
:
end;
procedure b;
begin
:
a; { legal }
end;
begin
:
end.
</pre><hr><p>
It is legal for procedure b to call procedure a. But procedure a can NEVER
call procedure b. It is ILLEGAL. Function can call procedures, procedures
can call functions, functions can also call other functions as long as the
caller is below the target (the one which is invoked).
So, you'd better arrange the procedures and functions you might have.</p>
<p>If the <tt>if</tt>-structure and loop structures could nest each other, can
procedures and functions nest each other ? <b>YES, IT COULD !</b> Example :</p><hr><pre>
procedure e; { e cannot access a, b, c, and d }
begin
:
end;
procedure a;
procedure b;
begin
c; {illegal}
e; {legal}
end;
procedure c;
begin
b; {legal}
e; {legal}
end;
begin
:
b; {legal}
c; {legal}
e; {legal}
end;
procedure d;
begin
:
b; {illegal}
c; {illegal}
a; {legal}
e; {legal}
end;
begin
:
b; {illegal}
c; {illegal}
a; {legal}
d; {legal}
e; {legal}
end.
</pre><hr><p>
Procedure c can call procedure b since c is below b, but procedure b cannot
call procedure c. Procedure a, whose begin..end block below procedure b and
procedure c, can call procedure b and c. Procedure b and c cannot be access
ed by procedure d and main block. So, nested procedure can only be accessed
by their brothers/sisters (among the same level of nested procedure), and
their parent (the procedure who endow them). Accesses between brothers
follow the rule of normal procedure calling.</p>
<h4>Practice a lot !</h4>
<p>How about calling ourselves ? Well, <b>IT IS PERFECTLY LEGAL</b> too !! Example :</p><hr><pre>
procedure a;
begin
a;
end;
begin
a;
end.
</pre><hr><p>
But it will say error since it call itself ENDLESSLY. The method of calling
oneselves is called <b>RECURSIVE CALLS</b>. In recursive calls, we must :<ol>
<li>Provide terminating conditions.</li>
<li>Be extremely careful in coding.</li>
<li>Not use too many recursive calls, say 50,000 times.</li></ol>
If not, you could find these symptoms :<ol>
<li>Hang / stopped responding.</li>
<li>Computer "auto-murmur".</li>
<li>Beeping eratically.</li>
<li>Auto-reboot.</li>
<li>Auto-format (no...no ! Just kidding !)</li>
<li>Other unexpected result</li></ol>
<p>Let's see a very good example of recursive calls : It's factorial. See the
non-recursive method of factorial function above, then see this recursive
version :</p><p><pre></pre>
<hr>
<pre>function factorial (n:byte):factorial;
begin
if n<2 then { This is the terminating condition }
factorial:=1;
else
factorial:=n*factorial(n-1); { This is the recursive part }
end;
var
x : byte;
begin
writeln('Enter a value : '); readln(x);
writeln(x,'! is ',factorial(x));
end.
</pre>
<hr>
<pre>If x = 5,
At first call, n = 5. Factorial:=5*factorial(4); => need second call
Second call, n = 4. Factorial:=4*factorial(3); => need third call
Third call, n = 3. Factorial:=3*factorial(2); => need fourth call
Fourth call, n = 2. Factorial:=2*factorial(1); => need fifth call
Fifth call, n = 1. Factorial:=1; => inserted back to above so
4th call becomes : Factorial:=2*1; (=2) => inserted back to above so
3rd call becomes : Factorial:=3*2; (=6) => inserted back to above so
2nd call becomes : Factorial:=4*6; (=24) => inserted back to above so
1st call becomes : Factorial:=5*24; (=120)
</pre>
<p>As you may see that factorial in recursive method is simpler than ever.
Suppose you miswrite n-1 to n, the terminating condition would never be
functional. So, it will loop forever ! Be careful !</p>
<p>Well, we come to a quite advanced matter. It is sometimes used though.
Inter-referenced calls. It means that 2 procedures or functions could call
each other.</p><p><pre></pre>
<hr>
<pre>procedure a;
begin
b; { illegal }
end;
procedure b;
begin
a;
end;
</pre>
<hr><p>
As you may see, calling a from b is legal, but calling b from a is illegal.
It sometimes necessary for a to call b and for b to call a. The real-life
problem is like context-sensitive help. Sometimes the description, when it
is pointed or clicked, it call the index. But also, the index has to call
its description after a topic is picked. The solution is : <b>FORWARD CALL</b>.
Example :</p><p><pre></pre>
<hr>
<pre>procedure b; forward;
procedure a;
begin
b; { now legal }
end;
procedure b;
begin
a;
end;
</pre>
<hr><p>
Use the statement <tt>forward</tt> to make b visible to a, so a can call b. It is
more dangerous than recursive call. If you are not careful, you may find
the same symptoms as recursive call did. What you must do is also the same
as in the recursive call. Just beware : Calling procedures uses a part of
memory called stack. Reciprocal calls wastes stacked much faster than
recursive calls. If you run out of stack, your program would stuck.</p>
<p>How could I break down complex problems ? How good your ability in breaking
problems is actually depends on your experience in programming. But, I can
only tell you this :</p><ol>
<li><b>Identify your problem correctly.</b><br>
Suppose you have to make a program to record employee data for
a bank. What is it for ? Employee data for just an information or
for salary statistics or what ?</li>
<li><b>Separate one process from another.</b><br>
Suppose you do employee data for information. The processes
are record it to disk, edit data, delete data, sort data, or print
and display data, or search data.</li>
<li><b>List the solution steps of each process.</b><br>
Suppose you first do record data. You take input from keyboard and
record it to disk. You ask if user wants to input again or not.</li>
<li><b>List the data requirements.</b><br>
Employe data may require name, position, residence, office
location, civil status, age, sex, years of service, and so on.</li>
<li><b>Determine the output requirements.</b><br>
You may design the output like a list of employee data. It is
useful for comparison reason. Or may be you would love to make it
like an archive form for complete document. Or you ask the user and
they can choose.</li>
<li><b>Construct an algorithm to do the process.</b><br>
Suppose taking data from keyboard, may sound : input name,
input age, input position, and so on. Then prepare file, record the
data to disk, close the file. Ask user if they want to input some
more. If they do, repeat the whole process, otherwise quit.</li>
<li><b>Use your creativity to expand the input, process and output.</b><br>
Don't stick the model from input to output. You may add your
creativity. Client may want the output format exactly the same as
they wish. Perhaps you could give suggestions in arranging them, or
perhaps if you think some data is important to display or print, go
tell the client.</li>
<li><b>Think of all other useful things to add in program.</b><br>
Suppose you want to add the feature of Auto-Correct, to minimize
the human-error. You probably record some usual names, like Jim,
Dave, and so on. If user types Dabe, for example, your program can
give suggestion to change it to Dave. Yeah, somethings like that.</li>
<li><b>Implement it, step by step.</b><br>
Don't let all dreams be dreams. Let it comes true.</li>
<li><b>Combine all the programs to tackle the problem.</b><br>
All the module of each process should be gathered. You may
want to generalize your input procedure to fit in each module to
save energy and time. Combine them using menus. And don't forget to
make finishing touches, to make the software looks great.</li>
</ol><p>
Well, that's one of the complex problems. You may follow the guidelines.
OK, that's all for today ! Have a good <a href="pasq1005.html">quiz</a> ! =)</p>
<hr><p><B><H3>Where to go ?</H3></B>
<A HREF="../news.html">Back to main page</A><BR>
<A HREF="pasles01.html">Back to Pascal Tutorial Lesson 1 contents</A><BR>
<A HREF="pasq1005.html">To the quiz</A><BR>
<A HREF="pasl1004.html">Back to Chapter 5</A> about looping<BR>
<A HREF="pasl1006.html">To Chapter 7</A> about arrays<BR>
<A HREF="../mylink.html">My page of programming link</A><BR>
<A HREF="../faq.html">Contact me here</a>
<hr><P class="cpy">By : Roby Joehanes, © 1996, 2000</P>
</BODY></HTML>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -