Scholarly Resources for CompSci Undergrads

C Programming Language

Annotations on K&R II

This document contains the following sections and subsections:


Upon re-reading The C Programming Language (second edition) by Brian W. Kernighan and Dennis M. Ritchie (aka K&R II) I was surprised to find it much richer than I had remembered. I took the uncharacteristic step of writing notes in the margins of my copy. Some of those notes are reproduced below in the hopes that others will find them helpful too.

I don't want to give the impression that K&R II should replace the ISO Standard or the ANSI Rationale. I use K&R II as an introduction and tutorial to the C language. Experienced C programmers will find Harbison and Steele's C: A Reference Manual a better reference work (in my opinion, of course). The Standard is, as its title implies, the definition of the modern C language. Harbison and Steele provide descriptions of both ISO/ANSI and pre-ANSI C, by the way.

Dateline 1999: A New Standard, A New C

Note that K&R II describes the 1989/1990 version of the ANSI/ISO C standard. In 1999 a new C standard (ISO/IEC 9899:1999) was approved by the ISO. I am not yet in a position to recommend a good reference to the new standard (other than itself). My understanding is that the only change in the new standard that could break old code is that // can now be used to begin a single-line comment. The mavens in the comp.lang.c.moderated newsgroup (Douglas Gwyn and Dan Pop in particular) know much more about this than I do.

Quick References

Below are some notes I use myself as a mini index.

Array bounds
pp. 100, 103
Arrays are row major (final dimension varies fastest)
p. 112
Boolean values (0 == FALSE)
p. 42
Brace style
p. 10
printf() string precision examples

I think Harbison and Steele is a better reference work about C than K&R is, but there are still some times when I prefer the tables in K&R. So I've put together a seperate document with a list of index of the tables I have written on page viii of my copy of K&R. That document uses the HTML table standard described in the HTML 3.2 standard. I also have a plaintext version. Use whichever you prefer:

Once upon a time, Greg Haley had online versions of all of the tables.

See also

My list of recommended books about computer programming includes full citation information about the books mentioned above and references to other online C resources. My example of how to encapsulate data types in C might interest you. It uses lots of stuff from K&R II.

Steve Summit has written a course about C programming largely consisting of annotations on K&R II (and another course that is largely independent of outside references).

The errata notices are helpful too.

Once upon a time Greg Haley had online versions of all of the tables.

Richard Heathfield maintains a list of Answers to Exercises from the book. Those answers are separate from those in The C Answer Book (2e) (by Clovis L. Tondo and Scott E. Gimpel, published and copyright by Prentice-Hall 1989) and, most importantly, some of the answers take account of the 1999 C Standard.

The Annotations

I've listed my annotations in three parts: clarifications, cross-references and scattered discussions. Also, I keep a very short list of so-called quick-references above.


p. 6
main() should have a return (see pp. 26 and 164)
p. 9
comments do not nest (see p. 34)
p. 10
The difference between semicolons in C and other languages, especially Pascal, is further explained on p. 55
pp. 53 - 54
The behaviour of code like a[i] = i++; is not unspecified, it is undefined!
This example is discussed in two sections of Steve Summit's comp.lang.c FAQ: Section 3 (`Expressions') explains why that code, and variations on it, are abominable. The book version of the FAQ list has some very clear advice on what to avoid when programming expressions; Section 11 (`ANSI/ISO Standard C') in the online list (and the book of course) explains the differences between implementation-defined, unspecified, and undefined behavior and why they exist.
p. 90
## and # are used during macro expansion only. The comp.lang.c FAQ has something to say about this point.
pp. 94, 103, 120
void * cannot hold function pointers. For further clarification within K&R II see Sections A6.8 (Pointers to Void on p. 199), A.4 (Meaning of Identifiers on p. 195) and A.5 (Objects and Lvalues on p. 197).
p. 126 (Excercise 5-20)
Before you try incorporating const into dcl see my comment on p. 146. (const was introduced on p. 40.)
p. 135
sizeof is better defined in Section A7.4.8 (Sizeof Operator, on p. 204).
p. 143
I think that a user supplied definition of strdup() (which is not in the standard library by the way) would violate the ISO standard for function names. Steve Summit wrote about this in question 1.29 (pp. 23 - 26) of C Programming FAQs.
p. 146
Be wary of using const with typedef: const qualifies the whole type encapsulated with typedef. For example `typedef char * String; const String cs' means the same as `char * const cs' (a constant pointer) not `const char * cs' (a pointer to a constant character).
p. 159
I find the statement that an array name is a pointer misleading. See p. 99 for the details.
p. 119
Note that: (1) char * is not the same as void * and (2) this qsort() is not necessarily the same as the standard library's. (I got these points from a comment on p. 229 (question 13.8) of Steve Summit's C Programming FAQs.)
p. 142
It is not necessary to cast the values returned by malloc in ANSI C. In fact it can make it hard to detect certain programming errors (caused by not including appropriate headers).
The same note applies to p. 167.
p. 163
Also, by default, stderr is unbuffered (p. 168)
pp. 164, 247
You are well advised not to use gets() as it cannot check for overflow. See question 12.23 on pp. 208 - 209 of Steve Summit's C Programming FAQs (or the online version) for more details.
p. 167
Peter Seebach has (or at least had on 6 May 1996) this comment on his so-called Useless K&R Page: It is asserted that the pointer returned by malloc or calloc must be converted to an appropriate type; this is not true in ANSI C.
p. 183
size_t is defined in <stddef.h> (pp. 260-1). (<sys/types.h> is not part of the ANSI/ISO C standard libraries, although it may be in the POSIX standard.)
p. 241
Peter Seebach has (or at least had on 6 May 1996) this comment on his so-called Useless K&R Page: Of course, actually the library is a part of the language, and although it must be possible to take the address of the functions in the library, a compiler is allowed to inline and optimize calls, and many do. However, it is a part of the language definition. (Of course, it's not a part of a freestanding implementation; in this respect, the book is correct.)
p. 244 (Table B-1)
x,X: argument must be unsigned. (An erratum that was included in the official errata list on 29 October 1998. Thanks to Dan Pop and Tanmoy Bhattacharya for pointing this out in comp.lang.c.)
pp. 247
Don't use gets(). See my note for p. 164 for more details.
p. 255
tm_sec: the committee mistakenly thought there could be as many as 2 leap seconds in one minute (thanks to Richard A. O'Keefe for the explanation)
p. 257
%S: the committee mistakenly thought there could be as many as 2 leap seconds in one minute (thanks to Richard A. O'Keefe for the explanation)

I found the errata notices helpful too.


I've included references to expanded definitions that appear later in the text. My copy also has exact page numbers for many of the cross-references by section, but there is no point to including those here.

p. 14 (Section 1.4: Symbolic Constants)
See bottom of p. 39 for discussion of an alternative (using enum)
p. 26
The conventional interpretation of the return statement appears at the top of p. 164.
p. 33
See extern declarations below
p. 38
More about string constants on p. 104
p. 40
The definition of static is on p. 83
p. 40
variable initialization is dealt with on p. 85
p. 42
NULL is equivalent to zero in this context (see p. 102)
p. 48 (Section 2.9: Bitwise Operators)
see also Section 6.9 (Bit-fields) on pp. 149 - 150
p. 48
There is an example of operator precedence on p. 52 (Section 2.12)
p. 63
A different swap appears on p. 96
p. 68
Pointers are discussed in Chapter 5
p. 73
For information about type conversion by return see the top of p. 255 and Section A6.5 (Arithmetic Conversions) on p. 198
p. 83 (Section 4.7: Register Variables)
Even though the compiler is free to ignore the declaration register variables can be used as documentation that the variables will be heavily used and that their addresses will not be computed, e.g. the & operator will not be applied to them.
p. 77
See extern declarations below
p. 80
See extern declarations below
pp. 91, 103
sizeof is explained on p. 135
p. 96
Compare this swap with pp. 62 - 3 and p. 88
p. 100
Regarding array bounds see also the top of p. 103 and the example (and accompanying text) on p. 138
p. 101
static variables are defined on p. 83
p. 104
string constants are static (see Section A2.6 on p. 194)
p. 110 (Section 5.7: Multi-dimensional Arrays)
See also Section A.6.2 (Array Declarators on pp. 216-7)
p. 135 NKEYS macro
What if an array is passed to a function? (See the paragraph beginning When an array name is passed to a function... on p. 99, and the binsearch() on p. 137.) [Although K&R make this point clearly some discussion in the comp.lang.c newsgroup makes me think that I should take extra steps to make sure that it stands out. (Jan 1998)]
p. 137 (binsearch())
Note that the size (int n) is still needed because the array's size cannot be determined when it is passed to a function (see p. 99).
p. 165
register declaration introduced on p. 83
p. 174
Section 7.6: Error Handling -- Stderr and Exit is on pp. 163-4
Section 7.3: Variable-length Argument Lists is on pp. 155-6
See also Errors: detecting and handling below
p. 243-245
The examples of printf() in Section 7.2 (pp. 153-155) are helpful

Scattered Discussions

extern declarations
introduced on
p. 33
example on
p. 77
additional discussion on
p. 80 (Section 4.4)
Errors: detecting and handling
Returns from functions should be checked for errors
p. 141
An example of an error indication being passed on to the caller
p. 143
Useful values should be returned from programs
p. 164
error(): an example of a general error-reporting function
p. 174
I prefer my version
p. 252


Full citation information for any works cited above can be found in my list of recommended books about computer programming that I mentioned at the top of this document. The Taylor library at UWO has a copy of the ISO/ANSI standard (989:1990(E), approved 3 Aug 1992) at shelf location QA76.73.C15 A44 1990.

The See also section above may also be of interest to you.

Last updated by J. Blustein on 04 November 2001

This document is copyright by its author, J. Blustein <>.

This document encoded in valid XHTML 1.0