📄 faqcatabdc.html
字号:
</p><p>To make the code fragment above work,you'd have to use an intermediate <TT>void *</TT> variable:<pre> double *dp; void *vp = dp; f(&vp); dp = vp;</pre>The assignments to and from <TT>vp</TT>give the compiler the opportunity to perform any conversions,if necessary.</p><p>Again,the discussion so far assumes that different pointer typesmight have different sizes or representations,which is rare today,but not unheard of.Toappreciate theproblem with <TT>void **</TT> more clearly,compare the situation to an analogous one involving, say,types <TT>int</TT> and <TT>double</TT>,which probably have different sizesand certainly have different representations.If we have a function<pre> void incme(double *p) { *p += 1; }</pre>then we can do something like<pre> int i = 1; double d = i; incme(&d); i = d;</pre>and <TT>i</TT> will be incremented by 1.(This is analogous to the correct <TT>void **</TT> code involving the auxiliary <TT>vp</TT>.)If, on the other hand,we were to attempt something like<pre> int i = 1; incme((double *)&i); /* WRONG */</pre>(this code is analogous to the fragment in the question),it would be highly unlikely to work.<hr><hr><hr><a name="refconst"><h1>comp.lang.c FAQ list<font color=blue>·</font><a href="../../ptrs/refconst.html"><!-- qtag -->Question 4.10</a></h1><p><font face=Helvetica size=8 color=blue><b>Q:</b></font>I have a function<pre> extern int f(int *);</pre>which accepts a pointer to an <TT>int</TT>.How can I pass a constantby reference?A call like<pre> f(&5);</pre>doesn't seem to work.</p><p><hr><p><font face=Helvetica size=8 color=blue><b>A:</b></font>In C99, you can use a ``compound literal'':<pre> f((int[]){5});</pre></p><p>Prior to C99,you couldn'tdothisdirectly;you had todeclare a temporary variable,and then pass its address to the function:<pre> int five = 5; f(&five);</pre>In C, a function that accepts a pointer to a value(rather thansimplyacceptingthe value itself)probably intends to modify the pointed-to value,so it may be a bad idea to pass pointers to constants.<a href="../../ptrs/fn17.html" rel=subdocument>[footnote]</a>Indeed,if <TT>f</TT> is in fact declared as accepting an <TT>int *</TT>,a diagnostic is required if you attempt to pass it a pointer to a <TT>const int</TT>.(<TT>f</TT> could be declared as accepting a<TT>const int *</TT> if it promises not to modify the pointed-to value.)</p><p>See also questions <a href="faqcat6b6b.html?sec=struct#anonstruct">2.10</a>,<a href="faqcatabdc.html?sec=ptrs#passptrinit">4.8</a>,and<a href="faqcat38c2.html?sec=misc#multretval">20.1</a>.<hr><hr><hr><a name="passbyref"><h1>comp.lang.c FAQ list<font color=blue>·</font><a href="../../ptrs/passbyref.html"><!-- qtag -->Question 4.11</a></h1><p><font face=Helvetica size=8 color=blue><b>Q:</b></font>Does C even have ``pass by reference''?</p><p><hr><p><font face=Helvetica size=8 color=blue><b>A:</b></font>Not really.</p><p>Strictly speaking, C always uses pass by value.You can simulate pass by reference yourself,by defining functions which accept pointersand then using the <TT>&</TT> operator when calling,andthecompiler willessentiallysimulate itfor you when you pass an array to a function(by passing a pointer instead,see question <a href="faqcatca65.html?sec=aryptr#aryptrparam">6.4</a> et al.).</p><p>Another way of looking at it is thatif an parameter has type, say, <TT>int *</TT>then an integer is being passed by referenceand a pointer to an integer is being passed by value.</p><p>Fundamentally,C has nothing trulyequivalent to formal pass by referenceor C++ reference parameters.(On the other hand,function-like preprocessor macroscanprovide a form of ``pass by name''.)</p><p>See alsoquestions <a href="faqcatabdc.html?sec=ptrs#passptrinit">4.8</a>, <a href="faqcatbafd.html?sec=malloc#mymallocretp">7.9</a>, <a href="faqcat1d60.html?sec=stdio#fopenfp">12.27</a>, and <a href="faqcat38c2.html?sec=misc#multretval">20.1</a>.</p><p>Additional links:A<a href="faqcatabdc.html?sec=ptrs#passbyref2">message of mine</a>further explaining how a function can modify a caller's passed array.</p><p>References:K&R1 Sec. 1.8 pp. 24-5, Sec. 5.2 pp. 91-3<br>K&R2 Sec. 1.8 pp. 27-8, Sec. 5.2 pp. 95-7<br>ISO Sec. 6.3.2.2<br>H&S Sec. 9.5 pp. 273-4<hr><hr><hr><a name="funccall"><h1>comp.lang.c FAQ list<font color=blue>·</font><a href="../../ptrs/funccall.html"><!-- qtag -->Question 4.12</a></h1><p><font face=Helvetica size=8 color=blue><b>Q:</b></font>I've seen different syntax used for calling functions via pointers.What's the story?</p><p><hr><p><font face=Helvetica size=8 color=blue><b>A:</b></font>Originally, a pointer to a function had to be``turned into'' a ``real''function,with the <TT>*</TT> operator,before calling:<pre> int r, (*fp)(), func(); fp = func; r = (*fp)();</pre>The interpretation of thelast line is clear:<TT>fp</TT> is a pointer to function,so <TT>*fp</TT> is the function;append an argument list in parentheses(and extra parentheses around <TT>*fp</TT> to get the precedence right),and you've got a function call.</p><p>It can also be arguedthat functions are always called via pointers,andthat ``real'' functionnamesalwaysdecay implicitly into pointers(in expressions, as they do in initializations;see question <a href="faqcatd3c2.html?sec=decl#ptrfuncinit">1.34</a>).This reasoningmeans that<pre> r = fp();</pre>is legal and works correctly,whether <TT>fp</TT> isthe name ofa function or a pointer to one.(The usage has always been unambiguous;there is nothing you ever could have done with a function pointerfollowed by an argument listexcept callthe function pointed to.)</p><p>The ANSI C Standard essentially adopts the latter interpretation,meaning that theexplicit <TT>*</TT> isnot required,though it isstill allowed.</p><p>See also question <a href="faqcatd3c2.html?sec=decl#ptrfuncinit">1.34</a>.</p><p>References:K&R1 Sec. 5.12 p. 116<br>K&R2 Sec. 5.11 p. 120<br>ISO Sec. 6.3.2.2<br>Rationale Sec. 3.3.2.2<br>H&S Sec. 5.8 p. 147, Sec. 7.4.3 p. 190<hr><hr><hr><a name="generic"><h1>comp.lang.c FAQ list<font color=blue>·</font><a href="../../ptrs/generic.html"><!-- qtag -->Question 4.13</a></h1><p><font face=Helvetica size=8 color=blue><b>Q:</b></font>What's the total generic pointer type?My compiler complainedwhen I tried to stuff function pointers into a <TT>void *</TT>.</p><p><hr><p><font face=Helvetica size=8 color=blue><b>A:</b></font>Thereis no``total generic pointer type.''</p><p><TT>void *</TT>'s are only guaranteed to hold object(i.e. data)pointers;it is not portable to convert a function pointer totype<TT>void *</TT>.(On some machines, function addressescan be very large,biggerthan anydata pointers.)</p><p>It is guaranteed,however,that all function pointerscan be interconverted,as long as they are converted backto an appropriate type before calling.Therefore,you can pick any function type(usually <TT>int (*)()</TT>or <TT>void (*)()</TT>,that is,pointer to functionof unspecified argumentsreturning <TT>int</TT> or <TT>void</TT>)as a generic function pointer.When you needa placeto hold object and function pointers interchangeably,the portable solution is to use a union of a<TT>void *</TT>and ageneric function pointer(of whichever type you choose).</p><p>See also questions <a href="faqcatd3c2.html?sec=decl#recurfuncp">1.22</a>and <a href="faqcat1f1a.html?sec=null#fcnptr">5.8</a>.</p><p>References:ISO Sec. 6.1.2.5, Sec. 6.2.2.3, Sec. 6.3.4<br>Rationale Sec. 3.2.2.3<br>H&S Sec. 5.3.3 p. 123<hr><hr><hr><a name="int2ptr"><h1>comp.lang.c FAQ list<font color=blue>·</font><a href="../../ptrs/int2ptr.html"><!-- qtag -->Question 4.14</a></h1><p><font face=Helvetica size=8 color=blue><b>Q:</b></font>How are integers converted to and from pointers?Can I temporarily stuff an integer into a pointer,or vice versa?</p><p><hr><p><font face=Helvetica size=8 color=blue><b>A:</b></font>Once upon a time,it was guaranteed that a pointer could be converted to an integer(though one never knewwhether an <TT>int</TT> or a <TT>long</TT> might be required),and that an integer could be converted to a pointer,and that a pointer remained unchanged when converted to a (large enough)integer and back again,andthat the conversions(and anymapping)were intended to be``unsurprising to those who know the addressing structure of the machine.''In other words,there issomeprecedent andsupport forinteger/pointerconversions,buttheyhave always been machine dependent,and hence nonportable.Explicit casts have always been required(though early compilers rarely complained if you left them out).</p><p>The ANSI/ISO C Standard,in order to ensure that C is widely implementable,hasweakenedthose earlier guarantees.Pointer-to-integer and integer-to-pointer conversionsare implementation-defined(see question <a href="faqcat7d4b.html?sec=ansi#undef">11.33</a>),andthereis no longer any guarantee that pointers can be converted to integers and back, without change.</p><p>Forcingpointers into integers,or integers into pointers,has never been good practice.When you need a generic slot that can hold eitherkind of data,a union is a much betteridea.</p><p>See also questions<a href="faqcatabdc.html?sec=ptrs#int2charp">4.15</a>,<a href="faqcat1f1a.html?sec=null#runtime0">5.18</a>,and <a href="faqcatea63.html?sec=osdep#rawmemadr">19.25</a>.</p><p>References:K&R1 Sec. A14.4 p. 210<br>K&R2 Sec. A6.6 p. 199<br>ISO Sec. 6.3.4<br>Rationale Sec. 3.3.4<br>H&S Sec. 6.2.3 p. 170, Sec. 6.2.7 pp. 171-2<hr><hr><hr><a name="int2charp"><h1>comp.lang.c FAQ list<font color=blue>·</font><a href="../../ptrs/int2charp.html"><!-- qtag -->Question 4.15</a></h1><p><font face=Helvetica size=8 color=blue><b>Q:</b></font>How do I convert an <TT>int</TT> to a <TT>char *</TT>?I tried a cast, but it's not working.</p><p><hr><p><font face=Helvetica size=8 color=blue><b>A:</b></font>It dependson what you're trying to do.If you tried a castbut it's not working,you're probably trying to convert an integer to a string,in which casesee question <a href="faqcat1067.html?sec=lib#itoa">13.1</a>.If you're trying to convert an integer to a character,see question <a href="faqcate107.html?sec=charstring#asciivals">8.6</a>.If you're trying to set a pointer to pointtoa particular memoryaddress,see question <a href="faqcatea63.html?sec=osdep#rawmemadr">19.25</a>.<hr><hr><hr><a name="charstarws3"><h1>comp.lang.c FAQ list<font color=blue>·</font><a href="../../ptrs/charstarws3.html"><!-- qtag -->Question 4.16</a></h1><p><font face=Helvetica size=8 color=blue><b>Q:</b></font>What's wrong withthisdeclaration?<pre>char* p1, p2;</pre>I get errors when I try touse<TT>p2</TT>.<p><hr><p><font face=Helvetica size=8 color=blue><b>A:</b></font>See question <a href="faqcatd3c2.html?sec=decl#charstarws">1.5</a>.<hr><hr><hr><a name="nearfar2"><h1>comp.lang.c FAQ list<font color=blue>·</font><a href="../../ptrs/nearfar2.html"><!-- qtag -->Question 4.17</a></h1><p><font face=Helvetica size=8 color=blue><b>Q:</b></font>What are ``near'' and ``far'' pointers?<p><hr><p><font face=Helvetica size=8 color=blue><b>A:</b></font>See question <a href="faqcatea63.html?sec=osdep#nearfar">19.40d</a>.<hr><hr><hr><hr><p>Read sequentially:<a href="faqcatee08.html?sec=expr" rev=precedes>prev</a><a href="faqcat1f1a.html?sec=null" rel=precedes>next</a><a href="faqcat.html" rev=subdocument>up</a></p><hr><p><br><!-- lastfooter --><a href="../../about.html">about this FAQ list</a> <a href="../../eskimo.html">about eskimo</a> <a href="../../search.html">search</a> <a href="../../feedback.html">feedback</a> <a href="../../ptrs/copyright.html">copyright</a><p>Hosted by<a href="http://www.eskimo.com/"><img src="../../../www.eskimo.com/img/link/eskitiny.gif" alt="Eskimo North"></a></body><!-- Mirrored from c-faq.com/~scs/cgi-bin/faqcat.cgi?sec=ptrs by HTTrack Website Copier/3.x [XR&CO'2008], Sat, 14 Mar 2009 07:57:40 GMT --></html>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -