📄 c-iaq.html
字号:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "HTTP://WWW.W3.ORG/TR/REC-HTML40/STRICT.DTD"><HTML> <HEAD> <TITLE>Infrequently Asked Questions in comp.lang.c</TITLE> </HEAD> <BODY> <H4>Meta: [<A HREF="c-iaq-a.html#meta">a</A>]</H4> <P>The HTML version of this list is now considered the master version; the text version may be updated occasionally, but is now obsolete. Additionally, there are now accompanying <A HREF="c-iaq-a.html#meta">annotations</A> for some of the material. (Eventually, for all of the material.) Annotations are denoted by a bracketed letter a, or occasionally by links in the document text.</P> <P>[Last modified April 16, 1999 by seebs.] [Revision: yes] </P><P>[Copyright 1995, 1996, 1997, 1998, 1999 Peter Seebach. All rights reserved, all wrongs reversed. Unauthorized duplication and distribution prohibited.] </P> <P>The following FAQ has been a hobby of mine since 1995. If you enjoy it, please consider sending a token donation to help pay for my web page, and help me fund future, similar works. (Yes, I am thinking about doing others.) Email <A HREF="mailto:seebs@plethora.net">seebs@plethora.net</A> for information. </P> <H4>Introduction: [<A HREF="c-iaq-a.html#intro">a</A>]</H4> <P>Certain topics never (well, hardly ever) come up on this newsgroup. They are stupid questions, to which the answers are immediately obvious, but they would be more fun to talk about than these arcane details of loop control. </P> <P>This article, which is posted yearly, attempts to answer these questions definitively, succinctly, and in such a way as to discourage further discussion. </P> <H4>Table of Contents:</H4> <P><A HREF="#section-1">1. Declarations and Initializations</A><BR> <A HREF="#section-2">2. Structures, Unions, and Enumerations</A><BR> <A HREF="#section-3">3. Expressions</A><BR> <A HREF="#section-4">4. Null Statements</A><BR> <A HREF="#section-5">5. Arrays and Pointers</A><BR> <A HREF="#section-6">6. Memory Allocation</A><BR> <A HREF="#section-7">7. Characters and Strings</A><BR> <A HREF="#section-8">8. Boolean Expressions and Variables</A><BR> <A HREF="#section-9">9. C Preprocessor</A><BR> <A HREF="#section-10">10. ANSI/ISO Standard C</A><BR> <A HREF="#section-11">11. Stdio</A><BR> <A HREF="#section-12">12. Library Functions</A><BR> <A HREF="#section-13">13. Floating Point</A><BR> <A HREF="#section-14">14. Variable-Length Argument Lists</A><BR> <A HREF="#section-15">15. Lint</A><BR> <A HREF="#section-16">16. Strange Problems</A><BR> <A HREF="#section-17">17. Style</A><BR> <A HREF="#section-18">18. System Dependencies</A><BR> <A HREF="#section-19">19. Miscellaneous</A><BR> </P> <P>Herewith, some infrequently-asked questions and their answers: </P> <H3><A NAME="section-1"></A>Section 1: Declarations and Initializations [<A HREF="c-iaq-a.html#section-1">a</A>]</H3> <H4><A NAME="question-1.1"></A>1.1: How do you decide which integer type to use?</H4> <P>Use ``short'' when you need to avoid values over 32,767, ``int'' when you want to store integers, ``long'' for long numbers (more than 6 digits), and ``float'' for numbers over 4 billion. </P> <H4><A NAME="question-1.2"></A>1.2: What should the 64-bit type on new, 64-bit machines be?</H4> <P>int. </P> <H4><A NAME="question-1.3"></A>1.3: If I write the code <CODE>int i, j;</CODE> can I assume that <CODE>(&i + 1) == &j</CODE>?</H4> <P>Only sometimes. It's not portable, because in EBCDIC, i and j are not adjacent. [<A HREF="c-iaq-a.html#question-1.3">a</A>]</P> <H4><A NAME="question-1.4"></A>1.4: What's the best way to declare and define global variables?</H4> <P>In headers; this way, you can get link errors when you include the same header twice. Generally, you will have to define a variable everywhere you want to use it, and then declare it someplace so you know what it is. [<A HREF="c-iaq-a.html#question-1.4">a</A>]</P> <H4><A NAME="question-1.5"></A>1.5: What does extern mean in a function declaration?</H4> <P>It refers to a variable which is not actually in your program. For instance, </P> <PRE>main() { extern int bar; printf("%d\n", bar); return 0;}</PRE> <P>will compile without errors because bar is declared as being external. (It won't run, though, because you never assign bar a value.) [<A HREF="c-iaq-a.html#question-1.5">a</A>]</P> <H4><A NAME="question-1.6"></A>1.6: I finally figured out the syntax for declaring pointers to functions, but now how do I initialize one?</H4> <P>With the assignment operator. You were perhaps expecting a screwdriver? </P> <H4><A NAME="question-1.7"></A>1.7: I've seen different methods used for calling through pointers to functions. What's the story?</H4> <P>In the old days, when Microsoft first invented C, the syntax for calling functions involved more parentheses; this was after their market research indicated that most C programmers would be coming from a Lisp environment. Later, when Kernighan took over the language design (right after AT&T bought Microsoft's language technology), he decided to eliminate the parentheses, but the old form is still allowed. </P> <P>You do need the parentheses to call a function with more than one argument, for instance, </P> <PRE>int (*foo)(char *, ...) = printf;(*foo)("hello, %s\n", "world!");</PRE> <P>needs the parens, but they would not be needed for </P> <PRE>foo, "hello, world!\n";</PRE> <P>(The ``*'' just means to execute foo, just like the ``*'' on the end of an executable filename in ``ls -F''.) [<A HREF="c-iaq-a.html#question-1.7">a</A>]</P> <H4><A NAME="question-1.8"></A>1.8: What's the <CODE>auto</CODE> keyword good for?</H4> <P>Declaring vehicles.</P> <H4><A NAME="question-1.9"></A>1.9: I can't seem to define a linked list successfully. I tried</H4> <PRE> typedef struct { char *item; NODEPTR next; } *NODEPTR;</PRE> <P>but the compiler gave me error messages. Can't a structure in C contain a pointer to itself? </P> <P>Not exactly; it can contain a pointer to another structure of the same type. Try: </P> <PRE>typedef struct { char *item; double *next;} NODEFAKE;</PRE> <PRE>typedef struct { char *item; NODEFAKE *next;} NODEPTR;</PRE> <P>Make sure that sizeof(NODEPTR) == sizeof(double). </P> <P>This technique is called a ``backwards reference''. [<A HREF="c-iaq-a.html#question-1.9">a</A>]</P> <H4><A NAME="question-1.10"></A>1.10: How do I enter values using hexadecimal?</H4> <P>long ints can be entered using hexadecimal notation; for instance, </P> <PRE>long int foo = 07;</PRE> <P>sets foo to hex 7. [<A HREF="c-iaq-a.html#question-1.10">a</A>]</P> <H4><A NAME="question-1.11"></A>1.11: How do I declare an array of N pointers to functions returning pointers to functions returning pointers to characters?</H4> <P>Well, first you need to know how to declare an array of N items of type T - that's </P> <PRE>T foo[N];</PRE> <P>Now you need to look at how to declare a pointer to function returning something, say, an object of type S. That's like this: </P> <PRE>S (*bar)();</PRE> <P>Now assume that S is ``pointer to function returning pointer to char''. We get </P> <PRE>(char *) (*)() (*bar)().</PRE> <P>So, the whole thing turns out to be (with appropriate parentheses) </P> <PRE>(((char)(*))((*)())(((*)((foo)))())([(N)]));</PRE> <P>If your compiler complains, break this down into subexpressions. </P> <P>To call it, just use </P> <PRE>foo[i]();</PRE> <P>This works because, in C, declaration reflects use, but it's one of those weird distorted mirrors. [<A HREF="c-iaq-a.html#question-1.11">a</A>]</P> <H3><A NAME="section-2"></A>Section 2: Structures, Unions, and Enumerations [<A HREF="c-iaq-a.html#section-2">a</A>]</H3> <H4><A NAME="question-2.1"></A>2.1: What is the difference between an <CODE>enum</CODE> and a series of preprocessor <CODE>#define</CODE>s?</H4> <P>The <CODE>enum</CODE> doesn't require the preprocessor. </P> <H4><A NAME="question-2.2"></A>2.2: I heard that structures could be assigned to variables and passed to and from functions, but <CITE>K&R I</CITE> says not.</H4> <P><CITE>K&R I</CITE> was wrong; they hadn't actually learned C very well before writing the book. Later, Ritchie got a job at Bell Labs, and worked closely with the authors of C, allowing the 2nd edition of the book to be much more accurate. (Kernighan already worked at Bell Labs, as a video game developer.) [<A HREF="c-iaq-a.html#question-2.2">a</A>]</P> <H4><A NAME="question-2.3"></A>2.3: How does struct passing and returning work? </H4> <P>The structures are put into the low part of the VGA card's VRAM. They are then removed before the next video update. This is why struct passing was not supported for a long time; VGA cards were prohibitively expensive. </P> <P>If you try to pass very large structures on the stack, you may see odd screen graphics. [<A HREF="c-iaq-a.html#question-2.3">a</A>]</P> <H4><A NAME="question-2.4"></A>2.4: Why can't you compare structs?</H4> <P>Compare them to what? A summer's day? </P> <H4><A NAME="question-2.5"></A>2.5: How can I read/write structs from/to data files?</H4> <P>Loop with <CODE>putchar</CODE>. Be careful; if your machine uses signed chars by default, all of the sign bits in your structure elements will be reversed. [<A HREF="c-iaq-a.html#question-2.5">a</A>]</P> <H4><A NAME="question-2.6"></A>2.6: How can I determine the byte offset of a field within a structure?</H4> <P>It's generally 4 times the number of members of the structure. It may be more or less on some machines. [<A HREF="c-iaq-a.html#question-2.6">a</A>]</P> <H4><A NAME="question-2.7"></A>2.7: How can I access structure fields by name at run time? </H4> <P>foo."name" should work. You may need to overload the . operator, which, in turn, may overload your C compiler. </P> <H4><A NAME="question-2.8"></A>2.8: Why does sizeof report a larger size than I expect for a structure type, as if there was padding at the end? </H4> <P>Because there's padding at the end. <STRONG>Duh</STRONG>. </P> <H4><A NAME="question-2.9"></A>2.9: My compiler is leaving holes in structures, which is wasting space and preventing ``binary'' I/O to external data files. Can I turn off the padding, or otherwise control the alignment of structs? </H4> <P>Sure. What you do to eliminate the padding in structures is use unions; for intance, </P> <PRE>struct foo { char c; long l; char d; char e; char f;};</PRE> <P>may cause struct foo to be padded to 12 bytes, rather than the correct size of 8. Try </P> <PRE>union foo { double _d; char c, d, e, f; long l;};</PRE> <P>which will be 8 bytes. (The double is for alignment.) [<A HREF="c-iaq-a.html#question-2.9">a</A>]</P> <H4><A NAME="question-2.10"></A>2.10: Can I initialize unions? </H4> <P>Depends. They may go on strike when provoked. Luckily, if your program involves air traffic control, the ISO standard guarantees that Ronald Reagan will fire any unions that go on strike, and replace them with structs, which should be close enough. [<A HREF="c-iaq-a.html#question-2.10">a</A>]</P> <H4><A NAME="question-2.11"></A>2.11: How can I pass constant values to routines which accept struct arguments? </H4> <P>Try foo((struct foo) 3). [<A HREF="c-iaq-a.html#question-2.11">a</A>]</P> <H3><A NAME="section-3"></A>Section 3: Expressions [<A HREF="c-iaq-a.html#section-3">a</A>]</H3> <H4><A NAME="question-3.1"></A>3.1: Why doesn't the code <CODE>a[i] = i++;</CODE> work? </H4> <P>You didn't declare either i or a. </P> <H4><A NAME="question-3.2"></A>3.2: Under my compiler, the code </H4> <PRE> int i = 7; printf("%d\n", i++ * i++);</PRE> <P>prints 49. Regardless of the order of evaluation, shouldn't it print 56? </P> <P>No. The only logical answer would be 81 - two postfix ++'s are automatically converted to prefix. </P> <H4><A NAME="question-3.3"></A>3.3: I've experimented with the code </H4> <PRE> int i = 2; i = i++;</PRE> <H4>on several compilers. Some gave i the value 2, some gave 3, but one gave 4. I know the behavior is undefined, but how could it give 4? </H4> <P>Because i is 2, the loop is executed twice. </P> <H4><A NAME="question-3.4"></A>3.4: People keep saying the behavior is undefined, but I just tried it on an ANSI-conforming compiler, and got the results I expected. </H4> <P>They were probably wrong. Flame them mercilessly. Be sure before you do that your compiler is <EM>really</EM> ANSI conforming, though. If it turns out you were wrong, they get a legal claim on your first-born. </P> <H4><A NAME="question-3.5"></A>3.5: Can I use explicit parentheses to force the order of evaluation I want? Even if I don't, doesn't precedence dictate it? </H4> <P>No. To force order of evaluation, you must threaten it. Take the comma operator hostage. Using it, you can force the other operators to do what you want. [<A HREF="c-iaq-a.html#question-3.5">a</A>]</P> <H4><A NAME="question-3.6"></A>3.6: But what about the <CODE>&&</CODE>, <CODE>||</CODE>, and comma operators? I see code like ``<CODE>if((c = getchar()) == EOF || c == '\n')</CODE>'' ... </H4> <P>As noted, once you've captured the comma operator, the others become docile. </P> <H4><A NAME="question-3.7"></A>3.7: If I'm not using the value of the expression, should I use <CODE>i++</CODE> or <CODE>++i</CODE> to increment a variable? </H4> <P><CODE>++i</CODE>. Only losers and idiots use <CODE>i++</CODE>. This is different if your native language would idiomatically use ``i increment'', but in English and related languages, you must use <CODE>++i</CODE>. Note that a modern program must use both, dependent on the current locale. </P> <H4><A NAME="question-3.8"></A>3.8: Why is <CODE>i = ++i</CODE> undefined? </H4> <P>Because it is unclear whether it is shorthand for <CODE>i = 42;</CODE> or <CODE>i = (char *) "forty two";</CODE>. </P> <P>Given the ambiguity, the standards committee decided to leave it undefined. </P> <H3><A NAME="section-4"></A>Section 4: Null Statements [a]</H3>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -