You've probably had the experience, in a bar or at a party, of losing a bet on whether you could perform some seemingly simple task which turned out, based on idiosyncrasies of the human body or the laws of physics, to be impossible. The guy making the bet knew that the more people he challenged, the more likely he was to keep winning, because those idiosyncrasies and laws, even if obscure, are fairly constant and predictable.
In a similar way, if you take a large number of people and set them at some complex task, such as learning the C programming language, many of them will run into exactly the same problems and have exactly the same questions. The questions and problems may or may not have been predictable when the task was first designed, and the answers may seem obvious in hindsight, but people will keep having some of the same problems, and the same questions will keep coming up. These problems and questions don't necessarily indicate that the task was impossible, but merely that it was difficult enough to be interesting.
Not surprisingly, these problems and questions are regularly asked on the Internet, particularly in the interactive discussion newsgroups known as Usenet. The reasonably obvious idea of collecting the frequent questions gave rise to a tradition of Frequently Asked Questions or FAQ lists. FAQ lists don't always serve their intended purpose of reducing the incidence of frequently asked questions, but if the questions are in fact consistent, the fact that they were asked often enough to be selected for inclusion in an FAQ list suggests that they might match questions which you or some other readers of this book are asking, too.
Most books (about C or any other topic) are written from the author's point of view. They discuss the topics the author thinks you should know, presented in a way which makes sense to the author. If that way doesn't make sense to you (and, at some level, it can't, because the author presumably knows the material already while you presumably don't), you may be left with deep, unanswered questions.
This book, however, is organized around some 400 of those questions, all based on real ones asked by real people attempting to learn or program in C. This book is not targeted at just those topics that the author thinks are important; it is targeted at the topics that real readers think are important, based on the questions they ask. The chances are good that if you are learning or using C, and you have a question about C which isn't answered in any of the other books you've checked, you'll find it answered here.
This book can't promise to answer every question you'll have when you're programming in C, since many of the questions that will come up in your programming will have to do with your problem domain, and this book covers only the C language itself. Just as it can't cover every aspect of every problem anyone might try to solve in C, this book cannot cover every aspect of every operating system which anyone might try to write a C program for, or every algorithm which anyone might try to implement in C. Specific problems, specific operating systems, and general-purpose algorithms are properly discussed in books or other materials devoted to those topics. Nevertheless, certain questions involving operating systems and algorithms are quite frequent, so chapters 19 and 20 provide brief, introductory answers to a few of them, but please don't expect the treatment to be complete.
The questions in this book are those that people typically have after reading an introductory C textbook or taking a C programming class. Therefore, this book will not teach you C, nor does it discuss fundamental issues which any C textbook should cover. Furthermore, this book's answers are intended for the most part to be definitively correct, and to avoid propagating any misconceptions. Therefore, a few answers are more elaborate than might at first seem necessary: they give you the complete picture, rather than oversimplifying or leaving out important details. (It is, after all, oversimplifications or omitted details which are behind many of the misconceptions which this book's questions and answers address.) Within the elaborate answers you will find shortcuts and simplifications where necessary, and in the Glossary beginning on page xxx you will find definitions of the precise terms which accurate explanations often demand. The shortcuts and simplifications are of course safe ones: they should not lead to later misunderstandings, and you can always come back to the more complete explanations, or pursue some of the references, if you later desire the full story.
As we'll see particularly in chapters 3 and 11, the standard definitions of C do not specify the behavior of every C program which can be written. Some programs fall into various gray areas: they may happen to work on some systems, and they may not be strictly illegal, but they are not guaranteed to work everywhere. This book is about portable C programming, so its answers advise against using nonportable constructs if at all possible.
The on-line FAQ list behind this book was written as a dialog: when people didn't understand it, they said so. That feedback has been invaluable in refining the form of the answers. Though a printed book is obviously more static, such a dialog is still appropriate: your comments, criticisms and suggestions are welcome. If you have access to the Internet, you may send comments to scs@aw.com, or you may send them on paper in care of the publisher. A list of any errors which are discovered in this book will be maintained and available on the Internet; see question 20.40 for information.
The bulk of this book consists of a series of question/answer pairs. Many answers also contain references and notes. The notes, where they appear, are on the order of footnotes; you can skip them if you find that they're too picky. Several respected references are cited repeatedly, under these abbreviations:
This constant width typeface is used to indicate C syntax (function and variable names, keywords, etc.), and also to indicate a few operating system commands (cc, etc.). An occasional notation of the form tty(4) indicates the section ``tty'' in chapter 4 of the Unix Programmer's manual.
This is a book about C, so many small pieces of it are necessarily written in C. The examples are written primarily for clarity of exposition. They are not always written in the most efficient way possible; making them ``faster'' would often make them less clear. (See question 20.13 for more information about code efficiency.) They are primarily written using modern, ANSI-style syntax; see question 11.29 for conversion tips if you're still using a ``Classic'' compiler.
The author and publisher invite you to use and modify these code fragments in your own programs, but of course we would appreciate acknowledgment if you do so. (Some fragments are from other sources, and are so attributed; please acknowledge those contributors if you use those codes.) The source code for the larger examples is available on the Internet via anonymous ftp from aw.com in directory cseng/authors/summit/cfaq (see also question 18.12).
To underscore certain points, it has unfortunately been necessary to include a few code fragments which are examples of things not to do. In the answers, such code fragments are marked with an explicit comment like /* WRONG */ to remind you not to emulate them. (Code fragments in questions are not usually so marked; it should be obvious that the code fragments in questions are suspect, as the question is usually ``Why doesn't this work?'')
As was already mentioned, this book's questions are based on real questions asked by real people, and real-world questions do not always fall into neat hierarchies. Many questions touch on several topics: what seems to be a memory allocation problem may actually reflect an improper declaration. (Several questions which straddle chapter boundaries appear in both chapters, to make them easier to find.) In any case, this is not a book you have to read through sequentially: use the table of contents, the list of questions beginning on page xxx, the index, and the cross-references between questions to find the topics that are of interest to you. (And, if you have some free time, you may find yourself reading through sequentially anyway; perhaps you'll encounter the answer to a question you hadn't thought to ask yet.)
Usually, before you can start writing code you have to declare your data structures, so chapter 1 starts out by talking about declaration and initialization. C's structure, union, and enumeration types are complicated enough that they deserve a chapter of their own; chapter 2 discusses how they are declared and used.
Most of the work of a program is carried out by expression statements, which are the subject of chapter 3.
Chapters 4 through 7 discuss the bane of many a beginning C programmer: pointers. Chapter 4 covers pointers in general, chapter 5 focuses on the special case of null pointers, chapter 6 describes the relationship between pointers and arrays, and chapter 7 explores what is often the real problem when pointers are misbehaving: the underlying memory allocation.
Almost all C programs manipulate characters and strings, but these types are implemented at a low level by the language. The programmer is often responsible for managing these types correctly; some questions which come up while doing so are collected in chapter 8. Similarly, C does not have a formal Boolean type; chapter 9 briefly discusses C's Boolean expressions and the appropriate ways of implementing a user-defined Boolean type, if desired.
The C preprocessor (the part of the compiler responsible for handling #include and #define directives, and in fact all lines beginning with #) is distinct enough that it almost represents a separate language, and is covered in its own chapter, chapter 10.
The ANSI C Standardization committee (X3J11), in the process of clarifying C's definition and making it palatable to the world, introduced a number of new features and made a few significant changes. Questions specific to ANSI/ISO Standard C are collected in chapter 11. If you had experience with pre-ANSI C (also called ``K&R'' or ``Classic'' C), you will find chapter 11 to be a useful introduction to the differences. If you are comfortably using ANSI C, on the other hand, the distinction between pre-ANSI and ANSI features may not be interesting. In any case, all of the questions in chapter 11 which also relate to other topics (declarations, the C preprocessor, library functions, etc.) also appear in or are otherwise cross-referenced from those other chapters.
C's definition is relatively Spartan in part because many features are not built in to the language, but are accessed via library functions. The most important of these are the ``Standard I/O'' or ``stdio'' functions, which are discussed in chapter 12. Other library functions are covered in chapter 13.
Chapters 14 and 15 discuss two more advanced topics: floating point and variable-length argument lists. Floating-point computations tend to be tricky no matter what system or language you're using; chapter 14 outlines a few general floating point issues and a few which are specific to C. The possibility that a function can accept a varying number of arguments, though perhaps arguably unnecessary or dangerous, is occasionally convenient and is central to C's printf function; techniques for dealing with variable-length argument lists are discussed in chapter 15.
Hiding in chapter 16 are some questions which you may want to jump to first if you're already comfortable with most of the preceding material: they concern the occasional strange problems and mysterious bugs which crop up in a program and can be agonizingly frustrating to track down.
When there are two or more equally ``correct'' ways of writing a program (and there usually are), one may be preferable based on subjective criteria having to do with more than whether the code simply compiles and runs correctly. Chapter 17 discusses a few of these ephemeral issues of programming style.
You can't build C programs in isolation: you need a compiler, and you may need some additional documentation, source code, or tools. Chapter 18 discusses some available tools and resources, including lint, a nearly forgotten but once indispensable tool for checking certain aspects of program correctness and portability.
As mentioned, the C language does not specify everything you necessarily need to get a real program working. Questions such as ``How do I read one character without waiting for the RETURN key?'' and ``How do I find the size of a file?'' are extremely common, but C does not define the answers; these operations depend on the facilities provided by the underlying operating system. Chapter 19 presents a number of these questions along with brief answers for popular operating systems.
Finally, chapter 20 collects the miscellaneous questions that don't fit anywhere else: bit manipulation, efficiency, algorithms, C's relationship to other languages, and a few trivia questions. (The introduction to chapter 20 contains a slightly more detailed breakdown of its disparate contents.)
To close this introduction, here are two preliminary questions, not so much about C, but more about this book:
Q: Why should I buy this book, if it's available for free on the net?
A: This book contains over three times as much material as does the version that's posted to comp.lang.c. and in spite of the advantages of electronic documentation, it really can be easier to deal with this amount of information in a printed form. (You'd spend a lot of time downloading this much information from the net and printing it, and the typography wouldn't be as pretty, either.)
Q: How do you pronounce ``FAQ''?
A: I pronounce it ``eff ay kyoo,'' and this was, I believe, the original pronunciation when FAQ lists were first ``invented.'' Many people now pronounce it ``fack,'' which is nicely evocative of the word ``fact.'' I'd pronounce the plural, as in the title of this book, ``eff ay kyooze'', but many people pronounce it like ``fax.'' None of these pronunciations are strictly right or wrong; ``FAQ'' is a new term, and popular usage plays a certain role in shaping any term's evolution.
(It's equally imponderable, by the way, whether ``FAQ'' refers to the question alone, or to the question plus its answer, or to the whole list of questions and answers.)
But now, on with the real questions!