Errata for The C Programming Language, Second Edition
This lists all known errors in The C Programming Language, Second
Edition, by Brian Kernighan and Dennis Ritchie (Prentice-Hall, 1988).
Changes between first and second printing:
The first printing of the book was made before the Standard was finalized;
these copies say "Based on Draft-Proposed ANSI C" on the front cover. All
subsequent printings are identified by a large red ``ANSI C'' on the right
center of the cover. Fortunately, the changes are minor; some repair our bugs, a
few account for last-minute changes in the draft standard. These changes were
made so early that they probably do not apply to you.
Two or three sentences in the Preface and Introduction are updated to
describe the state of the Standard.
atof is in stdlib.h, not math.h; this changes
pages 71, 76, 82, 121.
On page 86, error corrected: missing automatic initializers are zero too.
On page 168: changed 1 to 1.0 to avoid potential overflow.
Minor typos are corrected on pages 87, 89, 164, 165, 168, 180.
The inconspicuous references to noalias on pages 192 and 211 are
removed.
The following paragraph is added to the end of section A6.6 (page 199):
``A pointer may be converted to another pointer whose type is the same except
for the addition or removal of qualifiers (A4.4, A8.2) of the object type to
which the pointer refers. If qualifiers are added, the new pointer is equivalent
to the old except for restrictions implied by the new qualifiers. If qualifiers
are removed, operations on the underlying object remain subject to the
qualifiers in its actual declaration.''
On page 199, beginning of section A6.8, ``Any pointer may be converted to
type void *...'' is changed to ``Any pointer to an object may
be converted to type void *...''.
On page 204, A7.4.4, ``The operand of the unary + operator must have
arithmetic or pointer type...'' should read ``must have arithmetic type...''.
On page 206, A7.9, about relational operators: ``Pointers to objects of the
same type may be compared...'' is changed to ``Pointers to object of the same
type (ignoring any qualifiers) may be compared...''.
The indented material on page 209, ``According to the restrictions...
relaxing it.'' is removed. [This is related to the paragraph added above. The
wording of the penultimate draft made it useless to take an (int *)
pointer, cast it to (const int *), then cast it back to (int
*).]
On page 219 middle, initialization of structures, add ``Unnamed bit-field
members are ignored, and are not initialized.''
Appendix B changes:
p 242: Add ``fflush(NULL) flushes all output streams.'' to
fflush description.
p 243: Change to ``it must be called before reading, writing or any other
operation'' in setvbuf description.
p 249: Add ``Comparison functions treat arguments as unsigned char
arrays.'' to string.h description.
p 255: Change range of tm_sec to (0,61) for leap seconds.
p 255: Change CLK_TCK to CLOCKS_PER_SEC.
p 257: Drop U and L suffixes from limits.h constants.
tm_sec range is (0,61) here too.
Appendix C change:
p 261: Change ``External declarations without any specifiers...'' to
``External data declarations without any specifiers...''.
The index has been reprinted to fix a couple of typos and account for motion
within Appendix A; one page of the table of contents is changed.
A later printing in October, 1989, made minor changes on page 131 to add
& to the last example, on page 208 to change ``equal'' to ``unequal'' in the
description of logical OR, and on page 254 to clarify that only volatile
automatics are saved with longjmp.
Errors not corrected in any printing:
The following errors have not yet been fixed in any printing.
41: The loop at the bottom of the page is functionally equivalent to the one
on page 29, but not identical in form, as is implied by the text.
44: 1U is an unsigned int, not an int.
49: In the discussion of shift operators, `which must be positive' should be
`which must be non-negative'.
53: Note under the table should say & as well as + - * has higher
precedence as a unary operator.
102: NULL is standardly defined in <stddef.h>, although it is likely to
appear in <stdio.h> as well.
111: Indent is too large, and a bit of program text is cut off.
114: quote missing in "Jan, near top of page.
119-121: The qsort discussion needs recasting in several ways. First, qsort
is a standard routine in ANSI/ISO C, so the rendition here should be given a
different name, especially because the arguments to standard qsort are a bit
different: the standard accepts a base pointer and a count, while this example
uses a base pointer and two offsets.
Also, the comparison-routine argument is not treated well. The call shown on
p 119, with an argument
(int (*)(void*,void*))(numeric? numcmp : strcmp)
is not only complicated, but only barely passes muster. Both numcmp and
strcmp take char * arguments, but this expression casts pointers to these
functions to a function pointer that takes void * arguments. The standard does
say that void * and char * have the same representation, so the example will
almost certainly work in practice, and is at least defensible under the
standard. There are too many lessons in these pages.
142: The remark about casting the return value of malloc ("the proper method
is to declare ... then explicitly coerce") needs to be rewritten. The example is
correct and works, but the advice is debatable in the context of the 1988-1989
ANSI/ISO standards. It's not necessary (given that coercion of void * to
ALMOSTANYTYPE * is automatic), and possibly harmful if malloc, or a proxy for
it, fails to be declared as returning void *. The explicit cast can cover up an
unintended error. On the other hand, pre-ANSI, the cast was necessary, and it is
in C++ also.
143: strdup is not indexed.
164, 165: (text and code) fputs returns EOF on error, non-negative
for OK.
167: [the return value of malloc or calloc] "must be cast into the
appropriate type" is incorrect as stated. See the remarks just above for p. 142.
193: If an integer constant is suffixed with UL, it is unsigned
long.
195: To the list at the start of section A4, "Identifiers, or names, refer to
a variety of things...", add labels as well.
200 (Section A7.1): The actual list of operators that prevent the conversion
of arrays into pointers is just & and sizeof, not the
various assignment operators. In practice this is not important, because arrays
(converted or not) cannot be assigned to for other reasons.
229, 239: Syntax: the argument list is optional in macro definitions with
parentheses.
231: Extra right parenthesis in nested call to cat macro.
232: The result of the defined operator is not replaced literally by
0L or 1L, nor are undefined names literally by 0L,
but just by plain 0 or 1. However, the constant expression is
nevertheless evaluated as if these and other constants appearing have long or
unsigned long type.
244: In table B-1, the argument corresponding to x, X is unsigned int.
245: The scanf functions do not ignore white space in formats.
245: vprintf, vfprintf, vsprintf return
int.
246: First argument of sscanf should have type const char
*.
249: In the description of strncpy, t should be
ct.
210: In section 8.1, it is said that a register object cannot have the &
operator applied `explicitly or implicitly,' which is true, but needs an
amplifying clause to show that the implicit & comes from mention of an array
name, so declaring an array as a register is fruitless.
There is no mention of the offsetof macro.
Index: stddef.h is listed but not described in the text.
char, double, long, short are on page 9, not
page 10. sizeof is on 242, not 247. ``byte'' is not indexed.
Updated Feb 16 2001
Copyright © 1998 Lucent
Technologies. All rights reserved.
Оглавление
1.1 Начнем, пожалуй
1.2 Переменные и арифметические выражения
1.3 Инструкция for
1.4 Именованные константы
1.5 Ввод-вывод символов
1.5.1 Копирование файла
1.5.2 Подсчет символов
1.5.3 Подсчет строк
1.5.4 Подсчет слов
1.6 Массивы
1.7 Функции
1.8 Аргументы. Вызов по значению
1.9 Символьные массивы
1.10 Внешние переменные и область видимости
2.1 Имена переменных
2.2 Типы и размеры данных
2.3 Константы
2.4 Объявления
2.5 Арифметические операторы
2.6 Операторы отношения и логические операторы
2.7 Преобразования типов
2.8 Операторы инкремента и декремента
2.9 Побитовые операторы
2.10 Операторы и выражения присваивания
2.11 Условные выражения
2.12 Приоритет и очередность вычислений
3.1 Инструкции и блоки
3.2 Конструкция if-else
3.3 Конструкция else-if
3.4 Переключатель switch
3.5 Циклы while и for
3.6 Цикл do-while
3.7 Инструкции break и continue
3.8 Инструкция goto и метки
4.1 Основные сведения о функциях
4.2 Функции, возвращающие нецелые значения
4.3 Внешние переменные
4.4 Области видимости
4.5 Заголовочные файлы
4.6 Статические переменные
4.7 Регистровые переменные
4.8 Блочная структура
4.9 Инициализация
4.10 Рекурсия
4.11 Препроцессор языка Си
4.11.1 Включение файла
4.11.2 Макроподстановка
4.11.3 Условная компиляция
5.1 Указатели и адреса
5.2 Указатели и аргументы функций
5.3 Указатели и массивы
5.4 Адресная арифметика
5.5 Символьные указатели функции
5.6 Массивы указателей, указатели на указатели
5.7 Многомерные массивы
5.8 Инициализация массивов указателей
5.9 Указатели против многомерных массивов
5.10 Аргументы командной строки
5.11 Указатели на функции
5.12 Сложные объявления
6.1 Основные сведения о структурах
6.2 Структуры и функции
6.3 Массивы структур
6.4 Указатели на структуры
6.5 Структуры со ссылками на себя
6.6 Просмотр таблиц
6.7 Средство typedef
6.8 Объединения
6.9 Битовые поля
7.1 Стандартный ввод-вывод
7.2 Форматный вывод (printf)
7.3 Списки аргументов переменной длины
7.4 Форматный ввод (scanf)
7.5 Доступ к файлам
7.6 Управление ошибками (stderr и exit)
7.7 Ввод-вывод строк
7.8 Другие библиотечные функции
7.8.1 Операции со строками
7.8.2 Анализ класса символов и преобразование символов
7.8.3 Функция ungetc
7.8.4 Исполнение команд операционной системы
7.8.5 Управление памятью
7.8.6 Математические функции
7.8.7 Генератор случайных чисел
8.1 Дескрипторы файлов
8.2 Нижний уровень ввода-вывода (read и write)
8.3 Системные вызовы open, creat, close, unlink
8.4 Произвольный доступ (lseek)
8.5 Пример. Реализация функций fopen и getc
8.6 Пример. Печать каталогов
8.7 Пример. Распределитель памяти
A1. Введение
A2. Соглашения о лексике
A2.1. Лексемы (tokens)
A2.2. Комментарий
A2.3. Идентификаторы
A2.4. Ключевые слова
A2.5. Константы
A2.5.1. Целые константы
A2.5.2. Символьные константы
А2.5.3. Константы с плавающей точкой
A2.5.4. Константы-перечисления
A2.6. Строковые литералы
A3. Нотация синтаксиса
A4. Что обозначают идентификаторы
A4.1. Класс памяти
A4.2. Базовые типы
A4.3. Производные типы
A4.4. Квалификаторы типов
A5. Объекты и Lvalues
A6. Преобразования
A6.1. Целочисленное повышение
A6.2. Целочисленные преобразования
A6.3. Целые и числа с плавающей точкой
A6.4. Типы с плавающей точкой
А6.5. Арифметические преобразования
A6.6. Указатели и целые
A6.7. Тип void
А6.8. Указатели на void
A7. Выражения
A7.1. Генерация указателя
A7.2. Первичные выражения
A7.3. Постфиксные выражения
A7.3.1. Обращение к элементам массива
A7.3.2. Вызов функции
A7.3.3. Обращение к структурам
A7.3.4. Постфиксные операторы инкремента и декремента
А7.4. Унарные операторы
А7.4.1. Префиксные операторы инкремента и декремента
A7.4.2. Оператор получения адреса
A7.4.3. Оператор косвенного доступа
A7.4.4. Оператор унарный плюс
A7.4.5. Оператор унарный минус
A7.4.6. Оператор побитового отрицания
A7.4.7. Оператор логического отрицания
A7.4.8. Оператор определения размера sizeof
A7.5. Оператор приведения типа
A7.6. Мультипликативные операторы
A7.7. Аддитивные операторы
A7.8. Операторы сдвига
A7.9. Операторы отношения
A7.10. Операторы равенства
A7.11. Оператор побитового И
A7.12. Оператор побитового исключающего ИЛИ
A7.13. Оператор побитового ИЛИ
A7.14. Оператор логического И
A7.15. Оператор логического ИЛИ
А7.16. Условный оператор
A7.17. Выражения присваивания
A7.18. Оператор запятая
A7.19. Константные выражения
A8. Объявления
A8.1. Спецификаторы класса памяти
А8.2. Спецификаторы типа
A8.3. Объявления структур и объединений
A8.4. Перечисления
А8.5. Объявители
A8.6. Что означают объявители
A8.6.1. Объявители указателей
А8.6.2. Объявители массивов
А8.6.3. Объявители функций
A8.7. Инициализация
A8.8. Имена типов
А8.9. Объявление typedef
A8.10. Эквивалентность типов
A9. Инструкции
A9.1. Помеченные инструкции
A9.2. Инструкция-выражение
A9.3. Составная инструкция
A9.4. Инструкции выбора
A9.5. Циклические инструкции
A9.6. Инструкции перехода
А10. Внешние объявления
A10.1. Определение функции
A10.2. Внешние объявления
A11. Область видимости и связи
A11.1. Лексическая область видимости
A11.2. Связи
A12. Препроцессирование
A12.1. Трехзнаковые последовательности
A12.2. Склеивание строк
А12.3. Макроопределение и макрорасширение
A12.4. Включение файла
A12.5. Условная компиляция
A12.6. Нумерация строк
A12.7. Генерация сообщения об ошибке
A12.8. Прагма
A12.9. Пустая директива
A12.10. Заранее определенные имена
A13. Грамматика
B1. Ввод-вывод: <stdio.h>
B1.1. Операции над файлами
B1.2. Форматный вывод
B1.3. Форматный ввод
B1.4. Функции ввода-вывода символов
B1.5. Функции прямого ввода-вывода
B1.6. Функции позиционирования файла
B1.7. Функции обработки ошибок
B2. Проверки класса символа: <ctype.h>
B3. Функции, оперирующие со строками: <string.h>
B4. Математические функции: <math.h>
B5. Функции общего назначения: <stdlib.h>
B6. Диагностика: <assert.h>
B7. Списки аргументов переменной длины: <stdarg.h>
B8. Дальние переходы: <setjmp.h>
B9. Сигналы: <signal.h>
B10. Функции даты и времени: <time.h>
B11. Зависящие от реализации пределы: <limits.h> и <float.h>