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

📄 tut3-3.html

📁 a Complete C++ language tutorial on the cplusplus.com
💻 HTML
📖 第 1 页 / 共 2 页
字号:
  int numbers[5];
  int * p;
  p = numbers;  *p = 10;
  p++;  *p = 20;
  p = &numbers[2];  *p = 30;
  p = numbers + 3;  *p = 40;
  p = numbers;  *(p+4) = 50;
  for (int n=0; n<5; n++)
    cout << numbers[n] << ", ";
  return 0;
}
</PRE></TT>
</TD><TD BGCOLOR="silver" WIDTH=50% VALIGN="top">
<B><TT>10, 20, 30, 40, 50,</TT></B>
</TD></TR></TABLE>
</CENTER>

<p>
In chapter "<i>Arrays</i>" we used bracket signs <tt>[]</tt> several times 
in order to specify the index of the element of the Array to which we wanted to refer.
Well, the bracket signs operator <tt>[]</tt> are known as <i>offset</i> operators
and they are equivalent to adding the number within brackets to the address of a pointer.
For example, both following expressions:
<blockquote><tt><pre>
a[5] = 0;       <i><font color="green">// a [offset of 5] = 0</font></i>
*(a+5) = 0;     <i><font color="green">// pointed by (a+5) = 0</font></i>
</pre></tt></blockquote>
are equivalent and valid either if <tt><b>a</b></tt> is a pointer or if it is an array.

<p>
<h2>Pointer initialization</h2>
When declaring pointers we may want to explicitly specify to which variable we want
them to point,
<blockquote><tt>
 int number;<br>
 int *tommy = &number;<br>
</tt></blockquote>
this is equivalent to:
<blockquote><tt>
 int number;<br>
 int *tommy;<br>
 tommy = &number;<br>
</tt></blockquote>
When a pointer assignation takes place we are always assigning the address where it points
to, never the value pointed. You must consider that at the moment of declaring a pointer,
the asterisk (<tt>*</tt>) indicates only that it is a pointer, it in no case
indicates the reference operator (<tt>*</tt>). Remember, they are two different
operators, although they are written with the same sign. Thus, we must take care not
to confuse the previous with:
<blockquote><tt><font color="red">
 int number;<br>
 int *tommy;<br>
 *tommy = &number;<br>
</font></tt></blockquote>
that anyway would not have much sense in this case.
<p>
As in the case of arrays, the compiler allows the special case that we want to
initialize the content at which the pointer points with constants at the same moment
as declaring the variable pointer:<br>
<blockquote><tt>
char * terry = "hello";
</tt></blockquote>
in this case static storage is reserved for containing <tt>"hello"</tt> and a pointer
to the first <TT><B>char</B></TT> of this memory block (that corresponds to 'h') is
assigned to <tt><b>terry</b></tt>. If we imagine that <tt>"hello"</tt> is stored at
addresses 1702 and following, the previous declaration could be outlined thus:
 <blockquote><img src="imgpoin3.gif"></blockquote>
it is important to indicate that <tt><b>terry</b></tt> contains the value
<tt><b>1702</b></tt> and <u>not</u> <tt><b>'h'</b></tt> nor <tt><b>"hello"</b></tt>,
although <tt><b>1702</b></tt> points to these characters.
<p>
The pointer <tt><b>terry</b></tt> points to a string of characters and can be used
exactly as if it was an Array (remember that an array is just <i>a constant
pointer</i>). For example, if our temper changed and we wanted to replace
 the <tt><b>'o'</b></tt> by a <tt><b>'!'</b></tt> sign
in the content pointed by <tt><b>terry</b></tt>, we could do it
by any of the following two ways:<br>
<blockquote><tt>
terry[4] = '!';<br>
*(terry+4) = '!';<br>
</tt></blockquote>
remember that to write <tt><b>terry[4]</b></tt> is just the same as to write
<tt><b>*(terry+4)</b></tt>, although the most usual expression is the first one.
With either of those two expressions something like this would happen:
<blockquote><img src="imgpoin4.gif"></blockquote>

<p>
<h2>Arithmetic of pointers</h2>
To conduct arithmetical operations on pointers is a little different than to conduct them on
other integer data types. To begin with, only addition and subtraction operations are allowed to be
conducted, the others make no sense in the world of pointers.
But both addition and subtraction have a different behavior with pointers according
to the <u>size</u> of the data type to which they point.
<p>
When we saw the different data types that exist, we saw that some occupy
more or less space than others in the memory.  For example, in the case of integer numbers,
<i>char</i> occupies 1 byte, <i>short</i> occupies 2 bytes and <i>long</i> occupies 4.
<p>
Let's suppose that we have 3 pointers:
<blockquote><tt>
char *mychar;<br>
short *myshort;<br>
long *mylong;<br>
</tt></blockquote>
and that we know that they point to memory locations <tt><b>1000</b></tt>,
<tt><b>2000</b></tt> and <tt><b>3000</b></tt> respectively.
<p>
So if we write:
<blockquote><tt>
mychar++;<br>
myshort++;<br>
mylong++;<br>
</tt></blockquote>
<tt>mychar</tt>, as you may expect, would contain the value <tt>1001</tt>. 
Nevertheless, <tt>myshort</tt> would contain the value <tt>2002</tt>,
and <tt>mylong</tt> would contain <tt>3004</tt>. 
The reason is that when adding <TT>1</TT> to a pointer we are making it to point
to the following element of the same type with which it has been defined,
and therefore the size in <i>bytes</i> of the <i>type</i> pointed is added to the pointer.

<blockquote><img src="imgpoin5.gif"></blockquote>

This is applicable both when adding and subtracting any number to a pointer.
It would happen exactly the same if we write:
<blockquote><tt>
mychar = mychar + 1;<br>
myshort = myshort + 1;<br>
mylong = mylong + 1;<br>
</tt></blockquote>
It is important to warn you that both increase (<tt>++</tt>) and
decrease (<tt>--</tt>) operators have a greater priority than the reference operator
asterisk (<tt>*</tt>), therefore the following expressions may lead to confussion:
<blockquote><tt>
*p++;<br>
*p++ = *q++;
</tt></blockquote>
The first one is equivalent to <tt>*(p++)</tt> and what it does is to increase
<tt><b>p</b></tt> (the address where it points to - not the value that contains).<br>
In the second, because both increase operators (<tt>++</tt>) are after the expressions
to be evaluated and not before, first the value of <tt>*q</tt> is assigned to <tt>*p</tt>
and then both <tt>q</tt> and <tt>p</tt> are increased by one. It is equivalent to:
<blockquote><tt>
*p = *q;<br>
p++;<br>
q++;<br>
</tt></blockquote>
Like always, I recommend you use parenthesis <tt><b>()</b></tt>
in order to avoid unexpected results.
<p>
<h2>Pointers to pointers</h2>
C++ allows the use of pointers that point to pointers, that these, in its turn, point to data.
In order to do that we only need to add an asterisk (<tt>*</tt>) for each level of reference:
<blockquote><tt>
char a;<br>
char * b;<br>
char ** c;<br>
a = 'z';<br>
b = &a;<br>
c = &b;<br>
</tt></blockquote>
this, supposing the randomly chosen memory locations of <TT><B>7230</B></TT>, <TT><B>8092</B></TT> and
<TT><B>10502</B></TT>, could be described thus:
<blockquote><img src="imgpoin6.gif"></blockquote>
(inside the cells there is the content of the variable; under the cells its location)<P>
The new thing in this example is variable <tt><b>c</b></tt>, which
we can talk about in three different ways, each one of them would correspond to a different
value:
<blockquote><tt><font color="blue">
<B>c</B> is a variable of type (char **) with a value of 8092<br>
<B>*c</B> is a variable of type (char*) with a value of 7230<br>
<B>**c</B> is a variable of type (char) with a value of'z'<br>
</font></tt></blockquote>

<p>
<h2><i>void</i> pointers</h2>
The type of pointer <i>void</i> is a special type of pointer.  <i>void</i> pointers
can point to any data type, from an integer value or a float to a string of characters.
Its sole limitation is that the pointed data cannot be referenced directly (we can not use
reference asterisk <TT>*</TT> operator on them), since its
length is always undetermined, and for that reason we will always have to resort
to <i>type casting</i> or assignations to turn our <i>void</i> pointer to a pointer
of a concrete data type to which we can refer.
<p>
One of its utilities may be for passing generic parameters to a function:

<P>
<CENTER>
<TABLE WIDTH=100% CELLPADDING=5 CELLSPACING=5><TR><TD BGCOLOR="#FFFFBF" WIDTH=50% VALIGN="top">
<TT><PRE><I>// integer increaser</I>
#include &lt;iostream.h&gt;

