📄 ch10_06.htm
字号:
<html><head><title>Autoincrement and Autodecrement (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 & 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_05.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_07.htm"><img alt="Next" border="0" src="../gifs/txtnexta.gif" /></a></td></tr></table></div><h2 class="sect1">10.6. Autoincrement and Autodecrement</h2><p><a name="INDEX-666" /> <a name="INDEX-667" />You'll<a name="INDEX-668" /><a name="INDEX-669" />often want a <a name="INDEX-670" />scalar variable to count up or down byone. Since these are frequent constructs, there are shortcuts forthem, like nearly everything else we do frequently.</p><p>The autoincrement operator ("<tt class="literal">++</tt>") addsone to a scalar variable, like the same operator in C and similarlanguages:</p><blockquote><pre class="code">my $bedrock = 42;$bedrock++; # add one to $bedrock; it's now 43</pre></blockquote><p>Just like other ways of adding one to a variable, the scalar will becreated if necessary:</p><blockquote><pre class="code">my @people = qw{ fred barney fred wilma dino barney fred pebbles };my %count; # new empty hash$count{$_}++ foreach @people; # creates new keys and values as needed</pre></blockquote><p>The first time through that <tt class="literal">foreach</tt> loop,<tt class="literal">$count{$_}</tt> is incremented. That's<tt class="literal">$count{"fred"}</tt>, which thus goes from<tt class="literal">undef</tt> (since it didn't previously exist inthe hash) up to <tt class="literal">1</tt>. The next time through the loop,<tt class="literal">$count{"barney"}</tt> becomes <tt class="literal">1</tt>;after that, <tt class="literal">$count{"fred"}</tt> becomes<tt class="literal">2</tt>. Each time through the loop, one element in<tt class="literal">%count</tt> is incremented, and possibly created aswell. After that loop is done, <tt class="literal">$count{"fred"}</tt> is<tt class="literal">3</tt>. This provides a quick and easy way to see whichitems are in a list and how many times each one appears.</p><p>Similarly, the autodecrement operator("<tt class="literal">--</tt>") subtracts one from a scalarvariable:</p><blockquote><pre class="code">$bedrock--; # subtract one from $bedrock; it's 42 again</pre></blockquote><a name="lperl3-CHP-10-SECT-6.1" /><div class="sect2"><h3 class="sect2">10.6.1. The Value of Autoincrement</h3><p>You can fetch the value of a variable and change that value at thesame time. Put the <tt class="literal">++</tt> operator in front of thevariable name to increment the variable first and then fetch itsvalue. This is a<em class="firstterm">preincrement</em><a name="INDEX-671" />:</p><blockquote><pre class="code">my $a = 5;my $b = ++$a; # increment $a to 6, and put that value into $b</pre></blockquote><p>Or put the <tt class="literal">--</tt> operator in front to decrement thevariable first and then fetch its value. This is a<em class="firstterm">predecrement</em>:</p><blockquote><pre class="code">my $c = --$a; # decrement $a to 5, and put that value into $c</pre></blockquote><p>Here's the tricky part. Put the variable name first to fetchthe value first, and then do the increment or decrement. This iscalled a<em class="firstterm">postincrement</em><a name="INDEX-672" />or <em class="firstterm">postdecrement</em>:</p><blockquote><pre class="code">my $d = $a++; # $d gets the old value (5), then increment $a to 6my $e = $a--; # $e gets the old value (6), then decrement $a to 5</pre></blockquote><p>It's tricky because we're doing two things at once.We're fetching the value, and we're changing it in thesame expression. If the operator is first, we increment (ordecrement) first, then use the new value. If the variable is first,we return its (old) value first, then do the increment or decrement.Another way to say it is that these operators return a value, butthey also have the side effect of modifying the variable'svalue.</p><p>If you write these in an expression of their own,<a href="#FOOTNOTE-221">[221]</a> not using thevalue but only the side effect, there's no difference<a href="#FOOTNOTE-222">[222]</a> whether you put the operator beforeor after the variable:</p><blockquote class="footnote"><a name="FOOTNOTE-221" /><p>[221]That is, in a void context. </p> </blockquote><blockquote class="footnote"><a name="FOOTNOTE-222" /><p>[222]Programmers who get inside the implementations of languages mayexpect that postincrement and postdecrement would be less efficientthan their counterparts, but Perl's not like that. Perlautomatically optimizes the post- forms when they're used in avoid context.</p> </blockquote><blockquote><pre class="code">$bedrock++; # adds one to $bedrock++$bedrock; # just the same; adds one to $bedrock</pre></blockquote><p>A common use of these operators is in connection with a<a name="INDEX-673" />hash, to identify when an item has beenseen before:</p><blockquote><pre class="code">my @people = qw{ fred barney bamm-bamm wilma dino barney betty pebbles };my %seen;foreach (@people) { print "I've seen you somewhere before, $_!\n" if $seen{$_}++;}</pre></blockquote><p>When <tt class="literal">barney</tt> shows up for the first time, the valueof <tt class="literal">$seen{$_}++</tt> is false, since it's thevalue of <tt class="literal">$seen{$_}</tt>, which is<tt class="literal">$seen{"barney"}</tt>, which is<tt class="literal">undef</tt>. But that expression has the side effect ofincrementing <tt class="literal">$seen{"barney"}</tt>. When<tt class="literal">barney</tt> shows up again,<tt class="literal">$seen{"barney"}</tt> is now a true value, so themessage is printed.<a name="INDEX-674" /> <a name="INDEX-675" /> </p></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_05.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_07.htm"><img alt="Next" border="0" src="../gifs/txtnexta.gif" /></a></td></tr><tr><td align="left" valign="top" width="228">10.5. The elsif Clause</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.7. The for Control Structure</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 © 2002</a> O'Reilly & 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 + -