📄 faqcatca65.html
字号:
whatis thedifference between arrays and pointers?</p><p><hr><p><font face=Helvetica size=8 color=blue><b>A:</b></font>An array is a single,preallocatedchunk of contiguous elements(all of the same type),fixed in size and location.A pointer is a reference to any data element(of a particular type)anywhere.A pointermust be assigned to point to space allocated elsewhere,but it can be reassigned(and the space, if derived from <TT>malloc</TT>, can be resized)at any time.A pointer can point to an array,and can simulate(along with <TT>malloc</TT>)a dynamically allocated array,but a pointer is a much more general data structure(see also question <a href="faqcatabdc.html?sec=ptrs#goodfor">4.1</a>).</p><p>Due to theso-calledequivalence of arrays and pointers(see question<a href="faqcatca65.html?sec=aryptr#aryptrequiv">6.3</a>),arrays and pointers often seem interchangeable,and in particular a pointer to a block of memoryassigned by <TT>malloc</TT> is frequently treated(and can be referencedusing <TT>[]</TT>)exactlyas if it were a true array.See questions<a href="faqcatca65.html?sec=aryptr#dynarray">6.14</a>and<a href="faqcatca65.html?sec=aryptr#dynmuldimary">6.16</a>.(Be careful with <TT>sizeof</TT>;see question <a href="faqcatbafd.html?sec=malloc#sizeof">7.28</a>.)</p><p>See alsoquestions <a href="faqcatd3c2.html?sec=decl#strlitinit">1.32</a>, <a href="faqcatca65.html?sec=aryptr#ptrkindofary">6.10</a>, and <a href="faqcat38c2.html?sec=misc#eff2">20.14</a>.<hr><hr><hr><a name="constptr"><h1>comp.lang.c FAQ list<font color=blue>·</font><a href="../../aryptr/constptr.html"><!-- qtag -->Question 6.9</a></h1><p><font face=Helvetica size=8 color=blue><b>Q:</b></font>Someone explained to me that arrays were really just constant pointers.</p><p><hr><p><font face=Helvetica size=8 color=blue><b>A:</b></font>Thisis a bit of an oversimplification.An array name is ``constant''in that it cannot be assigned to,but an array is<em>not</em>a pointer,as the discussion and pictures inquestion<a href="faqcatca65.html?sec=aryptr#aryptr2">6.2</a>should make clear.See alsoquestions <a href="faqcatca65.html?sec=aryptr#aryptrequiv">6.3</a>, <a href="faqcatca65.html?sec=aryptr#practdiff">6.8</a>, and <a href="faqcatca65.html?sec=aryptr#ptrkindofary">6.10</a>.<hr><hr><hr><a name="ptrkindofary"><h1>comp.lang.c FAQ list<font color=blue>·</font><a href="../../aryptr/ptrkindofary.html"><!-- qtag -->Question 6.10</a></h1><p><font face=Helvetica size=8 color=blue><b>Q:</b></font>I'm still mystified.Is a pointer a kind of array,or is an array a kind of pointer?</p><p><hr><p><font face=Helvetica size=8 color=blue><b>A:</b></font>An array is <em>not</em> a pointer,nor vice versa.An array <em>reference</em>(that is,any mention of an arrayin a value context),<em>turns into</em> a pointer(see questions <a href="faqcatca65.html?sec=aryptr#aryptr2">6.2</a>and <a href="faqcatca65.html?sec=aryptr#aryptrequiv">6.3</a>).</p><p>There are perhaps three ways to think about the situation:<OL><li>Pointers can simulate arrays(though that's not all;see question <a href="faqcatabdc.html?sec=ptrs#goodfor">4.1</a>).<li>There's hardly such a thing as an array(it is, after all, a ``second-class citizen'');the subscripting operator <TT>[]</TT> is in fact a pointer operator.<li>At a higher level of abstraction,a pointer to a block of memory iseffectively the sameas an array(though this says nothing about other uses of pointers).</OL></p><p>But, to reiterate, here are two ways <em>not</em> to think about it:<OL><li>4.``They're completely the same.''(False; see question <a href="faqcatca65.html?sec=aryptr#aryptr2">6.2</a>.)<li>5.``Arrays are constant pointers.''(False; see question <a href="faqcatca65.html?sec=aryptr#constptr">6.9</a>.)</OL></p><p>See also question <a href="faqcatca65.html?sec=aryptr#practdiff">6.8</a>.<hr><hr><hr><a name="joke"><h1>comp.lang.c FAQ list<font color=blue>·</font><a href="../../aryptr/joke.html"><!-- qtag -->Question 6.11</a></h1><p><font face=Helvetica size=8 color=blue><b>Q:</b></font>I came across some ``joke'' code containing the ``expression''<TT>5["abcdef"]</TT> .How can this be legal C?</p><p><hr><p><font face=Helvetica size=8 color=blue><b>A:</b></font>Yes,Virginia,array subscripting is commutative in C.<a href="../../aryptr/commutative.html" rel=subdocument>[footnote]</a>This curious fact follows from the pointer definition of arraysubscripting,namely that <TT>a[e]</TT> isidenticalto<TT>*((a)+(e))</TT>,for<em>any</em>two expressions <TT>a</TT> and <TT>e</TT>,as long as one of them is a pointer expressionand one is integral.The ``proof'' looks like<pre> a[e] *((a) + (e)) <I>(by definition)</I> *((e) + (a)) <I>(by commutativity of addition)</I> e[a] <I>(by definition)</I></pre></p><p>This unsuspected commutativity is often mentioned in C textsas if it were something to be proud of,but it finds no useful applicationoutside of the Obfuscated C Contest(see question<a href="faqcat38c2.html?sec=misc#ioccc">20.36</a>).</p><p>Since strings in C are arrays of <TT>char</TT>,the expression <TT>"abcdef"[5]</TT> is perfectly legal,and evaluates to the character <TT>'f'</TT>.You can think of itas a shorthand for<pre> char *tmpptr = "abcdef"; ... tmpptr[5] ...</pre>See question <a href="faqcat38c2.html?sec=misc#hexio">20.10</a> for a realistic example.</p><p>References:Rationale Sec. 3.3.2.1<br>H&S Sec. 5.4.1 p. 124, Sec. 7.4.1 pp. 186-7<hr><hr><hr><a name="aryvsadr"><h1>comp.lang.c FAQ list<font color=blue>·</font><a href="../../aryptr/aryvsadr.html"><!-- qtag -->Question 6.12</a></h1><p><font face=Helvetica size=8 color=blue><b>Q:</b></font>Since array references decay into pointers,if <TT>arr</TT> is an array,what'sthe difference between<TT>arr</TT> and <TT>&arr</TT>?</p><p><hr><p><font face=Helvetica size=8 color=blue><b>A:</b></font>The type.</p><p>InStandard C,<TT>&arr</TT> yields a pointer,of type pointer-to-array-of-T,to the entire array.(Inpre-ANSI C,the <TT>&</TT> in <TT>&arr</TT> generally elicited a warning,and was generallyignored.)Under all C compilers,asimplereference(without an explicit <TT>&</TT>)to an arrayyields a pointer,of type pointer-to-T,to the array's first element.</p><p>For a simple array<pre> int a[10];</pre>a reference to <TT>a</TT> has type ``pointer to <TT>int</TT>,''and <TT>&a</TT> is ``pointer to array of 10 <TT>int</TT>s.''For a two-dimensional array like<pre> int array[NROWS][NCOLUMNS];</pre>a reference to <TT>array</TT> has type``pointer to array of <TT>NCOLUMNS</TT> <TT>int</TT>s,''while <TT>&array</TT> has type``pointer to array of <TT>NROWS</TT> arrays of <TT>NCOLUMNS</TT> <TT>int</TT>s.''</p><p>Seealso questions<a href="faqcatca65.html?sec=aryptr#aryptrequiv">6.3</a>,<a href="faqcatca65.html?sec=aryptr#ptrtoarray">6.13</a>,and<a href="faqcatca65.html?sec=aryptr#pass2dary">6.18</a>.</p><p>References:ISO Sec. 6.2.2.1, Sec. 6.3.3.2<br>Rationale Sec. 3.3.3.2<br>H&S Sec. 7.5.6 p. 198<hr><hr><hr><a name="ptrtoarray"><h1>comp.lang.c FAQ list<font color=blue>·</font><a href="../../aryptr/ptrtoarray.html"><!-- qtag -->Question 6.13</a></h1><p><font face=Helvetica size=8 color=blue><b>Q:</b></font>How do I declare a pointer to an array?</p><p><hr><p><font face=Helvetica size=8 color=blue><b>A:</b></font>Usually, you don't want to.When people speak casually of a pointer to an array,they usually mean a pointer to its first element.</p><p>Instead of a pointer to an array,considerusing a pointer to one of the array's elements.Arrays of type T decay into pointers to type T(see question<a href="faqcatca65.html?sec=aryptr#aryptrequiv">6.3</a>),which is convenient;subscripting or incrementingthe resultant pointerwill accesstheindividual members of the array.True pointers to arrays, whensubscripted or incremented, stepover entire arrays(see below),and are generally useful only when operatingon arrays of arrays,<a href="../../aryptr/fn31.html" rel=subdocument>[footnote]</a>if at all.(Seealsoquestion<a href="faqcatca65.html?sec=aryptr#pass2dary">6.18</a>.)</p><p>If you really need to declare a pointer to an entire array,use something like``<TT>int (*ap)[N];</TT>''where <TT>N</TT> is the size of the array.(See also question<a href="faqcatd3c2.html?sec=decl#cdecl1">1.21</a>.)If the size of the array is unknown, <TT>N</TT> canin principlebe omitted,but the resulting type, ``pointer to array of unknown size,''is useless.</p><p>Here is an exampleshowing the difference betweensimple pointersandpointers to arrays.Given the declarations<pre>int a1[3] = {0, 1, 2};int a2[2][3] = {{3, 4, 5}, {6, 7, 8}};int *ip; /* pointer to int */int (*ap)[3]; /* pointer to array [3] of int */</pre>you could use the simple pointer-to-<TT>int</TT>,<TT>ip</TT>,to access the one-dimensional array <TT>a1</TT>:<pre> ip = a1; printf("%d ", *ip); ip++; printf("%d\n", *ip);</pre>This fragment would print<pre> 0 1</pre>An attempt to use a pointer-to-array,<TT>ap</TT>,on<TT>a1</TT>:<pre> ap = &a1; printf("%d\n", **ap); ap++; /* WRONG */ printf("%d\n", **ap); /* undefined */</pre>would print <TT>0</TT> on the first lineand something undefined on the second(and might crash).The pointer-to-arraywould only be at all useful in accessingan array of arrays,such as <TT>a2</TT>:<pre> ap = a2; printf("%d %d\n", (*ap)[0], (*ap)[1]); ap++; /* steps over entire (sub)array */ printf("%d %d\n", (*ap)[0], (*ap)[1]);</pre>This last fragmentwould print<pre> 3 4 6 7</pre></p><p>See also question <a href="faqcatca65.html?sec=aryptr#aryvsadr">6.12</a>.</p><p>Additional links:<a href="faqcatca65.html?sec=aryptr#ptrary2">further reading</a></p><p>References:ISO Sec. 6.2.2.1<hr><hr><hr><a name="dynarray"><h1>comp.lang.c FAQ list<font color=blue>·</font><a href="../../aryptr/dynarray.html"><!-- qtag -->Question 6.14</a></h1><p><font face=Helvetica size=8 color=blue><b>Q:</b></font>How can I set an array's size at run time?<br>How can I avoidfixed-sized arrays?</p><p><hr><p><font face=Helvetica size=8 color=blue><b>A:</b></font>The equivalence between arrays and pointers(see question <a href="faqcatca65.html?sec=aryptr#aryptrequiv">6.3</a>)allows a pointer to <TT>malloc</TT>'ed memoryto simulate an arrayquite effectively.After executing<pre> #include <stdlib.h> int *dynarray; dynarray = malloc(10 * sizeof(int));</pre>(and if the call to <TT>malloc</TT> succeeds),you can reference <TT>dynarray[i]</TT>(for <TT>i</TT> from 0 to 9)almostas if <TT>dynarray</TT> were a conventional,statically-allocated array(<TT>int a[10]</TT>).The only difference is that<TT>sizeof</TT> will notgive the size of the ``array''(see question <a href="faqcatbafd.html?sec=malloc#sizeof">7.28</a>.See alsoquestions <a href="faqcatd3c2.html?sec=decl#fcninit">1.31b</a>, <a href="faqcatca65.html?sec=aryptr#dynmuldimary">6.16</a>, <a href="faqcatbafd.html?sec=malloc#cast">7.7</a>, and <a href="faqcatbafd.html?sec=malloc#realloc">7.29</a>.<hr><hr><hr><a name="dynlocarys"><h1>comp.lang.c FAQ list<font color=blue>·</font><a href="../../aryptr/dynlocarys.html"><!-- qtag -->Question 6.15</a></h1><p><font face=Helvetica size=8 color=blue><b>Q:</b></font>How can I declare local arrays of a size matching a passed-in array?</p><p><hr><p><font face=Helvetica size=8 color=blue><b>A:</b></font>Until recently, youcouldn't; arraydimensionsin Ctraditionallyhad to becompile-time constants.However,C99 introducesvariable-length arrays(VLA's)which solve this problem;local arrays may have sizes set by variables or other expressions,perhaps involving function parameters.(<TT>gcc</TT>has provided parameterized arraysas an extensionfor some time.)If you can't use C99 or <TT>gcc</TT>,you'llhave to use <TT>malloc</TT>,and remember to call <TT>free</TT> before the function returns.See also questions<a href="faqcatca65.html?sec=aryptr#dynarray">6.14</a>,<a href="faqcatca65.html?sec=aryptr#dynmuldimary">6.16</a>,<a href="faqcatca65.html?sec=aryptr#ary2dfunc2">6.19</a>,<a href="faqcatbafd.html?sec=malloc#local">7.22</a>,and maybe <a href="faqcatbafd.html?sec=malloc#alloca">7.32</a>.</p><p>References:ISO Sec. 6.4, Sec. 6.5.4.2<br>C9X Sec. 6.5.5.2<hr><hr><hr><a name="dynmuldimary"><h1>comp.lang.c FAQ list<font color=blue>·</font><a href="../../aryptr/dynmuldimary.html"><!-- qtag -->Question 6.16</a></h1><p><font face=Helvetica size=8 color=blue><b>Q:</b></font>How can I dynamically allocate a multidimensional array?</p><p><hr><p><font face=Helvetica size=8 color=blue><b>A:</b></font>The traditional solution isto allocatean array<a href="../../aryptr/arraysim.html" rel=subdocument>[footnote]</a>ofpointers topointers,and theninitializeeach pointertoa dynamically-allocated``row.''Here is a two-dimensional example:<pre> #include <stdlib.h> int **array1 = malloc(nrows * sizeof(int *)); for(i = 0; i < nrows; i++) array1[i] = malloc(ncolumns * sizeof(int));</pre>(In real code, of course,all of <TT>malloc</TT>'s return values would be checked.You can also use<TT>sizeof(*array1)</TT> and <TT>sizeof(**array1)</TT>instead of<TT>sizeof(int *)</TT> and <TT>sizeof(int)</TT>;see <a href="../../aryptr/fn33.html" rel=subdocument>[footnote]</a>.)</p><p>You can keep the array's contents contiguous,at the cost ofmaking later reallocation of individual rows more difficult,with a bit of explicit pointer arithmetic:<pre> int **array2 = malloc(nrows * sizeof(int *)); array2[0] = malloc(nrows * ncolumns * sizeof(int)); for(i = 1; i < nrows; i++) array2[i] = array2[0] + i * ncolumns;</pre>In either case(i.e for <TT>array1</TT> or <TT>array2</TT>),the elements of the dynamic array can be accessedwith normal-looking array subscripts:<TT>arrayx[i][j]</TT>(for 0 <= <TT>i</TT> < <TT>nrows</TT> and0 <= <TT>j</TT> < <TT>ncolumns</TT>).Here isa schematic illustrationof the layout of <TT>array1</TT> and <TT>array2</TT>:<br><br><img src="../../aryptr/array1.gif"><br><br><img src="../../aryptr/array2.gif"><p>If the double indirection implied by the above schemes is forsome reason unacceptable,<a href="../../aryptr/doubleindir.html" rel=subdocument>[footnote]</a>you can simulate a two-dimensionalarray with a single, dynamically-allocated one-dimensional array:<pre> int *array3 = malloc(nrows * ncolumns * sizeof(int));</pre>However, you must now perform subscript calculations manually,accessing the <TT>i</TT>,<TT>j</TT>th element withthe expression<pre><TT>array3[i * ncolumns + j]</TT></pre>and this array cannotnecessarilybepassed to functionswhich expectmultidimensional arrays.(A macrosuch as<pre>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -