* remove "\r" nonsense
[mascara-docs.git] / C / the.ansi.c.programming.language / c.programming.notes / sx10a.html
blob5a07a8af62c91d136655a6fd2146bd54f0d06f8b
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.1 Basic Pointer Operations</title>
10 <link href="sx10.html" rev=precedes>
11 <link href="sx10b.html" rel=precedes>
12 <link href="sx10.html" rev=subdocument>
13 </head>
14 <body>
15 <H2>10.1 Basic Pointer Operations</H2>
17 <p>[This section corresponds to K&amp;R Sec. 5.1]
18 </p><p>The first things to do with pointers are to
19 declare a pointer variable,
20 set it to point somewhere,
21 and finally manipulate the value that it points to.
22 A simple pointer declaration looks like this:
23 <pre>
24 int *ip;
25 </pre>
26 This declaration looks like our earlier declarations,
27 with one obvious difference:
28 that asterisk.
29 The asterisk means that <TT>ip</TT>,
30 the variable we're declaring,
31 is not of type <TT>int</TT>,
32 but rather of type pointer-to-<TT>int</TT>.
33 (Another way of looking at it is that <TT>*ip</TT>,
34 which as we'll see is the value pointed to by <TT>ip</TT>,
35 will be an <TT>int</TT>.)
36 </p><p>We may think of setting a pointer variable to point to another variable
37 as a two-step process:
38 first we generate a pointer to that other variable,
39 then we assign this new pointer to the pointer variable.
40 We can say
41 (but we have to be careful when we're saying it)
42 that a pointer variable has a value,
43 and that its value is ``pointer to that other variable''.
44 This
46 will make more sense when we see how to generate pointer values.
47 </p><p>Pointers
48 (that is, pointer values)
49 are generated with the ``address-of''
50 operator <TT>&amp;</TT>,
51 which we can also think of as the
52 ``pointer-to'' operator.
53 We demonstrate this by declaring (and initializing)
54 an <TT>int</TT> variable <TT>i</TT>,
55 and then setting <TT>ip</TT> to point to it:
56 <pre>
57 int i = 5;
58 ip = &amp;i;
59 </pre>
60 The assignment expression
61 <TT>ip = &amp;i;</TT>
62 contains both parts of the ``two-step process'':
63 <TT>&amp;i</TT> generates a pointer to <TT>i</TT>,
64 and the assignment operator assigns the new pointer to
65 (that is, places it ``in'')
66 the variable <TT>ip</TT>.
67 Now <TT>ip</TT> ``points to'' <TT>i</TT>,
68 which we can illustrate with this picture:
69 <br>
70 <center><img src="p1.gif"></center>
71 <br>
72 <TT>i</TT> is a variable of type <TT>int</TT>,
73 so the value in its box is a number, 5.
74 <TT>ip</TT> is a variable of type pointer-to-<TT>int</TT>,
75 so the ``value'' in its box
76 is an arrow pointing at another box.
77 Referring once again back to the ``two-step process''
78 for setting a pointer variable:
79 the <TT>&amp;</TT> operator draws us the arrowhead
80 pointing at <TT>i</TT>'s box,
81 and the assignment operator <TT>=</TT>,
82 with the pointer variable <TT>ip</TT> on its left,
83 anchors the other end of the arrow in <TT>ip</TT>'s box.
84 </p><p>We discover the value pointed to by a pointer using the
85 ``contents-of'' operator, <TT>*</TT>.
86 Placed in front of a pointer,
87 the <TT>*</TT> operator accesses the value pointed to by that pointer.
88 In other words, if <TT>ip</TT> is a pointer,
89 then the expression <TT>*ip</TT> gives us whatever it is
90 that's in the variable or location pointed to by <TT>ip</TT>.
91 For example,
92 we could write something like
93 <pre>
94 printf("%d\n", *ip);
95 </pre>
96 which would print 5,
97 since <TT>ip</TT> points to <TT>i</TT>,
98 and <TT>i</TT> is
99 (at the moment)
101 </p><p>(You may wonder how the asterisk <TT>*</TT> can be the pointer
102 contents-of operator when it is also the multiplication operator.
103 There is no ambiguity here:
104 it is the multiplication operator
105 when it sits between two variables,
106 and it is the contents-of operator
107 when it sits in front of a single variable.
108 The situation is analogous to the minus sign:
110 between two variables or expressions it's the subtraction operator,
111 but in front of a single operator or expression it's the negation operator.
112 Technical terms you may hear for these distinct roles are
113 <dfn>unary</dfn> and <dfn>binary</dfn>:
114 a <dfn>binary</dfn> operator applies to two operands,
115 usually on either side of it,
116 while a <dfn>unary</dfn> operator applies to a single operand.)
117 </p><p>The contents-of operator <TT>*</TT> does not merely fetch values
118 through pointers;
119 it can also <em>set</em> values through pointers.
120 We can write something like
121 <pre>
122 *ip = 7;
123 </pre>
124 which means ``set whatever <TT>ip</TT> points to to 7.''
125 Again, the <TT>*</TT> tells us to go to the location pointed
126 to by <TT>ip</TT>, but this time, the location isn't the one
127 to fetch from--we're on the left-hand sign of an assignment
128 operator, so <TT>*ip</TT> tells us the location to store
129 <em>to</em>.
130 (The situation is no different from array subscripting
131 expressions such as <TT>a[3]</TT> which we've already seen
132 appearing on both sides of assignments.)
133 </p><p>The result
134 of the assignment <TT>*ip = 7</TT>
135 is that <TT>i</TT>'s value is changed to 7,
136 and the picture changes to:
137 <br>
138 <center><img src="p2.gif"></center>
139 <br>
140 If we called
141 <TT>printf("%d\n", *ip)</TT> again,
142 it would now print 7.
143 </p><p>At this point,
144 you may be wondering why we're going through this
145 rigamarole--if
146 we wanted to set <TT>i</TT> to 7,
147 why didn't we do it directly?
148 We'll begin to explore that next,
150 but first let's notice the difference between changing a pointer
151 (that is, changing what variable it points to)
152 and changing the value
153 at the location
154 it points to.
155 When we wrote <TT>*ip = 7</TT>,
156 we changed the value pointed to by <TT>ip</TT>,
157 but if we declare another variable <TT>j</TT>:
158 <pre>
159 int j = 3;
160 </pre>
161 and write
162 <pre>
163 ip = &amp;j;
164 </pre>
165 we've changed <TT>ip</TT> itself.
166 The picture now looks like this:
167 <br>
168 <center><img src="p3.gif"></center>
169 <br>
170 We have to be careful
171 when we say that a pointer assignment
172 changes ``what the pointer points to.''
173 Our earlier assignment
174 <pre>
175 *ip = 7;
176 </pre>
177 changed the value pointed to by <TT>ip</TT>,
178 but this more recent assignment
179 <pre>
180 ip = &amp;j;
181 </pre>
182 has changed what <em>variable</em> <TT>ip</TT> points to.
183 It's true that ``what <TT>ip</TT> points to'' has changed,
184 but this time,
185 it has changed for a different reason.
186 Neither <TT>i</TT> (which is still 7)
187 nor <TT>j</TT> (which is still 3)
188 has changed.
189 (What has changed is <TT>ip</TT>'s value.)
190 If we again call
191 <pre>
192 printf("%d\n", *ip);
193 </pre>
194 this time it will print 3.
195 </p><p>We can also assign pointer values to other pointer variables.
196 If we declare a second pointer variable:
197 <pre>
198 int *ip2;
199 </pre>
200 then we can say
201 <pre>
202 ip2 = ip;
203 </pre>
204 Now <TT>ip2</TT> points where <TT>ip</TT> does;
205 we've essentially made a ``copy'' of the arrow:
206 <br>
207 <center><img src="p4.gif"></center>
208 <br>
209 </p><p>Now,
210 if we set <TT>ip</TT> to point back to <TT>i</TT> again:
211 <pre>
212 ip = &amp;i;
213 </pre>
214 the two arrows point to different places:
215 <br>
216 <center><img src="p5.gif"></center>
217 <br>
218 </p><p>We can now see that the two assignments
219 <pre>
220 ip2 = ip;
221 </pre>
223 <pre>
224 *ip2 = *ip;
225 </pre>
226 do two very different things.
227 The first would make <TT>ip2</TT>
228 again point to where <TT>ip</TT> points
229 (in other words, back to <TT>i</TT> again).
230 The second would store,
231 at the location pointed to by <TT>ip2</TT>,
232 a copy of the value pointed to by <TT>ip</TT>;
233 in other words
234 (if <TT>ip</TT> and <TT>ip2</TT> still point to
235 <TT>i</TT> and <TT>j</TT> respectively)
236 it would set <TT>j</TT> to <TT>i</TT>'s value, or 7.
237 </p><p>It's important to keep very clear in your mind
238 the distinction between
239 <em>a pointer</em> and <em>what it points to</em>.
240 The two are like apples and oranges
241 (or perhaps oil and water);
242 you can't mix them.
243 You can't ``set <TT>ip</TT> to 5'' by writing something like
244 <pre>
245 ip = 5; /* WRONG */
246 </pre>
247 5 is an integer, but <TT>ip</TT> is a pointer.
248 You probably wanted to
249 ``set <em>the value pointed to by</em> <TT>ip</TT> to 5,''
250 which you express by writing
251 <pre>
252 *ip = 5;
253 </pre>
254 Similarly,
255 you can't ``see what <TT>ip</TT> is'' by writing
256 <pre>
257 printf("%d\n", ip); /* WRONG */
258 </pre>
259 Again, <TT>ip</TT> is a pointer-to-<TT>int</TT>,
260 but <TT>%d</TT> expects an <TT>int</TT>.
261 To print <em>what</em> <TT>ip</TT> <em>points to</em>,
263 <pre>
264 printf("%d\n", *ip);
265 </pre>
266 </p><p>Finally,
267 a few more notes about
268 pointer declarations.
269 The <TT>*</TT> in a pointer declaration is related to,
270 but different from,
271 the contents-of operator <TT>*</TT>.
272 After we declare a pointer variable
273 <pre>
274 int *ip;
275 </pre>
276 the expression
277 <pre>
278 ip = &amp;i
279 </pre>
280 sets what <TT>ip</TT> points to
281 (that is, which location it points to),
282 while the expression
283 <pre>
284 *ip = 5
285 </pre>
286 sets the value of the location pointed to by <TT>ip</TT>.
287 On the other hand,
288 if we declare a pointer variable and include an initializer:
289 <pre>
290 int *ip3 = &amp;i;
291 </pre>
292 we're setting the initial value for <TT>ip3</TT>,
293 which is where <TT>ip3</TT> will point,
294 so that initial value is a pointer.
295 (In other words, the <TT>*</TT> in the declaration
296 <TT>int *ip3 = &amp;i;</TT>
297 is not the contents-of operator,
298 it's the indicator that <TT>ip3</TT> is a pointer.)
299 </p><p>If you have a pointer declaration containing an initialization,
300 and you ever have occasion to break it up into a simple
301 declaration and a conventional assignment,
302 do it like this:
303 <pre>
304 int *ip3;
305 ip3 = &amp;i;
306 </pre>
307 Don't write
308 <pre>
309 int *ip3;
310 *ip3 = &amp;i;
311 </pre>
312 or you'll be trying to mix oil and water again.
313 </p><p>Also,
314 when we write
315 <pre>
316 int *ip;
317 </pre>
318 although the asterisk affects <TT>ip</TT>'s type,
319 it goes with the identifier name <TT>ip</TT>,
320 not with the type <TT>int</TT> on the left.
321 To declare two pointers at once,
322 the declaration looks like
323 <pre>
324 int *ip1, *ip2;
325 </pre>
326 Some people write pointer declarations like this:
327 <pre>
328 int* ip;
329 </pre>
330 This works for one pointer,
331 because C essentially ignores whitespace.
332 But if you ever write
333 <pre>
334 int* ip1, ip2; /* PROBABLY WRONG */
335 </pre>
336 it will declare one pointer-to-<TT>int</TT> <TT>ip1</TT>
337 and one <em>plain</em> <TT>int</TT> <TT>ip2</TT>,
338 which is probably not what you meant.
339 </p><p></p><p>What is all of this good for?
340 If it was just for changing variables like <TT>i</TT> from 5 to 7,
341 it would not be good for much.
342 What it's good for,
343 among other things,
344 is when for various
345 reasons we don't know exactly which variable we want to change,
346 just like the bank didn't know
347 exactly which club member it wanted to send the statement to.
348 </p><hr>
350 Read sequentially:
351 <a href="sx10.html" rev=precedes>prev</a>
352 <a href="sx10b.html" rel=precedes>next</a>
353 <a href="sx10.html" rev=subdocument>up</a>
354 <a href="top.html">top</a>
355 </p>
357 This page by <a href="http://www.eskimo.com/~scs/">Steve Summit</a>
358 // <a href="copyright.html">Copyright</a> 1995, 1996
359 // <a href="mailto:scs@eskimo.com">mail feedback</a>
360 </p>
361 </body>
362 </html>