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

📄 faqcatee08.html

📁 this is a mirrored site c-faq. thought might need offline
💻 HTML
📖 第 1 页 / 共 3 页
字号:
<!DOCTYPE HTML PUBLIC "-//W3O//DTD W3 HTML 2.0//EN"><!-- This collection of hypertext pages is Copyright 1995-2005 by Steve Summit. --><!-- Content from the book "C Programming FAQs: Frequently Asked Questions" --><!-- (Addison-Wesley, 1995, ISBN 0-201-84519-9) is made available here by --><!-- permission of the author and the publisher as a service to the community. --><!-- It is intended to complement the use of the published text --><!-- and is protected by international copyright laws. --><!-- The on-line content may be accessed freely for personal use --><!-- but may not be published or retransmitted without explicit permission. --><!-- --><!-- this page built Sat Dec 24 21:47:45 2005 by faqproc version 2.7 --><!-- from source file expr.sgml dated Sat Jul  3 17:10:33 2004 --><!-- corresponding to FAQ list version 4.0 --><html><!-- Mirrored from c-faq.com/~scs/cgi-bin/faqcat.cgi?sec=expr by HTTrack Website Copier/3.x [XR&CO'2008], Sat, 14 Mar 2009 07:57:38 GMT --><head><base ><meta name=GENERATOR content="faqproc"><title>Expressions</title></head><body bgcolor="#ffffff"><H1>3. Expressions</H1><a name="evalorder1"><h1>comp.lang.c FAQ list<font color=blue>&middot;</font><a href="../../expr/evalorder1.html"><!-- qtag -->Question 3.1</a></h1><p><font face=Helvetica size=8 color=blue><b>Q:</b></font>Why doesn'tthis code:<pre>a[i] = i++;</pre>work?</p><p><hr><p><font face=Helvetica size=8 color=blue><b>A:</b></font>The subexpression <TT>i++</TT> causes aside effect--it modifies<TT>i</TT>'s value--which leads to undefined behaviorsince<TT>i</TT> is also referenced elsewhere in the same expression.There is no way of knowingwhether thereference will happenbefore or after the side effect--in fact,<em>neither</em>obvious interpretation might hold;see question <a href="faqcatee08.html?sec=expr#evalorder4">3.9</a>.(Note that although the language inK&amp;R suggests that the behaviorof this expression is unspecified,the C Standard makes the stronger statement that it isundefined--see question<a href="faqcat7d4b.html?sec=ansi#undef">11.33</a>.)</p><p>References:K&amp;R1 Sec. 2.12<br>K&amp;R2 Sec. 2.12<br>ISO Sec. 6.3<br>H&amp;S Sec. 7.12 pp. 227-9<hr><hr><hr><a name="evalorder2"><h1>comp.lang.c FAQ list<font color=blue>&middot;</font><a href="../../expr/evalorder2.html"><!-- qtag -->Question 3.2</a></h1><p><font face=Helvetica size=8 color=blue><b>Q:</b></font>Under my compiler, the code<pre>int i&nbsp;=&nbsp;7;printf("%d\n",&nbsp;i++&nbsp;*&nbsp;i++);</pre>prints 49.Regardless of the order of evaluation, shouldn't it print 56?</p><p><hr><p><font face=Helvetica size=8 color=blue><b>A:</b></font>It's true thatthe postincrement and postdecrement operators <TT>++</TT> and <TT>--</TT>performtheiroperations after yielding the former value.What's often misunderstood aretheimplicationsandprecise definitionofthe word``after.''It is<em>not</em>guaranteed thatan increment or decrementis performed immediately aftergiving up the previous value and before any other part of theexpression is evaluated.It is merely guaranteed that the update will be performedsometime before the expression is considered ``finished''(before the next``sequence point,'' in ANSI C's terminology;see question <a href="faqcatee08.html?sec=expr#seqpoints">3.8</a>).In the example, the compiler chose to multiply the previous valueby itself and to perform both increments later.</p><p>The behavior of code which containsmultiple, ambiguous side effectshas always been undefined.(Loosely speaking, by``multiple, ambiguous side effects''we meanany combination ofincrement, decrement, and assignment operators(<TT>++</TT>, <TT>--</TT>, <TT>=</TT>, <TT>+=</TT>,<TT>-=</TT>, etc.)in a single expressionwhich causes the sameobjecteither to bemodified twiceormodified and then inspected.This is a rough definition;see question <a href="faqcatee08.html?sec=expr#seqpoints">3.8</a> for a precise one,question <a href="faqcatee08.html?sec=expr#confused">3.11</a> for a simpler one,and question<a href="faqcat7d4b.html?sec=ansi#undef">11.33</a> for the meaning of ``undefined.'')Don't even try to find out how your compiler implements such things,let alone write code which depends on them(contrary to the ill-advised exercises in many C textbooks);asKernighan and Ritchiewisely point out,``if you don't know<em>how</em>they are done on various machines,that innocence may help to protect you.''</p><p>References:K&amp;R1 Sec. 2.12 p. 50<br>K&amp;R2 Sec. 2.12 p. 54<br>ISO Sec. 6.3<br>H&amp;S Sec. 7.12 pp. 227-9<br>CT&amp;P Sec. 3.7 p. 47<br>PCS Sec. 9.5 pp. 120-1<hr><hr><hr><a name="ieqiplusplus"><h1>comp.lang.c FAQ list<font color=blue>&middot;</font><a href="../../expr/ieqiplusplus.html"><!-- qtag -->Question 3.3</a></h1><p><font face=Helvetica size=8 color=blue><b>Q:</b></font>I've experimented withthe code<pre>int i&nbsp;=&nbsp;3;i&nbsp;=&nbsp;i++;</pre>on several compilers.Some gave <TT>i</TT> thevalue 3,andsome gave 4.Which compiler is correct?</p><p><hr><p><font face=Helvetica size=8 color=blue><b>A:</b></font>There is no correct answer;theexpression is undefined.See questions<a href="faqcatee08.html?sec=expr#evalorder1">3.1</a>,<a href="faqcatee08.html?sec=expr#seqpoints">3.8</a>,<a href="faqcatee08.html?sec=expr#evalorder4">3.9</a>,and<a href="faqcat7d4b.html?sec=ansi#undef">11.33</a>.(Also, note that neither <TT>i++</TT> nor <TT>++i</TT>is the same as <TT>i+1</TT>.If you want to increment <TT>i</TT>,use<TT>i=i+1</TT>,<TT>i+=1</TT>,<TT>i++</TT>,or<TT>++i</TT>,not some combination.See also question <a href="faqcatee08.html?sec=expr#plusplus">3.12b</a>.)<hr><hr><hr><a name="xorswapexpr"><h1>comp.lang.c FAQ list<font color=blue>&middot;</font><a href="../../expr/xorswapexpr.html"><!-- qtag -->Question 3.3b</a></h1><p><font face=Helvetica size=8 color=blue><b>Q:</b></font>Here's a slick expression:<pre>a&nbsp;^=&nbsp;b&nbsp;^=&nbsp;a&nbsp;^=&nbsp;b</pre>It swaps <TT>a</TT> and <TT>b</TT> without using a temporary.</p><p><hr><p><font face=Helvetica size=8 color=blue><b>A:</b></font>Not portably,it doesn't.It attempts to modifythe variable<TT>a</TT> twice between sequence points,soits behavior is undefined.</p><p>For example, it has been reportedthatwhen given the code<pre>	int a = 123, b = 7654;	a ^= b ^= a ^= b;</pre>the SCO Optimizing C compiler (<TT>icc</TT>)sets <TT>b</TT> to 123 and <TT>a</TT> to 0.</p><p>See also questions<a href="faqcatee08.html?sec=expr#evalorder1">3.1</a>,<a href="faqcatee08.html?sec=expr#seqpoints">3.8</a>,<a href="faqcat204f.html?sec=cpp#swapmacro">10.3</a>,and <a href="faqcat38c2.html?sec=misc#swapnotemp">20.15c</a>.<hr><hr><hr><a name="precvsooe"><h1>comp.lang.c FAQ list<font color=blue>&middot;</font><a href="../../expr/precvsooe.html"><!-- qtag -->Question 3.4</a></h1><p><font face=Helvetica size=8 color=blue><b>Q:</b></font>Can I use explicit parentheses to forcethe order of evaluation I want,and control these side effects?Even if I don't, doesn't precedence dictate it?</p><p><hr><p><font face=Helvetica size=8 color=blue><b>A:</b></font>Not in general.</p><p>Operator precedence and explicit parentheses impose only apartial ordering on the evaluation of anexpression.Inthe expression<pre>	f() + g() * h()</pre>although we know thatthe multiplication will happenbefore the addition,there is no telling whichof the three functionswill be called first.In other words, precedence only partially specifies order ofevaluation, where ``partially'' emphatically does<I>not</I>cover evaluation of operands.</p><p>Parentheses tell the compiler which operands go with which operators;theydo <em>not</em> force the compiler to evaluate everything within the parentheses first.Adding explicit parentheses to the above expressionto make it<pre>	f() + (g() * h())</pre>would make no difference in the order of the function calls.Similarly,adding explicit parentheses tothe expression from question <a href="faqcatee08.html?sec=expr#evalorder2">3.2</a>to make it<pre>	(i++) * (i++)		/* WRONG */</pre>accomplishes nothing(since <TT>++</TT> alreadyhas higher precedencethan <TT>*</TT>);the expression remains undefined with or without them.</p><p>When you need to ensure the order of subexpression evaluation,you may need to use explicit temporary variablesand separate statements.</p><p>References:K&amp;R1 Sec. 2.12 p. 49, Sec. A.7 p. 185<br>K&amp;R2 Sec. 2.12 pp. 52-3, Sec. A.7 p. 200<hr><hr><hr><a name="seqpointops"><h1>comp.lang.c FAQ list<font color=blue>&middot;</font><a href="../../expr/seqpointops.html"><!-- qtag -->Question 3.5</a></h1><p><font face=Helvetica size=8 color=blue><b>Q:</b></font>But what about the<TT>&amp;&amp;</TT>and<TT>||</TT>operators?<br>I see code like ``<TT>while((c&nbsp;=&nbsp;getchar())&nbsp;!=&nbsp;EOF&nbsp;&amp;&amp;&nbsp;c&nbsp;!=&nbsp;'\n')</TT>'' ...</p><p><hr><p><font face=Helvetica size=8 color=blue><b>A:</b></font>There is a special``short-circuiting''exception for theseoperators:the right-hand side is not evaluatedif the left-hand side determines the outcome(i.e. is true for <TT>||</TT> or false for <TT>&amp;&amp;</TT>).Therefore,left-to-rightevaluationisguaranteed,as italsois for the comma operator(but see question <a href="faqcatee08.html?sec=expr#comma">3.7</a>).Furthermore, all of these operators(along with<TT>?:</TT>)introduce an extra internal sequence point(see question <a href="faqcatee08.html?sec=expr#seqpoints">3.8</a>).</p><p>References:K&amp;R1 Sec. 2.6 p. 38, Secs. A7.11-12 pp. 190-1<br>K&amp;R2 Sec. 2.6 p. 41, Secs. A7.14-15 pp. 207-8<br>ISO Sec. 6.3.13, Sec. 6.3.14, Sec. 6.3.15<br>H&amp;S Sec. 7.7 pp. 217-8, Sec. 7.8 pp. 218-20, Sec. 7.12.1 p. 229<br>CT&amp;P Sec. 3.7 pp. 46-7<hr><hr><hr><a name="shortcircuit"><h1>comp.lang.c FAQ list<font color=blue>&middot;</font><a href="../../expr/shortcircuit.html"><!-- qtag -->Question 3.6</a></h1><p><font face=Helvetica size=8 color=blue><b>Q:</b></font>Is it safe to assumethat the right-hand sideof the<TT>&amp;&amp;</TT>and<TT>||</TT>operatorswon't be evaluatedif the left-hand side determines the outcome?</p><p><hr><p><font face=Helvetica size=8 color=blue><b>A:</b></font>Yes.Idioms like<pre>	if(d != 0 &amp;&amp; n / d &gt; 0)		{ /* average is greater than 0 */ }</pre>and<pre>	if(p == NULL || *p == '\0')		{ /* no string */ }</pre>are quite common in C,and depend onthis so-called short-circuiting behavior.In the first example,in the absence of short-circuiting behavior,the right-hand side would divide by 0--and perhaps crash--if<TT>d</TT> were equal to 0.In the second example,the right-hand side would attempt to referencenonexistent memory--and perhaps crash--if<TT>p</TT> were a null pointer.</p><p>References:ISO Sec. 6.3.13, Sec. 6.3.14<br>H&amp;S Sec. 7.7 pp. 217-8<hr><hr><hr><a name="comma"><h1>comp.lang.c FAQ list<font color=blue>&middot;</font><a href="../../expr/comma.html"><!-- qtag -->Question 3.7</a></h1><p><font face=Helvetica size=8 color=blue><b>Q:</b></font>Why did<pre>printf("%d&nbsp;%d",&nbsp;f1(),&nbsp;f2());</pre>call <TT>f2</TT> first?I thought the comma operator guaranteed left-to-right evaluation.</p><p><hr><p><font face=Helvetica size=8 color=blue><b>A:</b></font>The comma operator does guarantee left-to-right evaluation,but the commas separating the arguments in a function callare not comma operators.<a href="../../expr/fn15.html" rel=subdocument>[footnote]</a>The order of evaluation of the arguments to a function callis <a href="../../sx1/index.html#unspecified"><dfn>unspecified</dfn></a>.(See question <a href="faqcat7d4b.html?sec=ansi#undef">11.33</a>.)</p><p>References:K&amp;R1 Sec. 3.5 p. 59<br>K&amp;R2 Sec. 3.5 p. 63<br>ISO Sec. 6.3.2.2<br>H&amp;S Sec. 7.10 p. 224<hr><hr><hr><a name="seqpoints"><h1>comp.lang.c FAQ list<font color=blue>&middot;</font><a href="../../expr/seqpoints.html"><!-- qtag -->Question 3.8</a></h1><p><font face=Helvetica size=8 color=blue><b>Q:</b></font>How can I understandcomplex expressions like the ones in this section,and avoid writing undefined ones?What's a ``sequence point''?</p><p><hr><p><font face=Helvetica size=8 color=blue><b>A:</b></font>A sequence pointisapointin timeat whichthe dusthas settledandall side effectswhich have been seen so farare guaranteed to be complete.The sequence points listed in the C standard are:<UL><li>at the end ofthe evaluation ofa <a href="../../sx1/index.html#full expression"><dfn>full expression</dfn></a>(a full expression is an expression statement,or any other expression which is nota subexpression withinany larger expression);<li>at the <TT>||</TT>, <TT>&amp;&amp;</TT>, <TT>?:</TT>, and comma operators;and

⌨️ 快捷键说明

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