⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ch10_07.htm

📁 by Randal L. Schwartz and Tom Phoenix ISBN 0-596-00132-0 Third Edition, published July 2001. (See
💻 HTM
字号:
<html><head><title>The for Control Structure (Learning Perl, 3rd Edition)</title><link rel="stylesheet" type="text/css" href="../style/style1.css" /><meta name="DC.Creator" content="Randal L. Schwartz and Tom Phoenix" /><meta name="DC.Format" content="text/xml" scheme="MIME" /><meta name="DC.Language" content="en-US" /><meta name="DC.Publisher" content="O'Reilly &amp; Associates, Inc." /><meta name="DC.Source" scheme="ISBN" content="0596001320L" /><meta name="DC.Subject.Keyword" content="stuff" /><meta name="DC.Title" content="Learning Perl, 3rd Edition" /><meta name="DC.Type" content="Text.Monograph" /></head><body bgcolor="#ffffff"><img alt="Book Home" border="0" src="gifs/smbanner.gif" usemap="#banner-map" /><map name="banner-map"><area shape="rect" coords="1,-2,616,66" href="index.htm" alt="Learning Perl, 3rd Edition" /><area shape="rect" coords="629,-11,726,25" href="jobjects/fsearch.htm" alt="Search this book" /></map><div class="navbar"><table width="684" border="0"><tr><td align="left" valign="top" width="228"><a href="ch10_06.htm"><img alt="Previous" border="0" src="../gifs/txtpreva.gif" /></a></td><td align="center" valign="top" width="228"><a href="index.htm"></a></td><td align="right" valign="top" width="228"><a href="ch10_08.htm"><img alt="Next" border="0" src="../gifs/txtnexta.gif" /></a></td></tr></table></div><h2 class="sect1">10.7. The for Control Structure</h2><p><a name="INDEX-676" /> <a name="INDEX-677" />Perl's <tt class="literal">for</tt>control structure is like the common <tt class="literal">for</tt> controlstructure you may have seen in other languages such as C. It lookslike this:</p><blockquote><pre class="code">for (<em class="replaceable">initialization; test; increment</em>) {  <em class="replaceable">body;</em>  <em class="replaceable">body;</em>}</pre></blockquote><p>To Perl, though, this kind of loop is really a<tt class="literal">while</tt> loop in disguise, something likethis:<a href="#FOOTNOTE-223">[223]</a></p><blockquote class="footnote"> <a name="FOOTNOTE-223" /><p>[223]Actually, the increment happens in a<tt class="literal">continue</tt><a name="INDEX-678" /> block, which is beyond the scope of thisbook. See the <em class="emphasis">perlsyn</em><a name="INDEX-679" /> manpage for the truth.</p></blockquote><blockquote><pre class="code"><em class="replaceable">initialization;</em>while (<em class="replaceable">test</em>) {  <em class="replaceable">body;</em>  <em class="replaceable">body;</em>  <em class="replaceable">increment;</em>}</pre></blockquote><p>The most common use of the <tt class="literal">for</tt> loop, by far, isfor making computed iterations:</p><blockquote><pre class="code">for ($i = 1; $i &lt;= 10; $i++) {  # count from 1 to 10  print "I can count to $i!\n";}</pre></blockquote><p>When you've seen these before, you'll know what the firstline is saying even before you read the comment. Before the loopstarts, the control variable, <tt class="literal">$i</tt>, is set to<tt class="literal">1</tt>. Then, the loop is really a<tt class="literal">while</tt> loop in disguise, looping while<tt class="literal">$i</tt> is less than or equal to <tt class="literal">10</tt>.Between each iteration and the next is the increment, which here is aliteral increment, adding one to the control variable, which is<tt class="literal">$i</tt>.</p><p>So, the first time through this loop, <tt class="literal">$i</tt> is<tt class="literal">1</tt>. Since that's less than or equal to<tt class="literal">10</tt>, we see the message. Although the increment iswritten at the top of the loop, it logically happens at the bottom ofthe loop, after printing the message. So, <tt class="literal">$i</tt>becomes <tt class="literal">2</tt>, which is less than or equal to<tt class="literal">10</tt>, so we print the message again, and<tt class="literal">$i</tt> is incremented to <tt class="literal">3</tt>, whichis less than or equal to <tt class="literal">10</tt>, and so on.</p><p>Eventually, we print the message that our program can count to<tt class="literal">9</tt>. Then <tt class="literal">$i</tt> is incremented to<tt class="literal">10</tt>, which is less than or<em class="emphasis">equal</em> to <tt class="literal">10</tt>, so we run theloop one last time and print that our program can count to<tt class="literal">10</tt>. Finally, <tt class="literal">$i</tt> is incrementedfor the last time, to <tt class="literal">11</tt>, which is not less thanor equal to <tt class="literal">10</tt>. So control drops out of the loop,and we're on to the rest of the program.</p><p>All three parts are together at the top of the loop so thatit's easy for an experienced programmer to read that first lineand say, "Ah, it's a loop that counts<tt class="literal">$i</tt> from one to ten."</p><p>Note that after the loop is done, the control variable has a value"after" the loop. That is, in this case, the controlvariable has gone all the way to <tt class="literal">11.</tt><a href="#FOOTNOTE-224">[224]</a></p><blockquote class="footnote"><a name="FOOTNOTE-224" /><p>[224]Obligatory <em class="citetitle">This is Spinal Tap</em> outdatedpop-culture reference.</p> </blockquote><p>This loop is a very versatile loop, since you can make it count inall sorts of ways. This loop counts from <tt class="literal">-150</tt> to<tt class="literal">1000</tt> by threes:<a href="#FOOTNOTE-225">[225]</a></p><blockquote class="footnote"> <a name="FOOTNOTE-225" /><p>[225]Of course, itnever gets to <tt class="literal">1000</tt> exactly. The last iterationuses <tt class="literal">999</tt>, since each value of<tt class="literal">$i</tt> is a multiple of three.</p> </blockquote><blockquote><pre class="code">for ($i = -150; $i &lt;= 1000; $i += 3) {  print "$i\n";}</pre></blockquote><p>In fact, you could make any of the three control parts(initialization, test, or increment) empty, if you wish, but youstill need the two semicolons. In this (quite unusual) example, thetest is a substitution, and the increment is empty:</p><blockquote><pre class="code">for ($_ = "bedrock"; s/(.)//; ) {  # loops while the s/// is successful  print "One character is: $1\n";}</pre></blockquote><p>The test expression (in the implied <tt class="literal">while</tt> loop) isthe substitution, which will return a true value if it succeeded. Inthis case, the first time through the loop, the substitution willremove the <tt class="literal">b</tt> from <tt class="literal">bedrock</tt>. Eachiteration will remove another letter. When the string is empty, thesubstitution will fail, and the loop is done.</p><p>If the test expression (the one between the two semicolons) is empty,it's automatically true, making an infinite loop. Butdon't make an infinite loop like this until you see how tobreak out of such a loop, which we'll discuss later in thischapter:</p><blockquote><pre class="code">for (;;) {  print "It's an infinite loop!\n";}</pre></blockquote><p>A more Perl-like way to write an intentional infinite loop, when youreally want one,<a href="#FOOTNOTE-226">[226]</a> is with<tt class="literal">while</tt>:</p><blockquote class="footnote"> <a name="FOOTNOTE-226" /><p>[226]If you somehow made an infinite loopthat's gotten away from you, see whether Control-C will haltit. It's possible that you'll get a lot of output evenafter typing Control-C, depending upon your system's I/O andother factors. Hey, we warned you.</p> </blockquote><blockquote><pre class="code">while (1) {  print "It's another infinite loop!\n";}</pre></blockquote><p>Although C programmers are familiar with the first way, even abeginning Perl programmer should recognize that <tt class="literal">1</tt>is always true, making an intentional infinite loop, so the second isgenerally a better way to write it. Perl is smart enough to recognizea constant expression like that and optimize it away, sothere's no difference in efficiency.<a name="INDEX-680" /></p><a name="lperl3-CHP-10-SECT-7.1" /><div class="sect2"><h3 class="sect2">10.7.1. The Secret Connection Between foreach and for</h3><p>It turns out that, inside the Perl grammar, the keyword<tt class="literal">foreach</tt><a name="INDEX-681" /> is exactly equivalent to thekeyword <tt class="literal">for</tt><a name="INDEX-682" />. That is, any time Perl sees one ofthem, it's the same as if you had typed the other. Perl cantell which you meant by looking inside the parentheses. Ifyou've got the two <a name="INDEX-683" />semicolons, it's a computed<tt class="literal">for</tt> loop (like we've just been talkingabout). If you don't have the semicolons, it's really a<tt class="literal">foreach</tt> loop:</p><blockquote><pre class="code">for (1..10) {  # Really a foreach loop from 1 to 10  print "I can count to $_!\n";}</pre></blockquote><p>That's really a <tt class="literal">foreach</tt> loop, but it'swritten <tt class="literal">for</tt>. Except for that one example, allthrough this book, we'll spell out <tt class="literal">foreach</tt>wherever it appears. But in the real world, do you think that Perlfolks will type those extra four letters?<a href="#FOOTNOTE-227">[227]</a> Excepting onlybeginners' code, it's always written<tt class="literal">for</tt>, and you'll have to do as Perl does andlook for the semicolons to tell which kind of loop it is.</p><blockquote class="footnote"> <a name="FOOTNOTE-227" /><p>[227]If youthink that, you haven't been paying attention. Amongprogrammers, especially Perl programmers, laziness is one of theclassical virtues. If you don't believe us, ask someone at thenext Perl Mongers' meeting.</p> </blockquote><p>In Perl, the true <tt class="literal">foreach</tt> loop is almost always abetter choice. In the <tt class="literal">foreach</tt> loop (written<tt class="literal">for</tt>) in that previous example, it's easy tosee at a glance that the loop will go from <tt class="literal">1</tt> to<tt class="literal">10</tt>. But do you see what's wrong with thiscomputed loop that's trying to do the same thing? Don'tpeek at the answer in the footnote until you think you've foundwhat's wrong:<a href="#FOOTNOTE-228">[228]</a></p><blockquote class="footnote"> <a name="FOOTNOTE-228" /><p>[228]There are two and one-half bugs.First, the conditional uses a less-than sign, so the loop will runnine times, instead of ten. It's easy to get a so-called"fencepost" bug with this kind of loop, like whathappened when the rancher needed enough fenceposts to make a30-meter-long fence with a post every three meters. (The answer isnot ten fenceposts.) Second, the control variable is<tt class="literal">$i</tt>, but the loop body is using<tt class="literal">$_</tt>. And second and a half, it's a lot morework to read, write, maintain, and debug this type of loop, which iswhy we say that the true <tt class="literal">foreach</tt> is generally abetter choice in Perl.</p> </blockquote><a name="INDEX-684" /><blockquote><pre class="code">for ($i = 1; $i &lt; 10; $i++) {  # Oops! Something is wrong here!  print "I can count to $_!\n";}</pre></blockquote></div><hr width="684" align="left" /><div class="navbar"><table width="684" border="0"><tr><td align="left" valign="top" width="228"><a href="ch10_06.htm"><img alt="Previous" border="0" src="../gifs/txtpreva.gif" /></a></td><td align="center" valign="top" width="228"><a href="index.htm"><img alt="Home" border="0" src="../gifs/txthome.gif" /></a></td><td align="right" valign="top" width="228"><a href="ch10_08.htm"><img alt="Next" border="0" src="../gifs/txtnexta.gif" /></a></td></tr><tr><td align="left" valign="top" width="228">10.6. Autoincrement and Autodecrement</td><td align="center" valign="top" width="228"><a href="index/index.htm"><img alt="Book Index" border="0" src="../gifs/index.gif" /></a></td><td align="right" valign="top" width="228">10.8. Loop Controls</td></tr></table></div><hr width="684" align="left" /><img alt="Library Navigation Links" border="0" src="../gifs/navbar.gif" usemap="#library-map" /><p><p><font size="-1"><a href="copyrght.htm">Copyright &copy; 2002</a> O'Reilly &amp; Associates. All rights reserved.</font></p><map name="library-map"><area shape="rect" coords="1,0,85,94" href="../index.htm"><area shape="rect" coords="86,1,178,103" href="../lwp/index.htm"><area shape="rect" coords="180,0,265,103" href="../lperl/index.htm"><area shape="rect" coords="267,0,353,105" href="../perlnut/index.htm"><area shape="rect" coords="354,1,446,115" href="../prog/index.htm"><area shape="rect" coords="448,0,526,132" href="../tk/index.htm"><area shape="rect" coords="528,1,615,119" href="../cookbook/index.htm"><area shape="rect" coords="617,0,690,135" href="../pxml/index.htm"></map></body></html>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -