This repository has been archived on 2024-09-22. You can view files and clone it, but cannot push or open issues or pull requests.
pbi-ide/help/BasicStampHelp/Content/LanguageTopics/Commands/FOR_NEXT.htm

391 lines
22 KiB
HTML

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns:MadCap="http://www.madcapsoftware.com/Schemas/MadCap.xsd" MadCap:lastBlockDepth="6" MadCap:lastHeight="94" MadCap:lastWidth="853" MadCap:disableMasterStylesheet="true" MadCap:tocPath="" MadCap:InPreviewMode="false" MadCap:PreloadImages="false" MadCap:RuntimeFileType="Topic" MadCap:TargetType="WebHelp" lang="en-us" xml:lang="en-us" MadCap:PathToHelpSystem="../../../" MadCap:HelpSystemFileName="Default.xml" MadCap:SearchType="Stem">
<head><title>FOR…NEXT</title>
<link href="../../SkinSupport/MadCap.css" rel="stylesheet" />
<link href="../../Resources/Stylesheets/BSE_Help.css" rel="stylesheet" />
<script src="../../SkinSupport/MadCapAll.js" type="text/javascript">
</script>
</head>
<body>
<h1 class="code">FOR…NEXT</h1>
<div class="ImagePlusCaption">
<div class="Col2">
<p>
<img src="../../graphics/pgm_icon1.gif" border="0" alt="BS1 icon" title="BS1 icon" />
<img src="../../graphics/pgm_icon2.gif" border="0" alt="BS2 icon" title="BS2 icon" />
<img src="../../graphics/pgm_icon2e.gif" border="0" alt="BS2e icon" title="BS2e icon" />
<img src="../../graphics/pgm_icon2sx.gif" border="0" alt="BS2sx icon" title="BS2sx icon" />
<img src="../../graphics/pgm_icon2p.gif" border="0" alt="BS2p icon" title="BS2p icon" />
<img src="../../graphics/pgm_icon2pe.gif" border="0" alt="BS2pe icon" title="BS2pe icon" />
<img src="../../graphics/pgm_icon2px.gif" border="0" alt="BS2px icon" title="BS2px icon" />
</p>
</div>
<p style="text-align: right;"><a href="../ExampleTopics/ForNextEx.htm" target="" title="" alt="" class="MCXref_0">FOR...NEXT Examples</a>
</p>
<p>&#160;</p>
</div>
<p class="clear">&#160;</p>
<p>&#160;</p>
<p class="PlainText">Syntax <img align="absmiddle" src="../../graphics/mini_1.gif" /> :
<span class="keyword_in_text">FOR</span> <![CDATA[ ]]><i>Counter = StartValue</i> <![CDATA[ ]]><span class="keyword_in_text">TO</span> <![CDATA[ ]]><i>EndValue </i>{<span class="keyword_in_text">STEP </span>{-}<i> StepValue</i>} ... <span class="keyword_in_text">NEXT</span><i><![CDATA[ ]]></i>{<i>Counter</i>}</p>
<p class="PlainText">Syntax <img align="absmiddle" src="../../graphics/mini_2.gif" /> : <span class="keyword_in_text">FOR</span> <![CDATA[ ]]><i>Counter = StartValue</i> <![CDATA[ ]]><span class="keyword_in_text">TO</span> <![CDATA[ ]]><i>EndValue </i>{<span class="keyword_in_text">STEP</span><i> StepValue</i>}<i><![CDATA[ ]]></i>... <span class="keyword_in_text">NEXT</span></p>
<h2>Function</h2>
<p class="PlainText">Create a repeating loop that executes the program lines between <span class="keyword_in_text">FOR</span> and
<span class="keyword_in_text">NEXT</span>, incrementing or decrementing <i>Counter</i> according to <i>StepValue</i> until the value of the <i>Counter</i> variable passes the <i>EndValue</i>.
</p>
<ul>
<li value="1"><b><i>Counter</i></b> is a variable (usually a byte or a word) used as a
counter.</li>
<li value="2"><b><i>StartValue</i></b> is a variable/constant/expression* (0 - 65535) that
specifies the initial value of the variable (<i>Counter</i>).</li>
<li value="3"><b><i>EndValue</i></b> is a variable/constant/expression* (0 - 65535) that
specifies the end value of the variable (<i>Counter</i>). When the value
of Counter is outside of the range <i>StartValue</i> to <i>EndValue</i>, the
<span class="keyword_in_text">FOR...NEXT</span> loop stops executing and the program goes on to the instruction
after <span class="keyword_in_text">NEXT</span>.</li>
<li value="4"><b><i>StepValue</i></b> is an optional variable/constant/expression* (0 -
65535) by which the <i>Counter</i> increases or decreases with each iteration
through the <span class="keyword_in_text">FOR...NEXT</span> loop. On the BS1, use a minus sign (-)†
in front of the <i>StepValue</i> to indicate a negative step. On all other
BASIC Stamp models, if <i>StartValue</i> is larger than <i>EndValue</i>, PBASIC
understands <i>StepValue</i> to be negative, even though no minus sign is used.</li>
</ul>
<p class="PlainText">*<img src="../../graphics/bs1note.gif" style="vertical-align: super;" /> Note: expressions are not allowed as arguments on the BS1.</p>
<p class="PlainText"><img src="../../graphics/bs1note.gif" style="vertical-align: super;" /> Note: Use a minus sign to indicate negative <i>StepValues</i> on the BS1.</p>
<h2>Quick Facts</h2>
<table width="100%" cellpadding="4" cellspacing="0" border="1">
<tr>
<td width="26%" align="center" bgcolor="#CFCFCF">&#160;</td>
<td width="37%" align="center" bgcolor="#CFCFCF">BS1</td>
<td width="37%" align="center" bgcolor="#CFCFCF">BS2 Family</td>
</tr>
<tr>
<td align="center" bgcolor="#CFCFCF">Max. nested commands</td>
<td align="center">8</td>
<td align="center">16</td>
</tr>
<tr>
<td align="center" bgcolor="#CFCFCF">To decrement counter variable</td>
<td align="center">Set <i>StartValue</i> &gt; <i>EndValue</i><br></br>and enter
negative <i>StepValue</i> *</td>
<td align="center">Set <i>StartValue</i> &gt; <i>EndValue</i></td>
</tr>
<tr>
<td align="center" bgcolor="#CFCFCF"><i>Counter</i> comparison</td>
<td align="center">Exit loop if <i>Counter</i> exceeds <i>EndValue</i></td>
<td align="center">Exit loop if <i>Counter</i> outside of range set by
<i>StartValue</i> to <i>EndValue</i></td>
</tr>
<tr>
<td align="center" bgcolor="#CFCFCF">Related Commands</td>
<td align="center" colspan="1">
<p colspan="1" align="center">None</p>
</td>
<td align="center" colspan="1">
<p colspan="1" align="center"><a href="DO_LOOP.htm" target="" title="" alt="" class="MCXref_0">DO…LOOP</a>, <a href="EXIT.htm" target="" title="" alt="" class="MCXref_0">EXIT</a></p>
</td>
</tr>
</table>
<p>*Note: Direction (ie: increment/decrement) cannot be changed at runtime.</p>
<h2>Explanation</h2>
<p class="PlainText"><span class="keyword_in_text">FOR...NEXT</span> loops let your program execute a series of instructions for a
specified number of repetitions (called iterations). By default, each time through
the loop, the counter variable is incremented by 1. It will continue to loop until
the result of the counter is outside of the range set by <i>StartValue</i> and
<i>EndValue</i>. Also, <span class="keyword_in_text">FOR...NEXT</span> loops always execute at least once. The
simplest form is shown here: </p>
<p>
<img src="../../graphics/bs1_inline.gif" border="0">
</img>
</p><pre class="BScode" xml:space="preserve">
SYMBOL reps = B2 ' FOR...NEXT loop counter
Main:
FOR reps = 1 TO 3 ' repeat with Reps = 1, 2, 3
DEBUG "*" ' print * on the screen
NEXT
END
</pre>
<p>
<img src="../../graphics/bs2all_inline.gif" border="0">
</img>
</p><pre class="BScode" xml:space="preserve">
reps VAR Nib ' FOR...NEXT loop counter
Main:
FOR reps = 1 TO 3 ' repeat with Reps = 1, 2, 3
DEBUG "*" ' print * on the screen
NEXT
END
</pre>
<p class="PlainText">In the above code, the <span class="keyword_in_text">FOR</span> command sets Reps = 1. Then the <span class="keyword_in_text">DEBUG</span>
line (within the <span class="keyword_in_text">FOR...NEXT</span> loop) is executed; printing an asterisk (*) on
the screen. When the BASIC Stamp sees the <span class="keyword_in_text">NEXT</span> command, it goes back to
the previous <span class="keyword_in_text">FOR</span> command, adds 1 to Reps and compares the result to the
range set by <i>StartValue</i> and <i>EndValue</i>. If reps is still within range,
it executes the code in the loop again. Each time the <span class="keyword_in_text">FOR...NEXT</span> loop
executes, the value of reps is updated (incremented by 1) and the code within the
loop (the <span class="keyword_in_text">DEBUG</span> line) is executed; printing another asterisk on the screen.
This code will run through the loop three times; setting reps to 1, 2 and 3, and
printing three asterisks on the screen. After the third loop, again the BASIC
Stamp goes back up to the <span class="keyword_in_text">FOR</span> command, adds 1 to reps and compares the result
(4 in this case) to the range. Since the range is 1 to 3 and the value is 4 (outside
the range) the <span class="keyword_in_text">FOR...NEXT</span> loop is done and the BASIC Stamp will jump down
to the first line of code following the <span class="keyword_in_text">NEXT</span> command.</p>
<p class="PlainText">You can view the changing values of reps by including the reps variable in a
<span class="keyword_in_text">DEBUG</span> command within the loop: </p>
<p>
<img src="../../graphics/bs1_inline.gif" border="0">
</img>
</p><pre class="BScode" xml:space="preserve">
SYMBOL reps = B2 ' FOR...NEXT loop counter
Main:
FOR reps = 1 TO 3 ' repeat with Reps = 1, 2, 3
DEBUG #reps, CR ' print number on the screen
NEXT
END
</pre>
<p>
<img src="../../graphics/bs2all_inline.gif" border="0">
</img>
</p><pre class="BScode" xml:space="preserve">
reps VAR Nib ' FOR...NEXT loop counter
Main:
FOR reps = 1 TO 3 ' repeat with Reps = 1, 2, 3
DEBUG DEC reps, CR ' print number on the screen
NEXT
END
</pre>
<p class="PlainText">Running this example should display "1" , "2", and "3" on the screen.</p>
<p class="PlainText"><span class="keyword_in_text">FOR...NEXT</span> can also be made to decrement (rather than increment) the
counter variable. The BS1 does this when you specify a negative <i>StepValue</i>(as well as a <i>StartValue</i> that is greater than the <i>EndValue</i>). All
other BASIC Stamp models do this automatically when the <i>StartValue</i> is greater
than the <i>EndValue</i>. Examples of both are shown below:</p>
<p>
<img src="../../graphics/bs1_inline.gif" border="0">
</img>
</p><pre class="BScode" xml:space="preserve">
SYMBOL reps = B2 ' FOR...NEXT loop counter
Main:
FOR reps = 3 TO 1 STEP -1 ' repeat with Reps = 3, 2, 1
DEBUG #reps, CR ' print number on the screen
NEXT
END
</pre>
<p>
<img src="../../graphics/bs2all_inline.gif" border="0">
</img>
</p><pre class="BScode" xml:space="preserve">
reps VAR Nib ' FOR...NEXT loop counter
Main:
FOR reps = 3 TO 1 ' repeat with Reps = 3, 2, 1
DEBUG DEC reps, CR ' print number on the screen
NEXT
END
</pre>
<p class="PlainText">Note that the code for the BS2 series did not use the optional <span class="keyword_in_text">STEP</span> argument.
This is because we wanted to decrement by positive 1 anyway (the default unit)
and the BASIC Stamp realizes it needs to decrement because the <i>StartValue</i>is greater than the <i>EndValue</i>. A negative <i>StepValue</i> on the BS2 series
would be treated as its positive, two's complement counterpart. For example, -1
in two's complement is 65535. So the following code executes only once: </p><pre class="BScode" xml:space="preserve">
reps VAR Nib ' FOR...NEXT loop counter
Main:
FOR reps = 3 TO 1 STEP -1 ' decrement 3 by 65535
DEBUG DEC reps, CR ' print number on the screen
NEXT
END
</pre>
<p class="PlainText">The above code would run through the loop once with <i>reps</i> set to 3. The second
time around, it would decrement <i>reps</i> by 65535 (-1 is 65535 in two's complement)
effectively making the number -65532 (4 in two's complement) which is outside the
range of the loop.</p>
<p>All the arguments in the <span class="keyword_in_text">FOR...NEXT</span> command can be constants, variables
or expressions (on the BS2 series). This leads to some interesting uses. For
example, if you make the <i>StartValue</i> and <i>EndValue</i> a variable, and
change their values within the loop, you'll change the behavior of the loop itself.
Try the following:</p><pre class="BScode" xml:space="preserve">
reps VAR Byte ' counter for the FOR/NEXT loop
startVal VAR Byte
endVal VAR Byte
Setup:
startVal = 1 ' initialize startVal to 1
endVal = 3 ' initialize endVal to 3
Main:
FOR reps = startVal TO endVal ' repeat for 1 to 3
DEBUG DEC reps, CR
IF (reps = 3) THEN ' if reps = 3 then swap startVal and endVal
startVal = 3 ' otherwise continue loop
endVal = 1
ENDIF
NEXT
</pre>
<p class="PlainText">Here the loop starts with a range of 1 to 3. First, the <span class="keyword_in_text">DEBUG</span> line
prints the value of <i>reps</i>. Then the <span class="keyword_in_text">IF...THEN</span> line makes a decision; if
<i>reps</i> is equal to 3, then swap the order of <i>startVal</i> and <i>endVal</i>,
otherwise continue the loop execution. The next time through the loop (after
<i>startVal</i> and <i>endVal</i> have been swapped), <i>reps</i> will be decremented
instead of incremented because <i>startVal</i> is greater than <i>endVal</i>.
The result is a display on the screen of the numbers 1, 2, 3, 2, 1.</p>
<p class="PlainText">The following example uses the value of <i>reps</i> as the <i>StepValue</i>. This
creates a display of power's of 2 (1, 2, 4, 8, 16, 32, 64, etc):</p>
<p>
<img src="../../graphics/bs1_inline.gif" border="0">
</img>
</p><pre class="BScode" xml:space="preserve">
SYMBOL reps = B2 ' FOR...NEXT loop counter
Main:
FOR reps = 1 TO 256 STEP reps ' each loop add current value of Reps
DEBUG reps ' show reps in Debug window.
NEXT
END
</pre>
<p>
<img src="../../graphics/bs2all_inline.gif" border="0">
</img>
</p><pre class="BScode" xml:space="preserve">
reps VAR Byte ' FOR...NEXT loop counter
Main:
FOR reps = 1 TO 256 STEP reps ' each loop add current value of Reps
DEBUG ? DEC reps ' show reps in debug window.
NEXT
END
</pre>
<p class="PlainText">There is a potential bug that you should be careful to avoid. The BASIC Stamp
uses unsigned 16-bit integer math for any math operation it performs, regardless
of the size of values or variables. The maximum value the BASIC Stamp can internally
calculate is 65535 (the largest 16-bit number). If you add 1 to 65535, you get 0
as the 16-bit register rolls over (like a car's odometer does when you exceed
the maximum mileage it can display). Similarly, if you subtract 1 from 0, you'll
get 65535 as the 16-bit register rolls under (a rollover in the opposite direction).</p>
<p class="PlainText">If you write a <span class="keyword_in_text">FOR...NEXT</span> loop who's <i>StepValue</i> would cause the
counter variable to go past 65535, this rollover may cause the loop to execute
more times than you expect. Try the following example: </p>
<p>
<img src="../../graphics/bs1_inline.gif" border="0">
</img>
</p><pre class="BScode" xml:space="preserve">
SYMBOL reps = W1 ' FOR...NEXT loop counter
Main:
FOR reps = 0 TO 65535 STEP 3000 ' each loop add 3000
DEBUG reps ' show reps in debug window
NEXT
END
</pre>
<p>
<img src="../../graphics/bs2all_inline.gif" border="0">
</img>
</p><pre class="BScode" xml:space="preserve">
SYMBOL reps = W1 ' FOR...NEXT loop counter
Main:
FOR reps = 0 TO 65535 STEP 3000 ' each loop add 3000
DEBUG reps ' show reps in debug window
NEXT
END
</pre>
<p class="PlainText">The value of <i>reps</i> increases by 3000 each trip through the loop. As it approaches
the <i>EndValue</i>, an interesting thing happens; <i>reps</i> is: 57000, 60000, 63000,
464, 3464... It passes the <i>EndValue</i>, rolls over and keeps going. That's
because the result of the calculation 63000 + 3000 exceeds the maximum capacity
of a 16-bit number and then rolls over to 464. When the result of 464 is tested
against the range ("Is <i>reps</i> &gt; 0 and is <i>reps</i> &lt; 65500?") it passes the test and the
loop continues. </p>
<p class="PlainText">A similar symptom can be seen in a program whose <i>EndValue</i> is mistakenly
set higher than what the counter variable can hold. The example below uses a
byte-sized variable, but the <i>EndValue</i> is set to a number greater than what
will fit in a byte:</p>
<p>
<img src="../../graphics/bs1_inline.gif" border="0">
</img>
</p><pre class="BScode" xml:space="preserve">
SYMBOL reps = W1 ' FOR...NEXT loop counter
Main:
FOR reps = 0 TO 300 ' each loop add 1
DEBUG reps ' show reps in debug window
NEXT
END
</pre>
<p>
<img src="../../graphics/bs2all_inline.gif" border="0">
</img>
</p><pre class="BScode" xml:space="preserve">
reps VAR Byte ' FOR...NEXT loop counter
Main:
FOR reps = 0 TO 300 ' each loop add 1
DEBUG DEC ? reps ' show reps in debug window
NEXT
END
</pre>
<p class="PlainText">Here, <i>reps</i> is a byte variable; which can only hold the number range 0 to 255.
The <i>EndValue</i> is set to 300, however; greater than 255. This code will loop
endlessly because when reps is 255 and the <span class="keyword_in_text">FOR...NEXT</span> loop adds 1, reps
becomes 0 (bytes will rollover after 255 just like words will rollover after 65535).
The result, 0, is compared against the range (0 - 255) and it is found to be within
the range, so the <span class="keyword_in_text">FOR...NEXT</span> loop continues.</p>
<p class="PlainText">It's important to realize that on the BS2 series, the test is against the entire
range, not just the <i>EndValue</i>. The code below is a slight modification of
the previous example (the <i>StartValue</i> is 10 instead of 0) and will not loop
endlessly.</p>
<p>
<img src="../../graphics/bs2all_inline.gif" border="0">
</img>
</p><pre class="BScode" xml:space="preserve">
reps VAR Byte ' FOR...NEXT loop counter
Main:
FOR reps = 10 TO 300 ' each loop add 1
DEBUG DEC ? reps ' show reps in debug window
NEXT
END
</pre>
<p class="PlainText"><i>Reps</i> still rolls over to 0, as before, however, this time it is outside the
range of 10 to 255. The loop stops, leaving <i>reps</i> at 0. Note that this code is
still in error since <i>reps</i> will never reach 300 until it is declared as a Word.</p>
<p class="PlainText">NOTE: On the BS1, the loop will continue until <i>Counter</i> has gone past
<i>EndValue</i>. The rollover error will still occur if the BS1 cannot determine
if <i>Counter</i> went past <i>EndValue</i>.</p>
<div class="Col2">
<div class="MasterFoot">
<p MadCap:conditions="BSEconditions.BSEWebHelp (Primary)-INCLUDE"><a href="../../HomeTopics/HomePage.htm">Go to Welcome page</a>
</p>
</div>
</div>
<div class="Col2">
<div class="MasterFoot">
<p style="text-align: right;"><span class="ContactInfoProjectName">BASIC Stamp Help</span> <![CDATA[ ]]><span class="ContactInfoVersion#">Version 2.5.4</span> <![CDATA[ ]]></p>
<p style="text-align: right;">Copyright ©&#160;<span class="ContactInfoCompanyName">Parallax Inc.</span></p>
<p style="text-align: right;"><span class="SystemShortDate">8/8/2012</span>
</p>
</div>
</div>
<script type="text/javascript">/* <![CDATA[ */
var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-285614-1']);
_gaq.push(['_trackPageview']);
(function() {
var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
})();
/* ]]> */</script>
<script type="text/javascript" src="../../SkinSupport/MadCapBodyEnd.js">
</script>
</body>
</html>