File: control_structures.xml

package info (click to toggle)
pike7.8 7.8.866-7
  • links: PTS, VCS
  • area: main
  • in suites: stretch
  • size: 69,304 kB
  • ctags: 28,082
  • sloc: ansic: 252,877; xml: 36,537; makefile: 4,214; sh: 2,879; lisp: 655; asm: 591; objc: 212; pascal: 157; sed: 34
file content (380 lines) | stat: -rw-r--r-- 11,683 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
<chapter title="Control Structures">

<p>In this chapter all the control structures in Pike will be
explained. Control structures are used to control the flow of the
program execution. Note that functions that make the program pause and
simple function calls are not qualified as control structures.</p>

<section title="Conditions">

<p>Conditions are control structures that, given a test condition
selects what code to be executed. These range from the binary "execute
or not" to a large table of code where the selection of which code to
run is based on an input parameter.</p>

<subsection title="if">

<p>The simplest one is called the <b>if statement</b>. It can be
written anywhere where a statement is expected and it looks like
this:</p>

<example>
if( expression )
  statement1;
else
  statement2;
</example>

<p>Please note that there is no semicolon after the parenthesis or after the
<tt>else</tt>. Step by step, <tt>if</tt> does the following:</p>

<ol>
<li>First it evaluates <i>expression</i>.</li>
<li>If the result was <b>false</b> go to point 5.</li>
<li>Execute <i>statement1</i>.</li>
<li>Jump to point 6.</li>
<li>Execute <i>statement2</i>.</li>
<li>Done.</li>
</ol>

<p>This is actually more or less how the interpreter executes the if statement.
In short, <i>statement1</i> is executed if <i>expression</i> is <b>true</b>
otherwise <i>statement2</i> is executed. If you are not interested in
having something executed if the expression is false you can drop the
whole else part like this:</p>

<example>
if( expression )
  statement1;
</example>

<p>If on the other hand you are not interested in evaluating something
if the expression is <b>false</b> you should use the <b>not</b>
operator to negate the true/false value of the expression. See
<fixme>chapter</fixme> for more information about the <b>not</b>
operator. It would look like this:</p>

<example>
if( ! expression )
  statement2;
</example>

<p>Any of the statements here and in the rest of this chapter can
also be a <b>block</b> of statements. A block is a list of statements,
separated by semicolons and enclosed by brackets. Note that you should
never put a semicolon after a block of statements. The example above
would look like this;</p>

<example>
if ( ! expression )
{
  statement;
  statement;
  statement;
}
</example>

<p>It is also possible to place several if statements in sequence, so
that if the first expression is false it continues with the next one
and the next one until the first true expression is found.</p>

<example>
if ( expression1 )
  statement1;
else if ( expression2 )
  statement2;
else if ( expression3 )
  statement3;
else
  statement4;
</example>

<p>A special case of the above example is when in every expression you
compare one variable with different values. For those applications the
switch statement described below can be used instead to increas
performance and simplify the code.</p>

</subsection>

<subsection title="switch">

<p>A more sophisticated condition control structure is the <b>switch
statement</b>. A switch lets you select one of many choices depending
on the value of an expression and it can look something like this:</p>

<example>
switch ( expression )
{
  case constant1:
    statement1;
    break;

  case constant2:
    statement2;
    break;

  case constant3 .. constant4:
    statement3;
    break;

  default:
    statement5;
}
</example>

<p>As you can see, a switch statement is a bit more complicated than an
if statement. It is still fairly simple however. It starts by evaluating
the expression it then searches all the <tt>case</tt> statements in the
following block. If one is found to be equal to the value returned by
the expression, Pike will continue executing the code directly following
that <tt>case</tt> statement. When a <tt>break</tt> is encountered Pike
will skip the rest of the code in the switch block and continue executing
after the block. Note that it is not strictly necessary to have a break
before the next case statement. If there is no break before the next case
statement Pike will simply continue executing and execute the code after
that case statement as well.</p>

<p>One of the case statements in the above example differs in that it is
a <b>range</b>. In this case, any value between <i>constant3</i> and
<i>constant4</i> will cause Pike to jump to <i>statement3</i>. Note
that the ranges are inclusive, so the values <i>constant3</i> and
<i>constant4</i> are also valid.</p>
</subsection>

</section>

<section title="Loops">

<p>Loops are used to execute a piece of code more than once. Since this can
be done in quite a few different ways there are four different loop
control structures. They may all seem very similar, but using the right
one at the right time makes the code a lot shorter and simpler.</p>

<subsection title="while">

<p><tt>While</tt> is the simplest of the loop control structures. It looks
just like an <tt>if</tt> statement without the else part:</p>

<example>
	while ( expression )
	  statement;
</example>

<p>The difference in how it works isn't that big either, the statement is
executed if the expression is true. Then the expression is evaluated
again, and if it is true the statement is executed again. Then it
evaluates the expression again and so forth... Here is an example of
how it could be used:</p>

<example>
int e=1;
while(e&lt;5)
{
  show_record(e);
  e=e+1;
}
</example>

<p>This would call show_record with the values 1, 2, 3 and 4.</p>
</subsection>

<subsection title="for">

<p><tt>For</tt> is simply an extension of <tt>while</tt>. It provides an
even shorter and more compact way of writing loops. The syntax looks
like this:</p>

<example>
for ( initializer_statement ; expression ; incrementor_expression )
  statement ;
</example>

<p>For does the following steps:</p>

<ol>
<li> Executes the the <i>initializer_statement</i>. The initializer statement
     is executed only once and is most commonly used to initialize the loop
     variable.</li>
