* X more docs for C
[mascara-docs.git] / C / the.ansi.c.programming.language / c.programming.notes.int / sx9a.html
blobdefa80a9e8629e8c63df00b8173a3566e9845e07
1 <!DOCTYPE HTML PUBLIC "-//W3O//DTD W3 HTML 2.0//EN">
2 <!-- This collection of hypertext pages is Copyright 1995-7 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>23.1: Multidimensional Arrays and Functions</title>
10 <link href="sx9.html" rev=precedes>
11 <link href="sx9b.html" rel=precedes>
12 <link href="sx9.html" rev=subdocument>
13 </head>
14 <body>
15 <H2>23.1: Multidimensional Arrays and Functions</H2>
17 <p>The most straightforward way of passing a multidimensional array to a function
18 is to declare it in exactly the same way in the function as it
19 was declared in the caller.
20 If we were to call
21 <pre>
22 func(a2);
23 </pre>
24 then we might declare
25 <pre>
26 func(int a[5][7])
28 ...
30 </pre>
31 and it's clear that the array type which the caller passes
32 is the same as the type which the function <TT>func</TT> accepts.
33 </p><p>If we remember what we learned about simple arrays and functions, however,
34 two questions arise.
35 First, in our earlier function definitions, we were able to
36 leave out the (single) array dimension, with the understanding
37 that since the array was really defined in the caller, we didn't
38 have to say (or know) how big it is.
39 The situation is
40 the same
41 for multidimensional arrays,
42 although it may not seem so at first.
43 The hypothetical function <TT>func</TT> above
44 accepts a parameter <TT>a</TT>,
45 where <TT>a</TT> is an array of 5 things,
46 where each of the 5 things is itself an array.
47 By the same argument that applies in the single-dimension case,
48 the function does not have to know how big the array <TT>a</TT> is,
49 overall.
50 However, it certainly does need to know what <TT>a</TT> is an array <em>of</em>.
51 It is not enough to know that <TT>a</TT> is an array of
52 ``other arrays'';
53 the function
54 must know
55 that <TT>a</TT> is an array of
56 <em>arrays of 7 </em><TT>int</TT><em>s</em>.
57 The upshot is that although it does not need to know
58 how many ``rows'' the array has,
59 it <em>does</em> need to know the number of columns.
60 That is, if we want to leave out any dimensions, we can only
61 leave out the first one:
62 <pre>
63 func(int a[][7])
65 ...
67 </pre>
68 The second dimension is still required.
69 (For a three- or more dimensional array,
70 all but the first dimension are required;
71 again,
72 only the first dimension
73 may be omitted.)
74 </p><p>The second question we might ask concerns the equivalence between
75 pointers and arrays.
76 We know that when we pass an array to a function,
77 what really gets passed is a pointer to the array's first element.
78 We know that when we declare a function that seems to accept an
79 array as a parameter,
80 the compiler quietly compiles the function as if that parameter
81 were a pointer,
82 since a pointer is what it will actually receive.
83 What about multidimensional arrays?
84 What kind of pointer is passed down to the function?
85 </p><p>The answer is, a pointer to the array's first element.
86 And, since the first element of a multidimensional array is
87 another array,
88 what gets passed to the function is a <em>pointer to an array</em>.
89 If you want to declare the function <TT>func</TT> in a way that
90 explicitly shows the type which it receives, the declaration
91 would be
92 <pre>
93 func(int (*a)[7])
95 ...
97 </pre>
98 The declaration <TT>int (*a)[7]</TT> says that <TT>a</TT> is a
99 pointer to an array of 7 <TT>int</TT>s.
100 Since declarations like this are hard to write and hard to
101 understand,
102 and since pointers to arrays are generally confusing,
103 I recommend that when you write functions which accept
104 multidimensional arrays,
105 you declare the parameters using array notation,
106 not pointer notation.
107 </p><p>What if you don't know what the dimensions of the array will be?
108 What if you want to be able to call a function with arrays of
109 different sizes and shapes?
110 Can you say something like
111 <pre>
112 func(int x, int y, int a[x][y])
116 </pre>
117 where the array dimensions are specified by other parameters to
118 the function?
119 Unfortunately, in C, you cannot.
120 (You can do so in FORTRAN, and you can do so in the extended
121 language implemented by <TT>gcc</TT>,
122 and you will be able to do so in the new version of the C Standard
123 (``C9X'')
124 to be completed in 1999,
125 but you cannot do so in standard, portable C,
126 today.)
127 </p><p>Finally, we might explicitly note that if we pass a
128 multidimensional array to a function:
129 <pre>
130 int a2[5][7];
131 func(a2);
132 </pre>
133 we can <em>not</em> declare that function as accepting a
134 pointer-to-pointer:
135 <pre>
136 func(int **a) /* WRONG */
140 </pre>
141 As we said above, the function ends up receiving a pointer to an array,
142 not a pointer to a pointer.
143 </p><hr>
145 Read sequentially:
146 <a href="sx9.html" rev=precedes>prev</a>
147 <a href="sx9b.html" rel=precedes>next</a>
148 <a href="sx9.html" rev=subdocument>up</a>
149 <a href="top.html">top</a>
150 </p>
152 This page by <a href="http://www.eskimo.com/~scs/">Steve Summit</a>
153 // <a href="copyright.html">Copyright</a> 1996-1999
154 // <a href="mailto:scs@eskimo.com">mail feedback</a>
155 </p>
156 </body>
157 </html>