home *** CD-ROM | disk | FTP | other *** search
Text File | 1994-04-16 | 38.8 KB | 1,271 lines |
- Path: bloom-beacon.mit.edu!hookup!nntp.cs.ubc.ca!cyber2.cyberstore.ca!nwnexus!ole!rwing!eskimo!scs
- From: scs@eskimo.com (Steve Summit)
- Newsgroups: comp.lang.c,comp.answers,news.answers
- Subject: comp.lang.c Answers (Abridged) to Frequently Asked Questions (FAQ)
- Message-ID: <1994Apr15.0300.scs.0001@eskimo.com>
- Date: 15 Apr 94 10:00:24 GMT
- Expires: Tue, 3 May 1994 00:00:00 GMT
- Sender: scs@eskimo.com (Steve Summit)
- Reply-To: scs@eskimo.com
- Followup-To: poster
- Organization: none, at the moment
- Lines: 1252
- Approved: news-answers-request@MIT.Edu
- Supersedes: <1994Apr01.0306.scs.0003@eskimo.com>
- X-Archive-Name: C-faq/abridged
- X-Last-Modified: March 1, 1994
- Xref: bloom-beacon.mit.edu comp.lang.c:38589 comp.answers:4922 news.answers:18103
-
- Archive-name: C-faq/abridged
- Comp-lang-c-archive-name: C-FAQ-list.abridged
-
- [Last modified March 1, 1994 by scs.]
-
- This article contains minimal answers to the comp.lang.c frequently-
- asked questions list. Please see the long version (posted on the
- first of each month, or see question 17.33 for availability) for more
- detailed explanations and references.
-
-
- Section 1. Null Pointers
-
- 1.1: What is this infamous null pointer, anyway?
-
- A: For each pointer type, there is a special value -- the "null
- pointer" -- which is distinguishable from all other pointer
- values and which is not the address of any object or function.
-
- 1.2: How do I "get" a null pointer in my programs?
-
- A: A constant 0 in a pointer context is converted into a null
- pointer at compile time. A "pointer context" is an
- initialization, assignment, or comparison with one side a
- variable or expression of pointer type, and (in ANSI standard C)
- a function argument which has a prototype in scope declaring a
- certain parameter as being of pointer type. In other contexts
- (function arguments without prototypes, or in the variable part
- of variadic function calls) a constant 0 with an appropriate
- explicit cast is required.
-
- 1.3: What is NULL and how is it #defined?
-
- A: NULL is simply a preprocessor macro, #defined as 0 (or
- (void *)0), which is used (as a stylistic convention, in
- preference to unadorned 0's) to generate null pointers,
-
- 1.4: How should NULL be #defined on a machine which uses a nonzero
- bit pattern as the internal representation of a null pointer?
-
- A: The same as any other machine: as 0 (or (void *)0). (The
- compiler makes the translation, upon seeing a 0, not the
- preprocessor.)
-
- 1.5: If NULL were defined as "(char *)0," wouldn't that make function
- calls which pass an uncast NULL work?
-
- A: Not in general. The problem is that there are machines which
- use different internal representations for pointers to different
- types of data. A cast is still required to tell the compiler
- which kind of null pointer is required, since it may be
- different from (char *)0.
-
- 1.6: I use the preprocessor macro "#define Nullptr(type) (type *)0"
- to help me build null pointers of the correct type.
-
- A: This trick, though valid, does not buy much.
-
- 1.7: Is the abbreviated pointer comparison "if(p)" to test for non-
- null pointers valid? What if the internal representation for
- null pointers is nonzero?
-
- A: The construction "if(p)" works, regardless of the internal
- representation of null pointers, because the compiler
- essentially rewrites it as "if(p != 0)" and goes on to convert 0
- into the correct null pointer.
-
- 1.8: If "NULL" and "0" are equivalent, which should I use?
-
- A: Either; the distinction is entirely stylistic.
-
- 1.9: But wouldn't it be better to use NULL (rather than 0) in case
- the value of NULL changes, perhaps on a machine with nonzero
- null pointers?
-
- A: No. NULL is, and will always be, 0.
-
- 1.10: I'm confused. NULL is guaranteed to be 0, but the null pointer
- is not?
-
- A: A "null pointer" is a language concept whose particular internal
- value does not matter. A null pointer is requested in source
- code with the character "0". "NULL" is a preprocessor macro,
- which is always #defined as 0 (or (void *)0).
-
- 1.11: Why is there so much confusion surrounding null pointers? Why
- do these questions come up so often?
-
- A: The fact that null pointers are represented both in source code,
- and internally to most machines, as zero invites unwarranted
- assumptions. The use of a preprocessor macro (NULL) suggests
- that the value might change later, or on some weird machine.
-
- 1.12: I'm still confused. I just can't understand all this null
- pointer stuff.
-
- A: A simple rule is, "Always use `0' or `NULL' for null pointers,
- and always cast them when they are used as arguments in function
- calls."
-
- 1.13: Given all the confusion surrounding null pointers, wouldn't it
- be easier simply to require them to be represented internally by
- zeroes?
-
- A: Such a requirement would accomplish little.
-
- 1.14: Seriously, have any actual machines really used nonzero null
- pointers?
-
- A: Machines manufactured by Prime, Honeywell-Bull, and CDC, as well
- as Symbolics Lisp Machines, have done so.
-
- 1.15: What does a run-time "null pointer assignment" error mean?
-
- A: It means that you've written through a null pointer.
-
-
- Section 2. Arrays and Pointers
-
- 2.1: I had the definition char a[6] in one source file, and in
- another I declared extern char *a. Why didn't it work?
-
- A: The declaration extern char *a simply does not match the actual
- definition. Use extern char a[].
-
- 2.2: But I heard that char a[] was identical to char *a.
-
- A: Not at all. Arrays are not pointers. A reference like x[3]
- generates different code depending on whether x is an array or a
- pointer.
-
- 2.3: So what is meant by the "equivalence of pointers and arrays" in
- C?
-
- A: An lvalue of type array-of-T which appears in an expression
- decays into a pointer to its first element; the type of the
- resultant pointer is pointer-to-T. So for an array a and
- pointer p, you can say "p = a;" and then p[3] and a[3] will
- access the same element.
-
- 2.4: Why are array and pointer declarations interchangeable as
- function formal parameters?
-
- A: Since functions can never receive arrays as parameters, any
- parameter declarations which "look like" arrays are treated by
- the compiler as if they were pointers.
-
- 2.5: How can an array be an lvalue, if you can't assign to it?
-
- A: An array is not a "modifiable lvalue."
-
- 2.6: Why doesn't sizeof properly report the size of an array which is
- a parameter to a function?
-
- A: The sizeof operator reports the size of the pointer parameter
- which the function actually receives.
-
- 2.7: Someone explained to me that arrays were really just constant
- pointers.
-
- A: An array name is "constant" in that it cannot be assigned to,
- but an array is _not_ a pointer.
-
- 2.8: What is the real difference between arrays and pointers?
-
- A: Arrays automatically allocate space but are fixed (in size and
- location); pointers are dynamic.
-
- 2.9: I came across some "joke" code containing the "expression"
- 5["abcdef"] . How can this be legal C?
-
- A: Yes, array subscripting is commutative in C. The array
- subscripting operation a[e] is defined as being identical to
- *((a)+(e)).
-
- 2.10: My compiler complained when I passed a two-dimensional array to
- a routine expecting a pointer to a pointer.
-
- A: The rule by which arrays decay into pointers is not applied
- recursively. An array of arrays (i.e. a two-dimensional array
- in C) decays into a pointer to an array, not a pointer to a
- pointer.
-
- 2.11: How do I write functions which accept 2-dimensional arrays when
- the "width" is not known at compile time?
-
- A: It's not particularly easy.
-
- 2.12: How do I declare a pointer to an array?
-
- A: Usually, you don't want to. Consider using a pointer to one of
- the array's elements instead.
-
- 2.13: What's the difference between array and &array?
-
- A: Under ANSI/ISO Standard C, &array yields a pointer to the entire
- array. An unadorned reference to an array yields a pointer to
- the array's first element.
-
- 2.14: How can I dynamically allocate a multidimensional array?
-
- A: It is usually best to allocate an array of pointers, and then
- initialize each pointer to a dynamically-allocated "row." See
- the full list for code samples.
-
- 2.15: How can I use statically- and dynamically-allocated
- multidimensional arrays interchangeably when passing them to
- functions?
-
- A: There is no single perfect method, but see the full list for
- some ideas.
-
- 2.16: Can I simulate a non-0-based array with a pointer?
-
- A: Not if the pointer points outside of the block of memory it is
- intended to access.
-
- 2.17: I passed a pointer to a function which initialized it, but the
- pointer in the caller was unchanged.
-
- A: The called function probably altered only the passed copy of the
- pointer.
-
- 2.18: I have a char * pointer that happens to point to some ints, and
- I want to step it over them. Why doesn't "((int *)p)++;" work?
-
- A: In C, a cast operator is a conversion operator, and by
- definition it yields an rvalue, which cannot be assigned to, or
- incremented with ++.
-
- 2.19: Can I use a void ** pointer to pass a generic pointer to a
- function by reference?
-
- A: Not portably.
-
-
- Section 3. Memory Allocation
-
- 3.1: Why doesn't the code "char *answer; gets(answer);" work?
-
- A: The pointer variable "answer" has not been set to point to any
- valid storage. The simplest way to correct this fragment is to
- use a local array, instead of a pointer.
-
- 3.2: I can't get strcat to work. I tried "char *s1 = "Hello, ",
- *s2 = "world!", *s3 = strcat(s1, s2);" but I got strange
- results.
-
- A: Again, the problem is that space for the concatenated result is
- not properly allocated.
-
- 3.3: But the man page for strcat says that it takes two char *'s as
- arguments. How am I supposed to know to allocate things?
-
- A: In general, when using pointers you _always_ have to consider
- memory allocation, at least to make sure that the compiler is
- doing it for you.
-
- 3.4: I have a function that is supposed to return a string, but when
- it returns to its caller, the returned string is garbage.
-
- A: Make sure that the memory to which the function returns a
- pointer is correctly (i.e. not locally) allocated.
-
- 3.5: Why does some code carefully cast the values returned by malloc
- to the pointer type being allocated?
-
- A: Before ANSI/ISO C, these casts were required to silence certain
- warnings.
-
- 3.6: You can't use dynamically-allocated memory after you free it,
- can you?
-
- A: No. Some early documentation implied otherwise, but the claim
- is no longer valid.
-
- 3.7: How does free() know how many bytes to free?
-
- A: The malloc/free package remembers the size of each block it
- allocates and returns.
-
- 3.8: So can I query the malloc package to find out how big an
- allocated block is?
-
- A: Not portably.
-
- 3.9: When I free a dynamically-allocated structure containing
- pointers, do I have to free each subsidiary pointer first?
-
- A: Yes.
-
- 3.10: Why doesn't my program's memory usage go down when I free
- memory?
-
- A: Most implementations of malloc/free do not return freed memory
- to the operating system.
-
- 3.11: Must I free allocated memory before the program exits?
-
- A: You shouldn't have to.
-
- 3.12: Is it legal to pass a null pointer as the first argument to
- realloc()?
-
- A: ANSI C sanctions this usage, but several earlier implementations
- do not support it.
-
- 3.13: Is it safe to use calloc's zero-fill guarantee for pointer and
- floating-point values?
-
- A: No.
-
- 3.14: What is alloca and why is its use discouraged?
-
- A: alloca allocates memory which is automatically freed when the
- function which called alloca returns. alloca cannot be written
- portably, is difficult to implement on machines without a stack,
- and fails under certain conditions if implemented simply.
-
-
- Section 4. Expressions
-
- 4.1: Why doesn't the code "a[i] = i++;" work?
-
- A: The variable i is both referenced and modified in the same
- expression.
-
- 4.2: Under my compiler, the code "int i = 7;
- printf("%d\n", i++ * i++);" prints 49. Regardless of the order
- of evaluation, shouldn't it print 56?
-
- A: The operations implied by the postincrement and postdecrement
- operators ++ and -- are performed at some time after the
- operand's former values are yielded and before the end of the
- expression, but not necessarily immediately after, or before
- other parts of the expression are evaluated.
-
- 4.3: How could the code "int i = 2; i = i++;" ever give 4?
-
- A: Undefined behavior means _anything_ can happen.
-
- 4.4: I just tried some allegedly-undefined code on an ANSI-conforming
- compiler, and got the results I expected.
-
- A: A compiler may do anything it likes when faced with undefined
- behavior, including doing what you expect.
-
- 4.5: Don't precedence and parentheses dictate order of evaluation?
-
- A: Operator precedence and explicit parentheses impose only a
- partial ordering on the evaluation of an expression, which does
- not generally include the order of side effects.
-
- 4.6: But what about the &&, ||, and comma operators?
-
- A: There is a special exception for those operators, (as well as
- ?: ); left-to-right evaluation is guaranteed.
-
- 4.7: If I'm not using the value of the expression, should I use i++
- or ++i to increment a variable?
-
- A: Since the two forms differ only in the value yielded, they are
- entirely equivalent when only their side effect is needed.
-
- 4.8: Why doesn't the code "int a = 1000, b = 1000;
- long int c = a * b;" work?
-
- A: You must manually cast one of the operands to (long).
-
-
- Section 5. ANSI C
-
- 5.1: What is the "ANSI C Standard?"
-
- A: In 1983, the American National Standards Institute (ANSI)
- commissioned a committee to standardize the C language. Their
- work was ratified as ANS X3.159-1989, and has since been adopted
- as ISO/IEC 9899:1990.
-
- 5.2: How can I get a copy of the Standard?
-
- A: ANSI X3.159 has been officially superseded by ISO 9899. Copies
- are available from ANSI in New York, or from Global Engineering
- Documents in Irvine, CA. See the unabridged list for addresses.
-
- 5.3: Does anyone have a tool for converting old-style C programs to
- ANSI C, or for automatically generating prototypes?
-
- A: See the full list for details.
-
- 5.4: How do I keep the ANSI "stringizing" preprocessing operator from
- stringizing the macro's name rather than its value?
-
- A: You must use a two-step #definition to force the macro to be
- expanded as well as stringized.
-
- 5.5: Why can't I use const values in initializers and array
- dimensions?
-
- A: The value of a const-qualified object is _not_ a constant
- expression in the full sense of the term.
-
- 5.6: What's the difference between "char const *p" and
- "char * const p"?
-
- A: The former is a pointer to a constant character; the latter is a
- constant pointer to a character.
-
- 5.7: Why can't I pass a char ** to a function which expects a
- const char **?
-
- A: The rule which permits slight mismatches in qualified pointer
- assignments is not applied recursively.
-
- 5.8: My ANSI compiler complains about a mismatch when it sees
-
- extern int func(float);
-
- int func(x)
- float x;
- {...
-
- A: You have mixed the new-style prototype declaration
- "extern int func(float);" with the old-style definition
- "int func(x) float x;". "Narrow" types are treated differently
- according to which syntax is used. This problem can be fixed by
- avoiding narrow types, or by using either new-style (prototype)
- or old-style syntax consistently.
-
- 5.9: Can you mix old-style and new-style function syntax?
-
- A: Doing so is currently perfectly legal.
-
- 5.10: Why does the declaration "extern f(struct x {int s;} *p);" give
- me a warning message?
-
- A: A struct declared only within a prototype cannot be compatible
- with other structs declared in the same source file.
-
- 5.11: I'm getting strange syntax errors inside code which I've
- #ifdeffed out.
-
- A: Under ANSI C, #ifdeffed-out text must still consist of "valid
- preprocessing tokens." This means that there must be no
- unterminated comments or quotes (i.e. no single apostrophes),
- and no newlines inside quotes.
-
- 5.12: Can I declare main as void, to shut off these annoying "main
- returns no value" messages?
-
- A: No.
-
- 5.13: Is exit(status) truly equivalent to returning status from main?
-
- A: Essentially.
-
- 5.14: Why does the ANSI Standard not guarantee more than six monocase
- characters of external identifier significance?
-
- A: The problem is older linkers which cannot be forced (by mere
- words in a Standard) to upgrade.
-
- 5.15: What is the difference between memcpy and memmove?
-
- A: memmove offers guaranteed behavior if the source and destination
- arguments overlap.
-
- 5.16: My compiler is rejecting the simplest possible test programs,
- with all kinds of syntax errors.
-
- A: Perhaps it is a pre-ANSI compiler.
-
- 5.17: Why are some ANSI/ISO Standard library routines showing up as
- undefined, even though I've got an ANSI compiler?
-
- A: Perhaps you don't have ANSI-compatible headers and libraries.
-
- 5.18: Why won't frobozz-cc, which claims to be ANSI compliant, accept
- this code?
-
- A: Are you sure that the code being rejected doesn't rely on some
- non-Standard extension?
-
- 5.19: Why can't I perform arithmetic on a void * pointer?
-
- A: The compiler doesn't know the size of the pointed-to objects.
-
- 5.20: Is char a[3] = "abc"; legal?
-
- A: Yes, in ANSI C.
-
- 5.21: What are #pragmas and what are they good for?
-
- A: The #pragma directive provides a single, well-defined "escape
- hatch" which can be used for extensions.
-
- 5.22: What does #pragma once mean?
-
- A: It is an extension implemented by some preprocessors to help
- make header files idempotent.
-
- 5.23: What's the difference between implementation-defined,
- unspecified, and undefined behavior?
-
- A: If you're writing portable code, ignore the distinctions.
- Otherwise, see the full list.
-
-
- Section 6. C Preprocessor
-
- 6.1: How can I write a generic macro to swap two values?
-
- A: There is no good answer to this question. The best all-around
- solution is probably to forget about using a macro.
-
- 6.2: I have some old code that tries to construct identifiers with a
- macro like "#define Paste(a, b) a/**/b ", but it doesn't work
- any more.
-
- A: Try the ANSI token-pasting operator ##.
-
- 6.3: What's the best way to write a multi-statement cpp macro?
-
- A: #define Func() do {stmt1; stmt2; ... } while(0) /* (no trailing ;) */
-
- 6.4: Is it acceptable for one header file to #include another?
-
- A: It's a question of style, and thus receives considerable debate.
-
- 6.5: Does the sizeof operator work in preprocessor #if directives?
-
- A: No.
-
- 6.6: How can I use a preprocessor #if expression to detect
- endianness?
-
- A: You probably can't.
-
- 6.7: I've got this tricky processing I want to do at compile time and
- I can't figure out a way to get cpp to do it.
-
- A: Consider writing your own little special-purpose preprocessing
- tool, instead.
-
- 6.8: How can I preprocess some code to remove selected conditional
- compilations, without preprocessing everything?
-
- A: Look for a program called unifdef, rmifdef, or scpp.
-
- 6.9: How can I list all of the pre#defined identifiers?
-
- A: Try extracting printable strings from the compiler or
- preprocessor executable.
-
- 6.10: How can I write a cpp macro which takes a variable number of
- arguments?
-
- A: Here is one popular trick. Note that the parentheses around
- printf's argument list are in the macro call, not the
- definition.
-
- #define DEBUG(args) (printf("DEBUG: "), printf args)
-
- if(n != 0) DEBUG(("n is %d\n", n));
-
-
- Section 7. Variable-Length Argument Lists
-
- 7.1: How can I write a function that takes a variable number of
- arguments?
-
- A: Use the <stdarg.h> (or older <varargs.h>) header.
-
- 7.2: How can I write a function that takes a format string and a
- variable number of arguments, like printf, and passes them to
- printf to do most of the work?
-
- A: Use vprintf, vfprintf, or vsprintf.
-
- 7.3: How can I discover how many arguments a function was actually
- called with?
-
- A: Any function which takes a variable number of arguments must be
- able to determine from the arguments themselves how many of them
- there are.
-
- 7.4: I can't get the va_arg macro to pull in an argument of type
- pointer-to-function.
-
- A: Use a typedef.
-
- 7.5: How can I write a function which takes a variable number of
- arguments and passes them to some other function (which takes a
- variable number of arguments)?
-
- A: In general, you cannot.
-
- 7.6: How can I call a function with an argument list built up at run
- time?
-
- A: You can't.
-
-
- Section 8. Boolean Expressions and Variables
-
- 8.1: What is the right type to use for boolean values in C? Why
- isn't it a standard type? Should #defines or enums be used for
- the true and false values?
-
- A: C does not provide a standard boolean type, because picking one
- involves a space/time tradeoff which is best decided by the
- programmer. The choice between #defines and enums is arbitrary
- and not terribly interesting.
-
- 8.2: What if a built-in boolean or relational operator "returns"
- something other than 1?
-
- A: When a boolean value is generated by a built-in operator, it is
- guaranteed to be 1 or 0. (This is _not_ true for some library
- routines such as isalpha.)
-
-
- Section 9. Structs, Enums, and Unions
-
- 9.1: What is the difference between an enum and a series of
- preprocessor #defines?
-
- A: At the present time, there is little difference. The ANSI
- standard states that enumerations are compatible with integral
- types.
-
- 9.2: I heard that structures could be assigned to variables and
- passed to and from functions, but K&R I says not.
-
- A: These operations are supported by all modern compilers.
-
- 9.3: How does struct passing and returning work?
-
- A: If you really need to know, see the unabridged list.
-
- 9.4: I have a program which works correctly, but dumps core after it
- finishes. Why?
-
- A: Check to see if a structure type declaration just before main is
- missing its trailing semicolon, causing the compiler to believe
- that main returns a structure. See also question 17.21.
-
- 9.5: Why can't you compare structs?
-
- A: There is no reasonable way for a compiler to implement struct
- comparison which is consistent with C's low-level flavor.
-
- 9.6: How can I read/write structs from/to data files?
-
- A: It is relatively straightforward to use fread and fwrite.
-
- 9.7: I came across some code that declared a structure with the last
- member an array of one element, and then did some tricky
- allocation to make the array act like it had several elements.
- Is this legal and/or portable?
-
- A: An ANSI Interpretation Ruling has deemed it to be not strictly
- conforming.
-
- 9.8: How can I determine the byte offset of a field within a
- structure?
-
- A: ANSI C defines the offsetof macro, which should be used if
- available.
-
- 9.9: How can I access structure fields by name at run time?
-
- A: Build a table of names and offsets, using the offsetof() macro.
-
- 9.10: Why does sizeof report a larger size than I expect for a
- structure type, as if there was padding at the end?
-
- A: The alignment of arrays of structures must be preserved.
-
- 9.11: How can I turn off structure padding?
-
- A: There is no standard method.
-
- 9.12: Can I initialize unions?
-
- A: ANSI Standard C allows an initializer for the first member.
-
- 9.13: Can I pass constant values to routines which accept struct
- arguments?
-
- A: No. C has no way of generating anonymous struct values.
-
-
- Section 10. Declarations
-
- 10.1: How do you decide which integer type to use?
-
- A: If you might need large values, use long. Otherwise, if space
- is very important, use short. Otherwise, use int.
-
- 10.2: What should the 64-bit type on new, 64-bit machines be?
-
- A: There are arguments in favor of long int and long long int,
- among other options.
-
- 10.3: I can't seem to define a linked list node which contains a
- pointer to itself.
-
- A: Structs in C can certainly contain pointers to themselves; the
- discussion and example in section 6.5 of K&R make this clear.
- Problems arise if an attempt is made to define (and use) a
- typedef in the midst of such a declaration; avoid this.
-
- 10.4: How do I declare an array of N pointers to functions returning
- pointers to functions returning pointers to characters?
-
- A: char *(*(*a[N])())();
- Using a chain of typedefs, or the cdecl program, makes these
- declarations easier.
-
- 10.5: How can I declare a function that returns a pointer to a
- function of its own type?
-
- A: You can't do it directly. Use a cast, or wrap a struct around
- the pointer and return that.
-
- 10.6: My compiler is complaining about an invalid redeclaration of a
- function, but I only define it once and call it once.
-
- A: Non-int functions must be declared before they are called.
-
- 10.7: What's the best way to declare and define global variables?
-
- A: It is best to place the definition in some central .c file, with
- an external declaration in a header file.
-
- 10.8: What does extern mean in a function declaration?
-
- A: Nothing, really.
-
- 10.9: How do I initialize a pointer to a function?
-
- A: Use something like "extern int func(); int (*fp)() = func; " .
-
- 10.10: I've seen different methods used for calling through pointers to
- functions.
-
- A: The extra parentheses and explicit * are now officially
- optional, although some older implementations require them.
-
- 10.11: What's the auto keyword good for?
-
- A: Nothing.
-
-
- Section 11. Stdio
-
- 11.1: Why doesn't the code "char c; while((c = getchar()) != EOF)..."
- work?
-
- A: The variable to hold getchar's return value must be an int.
-
- 11.2: Why doesn't the code scanf("%d", i); work?
-
- A: scanf needs pointers to the variables it is to fill in.
-
- 11.3: Why doesn't the code double d; scanf("%f", &d); work?
-
- A: Unlike printf, scanf uses %lf for double, and %f for float.
-
- 11.4: Why won't the code "while(!feof(infp)) {
- fgets(buf, MAXLINE, infp); fputs(buf, outfp); }" work?
-
- A: EOF is only indicated _after_ an input routine has reached end-
- of-file.
-
- 11.5: Why does everyone say not to use gets()?
-
- A: It cannot be prevented from overflowing the input buffer.
-
- 11.6: Why does errno contain ENOTTY after a call to printf?
-
- A: Don't worry about it. It is only meaningful for a program to
- inspect the contents of errno after an error has occurred.
-
- 11.7: My program's prompts and intermediate output don't always show
- up on the screen, especially when I pipe the output through
- another program.
-
- A: It is best to use an explicit fflush(stdout) whenever output
- should definitely be visible.
-
- 11.8: When I read from the keyboard with scanf, it seems to hang until
- I type one extra line of input.
-
- A: scanf was designed for free-format input, which is seldom what
- you want when reading from the keyboard.
-
- 11.9: I'm trying to update a file in place, by using fopen mode "r+",
- but it's not working.
-
- A: Be sure to call fseek between reading and writing.
-
- 11.10: How can I read one character at a time, without waiting for the
- RETURN key?
-
- A: See question 16.1.
-
- 11.11: Will fflush(stdin) flush unread characters from the standard
- input stream?
-
- A: No.
-
- 11.12: How can I redirect stdin or stdout from within a program?
-
- A: Use freopen.
-
- 11.13: Once I've used freopen, how can I get the original stdout back?
-
- A: It's not easy. Try avoiding freopen.
-
- 11.14: How can I recover the file name given an open file descriptor?
-
- A: This problem is, in general, insoluble. It is best to remember
- the names of files yourself when you open them.
-
-
- Section 12. Library Subroutines
-
- 12.1: Why does strncpy not always write a '\0'?
-
- A: For mildly-interesting historical reasons.
-
- 12.2: I'm trying to sort an array of strings with qsort, using strcmp
- as the comparison function, but it's not working.
-
- A: You'll have to write a "helper" comparison function which takes
- two generic pointer arguments, converts them to char **, and
- dereferences them, yielding char *'s which can be usefully
- compared.
-
- 12.3: Now I'm trying to sort an array of structures with qsort. My
- comparison routine takes pointers to structures, but the
- compiler complains that the function is of the wrong type for
- qsort. How can I cast the function pointer to shut off the
- warning?
-
- A: The conversions must be in the comparison function, which must
- be declared as accepting "generic pointers" (const void * or
- char *).
-
- 12.4: How can I convert numbers to strings?
-
- A: Just use sprintf.
-
- 12.5: How can I get the time of day in a C program?
-
- A: Just use the time, ctime, and/or localtime functions.
-
- 12.6: How can I convert a struct tm or a string into a time_t?
-
- A: The ANSI mktime routine converts a struct tm to a time_t. No
- standard routine exists to parse strings.
-
- 12.7: How can I perform calendar manipulations?
-
- A: The ANSI/ISO Standard C mktime and difftime functions provide
- support for both problems.
-
- 12.8: I need a random number generator.
-
- A: The standard C library has one: rand().
-
- 12.9: How can I get random integers in a certain range?
-
- A: One method is something like
-
- (int)((double)rand() / ((double)RAND_MAX + 1) * N)
-
- 12.10: Each time I run my program, I get the same sequence of numbers
- back from rand().
-
- A: You can call srand() to seed the pseudo-random number generator
- with a more random initial value.
-
- 12.11: I need a random true/false value, so I'm taking rand() % 2, but
- it's just alternating 0, 1, 0, 1, 0...
-
- A: Try using the higher-order bits.
-
- 12.12: I'm trying to port this old program. Why do I get "undefined
- external" errors for some library routines?
-
- A: Some semistandard routines have been renamed or replaced over
- the years; see the full list for details.
-
- 12.13: I get errors due to library routines being undefined even though
- I #include the right header files.
-
- A: You may have to explicitly ask for the correct libraries to be
- searched.
-
- 12.14: I'm still getting errors due to library routines being
- undefined, even though I'm requesting the right libraries.
-
- A: Library search order is significant; usually, you must search
- the libraries last.
-
- 12.15: I need some code to do regular expression matching.
-
- A: regexp libraries abound; see the full list for details.
-
- 12.16: How can I split up a string into whitespace-separated arguments?
-
- A: Try strtok.
-
-
- Section 13. Lint
-
- 13.1: I just typed in this program, and it's acting strangely. Can
- you see anything wrong with it?
-
- A: Try running lint first.
-
- 13.2: How can I shut off the "warning: possible pointer alignment
- problem" message lint gives me for each call to malloc?
-
- A: It may be easier simply to ignore the message, perhaps in an
- automated way with grep -v.
-
- 13.3: Where can I get an ANSI-compatible lint?
-
- A: See the unabridged list for two commercial products.
-
-
- Section 14. Style
-
- 14.1: Is the code "if(!strcmp(s1, s2))" good style?
-
- A: Not particularly.
-
- 14.2: What's the best style for code layout in C?
-
- A: There is no one "best style," but see the full list for a few
- suggestions.
-
- 14.3: Where can I get the "Indian Hill Style Guide" and other coding
- standards?
-
- A: See the unabridged list.
-
-
- Section 15. Floating Point
-
- 15.1: My floating-point calculations are acting strangely and giving
- me different answers on different machines.
-
- A: First, make sure that you have #included <math.h>, and correctly
- declared other functions returning double. If the problem isn't
- that simple, see the full list for a brief explanation, or any
- good programming book for a better one.
-
- 15.2: I keep getting "undefined: _sin" compilation errors.
-
- A: Make sure you're linking with the correct math library.
-
- 15.3: Where is C's exponentiation operator?
-
- A: Try using the pow() function.
-
- 15.4: How do I round numbers?
-
- A: The simplest way is with code like (int)(x + 0.5) .
-
- 15.5: How do I test for IEEE NaN and other special values?
-
- A: There is not yet a portable way, but see the full list for
- ideas.
-
- 15.6: I'm having trouble with a Turbo C program which crashes and says
- something like "floating point formats not linked."
-
- A: Some compilers for small machines, including Turbo C, attempt to
- leave out floating point support if it looks like it will not be
- needed. The programmer must occasionally insert an extra,
- explicit call to a floating-point library routine to force
- loading of floating-point support.
-
-
- Section 16. System Dependencies
-
- 16.1: How can I read a single character from the keyboard without
- waiting for a newline?
-
- A: Contrary to popular belief and many people's wishes, this is not
- a C-related question. How to do so is a function of the
- operating system in use.
-
- 16.2: How can I find out if there are characters available for reading
- (and if so, how many)? Alternatively, how can I do a read that
- will not block if there are no characters available?
-
- A: These, too, are entirely operating-system-specific.
-
- 16.3: How can I clear the screen?
-
- A: Such things depend on the output device you're using.
-
- 16.4: How do I read the mouse?
-
- A: What system are you using?
-
- 16.5: How can my program discover the complete pathname to the
- executable file from which it was invoked?
-
- A: argv[0] may contain all or part of the pathname. You may be
- able to duplicate the command language interpreter's search path
- logic to locate the executable.
-
- 16.6: How can a process change an environment variable in its caller?
-
- A: In general, it cannot.
-
- 16.7: How can I check whether a file exists?
-
- A: You can try the access() routine.
-
- 16.8: How can I find out the size of a file, prior to reading it in?
-
- A: You might be able to get an estimate using stat() or
- fseek/ftell.
-
- 16.9: How can a file be shortened in-place without completely clearing
- or rewriting it?
-
- A: There are various ways to do this, but there is no truly
- portable solution.
-
- 16.10: How can I implement a delay, or time a user's response, with
- sub-second resolution?
-
- A: Unfortunately, there is no portable way.
-
- 16.11: How can I read in an object file and jump to routines in it?
-
- A: You want a dynamic linker and/or loader.
-
- 16.12: How can I invoke an operating system command from within a
- program?
-
- A: Use system().
-
- 16.13: How can I invoke an operating system command and trap its
- output?
-
- A: Unix and some other systems provide a popen() routine.
-
- 16.14: How can I read a directory in a C program?
-
- A: See if you can use the opendir() and readdir() routines.
-
- 16.15: How can I do serial ("comm") port I/O?
-
- A: It's system-dependent.
-
-
- Section 17. Miscellaneous
-
- 17.1: What can I safely assume about the initial values of variables
- which are not explicitly initialized?
-
- A: Variables with "static" duration start out as 0, as if the
- programmer had initialized them. Variables with "automatic"
- duration, and dynamically-allocated memory, start out containing
- garbage (with the exception of calloc).
-
- 17.2: What's wrong with
-
- f() { char a[] = "Hello, world!"; }
-
- A: Perhaps you have a pre-ANSI compiler.
-
- 17.3: How can I write data files which can be read on other machines
- with different data formats?
-
- A: The best solution is to use text files.
-
- 17.4: How can I delete a line from the middle of a file?
-
- A: Short of rewriting the file, you probably can't.
-
- 17.5: How can I return several values from a function?
-
- A: Either pass pointers to locations which the function can fill
- in, or have the function return a structure containing the
- desired values.
-
- 17.6: How can I call a function, given its name as a string?
-
- A: The most straightforward thing to do is maintain a
- correspondence table of names and function pointers.
-
- 17.7: I seem to be missing the system header file <sgtty.h>. Can
- someone send me a copy?
-
- A: You cannot just pick up a copy of someone else's header file and
- expect it to work, since the definitions within header files are
- frequently system-dependent. Contact your vendor.
-
- 17.8: How can I call FORTRAN (C++, BASIC, Pascal, Ada, LISP) functions
- from C?
-
- A: The answer is entirely dependent on the machine and the specific
- calling sequences of the various compilers in use.
-
- 17.9: Does anyone know of a program for converting Pascal or FORTRAN
- to C?
-
- A: Several public-domain programs are available, namely ptoc, p2c,
- and f2c. See the full list for details.
-
- 17.10: Can I use a C++ compiler to compile C code?
-
- A: Not necessarily; C++ is not a strict superset of C.
-
- 17.11: I'm looking for C development tools (cross-reference generators,
- code beautifiers, etc.).
-
- A: See the full list for a few names.
-
- 17.12: Where can I get copies of all these public-domain programs?
-
- A: See the regular postings in the comp.sources.unix and
- comp.sources.misc newsgroups for information.
-
- 17.13: When will the next Obfuscated C Code Contest be held? How can I
- get a copy of the previous winning entries?
-
- A: See the full list, or send e-mail to judges@toad.com .
-
- 17.14: Why don't C comments nest? Are they legal inside quoted
- strings?
-
- A: Nested comments would cause more harm than good. The character
- sequences /* and */ are not special within double-quoted
- strings.
-
- 17.15: How can I get the ASCII value corresponding to a character?
-
- A: In C, if you have the character, you have its value.
-
- 17.16: How can I implement sets and/or arrays of bits?
-
- A: Use arrays of char or int, with a few macros to access the right
- bit at the right index.
-
- 17.17: What is the most efficient way to count the number of bits which
- are set in a value?
-
- A: This and many other similar bit-twiddling problems can often be
- sped up and streamlined using lookup tables.
-
- 17.18: How can I make this code more efficient?
-
- A: Efficiency is not important nearly as often as people tend to
- think it is. Most of the time, by simply paying attention to
- good algorithm choices, perfectly acceptable results can be
- achieved.
-
- 17.19: Are pointers really faster than arrays? How much do function
- calls slow things down?
-
- A: Precise answers to these and many similar questions depend of
- course on the processor and compiler in use.
-
- 17.20: Why does the code "char *p = "Hello, world!";
- p[0] = tolower(p[0]);" crash?
-
- A: String literals are not modifiable, except (in effect) when they
- are used as array initializers.
-
- 17.21: This program crashes before it even runs!
-
- A: Look for very large, local arrays.
- (See also question 9.4.)
-
- 17.22: What does "Segmentation violation" mean?
-
- A: It generally means that your program tried to access memory it
- shouldn't have.
-
- 17.23: My program is crashing, apparently somewhere down inside malloc.
-
- A: Make sure you aren't using more memory than you malloc'ed,
- especially for strings (which need strlen() + 1 bytes).
-
- 17.24: Does anyone have a C compiler test suite I can use?
-
- A: See the full list for several sources.
-
- 17.25: Where can I get a YACC grammar for C?
-
- A: See the ANSI Standard, or the unabridged list.
-
- 17.26: I need code to parse and evaluate expressions.
-
- A: Two available packages are mentioned in the full list.
-
- 17.27: I need to compare two strings for close, but not necessarily
- exact, equality.
-
- A: The traditional routine for doing this sort of thing involves
- the "soundex" algorithm.
-
- 17.28: How can I find the day of the week given the date?
-
- A: Use Zeller's congruence.
-
- 17.29: Will 2000 be a leap year?
-
- A: Yes.
-
- 17.30: How do you pronounce "char"?
-
- A: Like the English words "char," "care," or "car" (your choice).
-
- 17.31: What's a good book for learning C?
-
- A: There are far too many to list here; the full list contains a
- few pointers.
-
- 17.32: Are there any C tutorials on the net?
-
- A: There are at least two of them.
-
- 17.33: Where can I get extra copies of this list?
-
- A: For now, just pull it off the net; the unabridged version is
- normally posted on the first of each month, with an Expires:
- line which should keep it around all month. It can also be
- found in the newsgroups comp.answers and news.answers . Several
- sites archive news.answers postings and other FAQ lists,
- including this one: two sites are rtfm.mit.edu (directory
- pub/usenet), and ftp.uu.net (directory usenet). The archie
- server should help you find others.
-
- Steve Summit
- scs@eskimo.com
-
- This article is Copyright 1988, 1990-1994 by Steve Summit.
- It may be freely redistributed so long as the author's name, and this
- notice, are retained.
-