?? 021.htm
字號:
29:
30: cout << "Done." << endl;
31: return 0;
32: }
33:
34: int sortFunction( const void *a, const void *b)
35: {
36: int intOne = *((int*)a);
37: int intTwo = *((int*)b);
38: if (intOne < intTwo)
39: return -1;
40: if (intOne == intTwo)
41: return 0;
42: return 1;
<TT>43: }</TT>
Output: Enter a number: 2
Enter a number: 9
Enter a number: 12
Enter a number: 873
Enter a number: 0
Enter a number: 45
Enter a number: 93
Enter a number: 2
Enter a number: 66
Enter a number: 1
<BR>
Table[0]: 0
Table[1]: 1
Table[2]: 2
Table[3]: 2
Table[4]: 9
Table[5]: 12
Table[6]: 45
Table[7]: 66
Table[8]: 93
Table[9]: 873
Done.
</FONT></PRE>
<P><FONT COLOR="#000077"><B>Analysis:</B></FONT><B> </B>On line 4, the standard library
header is included, which is required by the <TT>qsort()</TT> function. On line 7,
the function <TT>sortFunction()</TT> is declared, which takes the required four parameters.<BR>
<BR>
An array is declared on line 13 and filled by user input on lines 16-20. <TT>qsort()</TT>
is called on line 24, casting the address of the array name <TT>table</TT> to be
a <TT>void*</TT>.</P>
<P>Note that the parameters for <TT>sortFunction</TT> are not passed to the call
to <TT>qsort()</TT>. The name of the <TT>sortFunction</TT>, which is itself a pointer
to that function, is the parameter to <TT>qsort()</TT>.</P>
<P>Once <TT>qsort()</TT> is running, it will fill the constant <TT>void</TT> pointers
<TT>a</TT> and <TT>b</TT> with each value of the array. If the first value is smaller
than the second, the comparison function must return <TT>-1</TT>. If it is equal,
the comparison function must return <TT>0</TT>. Finally, if the first value is greater
than the second value, the comparison function must return <TT>1</TT>. This is reflected
in the <TT>sortFunction()</TT>, as shown on lines 34 to 43.
<H4 ALIGN="CENTER"><A NAME="Heading18"></A><FONT COLOR="#000077">Other Libraries</FONT></H4>
<P>Your C++ compiler supplies a number of other libraries, among them the standard
input and output libraries and the stream libraries that you've been using throughout
this book. It is well worth your time and effort to explore the documentation that
came with your compiler to find out what these libraries have to offer.
<H3 ALIGN="CENTER"><A NAME="Heading19"></A><FONT COLOR="#000077">Bit Twiddling</FONT></H3>
<P>Often you will want to set flags in your objects to keep track of the state of
your object. (Is it in <TT>AlarmState</TT>? Has this been initialized yet? Are you
coming or going?)</P>
<P>You can do this with user-defined Booleans, but when you have many flags, and
when storage size is an issue, it is convenient to be able to use the individual
bits as flags.</P>
<P>Each byte has eight bits, so in a four-byte <TT>long</TT> you can hold 32 separate
flags. A bit is said to be "set" if its value is <TT>1</TT>, and clear
if its value is <TT>0</TT>. When you set a bit, you make its value <TT>1</TT>, and
when you clear it, you make its value <TT>0</TT>. (Set and clear are both adjectives
and verbs). You can set and clear bits by changing the value of the <TT>long</TT>,
but that can be tedious and confusing.
<BR>
<BR>
<BLOCKQUOTE>
<P>
<HR>
<FONT COLOR="#000077"><B>NOTE:</B></FONT><B> </B>Appendix C, "Binary and Hexadecimal,"
provides valuable additional information about binary and hexadecimal manipulation.
<HR>
<BR>
<BR>
</BLOCKQUOTE>
<BR>
<P>C++ provides bitwise operators that act upon the individual bits.These look like,
but are different from, the logical operators, so many novice programmers confuse
them. The bitwise operators are presented in Table 21.1. <BR>
<BR>
<FONT SIZE="4"><B>Table 21.1. The Bitwise Operators. </B></FONT>
<TABLE BORDER="0" WIDTH="145">
<TR ALIGN="LEFT" rowspan="1">
<TD WIDTH="64" ALIGN="LEFT"><B><I>symbol</I></B></TD>
<TD ALIGN="LEFT"><B><I>operator</I></B></TD>
</TR>
<TR ALIGN="LEFT" rowspan="1">
<TD WIDTH="64" ALIGN="LEFT"><TT>&</TT></TD>
<TD ALIGN="LEFT"><TT>AND</TT></TD>
</TR>
<TR ALIGN="LEFT" rowspan="1">
<TD WIDTH="64" ALIGN="LEFT"><TT>|</TT></TD>
<TD ALIGN="LEFT"><TT>OR</TT></TD>
</TR>
<TR ALIGN="LEFT" rowspan="1">
<TD WIDTH="64" ALIGN="LEFT"><TT>^</TT></TD>
<TD ALIGN="LEFT">exclusive <TT>OR</TT></TD>
</TR>
<TR ALIGN="LEFT" rowspan="1">
<TD WIDTH="64" ALIGN="LEFT"><TT>~</TT></TD>
<TD ALIGN="LEFT">complement</TD>
</TR>
</TABLE>
<BR>
<CENTER>
<H4><A NAME="Heading20"></A><FONT COLOR="#000077">Operator AND</FONT></H4>
</CENTER>
<P>The <TT>AND</TT> operator (<TT>&</TT>) is a single ampersand, as opposed to
the logical <TT>AND</TT>, which is two ampersands. When you <TT>AND</TT> two bits,
the result is <TT>1</TT> if both bits are <TT>1</TT>, but <TT>0</TT> if either or
both bits are <TT>0</TT>. The way to think of this is: The result is <TT>1</TT> if
bit 1 is set and if bit 2 is set.
<CENTER>
<H4><A NAME="Heading21"></A><FONT COLOR="#000077">Operator OR</FONT></H4>
</CENTER>
<P>The second bitwise operator is <TT>OR</TT> (<TT>|</TT>). Again, this is a single
vertical bar, as opposed to the logical <TT>OR</TT>, which is two vertical bars.
When you <TT>OR</TT> two bits, the result is <TT>1</TT> if either bit is set or if
both are.
<CENTER>
<H4><A NAME="Heading22"></A><FONT COLOR="#000077">Operator Exclusive OR</FONT></H4>
</CENTER>
<P>The third bitwise operator is exclusive <TT>OR</TT> (<TT>^</TT>). When you exclusive
<TT>OR</TT> two bits, the result is <TT>1</TT> if the two bits are different.
<CENTER>
<H4><A NAME="Heading23"></A><FONT COLOR="#000077">The Complement Operator</FONT></H4>
</CENTER>
<P>The complement operator (<TT>~</TT>) clears every bit in a number that is set
and sets every bit that is clear. If the current value of the number is <TT>1010
0011</TT>, the complement of that number is <TT>0101 1100</TT>.
<CENTER>
<H4><A NAME="Heading24"></A><FONT COLOR="#000077">Setting Bits</FONT></H4>
</CENTER>
<P>When you want to set or clear a particular bit, you use masking operations. If
you have a 4-byte flag and you want to set bit 8 TRUE, you need to <TT>OR</TT> the
flag with the value <TT>128</TT>. Why? <TT>128</TT> is <TT>1000 0000</TT> in binary;
thus the value of the eighth bit is <TT>128</TT>. Whatever the current value of that
bit (<TT>set</TT> or <TT>clear</TT>), if you <TT>OR</TT> it with the value <TT>128</TT>
you will set that bit and not change any of the other bits. Let's assume that the
current value of the 8 bits is <TT>1010 0110 0010 0110</TT>. <TT>OR</TT>ing 128 to
it looks like this:</P>
<PRE><FONT COLOR="#0066FF" font style="font-size:10pt">9 8765 4321
1010 0110 0010 0110 // bit 8 is clear
| 0000 0000 1000 0000 // 128
----------------------
1010 0110 1010 0110 // bit 8 is set
</FONT></PRE>
<P>There are a few things to note. First, as usual, bits are counted from right to
left. Second, the value <TT>128</TT> is all zeros except for bit 8, the bit you want
to set. Third, the starting number <TT>1010 0110 0010 0110</TT> is left unchanged
by the <TT>OR</TT> operation, except that bit 8 was set. Had bit 8 already been set,
it would have remained set, which is what you want.
<CENTER>
<H4><A NAME="Heading25"></A><FONT COLOR="#000077">Clearing Bits</FONT></H4>
</CENTER>
<P>If you want to clear bit 8, you can <TT>AND</TT> the bit with the complement of
128. The complement of 128 is the number you get when you take the bit pattern of
128 (1000 0000), set every bit that is <TT>clear</TT>, and clear every bit that is
<TT>set</TT> (0111 1111). When you <TT>AND</TT> these numbers, the original number
is unchanged, except for the eighth bit, which is forced to zero.</P>
<PRE><FONT COLOR="#0066FF" font style="font-size:10pt">1010 0110 1010 0110 // bit 8 is set
& 1111 1111 0111 1111 // ~128
----------------------
1010 0110 0010 0110 // bit 8 cleared
</FONT></PRE>
<P>To fully understand this solution, do the math yourself. Each time both bits are
<TT>1</TT>, write 1 in the answer. If either bit is <TT>0</TT>, write 0 in the answer.
Compare the answer with the original number. It should be the same except that bit
8 was cleared.
<CENTER>
<H4><A NAME="Heading26"></A><FONT COLOR="#000077">Flipping Bits</FONT></H4>
</CENTER>
<P>Finally, if you want to flip bit 8, no matter what its state, you exclusive <TT>OR</TT>
the number with 128. Thus:</P>
<PRE><FONT COLOR="#0066FF" font style="font-size:10pt">1010 0110 1010 0110 // number
^ 0000 0000 1000 0000 // 128
----------------------
1010 0110 0010 0110 // bit flipped
^ 0000 0000 1000 0000 // 128
----------------------
1010 0110 1010 0110 // flipped back
</FONT></PRE>
<BR>
<BR>
<BLOCKQUOTE>
<P>
<HR>
<B>DO</B> set bits by using masks and the <TT>OR</TT> operator. <B>DO</B> clear bits
by using masks and the <TT>AND</TT> operator.<B> DO </B>flip bits using masks and
the exclusive <TT>OR</TT> operator.
<HR>
<BR>
<BR>
</BLOCKQUOTE>
<BR>
<CENTER>
<H4><A NAME="Heading27"></A><FONT COLOR="#000077">Bit Fields</FONT></H4>
</CENTER>
<P>There are circumstances under which every byte counts, and saving six or eight
bytes in a class can make all the difference. If your class or structure has a series
of Boolean variables, or variables that can have only a very small number of possible
values, you may save some room using bit fields.</P>
<P>Using the standard C++ data types, the smallest type you can use in your class
is a type <TT>char</TT>, which is one byte. You will usually end up using an <TT>int</TT>,
which is two, or more often four, bytes. By using bit fields, you can store eight
binary values in a <TT>char</TT> and 32 such values in a <TT>long</TT>.</P>
<P>Here's how bit fields work: bit fields are named and accessed like any class member.
Their type is always declared to be <TT>unsigned</TT> <TT>int</TT>. After the bit
field name, write a colon followed by a number. The number is an instruction to the
compiler as to how many bits to assign to this variable. If you write 1, the bit
will represent either the value <TT>0</TT> or <TT>1</TT>. If you write 2, the bit
can represent <TT>0</TT>, <TT>1</TT>, <TT>2</TT>, or <TT>3</TT>, a total of four
values. A three-bit field can represent eight values, and so forth. Appendix C reviews
binary numbers. Listing 21.8 illustrates the use of bit fields.</P>
<BR>
<P><A NAME="Heading28"></A><FONT SIZE="4" COLOR="#000077"><B>Listing 21.8. Using
bit fields.</B></FONT>
<PRE><FONT COLOR="#0066FF" font style="font-size:10pt">0: #include <iostream.h>
1: #include <string.h>
2:
3: enum STATUS { FullTime, PartTime } ;
4: enum GRADLEVEL { UnderGrad, Grad } ;
5: enum HOUSING { Dorm, OffCampus };
6: enum FOODPLAN { OneMeal, AllMeals, WeekEnds, NoMeals };
7:
8: class student
9: {
10: public:
11: student():
12: myStatus(FullTime),
13: myGradLevel(UnderGrad),
14: myHousing(Dorm),
15: myFoodPlan(NoMeals)
16: {}
17: ~student(){}
18: STATUS GetStatus();
19: void SetStatus(STATUS);
20: unsigned GetPlan() { return myFoodPlan; }
21:
22: private:
23: unsigned myStatus : 1;
24: unsigned myGradLevel: 1;
25: unsigned myHousing : 1;
26: unsigned myFoodPlan : 2;
27: };
28:
29: STATUS student::GetStatus()
30: {
31: if (myStatus)
32: return FullTime;
33: else
34: return PartTime;
35: }
36: void student::SetStatus(STATUS theStatus)
37: {
38: myStatus = theStatus;
39: }
40:
41:
42: int main()
43: {
44: student Jim;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -