📄 ch04.htm
字号:
<P><A NAME="Heading12"></A><FONT SIZE="4" COLOR="#000077"><B>Listing 4.2. A demonstrationof subtraction and integer overflow</B></FONT><FONT SIZE="2" COLOR="#000077"><B>.</B></FONT><FONTCOLOR="#0066FF"></FONT><PRE><FONT COLOR="#0066FF">1: // Listing 4.2 - demonstrates subtraction and2: // integer overflow3: #include <iostream.h>4:5: int main()6: {7: unsigned int difference;8: unsigned int bigNumber = 100;9: unsigned int smallNumber = 50;10: difference = bigNumber - smallNumber;11: cout << "Difference is: " << difference;12: difference = smallNumber - bigNumber;13: cout << "\nNow difference is: " << difference <<endl;14: return 0;<TT>15: }</TT>Output: Difference is: 50Now difference is: 4294967246</FONT></PRE><P><FONT COLOR="#000077"><B>Analysis:</B></FONT><B> </B>The subtraction operatoris invoked on line 10, and the result is printed on line 11, much as we might expect.The subtraction operator is called again on line 12, but this time a large <TT>unsigned</TT>number is subtracted from a small <TT>unsigned</TT> number. The result would be negative,but because it is evaluated (and printed) as an <TT>unsigned</TT> number, the resultis an overflow, as described yesterday. This topic is reviewed in detail in AppendixA, "Operator Precedence."<H4 ALIGN="CENTER"><A NAME="Heading14"></A><FONT COLOR="#000077">Integer Divisionand Modulus</FONT></H4><P>Integer division is somewhat different from everyday division. When you divide21 by 4, the result is a real number (a number with a fraction). Integers don't havefractions, and so the "remainder" is lopped off. The answer is therefore5. To get the remainder, you take 21 modulus 4 (21 % 4) and the result is 1. Themodulus operator tells you the remainder after an integer division.</P><P>Finding the modulus can be very useful. For example, you might want to print astatement on every 10th action. Any number whose value is 0 when you modulus 10 withthat number is an exact multiple of 10. Thus 1 % 10 is 1, 2 % 10 is 2, and so forth,until 10 % 10, whose result is 0. 11 % 10 is back to 1, and this pattern continuesuntil the next multiple of 10, which is 20. We'll use this technique when loopingis discussed on Day 7, "More Program Flow."<DL> <DD><HR><FONT COLOR="#000077"><B>WARNING:</B></FONT><B> </B>Many novice C++ programmers inadvertently put a semicolon after their <TT>if</TT> statements: <PRE><FONT COLOR="#0066FF">if(SomeValue < 10);SomeValue = 10;</FONT></PRE> <DD><BR> What was intended here was to test whether <TT>SomeValue</TT> is less than 10, and if so, to set it to <TT>10</TT>, making <TT>10</TT> the minimum value for <TT>SomeValue</TT>. Running this code snippet will show that <TT>SomeValue</TT> is always set to <TT>10</TT>! Why? The <TT>if</TT> statement terminates with the semicolon (the do-nothing operator). Remember that indentation has no meaning to the compiler. This snippet could more accurately have been written as: <PRE><FONT COLOR="#0066FF">if (SomeValue < 10) // test; // do nothingSomeValue = 10; // assign</FONT></PRE> <DD>Removing the semicolon will make the final line part of the <TT>if</TT> statement and will make this code do what was intended. <HR></DL><H3 ALIGN="CENTER"><A NAME="Heading15"></A><FONT COLOR="#000077">Combining the Assignmentand Mathematical Operators</FONT></H3><P>It is not uncommon to want to add a value to a variable, and then to assign theresult back into the variable. If you have a variable <TT>myAge</TT> and you wantto increase the value by two, you can write</P><PRE><FONT COLOR="#0066FF">int myAge = 5;int temp;temp = myAge + 2; // add 5 + 2 and put it in tempmyAge = temp; // put it back in myAge</FONT></PRE><P>This method, however, is terribly convoluted and wasteful. In C++, you can putthe same variable on both sides of the assignment operator, and thus the precedingbecomes</P><PRE><FONT COLOR="#0066FF">myAge = myAge + 2;</FONT></PRE><P>which is much better. In algebra this expression would be meaningless, but inC++ it is read as "add two to the value in <TT>myAge</TT> and assign the resultto <TT>myAge</TT>."</P><P>Even simpler to write, but perhaps a bit harder to read is</P><PRE><FONT COLOR="#0066FF">myAge += 2;</FONT></PRE><P>The self-assigned addition operator (<TT>+=</TT>) adds the rvalue to the lvalueand then reassigns the result into the lvalue. This operator is pronounced "plus-equals."The statement would be read "<TT>myAge</TT> plus-equals two." If <TT>myAge</TT>had the value <TT>4</TT> to start, it would have <TT>6</TT> after this statement.</P><P>There are self-assigned subtraction (<TT>-=</TT>), division (<TT>/=</TT>), multiplication(<TT>*=</TT>), and modulus (<TT>%=</TT>) operators as well.<H3 ALIGN="CENTER"><A NAME="Heading16"></A><FONT COLOR="#000077">Increment and Decrement</FONT></H3><P>The most common value to add (or subtract) and then reassign into a variable is<TT>1</TT>. In C++, increasing a value by 1 is called incrementing, and decreasingby 1 is called decrementing. There are special operators to perform these actions.</P><P>The increment operator (<TT>++</TT>) increases the value of the variable by 1,and the decrement operator (<TT>--</TT>) decreases it by 1. Thus, if you have a variable,<TT>C</TT>, and you want to increment it, you would use this statement:</P><PRE><FONT COLOR="#0066FF">C++; // Start with C and increment it.</FONT></PRE><P>This statement is equivalent to the more verbose statement</P><PRE><FONT COLOR="#0066FF">C = C + 1;</FONT></PRE><P>which you learned is also equivalent to the moderately verbose statement</P><PRE><FONT COLOR="#0066FF">C += 1;</FONT></PRE><H4 ALIGN="CENTER"><A NAME="Heading17"></A><FONT COLOR="#000077">Prefix and Postfix</FONT></H4><P>Both the increment operator (<TT>++</TT>) and the decrement operator(<TT>--</TT>)come in two varieties: prefix and postfix. The prefix variety is written before thevariable name (<TT>++myAge</TT>); the postfix variety is written after (<TT>myAge++</TT>).</P><P>In a simple statement, it doesn't much matter which you use, but in a complexstatement, when you are incrementing (or decrementing) a variable and then assigningthe result to another variable, it matters very much. The prefix operator is evaluatedbefore the assignment, the postfix is evaluated after.</P><P>The semantics of prefix is this: Increment the value and then fetch it. The semanticsof postfix is different: Fetch the value and then increment the original.</P><P>This can be confusing at first, but if <TT>x</TT> is an integer whose value is<TT>5</TT> and you write</P><PRE><FONT COLOR="#0066FF">int a = ++x;</FONT></PRE><P>you have told the compiler to increment <TT>x</TT> (making it <TT>6</TT>) andthen fetch that value and assign it to <TT>a</TT>. Thus, <TT>a</TT> is now <TT>6</TT>and <TT>x</TT> is now <TT>6</TT>.</P><P>If, after doing this, you write</P><PRE><FONT COLOR="#0066FF">int b = x++;</FONT></PRE><P>you have now told the compiler to fetch the value in <TT>x</TT> (<TT>6</TT>) andassign it to <TT>b</TT>, and then go back and increment <TT>x</TT>. Thus, <TT>b</TT>is now <TT>6</TT>, but <TT>x</TT> is now <TT>7</TT>. Listing 4.3 shows the use andimplications of both types.</P><P><A NAME="Heading18"></A><FONT SIZE="4" COLOR="#000077"><B>Listing 4.3. A demonstrationof prefix and postfix operators.</B></FONT><FONT COLOR="#0066FF"></FONT><PRE><FONT COLOR="#0066FF">1: // Listing 4.3 - demonstrates use of2: // prefix and postfix increment and3: // decrement operators4: #include <iostream.h>5: int main()6: {7: int myAge = 39; // initialize two integers8: int yourAge = 39;9: cout << "I am: " << myAge << " years old.\n";10: cout << "You are: " << yourAge << " years old\n";11: myAge++; // postfix increment12: ++yourAge; // prefix increment13: cout << "One year passes...\n";14: cout << "I am: " << myAge << " years old.\n";15: cout << "You are: " << yourAge << " years old\n";16: cout << "Another year passes\n";17: cout << "I am: " << myAge++ << " years old.\n";18: cout << "You are: " << ++yourAge << " years old\n";19: cout << "Let's print it again.\n";20: cout << "I am: " << myAge << " years old.\n";21: cout << "You are: " << yourAge << " years old\n";22: return 0;<TT>23: }</TT>Output: I am 39 years oldYou are 39 years oldOne year passesI am 40 years oldYou are 40 years oldAnother year passesI am 40 years oldYou are 41 years oldLet's print it againI am 41 years oldYou are 41 years old</FONT></PRE><P><FONT COLOR="#000077"><B>Analysis: </B></FONT>On lines 7 and 8, two integer variablesare declared, and each is initialized with the value <TT>39</TT>. Their values areprinted on lines 9 and 10.<BR>On line 11, <TT>myAge</TT> is incremented using the postfix increment operator, andon line 12, <TT>yourAge</TT> is incremented using the prefix increment operator.The results are printed on lines 14 and 15, and they are identical (both <TT>40</TT>).</P><P>On line 17, <TT>myAge</TT> is incremented as part of the printing statement, usingthe postfix increment operator. Because it is postfix, the increment happens afterthe print, and so the value <TT>40</TT> is printed again. In contrast, on line 18,<TT>yourAge</TT> is incremented using the prefix increment operator. Thus, it isincremented before being printed, and the value displays as <TT>41</TT>.</P><P>Finally, on lines 20 and 21, the values are printed again. Because the incrementstatement has completed, the value in <TT>myAge</TT> is now <TT>41</TT>, as is thevalue in <TT>yourAge</TT>.<H4 ALIGN="CENTER"><A NAME="Heading20"></A><FONT COLOR="#000077">Precedence</FONT></H4><P>In the complex statement</P><PRE><FONT COLOR="#0066FF">x = 5 + 3 * 8;</FONT></PRE><P>which is performed first, the addition or the multiplication? If the additionis performed first, the answer is 8 * 8, or 64. If the multiplication is performedfirst, the answer is 5 + 24, or 29.</P><P>Every operator has a precedence value, and the complete list is shown in AppendixA, "Operator Precedence." Multiplication has higher precedence than addition,and thus the value of the expression is 29.</P><P>When two mathematical operators have the same precedence, they are performed inleft-to-right order. Thus</P><PRE><FONT COLOR="#0066FF">x = 5 + 3 + 8 * 9 + 6 * 4;</FONT></PRE><P>is evaluated multiplication first, left to right. Thus, 8*9 = 72, and 6*4 = 24.Now the expression is essentially</P><PRE><FONT COLOR="#0066FF">x = 5 + 3 + 72 + 24;</FONT></PRE><P>Now the addition, left to right, is 5 + 3 = 8; 8 + 72 = 80; 80 + 24 = 104.</P><P>Be careful with this. Some operators, such as assignment, are evaluated in right-to-leftorder! In any case, what if the precedence order doesn't meet your needs? Considerthe expression</P><PRE><FONT COLOR="#0066FF">TotalSeconds = NumMinutesToThink + NumMinutesToType * 60</FONT></PRE><P>In this expression, you do not want to multiply the <TT>NumMinutesToType</TT>variable by 60 and then add it to <TT>NumMinutesToThink</TT>. You want to add thetwo variables to get the total number of minutes, and then you want to multiply thatnumber by 60 to get the total seconds.</P><P>In this case, you use parentheses to change the precedence order. Items in parenthesesare evaluated at a higher precedence than any of the mathematical operators. Thus</P><PRE><FONT COLOR="#0066FF">TotalSeconds = (NumMinutesToThink + NumMinutesToType) * 60</FONT></PRE><P>will accomplish what you want.<H3 ALIGN="CENTER"><A NAME="Heading21"></A><FONT COLOR="#000077">Nesting Parentheses</FONT></H3><P>For complex expressions, you might need to nest parentheses one within another.For example, you might need to compute the total seconds and then compute the totalnumber of people who are involved before multiplying seconds times people:</P><PRE><FONT COLOR="#0066FF">TotalPersonSeconds = ( ( (NumMinutesToThink + NumMinutesToType) * 60) * Â(PeopleInTheOffice + PeopleOnVacation) )</FONT></PRE><P>This complicated expression is read from the inside out. First, <TT>NumMinutesToThink</TT>is added to <TT>NumMinutesToType</TT>, because these are in the innermost parentheses.Then this sum is multiplied by 60. Next, <TT>PeopleInTheOffice</TT> is added to <TT>PeopleOnVacation</TT>.Finally, the total number of people found is multiplied by the total number of seconds.</P><P>This example raises an important related issue. This expression is easy for acomputer to understand, but very difficult for a human to read, understand, or modify.Here is the same expression rewritten, using some temporary integer variables:</P><PRE><FONT COLOR="#0066FF">TotalMinutes = NumMinutesToThink + NumMinutesToType;TotalSeconds = TotalMinutes * 60;TotalPeople = PeopleInTheOffice + PeopleOnVacation;TotalPersonSeconds = TotalPeople * TotalSeconds;</FONT></PRE><P>This example takes longer to write and uses more temporary variables than thepreceding example, but it is far easier to understand. Add a comment at the top toexplain what this code does, and change the <TT>60</TT> to a symbolic constant. Youthen will have code that is easy to understand and maintain.<BLOCKQUOTE> <P><HR><B>DO</B> remember that expressions have a value.<B> DO</B> use the prefix operator (<TT>++</TT>variable) to increment or decrement the variable before it is used in the expression. <B>DO</B> use the postfix operator (variable<TT>++</TT>) to increment or decrement the variable after it is used. <B>DO</B> use parentheses to change the order of precedence. <B>DON'T</B> nest too deeply, because the expression becomes hard to understand and maintain. <HR></BLOCKQUOTE><H3 ALIGN="CENTER"><A NAME="Heading22"></A><FONT COLOR="#000077">The Nature of Truth</FONT></H3><P>In C++, zero is considered false, and all other values are considered true, althoughtrue is usually represented by 1. Thus, if an expression is false, it is equal tozero, and if an expression is equal to zero, it is false. If a statement is true,all you know is that it is nonzero, and any nonzero statement is true.<H4 ALIGN="CENTER"><A NAME="Heading23"></A><FONT COLOR="#000077">Relational Operators</FONT></H4><P>The relational operators are used to determine whether two numbers are equal,or if one is greater or less than the other. Every relational statement evaluatesto either <TT>1</TT> (<TT>TRUE</TT>) or <TT>0</TT> (<TT>FALSE</TT>). The relationaloperators are presented later, in Table 4.1.</P><P>If the integer variable <TT>myAge</TT> has the value <TT>39</TT>, and the integervariable <TT>yourAge</TT> has the value <TT>40</TT>, you can determine whether theyare equal by using the relational "equals" operator:</P><PRE><FONT COLOR="#0066FF">myAge == yourAge; // is the value in myAge the same as in yourAge?</FONT></PRE><P>This expression evaluates to <TT>0</TT>, or <TT>false</TT>, because the variablesare not equal. The expression</P><PRE><FONT COLOR="#0066FF">myAge > yourAge; // is myAge greater than yourAge?</FONT></PRE><P>evaluates to <TT>0</TT> or <TT>false</TT>.<BLOCKQUOTE> <P><HR><FONT COLOR="#000077"><B>WARNING:</B></FONT><B> </B>Many novice C++ programmers confuse the assignment operator (<TT>=</TT>) with the equals operator (<TT>==</TT>). This can create a nasty bug in your program. <HR></BLOCKQUOTE><P>There are six relational operators: equals (<TT>==</TT>), less than (<TT><</TT>),greater than (<TT>></TT>), less than or equal to (<TT><=</TT>), greater thanor equal to (<TT>>=</TT>), and not equals (<TT>!=</TT>). Table 4.1 shows eachrelational operator, its use, and a sample code use.<BR><BR><FONT SIZE="4"><B>Table 4.1. The Relational Operators. </B></FONT><TABLE BORDER="0"> <TR ALIGN="LEFT" rowspan="1"> <TD ALIGN="LEFT"><B><I>Name</I></B></TD>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -