📄 ch02.htm
字号:
<P>The while loop differs from the for loop in that it contains a test conditionthat is checked at the start of each iteration. As long as the test condition isTrue, the loop keeps running.</P><P><PRE>var X : Integer;begin X := 0; while X < 1000 do begin X := DoSomeCalculation; DoSomeMoreStuff; end; { ...more code }end;</PRE><P>In this example, I am calling a function that I assume will eventually returna value greater than or equal to 1,000. As long as the return value from this functionis less than 1,000, the while loop continues to run. When the variable X containsa value greater than or equal to 1,000, the test condition yields False and programexecution jumps to the first line following the body of the while loop. A commonimplementation of a while loop uses a Boolean test variable. The state of the testvariable can be set somewhere within the body of the loop:</P><P><PRE>var Done : Boolean;begin Done := False; while not Done do begin DoSomeStuff; Done := SomeFunctionReturningABoolean; DoSomeMoreStuff; end;end;</PRE><P>At some point it is expected that the variable Done will be True, and the loopwill terminate. Let's do another simple program that illustrates the use of the whileloop. Start a new application and place a button and a memo on the form. Double-clickthe button and modify the event handler so that it looks like this:</P><P><PRE>procedure TForm1.Button1Click(Sender: TObject);var I : Integer;begin I := 5; Memo1.Lines.Clear; while I > -1 do begin Memo1.Lines.Add(`Today I have ` + IntToStr(I) + ` problems to worry about.'); Dec(I); end; Memo1.Lines.Add(`Yeah!');end;</PRE><P>When you run the program and click the form's button, you will see this text inthe memo:</P><P><PRE>Today I have 5 problems to worry about.Today I have 4 problems to worry about.Today I have 3 problems to worry about.Today I have 2 problems to worry about.Today I have 1 problems to worry about.Today I have 0 problems to worry about.Yeah!</PRE><P>This program declares a variable, I, and initializes it to a value of 5. Next,a while loop is started. Text is added to the Memo component each time through theloop, and the variable I is decremented by one. When I is equal to -1, the loop stopsand a final line is added to the memo.</P><P><H4>The while Loop Statement</H4><PRE>while <I>cond_expr</I> do begin <I>statements</I>;</PRE><PRE>end;</PRE><P>The while loop repeatedly executes the block of code indicated by <I>statements</I>as long as the conditional expression <I>cond_expr</I> is True. The state of theloop must be initialized prior to the while statement and modification of the statemust be explicit in the block of code. When the conditional expression <I>cond_expr</I>evaluates to False, the loop terminates. If the body of the loop is a single statement,the begin and end statements are not required.</P><P><H3><A NAME="Heading8"></A>The repeat Loop</H3><P>The repeat loop is nearly identical to the while loop. The distinction betweenthe two is important, though. As you found out in the last exercise, the while loopchecks the conditional expression at the top of the loop. In the case of the repeatloop, the conditional expression is checked at the bottom of the loop. For example,here's the previous exercise you did except that a repeat loop has been substitutedfor the while loop:</P><P><PRE>procedure TForm1.Button1Click(Sender: TObject);var I : Integer;begin I := 5; Memo1.Clear; repeat Memo1.Lines.Add(`Today I have ` + IntToStr(I) + ` problems to worry about.'); Dec(I); until I = -1; Memo1.Lines.Add(`Yeah!');end;</PRE><P>This code will result in the same text displayed in the memo as the previous exercise.Note that it is not necessary to use begin and end because the repeat keyword marksthe beginning of the code block, and the until keyword marks the end of the codeblock. Whether you use a while or a repeat loop depends on what the loop itself does.</P><P><H4>The repeat Loop Statement</H4><PRE>repeat <I>statements</I>;until <I>cond_expr;</I></PRE><P>The repeat loop repeatedly executes the block of code indicated by <I>statements</I>as long as the conditional expression <I>cond_expr</I> is False. The state of theloop must be initialized prior to the repeat statement, and modification of the statemust be explicit in the block of code. When the conditional expression <I>cond_expr</I>evaluates to True, the loop terminates.</P><BLOCKQUOTE> <P><HR><strong>NOTE:</strong> Due to the way the repeat loop works, the code in the body of the loop will be executed at least once regardless of the value of the test condition (because the condition is evaluated at the bottom of the loop). In the case of the while loop, the test condition is evaluated at the top of the loop, so the body of the loop might never be executed. <HR></BLOCKQUOTE><H3></H3><H3><A NAME="Heading9"></A>The goto Statement</H3><P>I'll mention goto just so you know it exists. The goto statement enables you tojump program execution to a label that you have previously declared with the labelkeyword. The label itself is placed in the code followed by a colon. The followingcode snippet illustrates:</P><P><PRE>procedure TForm1.Button1Click(Sender: TObject);var I: Integer;label MyLabel;begin Memo1.Clear; I := 0;MyLabel: Inc(I); Memo1.Lines.Add(IntToStr(I)); if I < 5 then goto MyLabel;end;</PRE><P>It is not necessary to use begin and end here because all lines of code betweenthe goto statement and the label will be executed.</P><BLOCKQUOTE> <P><HR><strong>NOTE:</strong> The goto statement is considered bad form in an Object Pascal program. Just about anything you can accomplish with goto you can accomplish with a while or repeat loop. Very few self-respecting Object Pascal programmers have goto in their code. If you are moving to Object Pascal from another language that uses goto statements, you will find that the basic structure of Object Pascal makes the goto statement unnecessary. <HR></BLOCKQUOTE><H4><BR>The goto Statement</H4><PRE>label <I>label_name</I>; goto <I>label_name</I> . . .<I>label_name:</I></PRE><P>The goto statement unconditionally transfers the program execution sequence tothe label represented by <I>label_name</I>.</P><P><H3><A NAME="Heading10"></A>Continue and Break Procedures</H3><PRE>Before we leave this discussion of loops, you need to know about two procedures that help control program execution in a loop. The Continue procedure is used to force program execution to the bottom of the loop, skipping any statements that come after the call to Continue. For example, you might have part of a loop that you don't want to execute if a particular test returns True. In that case, you would use Continue to avoid execution of any code below that point in the code:</PRE><PRE>var Done : Boolean; Error : Boolean;begin Done := False; while not Done do begin { some code } Error := SomeFunction; if Error then Continue; { jumps to the bottom of the loop } { other code that will execute only if no error occurred } end;end;</PRE><P>The Break procedure is used to halt execution of a loop prior to the loop's normaltest condition being met. For example, you might be searching an array of integersfor a particular number. By breaking execution of your search loop when the numberis found, you can obtain the array index where the number was located:</P><P><PRE>var MyArray : array [0..99] of Integer; Index : Integer; SearchNumber : Integer; I : Integer;begin FillArray; { procedure which fills the array } Index := -1; SearchNumber := 50; for I := 0 to High(MyArray) do begin if MyArray[I] = SearchNumber then begin Index := I; Break; end; end; if Index <> -1 then Label1.Caption := `Number found at index ` + IntToStr(Index) else Label1.Caption := `Number not found in array.';end;</PRE><P>Continue and Break are only used within for, while, and repeat loops. If you attemptto use these procedures outside of a loop, the compiler will generate a compilererror that says BREAK or CONTINUE outside of loop.</P><P>There are many situations in which the Continue and Break procedures are useful.As with most of what I've been talking about, it will take some experience programmingin Object Pascal before you discover all the possible uses for these two procedures.</P><P><H2><A NAME="Heading11"></A>The case Statement</H2><P>The case statement can be considered a glorified if statement. It enables youto execute one of several code blocks based on the result of an expression. The expressionmight be a variable, the result of a function call, or any valid Object Pascal codethat evaluates to an expression. Here is an example of a case statement:</P><P><PRE>case AmountOverSpeedLimit of 0 : Fine := 0; 10 : Fine := 20; 15 : Fine := 50; 20, 25, 30 : Fine := AmountOverSpeedLimit * 10; else begin Fine := GoToCourt; JailTime := GetSentence; end;end;</PRE><P>There are several parts that make up a case statement. First, you can see thatthere is the expression, which in this example is the variable AmountOverSpeedLimit(remember, I warned you about long variable names!). Next, the case statement teststhe expression for equality. If AmountOverSpeedLimit equals 0 (0 :), the value 0is assigned to the variable Fine. If AmountOverSpeedLimit is equal to 10, a valueof 20 is assigned to Fine, and so on. In each of the first three cases a value isassigned to Fine and code execution jumps out of the case statement, which meansthat a case matching the expression has been found and the rest of the case statementcan be ignored.</P><P>Notice that cases 20 and 25 have commas following them, but no statements. Ifthe expression AmountOverSpeedLimit evaluates to 20 or 25, those cases fall throughand the next code block encountered will be executed. In this situation, values of20, 25, or 30 will all result in the same code being executed.</P><P>Finally, you see the else statement. The code block following the else statementwill be executed if no matching cases are found. Inclusion of the else statementis optional. You could write a case statement without an else:</P><P><PRE>case X of 10 : DoSomething; 20 : DoAnotherThing; 30 : TakeABreak;end;</PRE><P>As I said earlier, you might want to use a case statement if you find that youhave several if statements back to back. The case statement is a bit clearer to othersreading your program.</P><BLOCKQUOTE> <P><HR><strong>NOTE:</strong> The expression portion of a case statement must evaluate to an Object Pascal ordinal type (Integer, Word, Byte, and so on). The following, for example, is not allowed: <HR></BLOCKQUOTE><PRE>case SomeStringVariable of `One' : { code } `Two' : { code }end;</PRE><PRE>String values are not allowed, nor are floating-point values.</PRE><P><H4>The case Statement</H4><PRE>case expr of <I>value_1</I>: <I>statements_1</I>; <I>value_2</I>: <I>statements_2</I>; . . . <I>value_n</I>: <I>statements_n</I>;else <I>else_statements</I>;end;</PRE><P>The case statement offers a way to execute different blocks of code dependingon various values of an expression <I>expr</I>. The block of code represented by<I>statements_1</I> is executed when <I>expr</I> is equal to <I>value_1</I>, theblock of code represented by <I>statements_2</I> when <I>expr</I> is equal to <I>value_2</I>,and so on through the block of code represented by <I>statements_n</I> when <I>expr</I>is equal to <I>value_n</I>. When <I>expr</I> is not equal to any of the <I>value_1</I>through <I>value_n</I>, the block of code at <I>else_statements</I> is executed.The else statement is optional.</P><P><H2><A NAME="Heading12"></A>Scope</H2><P>The term scope refers to the visibility of variables within different parts ofyour program. Most variables have <I>local scope</I>, which means that the variableis visible only within the code block in which it is declared. Take a look at theprogram in Listing 2.1. (This is the first look you've had at a complete unit asgenerated by Delphi. There is some code here that you haven't seen before, and I'llexplain it all in due time, but for the time being you can ignore the parts you aren'tfamiliar with.)</P><P><strong>New Term:</strong> The term <I>scope</I> refers to the visibility of variableswithin different parts of your program.</P><P><H4>LISTING 2.1. SCOPEU.PAS.</H4><PRE>01: unit ScopeU;02: 03: interface04: 05: uses06: Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, ÂDialogs,07: StdCtrls;08: 09: type10: TForm1 = class(TForm)11: Button1: TButton;12: Memo1: TMemo;13: procedure Button1Click(Sender: TObject);14: procedure FormCreate(Sender: TObject);15: private16: { Private declarations }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -