📄 faqcatd3c2.html
字号:
<!DOCTYPE HTML PUBLIC "-//W3O//DTD W3 HTML 2.0//EN"><!-- This collection of hypertext pages is Copyright 1995-2005 by Steve Summit. --><!-- Content from the book "C Programming FAQs: Frequently Asked Questions" --><!-- (Addison-Wesley, 1995, ISBN 0-201-84519-9) is made available here by --><!-- permission of the author and the publisher as a service to the community. --><!-- It is intended to complement the use of the published text --><!-- and is protected by international copyright laws. --><!-- The on-line content may be accessed freely for personal use --><!-- but may not be published or retransmitted without explicit permission. --><!-- --><!-- this page built Sat Dec 24 21:47:45 2005 by faqproc version 2.7 --><!-- from source file decl.sgml dated Wed Dec 21 12:56:18 2005 --><!-- corresponding to FAQ list version 4.0 --><html><!-- Mirrored from c-faq.com/~scs/cgi-bin/faqcat.cgi?sec=decl by HTTrack Website Copier/3.x [XR&CO'2008], Sat, 14 Mar 2009 07:57:28 GMT --><head><base ><meta name=GENERATOR content="faqproc"><title>Declarations and Initializations</title></head><body bgcolor="#ffffff"><H1>1. Declarations and Initializations</H1><a name="inttypes"><h1>comp.lang.c FAQ list<font color=blue>·</font><a href="../../decl/inttypes.html"><!-- qtag -->Question 1.1</a></h1><p><font face=Helvetica size=8 color=blue><b>Q:</b></font>How should I decide which integer type to use?</p><p><hr><p><font face=Helvetica size=8 color=blue><b>A:</b></font>If you might need large values(above 32,767 or below -32,767),use <TT>long</TT>.Otherwise,ifspace is very important(i.e. ifthere are large arrays or many structures),use <TT>short</TT>.Otherwise,use <TT>int</TT>.If well-defined overflow characteristics are importantandnegative values are not,or if you want tosteer clear ofsign-extension problems when manipulating bits or bytes,useone ofthe corresponding <TT>unsigned</TT> types.(Bewarewhenmixing signed and unsignedvaluesin expressions,though;see question <a href="faqcatee08.html?sec=expr#preservingrules">3.19</a>.)</p><p>Althoughcharacter types(especially <TT>unsigned char</TT>)canbe used as``tiny''integers,doing so issometimesmore trouble than it's worth.The compiler will have to emit extra codeto convert between <TT>char</TT> and <TT>int</TT>(making the executable larger),andunexpected sign extension canbe troublesome.(Using <TT>unsigned char</TT> can help;see question <a href="faqcat1d60.html?sec=stdio#getcharc">12.1</a> for a related problem.)</p><p>A similar space/time tradeoff applieswhen deciding between <TT>float</TT>and <TT>double</TT>.(Many compilers still convert all <TT>float</TT> values to <TT>double</TT>during expression evaluation.)None of the above rulesapplyifpointers to the variablemust have a particular type.</p><p>Variables referring to certain kinds of data,such as sizes of objects in memory,can and should used predefined abstract typessuch as <TT>size_t</TT>.</p><p>It's oftenincorrectlyassumed that C's types are defined to have certain, exact sizes.In fact,what's guaranteed is that:<UL><li>type <TT>char</TT> can hold values up to 127;<li>types <TT>short int</TT> and <TT>int</TT> can hold values up to 32,767;and<li>type <TT>long int</TT> can hold values up to 2,147,483,647.<li>something likethe relation<pre> sizeof(char) <= sizeof(short) <= sizeof(int) <= sizeof(long) <= sizeof(long long)</pre>holds.<a href="../../decl/fn1.html" rel=subdocument>[footnote]</a></UL></p><p>From these values, it can be inferred that <TT>char</TT> is at least 8 bits,<TT>short int</TT> and <TT>int</TT> are at least 16 bits,and <TT>long int</TT> is at least 32 bits.(The signed and unsigned versions of each typeare guaranteed to have the same size.)Under ANSI C,the maximum and minimum values for a particular machinecan be found in the header file <TT><limits.h></TT>;here is a summary:<table><tr><td>Base type</td><td>Minimum size (bits)</td><td>Minimum value (signed)</td><td>Maximum value (signed)</td><td>Maximum value (unsigned)</td></tr><tr><td><TT>char</TT></td><td>8</td><td>-127</td><td>127</td><td>255</td></tr><tr><td><TT>short</TT></td><td>16</td><td>-32,767</td><td>32,767</td><td>65,535</td></tr><tr><td><TT>int</TT></td><td>16</td><td>-32,767</td><td>32,767</td><td>65,535</td></tr><tr><td><TT>long</TT></td><td>32</td><td>-2,147,483,647</td><td>2,147,483,647</td><td>4,294,967,295</td></tr></table>(These values are the minimums guaranteed by the Standard.Many implementations allow larger values,but portable programs shouldn't depend on it.)</p><p>If for some reason you need to declare something with anexactsize(usually the only good reason for doing sois when attempting to conformto some externally-imposed storage layout,but see question<a href="faqcat38c2.html?sec=misc#binaryfiles">20.5</a>),be sure to encapsulate the choicebehind an appropriate typedef,but see question <a href="faqcatd3c2.html?sec=decl#int16">1.3</a>.</p><p>If you need to manipulate huge values,larger than the guaranteed range of C's built-in types,you need an arbitrary-precision(or ``multiple precision'')arithmetic library;see question <a href="faqcatccbd.html?sec=resources#mplib">18.15d</a>.</p><p>References:K&R1 Sec. 2.2 p. 34<br>K&R2 Sec. 2.2 p. 36, Sec. A4.2 pp. 195-6, Sec. B11 p. 257<br>ISO Sec. 5.2.4.2.1, Sec. 6.1.2.5<br>H&S Secs. 5.1,5.2 pp. 110-114<hr><hr><hr><a name="exactsizes"><h1>comp.lang.c FAQ list<font color=blue>·</font><a href="../../decl/exactsizes.html"><!-- qtag -->Question 1.2</a></h1><p><font face=Helvetica size=8 color=blue><b>Q:</b></font>Why aren't the sizes of the standard types precisely defined?</p><p><hr><p><font face=Helvetica size=8 color=blue><b>A:</b></font>Though C is considered relatively low-levelas high-level languages go,it does take the positionthat the exact size ofan object(i.e. in bits)is an implementation detail.(The only place where C lets you specify a size in bitsis in bit-fields within structures;see questions <a href="faqcat6b6b.html?sec=struct#bitfield0">2.25</a> and <a href="faqcat6b6b.html?sec=struct#bitfields">2.26</a>.)Most programsdo not need precise controloverthese sizes;many programs that dotry to achieve this controlwould be better off if they didn't.</p><p>Type<TT>int</TT> is supposed to represent a machine's natural word size.It's the right type to use for most integer variables;see question <a href="faqcatd3c2.html?sec=decl#inttypes">1.1</a> for other guidelines.See also questions<a href="faqcat1d60.html?sec=stdio#extconform">12.42</a>and<a href="faqcat38c2.html?sec=misc#binaryfiles">20.5</a>.<hr><hr><hr><a name="int16"><h1>comp.lang.c FAQ list<font color=blue>·</font><a href="../../decl/int16.html"><!-- qtag -->Question 1.3</a></h1><p><font face=Helvetica size=8 color=blue><b>Q:</b></font>Since C doesn't define sizes exactly,I've been usingtypedefslike <TT>int16</TT> and<TT>int32</TT>.I can then define these typedefsto be <TT>int</TT>, <TT>short</TT>, <TT>long</TT>,etc. depending on what machine I'm using.That should solve everything, right?</p><p><hr><p><font face=Helvetica size=8 color=blue><b>A:</b></font>If you truly needcontrolover exact type sizes,this is the right approach.There remain several things to be aware of:<UL><li>There might not be an exact match on some machines.(There are, for example, 36-bit machines.)<li>A typedef like <TT>int16</TT> or <TT>int32</TT>accomplishes nothingif its intended meaning is ``at least'' the specified size,because types <TT>int</TT> and <TT>long</TT>are <em>already</em> essentially defined as being``at least 16 bits'' and``at least 32 bits,'' respectively.<li>Typedefswill neverdo anything about byte order problems(e.g.if you're trying to interchange dataor conform toexternally-imposed storage layouts).<li>You no longer have to define your own typedefs,because the Standard header <TT><inttypes.h></TT>contains a complete set.</UL></p><p>See also questions<a href="faqcat204f.html?sec=cpp#ifendian">10.16</a>and<a href="faqcat38c2.html?sec=misc#binaryfiles">20.5</a>.<hr><hr><hr><a name="octabyte"><h1>comp.lang.c FAQ list<font color=blue>·</font><a href="../../decl/octabyte.html"><!-- qtag -->Question 1.4</a></h1><p><font face=Helvetica size=8 color=blue><b>Q:</b></font>What should the 64-bit type beon amachine that can support it?</p><p><hr><p><font face=Helvetica size=8 color=blue><b>A:</b></font>ThenewC99 Standardspecifies type <TT>long long</TT> as effectively beingat least 64 bits,and this type has been implemented by a number of compilersfor some time.(Others have implemented extensions such as <TT>__longlong</TT>.)On the other hand,it's also appropriate toimplementtype <TT>short int</TT> as 16,<TT>int</TT> as 32,and <TT>long int</TT> as 64 bits,and some compilers do.</p><p>See alsoquestions <a href="faqcatd3c2.html?sec=decl#int16">1.3</a> and <a href="faqcatccbd.html?sec=resources#mplib">18.15d</a>.</p><p>Additional links:Part of a<a href="../../decl/longlong.awjd.html">proposal for <TT>long long</TT> for C9X</a>by Alan Watson and Jutta Degener,succinctly outlining the arguments.</p><p>References:C9X Sec. 5.2.4.2.1, Sec. 6.1.2.5<hr><hr><hr><a name="charstarws"><h1>comp.lang.c FAQ list<font color=blue>·</font><a href="../../decl/charstarws.html"><!-- qtag -->Question 1.5</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><p><hr><p><font face=Helvetica size=8 color=blue><b>A:</b></font>Nothing is wrong with the declaration--exceptthat it doesn't do what you probably want.The <TT>*</TT> in a pointer declaration is not part of the base type;it is part of the <a href="../../sx1/index.html#declarator"><dfn>declarator</dfn></a>containing the name being declared(see question <a href="faqcatd3c2.html?sec=decl#cdecl1">1.21</a>).That is,in C, the syntax and interpretation of a declaration is not really<pre> <I>type identifier</I> ;</pre>but rather<pre> <I>base_type thing_that_gives_base_type</I> ;</pre>where ``<I>thing_that_gives_base_type</I>''--the<a href="../../sx1/index.html#declarator"><dfn>declarator</dfn></a>--iseither a simple identifier,or a notation like <TT>*p</TT> or <TT>a[10]</TT> or <TT>f()</TT>indicating that the variable being declared is a pointer to,array of, or function returning that <I>base_type</I>.(Of course, more complicated declarators are possible as well.)</p><p>In the declarationas written in the question,no matter what the whitespacesuggests,the base type is <TT>char</TT> andthe first declarator is ``<TT>* p1</TT>'',and since the declarator contains a <TT>*</TT>,it declares <TT>p1</TT> as a pointer-to-<TT>char</TT>.The declarator for <TT>p2</TT>, however,contains nothing but <TT>p2</TT>,so <TT>p2</TT> is declared as a plain <TT>char</TT>,probably not what was intended.To declare two pointers within the same declaration,use<pre> char *p1, *p2;</pre>Since the <TT>*</TT> is part of the declarator,it's best to use whitespace as shown;writing <TT>char*</TT> invites mistakes and confusion.</p><p>See also question <a href="faqcatd3c2.html?sec=decl#typedefvsdefine">1.13</a>.</p><p>Additional links:<a href="http://www.research.att.com/~bs/bs_faq2.html#whitespace">Bjarne Stroustrup's opinion</a><hr><hr><hr><a name="mimic"><h1>comp.lang.c FAQ list<font color=blue>·</font><a href="../../decl/mimic.html"><!-- qtag -->Question 1.6</a></h1><p><font face=Helvetica size=8 color=blue><b>Q:</b></font>I'm trying to declare a pointer and allocate some space for it,but it'snot working.What's wrong withthis code?<pre>char *p;*p = malloc(10);</pre></p><p><hr><p><font face=Helvetica size=8 color=blue><b>A:</b></font>The pointer you declared is <TT>p</TT>,not <TT>*p</TT>.See question <a href="faqcatabdc.html?sec=ptrs#mimic">4.2</a>.<hr><hr><hr><a name="decldef"><h1>comp.lang.c FAQ list<font color=blue>·</font><a href="../../decl/decldef.html"><!-- qtag -->Question 1.7</a></h1><p><font face=Helvetica size=8 color=blue><b>Q:</b></font>What's the best way to declare and defineglobal variablesand functions?</p><p><hr><p><font face=Helvetica size=8 color=blue><b>A:</b></font>First, though there can be many<a href="../../sx1/index.html#declarations"><dfn>declarations</dfn></a>(and in many translation units)of a singleglobalvariableor function,there must be exactly one<a href="../../sx1/index.html#definition"><dfn>definition</dfn></a>.<a href="../../decl/unused.html" rel=subdocument>[footnote]</a>For global variables,thedefinition is the declaration that actually allocates space,and provides an initialization value, if any.For functions,the definition isthe ``declaration''that provides the function body.For example,these are declarations:<pre> extern int i; extern int f();</pre>and these are definitions:<pre> int i = 0; int f() { return 1; }</pre>(Actually, the keyword <TT>extern</TT> is optional in function declarations;see question <a href="faqcatd3c2.html?sec=decl#extern">1.11</a>.)</p><p>When you need to share variables or functionsacross severalsource files,you will of course want to ensurethat all definitions and declarations are consistent.The best arrangementis toplace eachdefinition in some relevant.c file.Then,putan external declaration in aheader(``<TT>.h</TT>'')file,and <TT>#include</TT> itwherever the declaration is needed.The <TT>.c</TT> file containing the definition should also <TT>#include</TT> thesame header file,so the compiler can checkthat the definition matches the declarations.</p><p>This rule promotes a high degree of portability:itis consistent with the requirements of the ANSI C Standard,and is also consistent with most pre-ANSI compilers and linkers.(Unixcompilers and linkers typically use a ``common model''which allows multiple definitions,as long as at most one is initialized;thisbehavior is mentioned as a ``common extension'' bythe ANSI Standard,no<a href="faqcatd3c2.html?sec=decl#common">pun</a>intended.A fewvery oldsystemsmight once have requiredan explicit initializer todistinguish a definition from an external declaration.)</p><p>It is possible to use preprocessor tricksto arrange thata line like<pre> DEFINE(int, i);</pre>need only be entered once in one header file,and turned into a definition or a declarationdepending on the setting of some macro,but it's not clear ifthis isworth the trouble,especially since it's usually abetterideato keep global variables to a minimum.</p><p>It'snot just a good ideato put global declarations in header files:if you want the compilertobe able tocatch inconsistent declarations for you,you <em>must</em> place them in header files.In particular,never place a prototype for an external functionin a .c file--ifthe definition of the function ever changes,it would be too easy to forget to change the prototype,and an incompatibleprototype is worse than useless.</p><p>See alsoquestions <a href="faqcatd3c2.html?sec=decl#extarraysize">1.24</a>, <a href="faqcat204f.html?sec=cpp#hfiles">10.6</a>, <a href="faqcataae2.html?sec=style#srcfiles">17.2</a>, and <a href="faqcatccbd.html?sec=resources#lintvsansi">18.8</a>.</p><p>References:K&R1 Sec. 4.5 pp. 76-7<br>K&R2 Sec. 4.4 pp. 80-1<br>ISO Sec. 6.1.2.2, Sec. 6.7, Sec. 6.7.2, Sec. G.5.11<br>Rationale Sec. 3.1.2.2<br>H&S Sec. 4.8 pp. 101-104, Sec. 9.2.3 p. 267<br>CT&P Sec. 4.2 pp. 54-56<hr><hr><hr><a name="opaque"><h1>comp.lang.c FAQ list<font color=blue>·</font><a href="../../decl/opaque.html"><!-- qtag -->Question 1.8</a></h1><p><font face=Helvetica size=8 color=blue><b>Q:</b></font>How can I implementopaque (abstract) data types in C?</p><p><hr><p><font face=Helvetica size=8 color=blue><b>A:</b></font>See question <a href="faqcat6b6b.html?sec=struct#opaquetypes">2.4</a>.<hr><hr><hr><a name="semiglobal"><h1>comp.lang.c FAQ list<font color=blue>·</font><a href="../../decl/semiglobal.html"><!-- qtag -->Question 1.9</a></h1><p><font face=Helvetica size=8 color=blue><b>Q:</b></font>How can I make a sort of ``semi-global'' variable,that is,one that'sprivate to a few functions spread across a few source files?</p><p><hr><p><font face=Helvetica size=8 color=blue><b>A:</b></font>You can't do this in C.If it's impossible or inconvenient to put all the functions in the same source file,there are two usual solutions:<OL><li>Pick a unique prefixfor the namesof all functions and global variables in alibrary or package of related routines,and warn users of the packagenot to defineor useany symbols with names matching that prefixother than those documented as being for public consumption.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -