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

📄 ch11.htm

📁 vc的电子书
💻 HTM
📖 第 1 页 / 共 5 页
字号:
44:          cout << sentinelTwo[i]<< "\n";
45:       }
46:
47:     return 0;
<TT>48: }</TT></FONT>
<FONT COLOR="#0066FF">
Output: Test 1:
TargetArray[0]: 0
TargetArray[24]: 0

SentinelOne[0]: 0
SentinelTwo[0]: 0
SentinelOne[1]: 0
SentinelTwo[1]: 0
SentinelOne[2]: 0
SentinelTwo[2]: 0

Assigning...
Test 2:
TargetArray[0]: 20
TargetArray[24]: 20
TargetArray[25]: 20

SentinelOne[0]: 20
SentinelTwo[0]: 0
SentinelOne[1]: 0
SentinelTwo[1]: 0
SentinelOne[2]: 0
SentinelTwo[2]: 0
</FONT></PRE>
<P><FONT COLOR="#000077"><B>Analysis: </B></FONT>Lines 9 and 10 declare two arrays
of three integers that act as sentinels around <TT>TargetArray</TT>. These sentinel
arrays are initialized with the value <TT>0</TT>. If memory is written to beyond
the end of <TT>TargetArray</TT>, the sentinels are likely to be changed. Some compilers
count down in memory; others count up. For this reason, the sentinels are placed
on both sides of <TT>TargetArray</TT>.<BR>
<BR>
Lines 19-29 confirm the sentinel values in Test 1. In line 33 <TT>TargetArray</TT>'s
members are all initialized to the value <TT>20</TT>, but the counter counts to <TT>TargetArray</TT>
offset 25, which doesn't exist in <TT>TargetArray</TT>.</P>
<P>Lines 36-38 print <TT>TargetArray</TT>'s values in Test 2. Note that <TT>TargetArray[25]</TT>
is perfectly happy to print the value <TT>20</TT>. However, when <TT>SentinelOne</TT>
and <TT>SentinelTwo</TT> are printed, <TT>SentinelTwo[0]</TT> reveals that its value
has changed. This is because the memory that is 25 elements after <TT>TargetArray[0]</TT>
is the same memory that is at <TT>SentinelTwo[0]</TT>. When the nonexistent <TT>TargetArray[0]</TT>
was accessed, what was actually accessed was <TT>SentinelTwo[0]</TT>.</P>
<P>This nasty bug can be very hard to find, because <TT>SentinelTwo[0]</TT>'s value
was changed in a part of the code that was not writing to <TT>SentinelTwo</TT> at
all.</P>
<P>This code uses &quot;magic numbers&quot; such as 3 for the size of the sentinel
arrays and 25 for the size of <TT>TargetArray</TT>. It is safer to use constants,
so that you can change all these values in one place.
<H3 ALIGN="CENTER"><A NAME="Heading11"></A><FONT COLOR="#000077">Fence Post Errors</FONT></H3>
<P>It is so common to write to one past the end of an array that this bug has its
own name. It is called a fence post error. This refers to the problem in counting
how many fence posts you need for a 10-foot fence if you need one post for every
foot. Most people answer 10, but of course you need 11. Figure 11.2 makes this clear.<BR>
<BR>
<A NAME="Heading12"></A><A HREF="11zcp02.jpg" tppabs="http://www.mcp.com/814147200/0-672/0-672-31070-8/art/ch11/11zcp02.jpg"><FONT COLOR="#000077">Figure
11.2.</FONT></A><FONT COLOR="#000077"> </FONT><I>Fence post errors.</I> <BR>
<BR>
This sort of &quot;off by one&quot; counting can be the bane of any programmer's
life. Over time, however, you'll get used to the idea that a 25-element array counts
only to element 24, and that everything counts from 0. (Programmers are often confused
why office buildings don't have a floor zero. Indeed, some have been known to push
the 4 elevator button when they want to get to the fifth floor.)


<BLOCKQUOTE>
	<P>
<HR>
<FONT COLOR="#000077"><B>NOTE:</B></FONT><B> </B>Some programmers refer to <TT>ArrayName[0]</TT>
	as the zeroth element. Getting into this habit is a big mistake. If <TT>ArrayName[0]</TT>
	is the zeroth element, what is <TT>ArrayName[1]</TT>? The oneth? If so, when you
	see <TT>ArrayName[24]</TT>, will you realize that it is not the 24th element, but
	rather the 25th? It is far better to say that <TT>ArrayName[0]</TT> is at offset
	zero and is the first element. 
<HR>


</BLOCKQUOTE>

<H3 ALIGN="CENTER"><A NAME="Heading13"></A><FONT COLOR="#000077">Initializing Arrays</FONT></H3>
<P>You can initialize a simple array of built-in types, such as integers and characters,
when you first declare the array. After the array name, you put an equal sign (<TT>=</TT>)
and a list of comma-separated values enclosed in braces. For example,</P>
<PRE><FONT COLOR="#0066FF">int IntegerArray[5] = { 10, 20, 30, 40, 50 };
</FONT></PRE>
<P>declares <TT>IntegerArray</TT> to be an array of five integers. It assigns <TT>IntegerArray[0]</TT>
the value <TT>10</TT>, <TT>IntegerArray[1]</TT> the value <TT>20</TT>, and so forth.</P>
<P>If you omit the size of the array, an array just big enough to hold the initialization
is created. Therefore, if you write</P>
<PRE><FONT COLOR="#0066FF">int IntegerArray[] = { 10, 20, 30, 40, 50 };
</FONT></PRE>
<P>you will create exactly the same array as you did in the previous example.</P>
<P>If you need to know the size of the array, you can ask the compiler to compute
it for you. For example,</P>
<PRE><FONT COLOR="#0066FF">const USHORT IntegerArrayLength;
IntegerArrayLength = sizeof(IntegerArray)/sizeof(IntegerArray[0]);
</FONT></PRE>
<P>sets the constant <TT>USHORT</TT> variable <TT>IntegerArrayLength</TT> to the
result obtained from dividing the size of the entire array by the size of each individual
entry in the array. That quotient is the number of members in the array.</P>
<P>You cannot initialize more elements than you've declared for the array. Therefore,</P>
<PRE><FONT COLOR="#0066FF">int IntegerArray[5] = { 10, 20, 30, 40, 50, 60};
</FONT></PRE>
<P>generates a compiler error because you've declared a five-member array and initialized
six values. It is legal, however, to write</P>
<PRE><FONT COLOR="#0066FF">int IntegerArray[5] = { 10, 20};
</FONT></PRE>
<P>Although uninitialized array members have no guaranteed values, actually, aggregates
will be initialized to <TT>0</TT>. If you don't initialize an array member, its value
will be set to <TT>0</TT>.


<BLOCKQUOTE>
	<P>
<HR>
<B>DO</B> let the compiler set the size of initialized arrays. <B>DON'T</B> write
	past the end of the array. <B>DO</B> give arrays meaningful names, as you would with
	any variable.<B>DO</B> remember that the first member of the array is at offset 0.
	
<HR>


</BLOCKQUOTE>

<H3 ALIGN="CENTER"><A NAME="Heading14"></A><FONT COLOR="#000077">Declaring Arrays</FONT></H3>
<P>Arrays can have any legal variable name, but they cannot have the same name as
another variable or array within their scope. Therefore, you cannot have an array
named <TT>myCats[5]</TT> and a variable named <TT>myCats</TT> at the same time.</P>
<P>You can dimension the array size with a <TT>const</TT> or with an enumeration.
Listing 11.3 illustrates this.</P>
<P><A NAME="Heading15"></A><FONT SIZE="4" COLOR="#000077"><B>Listing 11.3. Using
consts and enums in arrays.</B></FONT></P>
<PRE><FONT COLOR="#0066FF">1:     // Listing 11.3
2:     // Dimensioning arrays with consts and enumerations
3:
4:     #include &lt;iostream.h&gt;
5:     int main()
6:     {
7:        enum WeekDays { Sun, Mon, Tue, 
8:             Wed, Thu, Fri, Sat, DaysInWeek };
9:        int ArrayWeek[DaysInWeek] = { 10, 20, 30, 40, 50, 60, 70 };
10:
11:       cout &lt;&lt; &quot;The value at Tuesday is: &quot; &lt;&lt; ArrayWeek[Tue];
12:     return 0;
<TT>13: }</TT>
Output: The value at Tuesday is: 30
</FONT></PRE>
<P><FONT COLOR="#000077"><B>Analysis:</B></FONT><B> </B>Line 7 creates an enumeration
called <TT>WeekDays</TT>. It has eight members. Sunday is equal to 0, and <TT>DaysInWeek</TT>
is equal to 7.<BR>
<BR>
Line 11 uses the enumerated constant <TT>Tue</TT> as an offset into the array. Because
<TT>Tue</TT> evaluates to <TT>2</TT>, the third element of the array, <TT>DaysInWeek[2]</TT>,
is returned and printed in line 11.
<H3 ALIGN="CENTER"><A NAME="Heading17"></A><FONT COLOR="#000077">Arrays</FONT></H3>
<P>To declare an array, write the type of object stored, followed by the name of
the array and a subscript with the number of objects to be held in the array. Example
1</P>
<PRE><FONT COLOR="#0066FF">int MyIntegerArray[90];
</FONT></PRE>
<P>Example 2</P>
<PRE><FONT COLOR="#0066FF">long * ArrayOfPointersToLongs[100];
</FONT></PRE>
<P>To access members of the array, use the subscript operator. Example 1</P>
<PRE><FONT COLOR="#0066FF">int theNinethInteger = MyIntegerArray[8];
</FONT></PRE>
<P>Example 2</P>
<PRE><FONT COLOR="#0066FF">long * pLong = ArrayOfPointersToLongs[8]
</FONT></PRE>
<P>Arrays count from zero. An array of n items is numbered from 0 to n-1.
<H3 ALIGN="CENTER"><A NAME="Heading18"></A><FONT COLOR="#000077">Arrays of Objects</FONT></H3>
<P>Any object, whether built-in or user-defined, can be stored in an array. When
you declare the array, you tell the compiler the type of object to store and the
number of objects for which to allocate room. The compiler knows how much room is
needed for each object based on the class declaration. The class must have a default
constructor that takes no arguments so that the objects can be created when the array
is defined.</P>
<P>Accessing member data in an array of objects is a two-step process. You identify
the member of the array by using the index operator (<TT>[ ]</TT>), and then you
add the member operator (<TT>.</TT>) to access the particular member variable. Listing
11.4 demonstrates how you would create an array of five <TT>CAT</TT>s.</P>
<P><A NAME="Heading19"></A><FONT SIZE="4" COLOR="#000077"><B>Listing 11.4. Creating
an array of objects.</B></FONT></P>
<PRE><FONT COLOR="#0066FF">
1:     // Listing 11.4 - An array of objects
2:
3:     #include &lt;iostream.h&gt;
4:
5:     class CAT
6:     {
7:        public:
8:           CAT() { itsAge = 1; itsWeight=5; } 
9:           ~CAT() {}        
10:          int GetAge() const { return itsAge; }
11:          int GetWeight() const { return itsWeight; }
12:          void SetAge(int age) { itsAge = age; }
13:
14:       private:
15:          int itsAge;
16:          int itsWeight;
17:    };
18:
19:    int main()
20:    {
21:       CAT Litter[5];
22:       int i;
23:       for (i = 0; i &lt; 5; i++)
24:          Litter[i].SetAge(2*i +1);
25:
26:       for (i = 0; i &lt; 5; i++)
27:       {
28:          cout &lt;&lt; &quot;Cat #&quot; &lt;&lt; i+1&lt;&lt; &quot;: &quot;;
29:          cout &lt;&lt; Litter[i].GetAge() &lt;&lt; endl;
30:       }
31:     return 0;
<TT>32: }</TT>