<li> Evaluates <i>expression</i></li>
<li> If the result was false it exits the loop and continues with the
     program after the loop.</li>
<li> Executes <i>statement</i>.</li>
<li> Executes the <i>increment_expression</i>.</li>
<li> Starts over from 2.</li>
</ol>

<p>This means that the example in the while section can be written like this:</p>

<example>
for(int e=1; e&lt;5; e=e+1)
  show_record(e);
</example>

</subsection>

<subsection title="do-while">

<p>Sometimes it is unpractical that the expression is always evaluated before
the first time the loop is executed. Quite often you want to execute
something, and then do it over and over until some condition is satisfied.
This is exactly when you should use the do-while statement.</p>

<example>
do
  statement;
while ( expression );
</example>

<p>As usual, the <i>statement</i> can also be a block of statements, and then
you do not need a semicolon after it. To clarify, this statement executes
<i>statement</i> first, and then evaluates the <i>expression</i>. If the
expression is <b>true</b> it executes the loop again. For instance, if you
want to make a program that lets your modem dial your Internet provider,
it could look something like this:</p>

<!-- Can someone come up with a better example? -->
<example>
do {
  modem-&gt;write("ATDT441-9109\n"); // Dial 441-9109
} while(modem-&gt;gets()[..6]] != "CONNECT");
</example>

<p>This example assumes you have written something that can communicate with
the modem by using the functions <tt>write</tt> and <tt>gets</tt>.</p>

</subsection>

<subsection title="foreach">

<p><tt>Foreach</tt> is unique in that it does not have an explicit test expression
evaluated for each iteration in the loop. Instead, <tt>foreach</tt> executes
the statement once for each element in an array. <tt>Foreach</tt> looks like
this:</p>

<example>
foreach ( array_expression, variable )
  statement ;
</example>

<p>We have already seen an example of <tt>foreach</tt> in the <tt>find_song</tt>
function in chapter 2. What foreach does is:</p>

<ol>
<li> It evaluates the <i>array_expression</i> which must return an array.</li>
<li> If the array is empty, exit the loop.</li>
<li> It then assigns the first element from the array to the <i>variable</i>.</li>
<li> Then it executes the <i>statement</i>.</li>
<li> If there are more elements in the array, the next one is assigned to
     the <i>variable</i>, otherwise exit the loop.</li>
<li> Go to point 4.</li>
</ol>

<p><tt>Foreach</tt> is not really necessary, but it is faster and clearer than
doing the same thing with a <tt>for</tt> loop, as shown here:</p>

<example>
array tmp1= array_expression;
for ( tmp2 = 0; tmp2 &lt; sizeof(tmp1); tmp2++ )
{
  variable = tmp1 [ tmp2 ];
  statement;
}
</example>

</subsection>
</section>

<section title="Breaking out of loops">

<p>The loop control structures above are enough to solve any problem, but
they are not enough to provide an easy solution to all problems. One thing
that is still missing is the ability to exit a loop in the middle of it.
There are three ways to do this:</p>

<subsection title="break">
<p><tt>break</tt> exits a loop or switch statement immediately and continues
executing after the loop. <tt>Break</tt> can not be used outside of a loop or
switch. It is quite useful in conjunction with <tt>while(1)</tt> to
construct command parsing loops for instance:</p>

<example>
while(1)
{
  string command=Stdio.Readline()->read("&gt; ");
  if(command=="quit") break;
  do_command(command);
}
</example>

<p>When you want to break out of more than the innermost loop, you can tell
<tt>break</tt> what loop to break free of using lables, as in:</p>

<example>
array arr1, arr2;
while(1)
{
  // ...
a:if(sizeof(arr1) >= sizeof(arr2))
  {
    int i = sizeof(b), j = sizeof(yb);
    while(i)
      if(b[--i] != yb[--j])
        break a;
    // the code here is only run when arr1
    // and arr2 share some common suffix
  }
  // execution continues here
}
</example>
</subsection>

<subsection title="continue">
<p><tt>Continue</tt> does almost the same thing as <tt>break</tt>, except instead of
breaking out of the loop it only breaks out of the loop body. It then continues
to execute the next iteration in the loop. For a <tt>while</tt> loop, this
means it jumps up to the top again. For a <tt>for</tt> loop, it jumps to the
incrementor expression. For a <tt>do-while</tt> loop it jumps down to the
expression at the end. To continue our example above, <tt>continue</tt> can be used
like this:</p>

<example>
while(1)
{
  string command=Stdio.Readline()->read("&gt; ");
  if(strlen(command) == 0) continue;
  if(command=="quit") break;
  do_command(command);
}
</example>

<p>This way, <tt>do_command</tt> will never be called with an empty string as
argument.</p>
</subsection>

<subsection title="return">

<p><tt>Return</tt> doesn't just exit the loop, it exits the whole function. We have seen
several examples how to use it chapter 2. None of the functions in chapter
two returned anything in particular however. To do that you just put the return
value right after <tt>return</tt>. Of course the type of the return value
must match the type in the function declaration. If your function declaration
is <tt>int main()</tt> the value after <tt>return</tt> must be an <b>int</b>.
For instance, if we wanted to make a program that always returns an error
code to the system, just like the UNIX command <tt>false</tt> this is how
it would be done:</p>

<example>
#!/usr/local/bin/pike

int main()
{
  return 1;
}
</example>

<p>This would return the error code <tt>1</tt> to the system when the program
is run.</p>
</subsection>
</section>

</chapter>