void increase (void* data, int type)
{
  switch (type)
  {
    case sizeof(char) : (*((char*)data))++; break;
    case sizeof(short): (*((short*)data))++; break;
    case sizeof(long) : (*((long*)data))++; break;
  }
}

int main ()
{
  char a = 5;
  short b = 9;
  long c = 12;
  increase (&a,sizeof(a));
  increase (&b,sizeof(b));
  increase (&c,sizeof(c));
  cout &lt;&lt; (int) a &lt;&lt; ", " &lt;&lt; b &lt;&lt; ", " &lt;&lt; c;
  return 0;
}
</PRE></TT>
</TD><TD BGCOLOR="silver" WIDTH=50% VALIGN="top">
<B><TT>6, 10, 13</TT></B>
</TD></TR></TABLE>
</CENTER>

<tt><b>sizeof</b></tt> is an operator integrated in the C++ language that returns a constant
value with the size in bytes of its parameter, so, for example,
<tt><b>sizeof(char)</b></tt> is <tt><b>1</b></tt>, because <TT><B>char</B></TT> type is
1 byte long.

<p>
<h2>Pointers to functions</h2>
C++ allows operations with pointers to functions. The greatest use of this is for
passing a function as a parameter to another function, since these cannot be passed
dereferenced. In order to declare a pointer to a function we must declare it like the
prototype of the function except the name of the function is enclosed between parenthesis 
<tt>()</tt> and a pointer asterisk (<tt>*</tt>) is inserted before the name.
It might not be a very handsome syntax, but that is how it is done in C++:
<P>
<CENTER>
<TABLE WIDTH=100% CELLPADDING=5 CELLSPACING=5><TR><TD BGCOLOR="#FFFFBF" WIDTH=50% VALIGN="top">
<TT><PRE><I>// pointer to functions</I>
#include &lt;iostream.h&gt;

int addition (int a, int b)
{ return (a+b); }

int subtraction (int a, int b)
{ return (a-b); }

int (*minus)(int,int) = subtraction;

int operation (int x, int y, int (*functocall)(int,int))
{
  int g;
  g = (*functocall)(x,y);
  return (g);
}

int main ()
{
  int m,n;
  m = operation (7, 5, addition);
  n = operation (20, m, minus);
  cout &lt;&lt;n;
  return 0;
}
</PRE></TT>
</TD><TD BGCOLOR="silver" WIDTH=50% VALIGN="top">
<B><TT>8</TT></B>
</TD></TR></TABLE>
</CENTER>

In the example, <tt><b>minus</b></tt> is a global pointer to a function that has two
parameters of type <tt><b>int</b></tt>, it is immediately assigned to point to
the function <tt><b>subtraction</b></tt>, all in a single line:
<blockquote><tt>int (* minus)(int,int) = subtraction;</tt></blockquote>

<!--cuatut-->
<P>
<CENTER><TABLE WIDTH=100% CELLPADDING=0 CELLSPACING=0 BORDER=0>
 <TR><TD BGCOLOR="#0000FF"><IMG SRC="head0.gif" WIDTH=2 HEIGHT=2></TD></TR>
 <TR><TD ALIGN="right"><FONT FACE="arial,helvetica" SIZE=1>&copy; The C++ Resources Network, 2000-2003 - All rights reserved</FONT></TD></TR>
</TABLE></CENTER>
<P>
<CENTER>
<TABLE CELLPADDING=0 WIDTH=100%>
<TR><TD ALIGN="right" WIDTH=45%><A HREF="tut3-2.html">
 <IMG SRC="butnback.gif" ALIGN="right" BORDER=0>
 Previous:<BR><B>3-2. Strings of characters.</B></A></TD>
<TD ALIGN="center" WIDTH=10%><A HREF="index.html">
 <IMG SRC="butnindx.gif" BORDER=0><BR>
 index</A></TD>
<TD ALIGN="left" WIDTH=45%><A HREF="tut3-4.html">
 <IMG SRC="butnnext.gif" ALIGN="left" BORDER=0>
 Next:<BR><B>3-4. Dynamic memory.</B></A>
</TD></TR></TABLE>
</CENTER>
<!--/cuatut-->

</body>
</html>

⌨️ 快捷键说明

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