Output: cat #1: 1
cat #2: 3
cat #3: 5
cat #4: 7
cat #5: 9
</FONT></PRE>
<P><FONT COLOR="#000077"><B>Analysis</B></FONT><B>: </B>Lines 5-17 declare the <TT>CAT</TT>
class. The <TT>CAT</TT> class must have a default constructor so that <TT>CAT</TT>
objects can be created in an array. Remember that if you create any other constructor,
the compiler-supplied default constructor is not created; you must create your own.<BR>
<BR>
The first <TT>for</TT> loop (lines 23 and 24) sets the age of each of the five <TT>CAT</TT>s
in the array. The second <TT>for</TT> loop (lines 26 and 27) accesses each member
of the array and calls <TT>GetAge()</TT>.</P>
<P>Each individual <TT>CAT</TT>'s <TT>GetAge()</TT> method is called by accessing
the member in the array, <TT>Litter[i]</TT>, followed by the dot operator (<TT>.</TT>),
and the member function.
<H3 ALIGN="CENTER"><A NAME="Heading21"></A><FONT COLOR="#000077">Multidimensional
Arrays</FONT></H3>
<P>It is possible to have arrays of more than one dimension. Each dimension is represented
as a subscript in the array. Therefore, a two-dimensional array has two subscripts;
a three-dimensional array has three subscripts; and so on. Arrays can have any number
of dimensions, although it is likely that most of the arrays you create will be of
one or two dimensions.</P>
<P>A good example of a two-dimensional array is a chess board. One dimension represents
the eight rows; the other dimension represents the eight columns. Figure 11.3 illustrates
this idea.</P>
<P>Suppose that you have a class named <TT>SQUARE</TT>. The declaration of an array
named <TT>Board</TT> that represents it would be</P>
<PRE><FONT COLOR="#0066FF">SQUARE Board[8][8];
</FONT></PRE>
<P>You could also represent the same data with a one-dimensional, 64-square array.
For example,</P>
<PRE><FONT COLOR="#0066FF">SQUARE Board[64]
</FONT></PRE>
<P>This doesn't correspond as closely to the real-world object as the two-dimension.
When the game begins, the king is located in the fourth position in the first row.
Counting from zero array, that position corresponds to</P>
<PRE><FONT COLOR="#0066FF">Board[0][3];
</FONT></PRE>
<P>assuming that the first subscript corresponds to <TT>row</TT>, and the second
to <TT>column</TT>. The layout of positions for the entire board is illustrated in
Figure 11.3.<BR>
<BR>
<A NAME="Heading22"></A><A HREF="11zcp03.jpg" tppabs="http://www.mcp.com/814147200/0-672/0-672-31070-8/art/ch11/11zcp03.jpg"><FONT COLOR="#000077">Figure
11.3.</FONT></A><FONT COLOR="#000077"><I> </I></FONT><I>A chess board and a two-dimensional
array.</I>
<H3 ALIGN="CENTER"><A NAME="Heading23"></A><FONT COLOR="#000077">Initializing Multidimensional

⌨️ 快捷键说明

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