* better
[mascara-docs.git] / lang / C / the.ansi.c.programming.language / c.programming.notes / sx10b.html
bloba449702f8804e7b4859e0e0c898a67392b1dbdd4
1 <!DOCTYPE HTML PUBLIC "-//W3O//DTD W3 HTML 2.0//EN">
2 <!-- This collection of hypertext pages is Copyright 1995, 1996 by Steve Summit. -->
3 <!-- This material may be freely redistributed and used -->
4 <!-- but may not be republished or sold without permission. -->
5 <html>
6 <head>
7 <link rev="owner" href="mailto:scs@eskimo.com">
8 <link rev="made" href="mailto:scs@eskimo.com">
9 <title>10.2 Pointers and Arrays; Pointer Arithmetic</title>
10 <link href="sx10a.html" rev=precedes>
11 <link href="sx10c.html" rel=precedes>
12 <link href="sx10.html" rev=subdocument>
13 </head>
14 <body>
15 <H2>10.2 Pointers and Arrays; Pointer Arithmetic</H2>
17 <p>[This section corresponds to K&amp;R Sec. 5.3]
18 </p><p>Pointers do not have to point to single variables.
19 They can also point at the cells of an array.
20 For example, we can write
21 <pre>
22 int *ip;
23 int a[10];
24 ip = &amp;a[3];
25 </pre>
26 and we would end up with
27 <TT>ip</TT> pointing at the fourth cell of the array <TT>a</TT>
28 (remember, arrays are 0-based, so <TT>a[0]</TT> is the first cell).
29 We could illustrate the situation like this:
30 <br>
31 <center><img src="p6.gif"></center>
32 <br>
33 We'd use this <TT>ip</TT> just like the one in the previous section:
34 <TT>*ip</TT> gives us what <TT>ip</TT> points to,
35 which in this case will be the value in <TT>a[3]</TT>.
36 </p><p>Once we have a pointer pointing into an array,
37 we can start doing <dfn>pointer arithmetic</dfn>.
38 Given that <TT>ip</TT> is a pointer to <TT>a[3]</TT>,
39 we can add 1 to <TT>ip</TT>:
40 <pre>
41 ip + 1
42 </pre>
43 What does it mean to add one to a pointer?
44 In C,
45 it gives a pointer to the cell one farther on,
46 which in this case is <TT>a[4]</TT>.
47 To make this clear,
48 let's
49 assign this new pointer to another pointer variable:
50 <pre>
51 ip2 = ip + 1;
52 </pre>
53 Now the picture looks like this:
54 <br>
55 <center><img src="p7.gif"></center>
56 <br>
57 If we now do
58 <pre>
59 *ip2 = 4;
60 </pre>
61 we've set <TT>a[4]</TT> to 4.
62 But it's not necessary to assign a new pointer value to a pointer variable
63 in order to use it;
64 we could also compute a new pointer value and
65 use it immediately:
66 <pre>
67 *(ip + 1) = 5;
68 </pre>
69 In this last example,
70 we've changed <TT>a[4]</TT> again,
71 setting it to 5.
72 The parentheses are needed
73 because the unary ``contents of'' operator <TT>*</TT>
74 has higher <dfn>precedence</dfn>
75 (i.e., binds more tightly than)
76 the addition operator.
77 If we wrote <TT>*ip + 1</TT>,
78 without the parentheses,
79 we'd be fetching the value pointed to by <TT>ip</TT>,
80 and adding 1 to that value.
81 The expression <TT>*(ip + 1)</TT>,
82 on the other hand,
83 accesses the value one past the one pointed to by <TT>ip</TT>.
84 </p><p>Given that we can add 1 to a pointer,
85 it's not surprising
86 that we can add and subtract other numbers as well.
87 If <TT>ip</TT> still points to <TT>a[3]</TT>, then
88 <pre>
89 *(ip + 3) = 7;
90 </pre>
91 sets <TT>a[6]</TT> to 7, and
92 <pre>
93 *(ip - 2) = 4;
94 </pre>
95 sets <TT>a[1]</TT> to 4.
96 </p><p>Up above,
97 we added 1 to <TT>ip</TT> and assigned the new pointer to <TT>ip2</TT>,
98 but there's no reason we can't add one to a pointer,
99 and change the same pointer:
100 <pre>
101 ip = ip + 1;
102 </pre>
103 Now <TT>ip</TT> points one past where it used to
104 (to <TT>a[4]</TT>, if we hadn't changed it in the meantime).
105 The shortcuts we learned in a previous chapter
106 all work for pointers, too:
107 we could also increment a pointer using
108 <pre>
109 ip += 1;
110 </pre>
112 <pre>
113 ip++;
114 </pre>
115 </p><p>Of course, pointers are not limited to <TT>int</TT>s.
116 It's quite common to use pointers to other types,
117 especially <TT>char</TT>.
118 Here is the innards of the <TT>mystrcmp</TT> function
119 we saw in a previous chapter,
120 rewritten to use pointers.
121 (<TT>mystrcmp</TT>,
122 you may recall,
123 compares two strings, character by character.)
124 <pre>
125 char *p1 = &amp;str1[0], *p2 = &amp;str2[0];
127 while(1)
129 if(*p1 != *p2)
130 return *p1 - *p2;
131 if(*p1 == '\0' || *p2 == '\0')
132 return 0;
133 p1++;
134 p2++;
136 </pre>
137 </p><p>The autoincrement operator <TT>++</TT>
138 (like its companion, <TT>--</TT>)
139 makes it easy to do two things at once.
140 We've seen idioms like <TT>a[i++]</TT>
141 which accesses <TT>a[i]</TT> and simultaneously increments <TT>i</TT>,
142 leaving it referencing the next cell of the array <TT>a</TT>.
143 We can do the same thing with pointers:
144 an expression like <TT>*ip++</TT>
145 lets us access what <TT>ip</TT> points to,
146 while simultaneously incrementing <TT>ip</TT>
147 so that it points to the next element.
148 The preincrement form works, too:
149 <TT>*++ip</TT> increments <TT>ip</TT>,
150 then accesses what it points to.
151 Similarly,
152 we can use notations like <TT>*ip--</TT> and <TT>*--ip</TT>.
153 </p><p>As another example,
154 here is the <TT>strcpy</TT>
155 (string copy)
156 loop from a previous chapter,
157 rewritten to use pointers:
158 <pre>
159 char *dp = &amp;dest[0], *sp = &amp;src[0];
160 while(*sp != '\0')
161 *dp++ = *sp++;
162 *dp = '\0';
163 </pre>
164 </p><p>(One question that comes up
165 is whether the expression <TT>*p++</TT>
166 increments <TT>p</TT> or what it points to.
167 The answer is that it increments
168 <TT>p</TT>.
171 increment what <TT>p</TT> points to,
172 you can use <TT>(*p)++</TT>.)
173 </p><p>When you're doing pointer arithmetic,
174 you have to remember how big the array the pointer points into is,
175 so that you don't ever point outside it.
176 If the array <TT>a</TT> has 10 elements,
177 you can't access <TT>a[50]</TT> or <TT>a[-1]</TT> or even <TT>a[10]</TT>
178 (remember,
179 the valid subscripts for a 10-element array run from 0 to 9).
180 Similarly, if <TT>a</TT> has 10 elements and <TT>ip</TT> points to <TT>a[3]</TT>,
181 you can't compute or access <TT>ip + 10</TT> or <TT>ip - 5</TT>.
182 (There is one special case:
184 you can,
185 in this case,
186 compute, but not access,
187 a pointer to the nonexistent element just beyond the end of the array,
188 which in this case is <TT>&amp;a[10]</TT>.
189 This becomes useful when you're doing pointer comparisons,
190 which we'll look at next.)
191 </p><hr>
193 Read sequentially:
194 <a href="sx10a.html" rev=precedes>prev</a>
195 <a href="sx10c.html" rel=precedes>next</a>
196 <a href="sx10.html" rev=subdocument>up</a>
197 <a href="top.html">top</a>
198 </p>
200 This page by <a href="http://www.eskimo.com/~scs/">Steve Summit</a>
201 // <a href="copyright.html">Copyright</a> 1995, 1996
202 // <a href="mailto:scs@eskimo.com">mail feedback</a>
203 </p>
204 </body>
205 </html>