* remove "\r" nonsense
[mascara-docs.git] / C / the.ansi.c.programming.language / c.programming.notes / sx10f.html
blob432b6801fbfcee484c3f0e91a21e4fd6a4afe6d4
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.6 Arrays and Pointers as Function Arguments</title>
10 <link href="sx10e.html" rev=precedes>
11 <link href="sx10g.html" rel=precedes>
12 <link href="sx10.html" rev=subdocument>
13 </head>
14 <body>
15 <H2>10.6 Arrays and Pointers as Function Arguments</H2>
17 <p>[This section corresponds to K&amp;R Sec. 5.2]
18 </p><p>Earlier, we learned that functions in C receive copies of their arguments.
19 (This means that C uses <dfn>call by value</dfn>;
20 it means that a function can modify one of its arguments
21 without modifying the value in the caller.)
22 We didn't say so at the time,
23 but when a function is called,
24 the copies of the arguments are made as if by assignment.
25 But since arrays can't be assigned,
26 how can a function receive an array as an argument?
27 The answer will explain why arrays are an apparent exception
28 to the rule that functions cannot modify their arguments.
29 </p><p>We've been regularly calling a function <TT>getline</TT> like this:
30 <pre>
31 char line[100];
32 getline(line, 100);
33 </pre>
34 with the intention that <TT>getline</TT> read
35 the next line of input into the character array <TT>line</TT>.
36 But in the previous paragraph,
37 we learned that when we mention the name of an array in an expression,
38 the compiler generates a pointer to its first element.
39 So the call above is as if we had written
40 <pre>
41 char line[100];
42 getline(&amp;line[0], 100);
43 </pre>
44 In other words, the <TT>getline</TT> function does <em>not</em> receive
45 an array of <TT>char</TT>
46 at all;
47 it actually receives a pointer to <TT>char</TT>!
48 </p><p>As we've seen throughout this chapter,
49 it's straightforward to manipulate the elements of an array using pointers,
50 so there's no particular insurmountable difficulty
51 if <TT>getline</TT> receives a pointer.
52 One question remains, though:
53 we had been defining <TT>getline</TT>
54 with its <TT>line</TT> parameter declared as an array:
55 <pre>
56 int getline(char line[], int max)
58 ...
60 </pre>
61 We mentioned that we didn't have to specify a size
62 for the <TT>line</TT> parameter,
63 with the explanation that <TT>getline</TT> really used
64 the array in its caller,
65 where the actual size was specified.
66 But that declaration certainly does look like an array--how
67 can it work when <TT>getline</TT> actually receives a pointer?
68 </p><p>The answer is that the C compiler does a little something behind your back.
69 It knows that whenever you mention an array name in an expression,
71 (the compiler)
72 generates a pointer to the array's first element.
73 Therefore, it knows that a function
74 can never actually receive an array as a parameter.
75 Therefore,
76 whenever it sees you defining a function that seems to accept
77 an array as a parameter,
78 the compiler quietly pretends that you had declared it
79 as accepting a pointer, instead.
80 The definition of <TT>getline</TT> above
81 is compiled exactly as if it had been written
82 <pre>
83 int getline(char *line, int max)
85 ...
87 </pre>
88 Let's look at how <TT>getline</TT> might be written
89 if we thought of its first parameter (argument)
90 as a pointer, instead:
91 <pre>
92 int getline(char *line, int max)
94 int nch = 0;
95 int c;
96 max = max - 1; /* leave room for '\0' */
98 #ifndef FGETLINE
99 while((c = getchar()) != EOF)
100 #else
101 while((c = getc(fp)) != EOF)
102 #endif
104 if(c == '\n')
105 break;
107 if(nch &lt; max)
109 *(line + nch) = c;
110 nch = nch + 1;
114 if(c == EOF &amp;&amp; nch == 0)
115 return EOF;
117 *(line + nch) = '\0';
118 return nch;
120 </pre>
121 But, as we've learned,
122 we can also use ``array subscript'' notation with pointers,
123 so we could rewrite the pointer version of <TT>getline</TT> like this:
124 <pre>
125 int getline(char *line, int max)
127 int nch = 0;
128 int c;
129 max = max - 1; /* leave room for '\0' */
131 #ifndef FGETLINE
132 while((c = getchar()) != EOF)
133 #else
134 while((c = getc(fp)) != EOF)
135 #endif
137 if(c == '\n')
138 break;
140 if(nch &lt; max)
142 line[nch] = c;
143 nch = nch + 1;
147 if(c == EOF &amp;&amp; nch == 0)
148 return EOF;
150 line[nch] = '\0';
151 return nch;
153 </pre>
154 But this is exactly what we'd written before
155 (see chapter 6, Sec. 6.3),
156 except that the declaration of the <TT>line</TT> parameter is different.
157 In other words,
158 within the body of the function,
159 it hardly matters whether
160 we thought
161 <TT>line</TT>
163 an array or a pointer,
164 since
165 we can use array subscripting notation with
166 both arrays and pointers.
167 </p><p>These games that the compiler is playing
168 with arrays and pointers
169 may seem bewildering at first,
170 and it may seem faintly miraculous
171 that everything comes out in the wash
172 when you declare a function like <TT>getline</TT>
173 that seems to accept an array.
174 The equivalence in C between arrays and pointers can be confusing,
175 but it <em>does</em> work and is one of the central features of C.
176 If the games which the compiler plays
177 (pretending that you declared a parameter as a pointer
178 when you thought you declared it as an array)
179 bother you,
180 you can do two things:
181 <OL><li>Continue to pretend that functions can receive arrays as parameters;
182 declare
183 and use
184 them that way,
185 but remember that unlike other arguments,
186 a function can modify the copy in its caller of an argument that
187 (seems to be)
188 an array.
189 <li>Realize that arrays are always passed to functions as pointers,
190 and always declare your functions as accepting pointers.
191 </OL>
192 </p><hr>
194 Read sequentially:
195 <a href="sx10e.html" rev=precedes>prev</a>
196 <a href="sx10g.html" rel=precedes>next</a>
197 <a href="sx10.html" rev=subdocument>up</a>
198 <a href="top.html">top</a>
199 </p>
201 This page by <a href="http://www.eskimo.com/~scs/">Steve Summit</a>
202 // <a href="copyright.html">Copyright</a> 1995, 1996
203 // <a href="mailto:scs@eskimo.com">mail feedback</a>
204 </p>
205 </body>
206 </html>