A Book on C, Edition 4

by Al Kelley and Ira Pohl  

Addison-Wesley ISBN 0-201-18399-4

Now in its fourth edition, A Book on C retains the features that have made it a proven, best-selling tutorial and reference on the ANSI C programming language. This edition builds on the many existing strengths of the text to improve, update, and extend the coverage of C, and now includes information on transitioning to Java and C++ from C.

Beginners and professional programmers alike will benefit from the numerous examples and extensive exercises developed to guide readers through each concept. Step-by-step dissections of program code illuminate the correct usage and syntax of C language constructs and reveal the underlying logic of their application. The clarity of exposition and format of the book make it an excellent reference on all aspects of C.

Features

This book is written to work with current compilers such as GNU 2.7.1 and 5.0. As a consequence it adopts a mixed strategy in using some of the ANSI material. Examples include the use of iostream.h as a header file instead of iostream. The newer ANSI standard headers (named without .h) are to be wrapped in namespace std, the older headers don't require namespaces and will still be used. Some of these errata have been corrected in later printings. A note with the approximate month for the correction is at the end of any corrections which may already have been made. You can buy this book online through Barnes and Noble.

The C code examples in the book are available in several forms. The code is arranged in directories corresponding to the chapters of the book. To get to the unpacked version for any system, or to get individual program files, you can use the FTP directory (www.cse.ucsc.edu/~pohl/ABC4/). Files are also available in zip form for Windows users and compressed tar form for UNIX users.


Errata

Caveats: Some standard libraries may have been modified since this book was written and the function prototypes may differ from what is available on your compiler. Check your compiler vendor for the correct prototypes.

Notations: p425 means page 425  
                            +8 means 8 lines from top 
                             -7 means 7 lines from bottom

If you encounter errata in this book not listed here, please contact Ira Pohl via email at pohl@cse.ucsc.edu with your errata. You will be cited in the correction if you are the first to report it.


p26 (Jun Ni): line -6

The final comma in the first line of the printf() is misplaced. It should be outside the quote, not inside.

printf("\n%s\n%s", "Input three characters,"

Needs to be:

printf("\n%s\n%s", "Input three characters", 

p26 (Eric Smith): line -16

The min and max should be indented an additional 3 spaces for consistency.

Needs to be:

if (x < min)
   min = x;
else if (x  max)
   max = x;


p26 (Eric Smith): line 17

The printf statement is missing -------");


p27 (Eric Smith): lines 3 and -3

Screen output under "Average" missing -------


p32 (author): line 2

Missing blank lines in example. Here is what it should look like:

This program reads an integer value for n, and then
processes n real numbers to find max and min values.

Input n:  5

Input 5 real numbers:  737.7799  -11.2e+3  -777  0.001  3.14159

Maximum value:    737.780
Minimum value: -11200.000

p38 (Michael Johnson) line 20 "being overwritten with the original value of score[i]" should be:

"being overwritten with the original value of score[j-1]"


p40 (Michael Buck) line 7 There should be a blank lines before the output lines

and the letters in your name sum to 1142.
Have a nice day!

p41 (Eric Smith): line 9

Terminating " should be )

Needs to be:

c = (getchar() != '\n')


p63 (author): exercise 12

A blank line is missing and some underscores are missing from example output.

Needs to be:

:::::  A TABLE OF POWERS  :::::

Integer    Square    3rd power    4th power    5th power
-------    ------    ---------    ---------    ---------
      1         1            1            1            1
      2         4            8           16           32
      3         9           27           81          243



p79 (Jun Ni): line -10

"\n" should be changed to '\n' since it talks about a character.


p93 (Eric Smith): line -7

"Suppose that we execute the program and type 19..."

Needs to be:

"Suppose that we execute the program and type 23..."


p95 (Eric Smith): line 16

"The first time through the loop and every eight time thereafter"

Needs to be:

"The first time through the loop and every tenth time thereafter"


p98 (author): exercize 4

The line-up in exercise 4 is poor. The following is better:

3id        __yes            o_no_o_no     00_go         star*it 
1_i_am     one_i_aren"t     me_to-2       xYshouldI     int


p99 (author): line -7

Change the single quote to a double quote:

printf('%d %d %d\n", a, b, c);

Needs to be:

printf("%d %d %d\n", a, b, c);

p112 ( Michael Buck) line 7:

The corresponding integer value of z is 122, not 112.


p113 (Nick Beeson): line 11 Single quote characters in the comment need to be double quote characters.

 printf("%cabc%c", '\"', '"'); /* 'abc' is printed */ 

Needs to be:

 printf("%cabc%c", '\"', '"'); /* "abc" is printed */ 

p118 (Rui Zhang) line -7 On machines with 2-byte words the power of 2 should be 16, not 32.


p119 (Jack Weinstein) lines 14 and 21

Where the first digit is being talked about, the subscript for d should be changed from i to 1.


p119 (Nick Beeson) line -5

Fifth power is incorrectly 105 instead of 10 with superscript 5.


p120 (author): line -23

The layout is poor. Also, some of the subscripts have leading white space that should be removed. However, these are minimal errors.


p121 (Nick Beeson): line 14

-38 x n x 38 should read -38 < n < 38.


p126 (Nick Beeson) : line 24

 c >= 'a' && c <= 'z' and (c >= 'a')'&' (c <= 'z') 

Needs to be:

 c >= 'a' && c <= 'z' and (c >= 'a') && (c <= 'z') 


page 139 (Nick Beeson): line 13

The 5.1f should be 5lf (point one changes to EL) Since the variable to be printed is a double

printf("%5.1f: %.15e\n"
Needs to be:
printf("%5lf: %.15e\n" 

p141 (author): line 8

The four lines beginning with line 8 should be indented. Here are the lines:

      double f(double x)
      {
         return (tan(sin(x)) - sin(tan(x)));
      }

p144 (Jack Weinstein) line 4

Inf of Infinity

Needs to be:

Inf or Infinity


p149 (author): line 6

The layout is poor. However, this is a minimal style error.


p150 (Jack Weinstein): lines 9-11

Each of the declarations should end with a semicolon.

char c = 'w'
int i = 1, j = 2, k = -7
double x = 7e+33, y = 0.001

Needs to be:

char c = 'w';
int i = 1, j = 2, k = -7;
double x = 7e+33, y = 0.001;


p155 (Jack Weinstein): line 9

Each of the declarations should end with a semicolon.

double x = 0.0, y = 2.3

Needs to be:

double x = 0.0, y = 2.3;


p170 (author): line 2

Put a blank line after line 2.

Needs to be:

      /* Print a table of values for some boolean functions. */

      #include <stdio.h

p178 (Jack Weinstein): line 8

The label ::= identifier should be on its own line:

labeled_statement ::= label : statement label ::= identifier

Needs to be:

labeled_statement ::= label : statement

label ::= identifier


p190 (Jack Weinstein): line 4

The line needs to start with (a) so that it is consistent with the line below.

if ((x != ...

Needs to be:

(a) if ((x != ...


p190 (author): line -1

The equation in the second square root is incorrect with the parens. Remove them.

Also, the white space is unbalanced in this line. However, this is a minimal style error.


p191 (author): line -9

The white space above and below this line is unbalanced. However, this is a minimal style error.


p192: (author): line 4

The printout is not formatted correctly.

Needs to be:

      two complex roots: root1 = -1.000000 + i*1.414214
                         root2 = -1.000000 - i*1.414214


p194 (author): exercise 31

The code in this exercise is indented too far and it is not formatted correctly.

Needs to be:

      d = b * b - 4.0 * a * c;
      if (d == 0.0)
         goto L1;
      else if (d  0.0) {
         if (a != 0.0) {
            r1 = (-b + sqrt(d)) / (2.0 * a);
            r2 = (-b - sqrt(d)) / (2.0 * a);
            goto L4;
         }
         else
            goto L3;
      }
      else
         goto L2;
      L1:
      if (a != 0.0)
         r1 = r2 = -b / (2.0 * a);
      else
         goto L3;
      goto L4;
      L2:
      if (a != 0.0) {
         printf("imaginary roots\n");
         goto L4;
      }
      L3:
      printf("degenerate case\n");
      L4:
      .....


p197 (author): line -5

There is too much white space after the left brace.

Needs to be:

type  function_name( parameter list )
{ declarations   statements }


p211 (Jun Ni): line 22

Change prn.c to wrt.c so that the line reads

      cc -o pgm main.c  fct.c   wrt.c

p222 (author): line 9

There are two mistakes: remove the period and change Seed to seed

      return. (Seed / FLOATING_MODULUS);

Needs to be:

      return (seed / FLOATING_MODULUS);


p235 (author): line -5

There is too much white space after the left brace. And although not wrong, the space after function_name should be removed and everything should be written on three lines instead of two.

Needs to be:

type  function_name( parameter list ) declarations of the parameters
{ declarations   statements }


p242 (author): exercise 23

The printout in exercise 23 on page 242 is wrong: two a blank lines are missing.

Needs to be:

      Hailstones generated by 77:

              77       232       116        58        29        88
              44        22        11        34        17        52
              26        13        40        20        10         5
              16         8         4         2         1

      Number of hailstones generated: 23


p249 (author): line

The contents of the first two boxes after line 2 are wrong. In the a box change ? to 1. In the b box change ? to 2.


p250 (author): lines 7 and 8

The program at the top of the page is more readable if it is formatted as follows:

Needs to be:

      #include <stdio.h >

      int main(void)
      {
         int   i = 7, *p;

         p = &i;
         printf("%s%d\n%s%p\n",
            "   Value of i: ", *p,
            "Location of i: ",  p);
         return 0;
      }

However, this is a minimal style error.


p255 (Jack Weinstein): line -12

"then p - q yields"

Needs to be:

"q - p yields"


p255 (Jack Weinstein): line -5

The comment on line -5 needs to be lined up on the left.

Needs to be:

      p = a;                      /* points to base of array */
      q = p + 1;                  /* equivalent to q = &a[1] */
      printf("%d\n", q - p);                 /* 1 is printed */
      printf("%d\n", (int) q - (int) p);     /* 8 is printed */


p257 (Nick Beeson): last line

swap(a + i, a + j);

Needs to be:

swap(a + (j - 1), a + j);


p258: line 2 has incorrect number: 77 should be -77

int a[] = {7, 3, 66, 3, -5, 22, 77, 2};

Needs to be:
int a[] = {7, 3, 66, 3, -5, 22, -77, 2};


p261 (Jack Weinstein): line 10

The printf statement needs to use the plural elements and not singular element.

...sum of its element\n"

Needs to be:

...sum of its elements\n"

 


p261 (author): line 16

The single quotes are wrong. Use straight quotes putchar('\n')


p262 (Michael Buck) diagram near bottom of page

The shaded box above the 0 should not be shaded, since this is memory the programmer does "own."


p 267 (Charles Evans): line 1

Function call to cdalloc(n, needs to be calloc(n.


p271 (author): diagram

The arrow coming out of the p box is wrong. The arrow should point to the upper left hand corner of the abcde\0 box.


p320: (author): exercise 26

There should be a blank line after the first line of code in this exercise.

Needs to be:

      char   *p = "abc";

      *p = 'X';                /* illegal? */
      printf("%s\n", p);       /* Xbc gets printed? */


p327 (author): line 2

The blank line between lines 2 and 3 should be removed

Needs to be:

      #include <stdio.h >
      #include <string.h >


p327 (author): line 19

Change part of line 19 and line 20 as follows:

"Modify the program to get rid of the warning by using the generic void * type. "

Needs to be:

"Modify the program by changing the pointer type throughout to the generic void * type. Does this make your compiler happy? "


p346 (author): line -14

The three BNF lines that start with line -14 are not formatted correctly. There is too much white space before and after ::= and the | character is not properly placed. Line -11 has a serious mistake: two lines have been joined. After corrections have been made, here is how the lines should appear:

enum_declaration  ::=  enum_type_specifier  identifier  { , identifier }   ;
                                                                             0+

enum_type_specifier  ::=   enum  e_tag  { e_list }
                         | enum  e_tag
                         | enum  { e_list }

e_tag ::= identifier
e_list ::= enumerator  { , enumerator }
                                       0+

enumerator ::= identifier  { = constant_integral_expression }
                                                             opt


p348 (author): line 4

The body of the function find_next_day() needs to be rewritten.

Needs to be:

      day find_next_day(day d)
      {
         assert((int) d = 0 && (int) d < 7);
         return ((day) (((int) d + 1) % 7));
      }


p358 (author): line 13

There should be a blank line following the first line of what is seen on the screen in exercise 7.

Needs to be:

      Input a string of decimal digits:  12345678

      12345678 = 0001 0010 0011 0100 0101 0110 0111 1000

However, this is a minimal style error.


p362 (author): line 14

Remove the first two characters in the line.

   \&'abc' = 00000000 01100011 01100010 01100001

Needs to be:

   'abc' = 00000000 01100011 01100010 01100001


p363 (author): line 4

There should be a blank line following line 4.

Needs to be:

      set   a = 0X7;            /* a has elements 1, 2, 3 */
      set   b = 0X55;           /* b has elements 1, 3, 5, 7 */

      display(Union(a, b));     /* 1, 2, 3, 5, 7 is in the union */


p372 (author): lines 13 and 14

The second line of the code does not line up correctly.

Needs to be:

      void qsort(void *array, size_t n_els, size_t el_size,
                 int compare(const void *, const void *));


p373 (author): beginning lines of code

The comment that occurs on a line by itself should be moved to the end of the previous line, and the first two comments should match up on the right.

Needs to be:

      #include <stdio.h >
      #include <stdlib.h >
      #include <time.h >

      #define   N   11                           /* size of the array */

      enum when {before, after};

      typedef   enum when   when;

      int    cmp(const void *vp, const void *vq);   /* comparison fct */
      void   fill_array(double *a, int n);
      void   prn_array(when val, double *a, int n);


p373 (author): next to the last function

The ending brace should be moved to column 1.

Needs to be:

      int cmp(const void *vp, const void *vq)
      {
         const double   *p = vp;
         const double   *q = vq;
         double          diff = *p - *q;

         return ((diff = 0.0) ? ((diff  0.0) ? -1 : 0) : +1);
      } 


p373 (author): the last function

The comment should line up on the right with the comments that occur above on this same page.

Needs to be:

      void fill_array(double *a, int n)
      {
         int   i;

         srand(time(NULL));                            /* seed rand() */
         for (i = 0; i < n; ++i)
            a[i] = (rand() % 1001) / 10.0;
      }


p385 (author): line -6

Remove this line completely:

   remove: /* comparison fct */


p385 (author): line -9

The indented lines beginning with line -9 have a blank line in the wrong place.

Needs to be:

      #include "everything.h"

      #undef    PIE
      #define   PIE   "I like apple."
      .....


p385 (author): lines -1

Three lines have been run together.

Needs to be:

statements
      more statements
      and still more statements


p386 (author): line 3

Three lines have been run together, and the more statements should be in italic font.

Needs to be:

statements
      /*
      more statements
      */
      and still more statements


p386 (author): line 6

Three lines have been run together.

Needs to be:

statements
      #if 0
      more statements
      #endif
      and still more statements


p387 (author): table

The double underscore characters in the table run together. They should be visually separate.


p387 (author): line -9

This line needs to be indented further, and a blank line should follow it.

Needs to be:

      #define   message_for(a, b)  \
                printf(#a " and " #b ": We love you!\n")

      int main(void)
      {
         message_for(Carole, Debra);
         return 0;
      }
 


p388 (author): line 9

This sentence is technically wrong; it needs to be rewritten.

In the next section we will see how the "stringization" operator # is used in assertions.

Needs to be:

In the next section we use the "stringization" operator # in the assert() macro.


p388 (author): line 12

There should be a blank line that follows the #define line.

Needs to be:

      #define   X(i)   x ## i

      X(1) = X(2) = X(3);


p388 (author): line -10

There should be a blank line that follows this line.

Needs to be:

      #include <assert.h >

      void f(char *p, int n)
      {
         .....
         assert(p != NULL);
         assert(n  0 && n < 7);
         .....


p389 (author): line 6

The backslashes at the end should line up with the backslashes in the lines that follow. In lines 10 and 11, the double underscore characters run together. They should be visually separate.

Needs to be:

#include <stdio.h>
#include <stdlib.h>                             /* for abort() */

#if defined(NDEBUG)
   #define assert(ignore)   ((void) 0)            /* ignore it */
#else
   #define  assert(expr)                         \
      if (!(expr)) {                             \
         printf("\n%s%s\n%s%s\n%s%d\n\n",        \
         "Assertion failed: ", #expr,            \
         "in file ", __FILE__,                   \
         "at line ", __LINE__);                  \
         abort();                                \
   }
#endif


p397 (author): line 4

The colon following a_b_c.h should be in italics.


p397 (author): exercise 4

The first piece of code in this exercise is not layed out correctly.

Needs to be:

      #define   TRUE    1
      #define   A_B_C   int main(void)                           \
                        {                                        \
                           printf("A Big Cheery \"hello\"!\n");  \
                           return 0;                             \
                        }


p397 (author): exercise 4

The sentence near the end of this exercise needs to be changed:

Can you permute two lines in one of the files ...

Needs to be:

Can you interchange two lines in one of the files ...


p397 (author): exercise 6

The double underscore characters in the code run together. They should be visually separate.


p402 (author) line -12

The function prototype should be

void qsort(void *base, size_t nelem, size_t width,
           int (*compare)(const void *, const void *));


p402: (author): exercise 21

The code in exercise 21 is out of order. Put the code that is at the bottom of page 402 at the top of page 403, and put the code that is at the top of page 403 at the bottom of page 402.


p403 (author): lines 16 and 17

Lines 16 and 17 need to be interchanged, and a blank line should be between them.

Needs to be:

      #include <stdio.h >
      #include <stdlib.h >
      #include <time.h >

      #define   N   10000

      void   quicksort(int *, int *);

      int main(void)
      {
         int   a[N], i;

         srand(time(NULL));     /* seed the random number generator */
         for (i = 0; i < N; ++i)
            a[i] = rand() % 1000;
         quicksort(a, a + N - 1);
         .....


p404 (author): exercise 25

The code in exercise 25 is not indented properly. The trouble begins with line 9.

Needs to be:

      int quicksort(int *left, int *right)
      {
         int          *p, *q, pivot;
         static int   cnt = 0;

         if (right - left < 7) {
            for (p = left; p < right; ++p)
               for (q = p + 1; q <= right; ++q)
                  if (*p  *q)
                     swap(*p, *q);
         }
         else if (find_pivot(left, right, &pivot) == yes) {
            p = partition(left, right, pivot);
            quicksort(left, p - 1);
            quicksort(p, right);
         }
         return ++cnt;
      }


p409 (author): line -13

The BNF lines beginning with line -13 are wrong.

Needs to be:

structure_declaration ::= struct_specifier  declarator_list ;
struct_specifier ::=   struct  tag_name
                     | struct  tag_name    { { member_declaration }   }
                                       opt                         1+

tag_name ::= identifier

member_declaration ::= type_specifier  declarator_list ;

declarator_list ::= declarator  { , declarator }
                                                0+


p425: (author): line 24

This line of printout is wrong.

i:       4444     f: 0.6227370375e-41

Needs to be:

i:       4444     f: 6.2273703755e-42


p415 (author): line 9

There should be some white space following the + so that it looks like + (unary).


p432 (Jack Weinstein): line 9

There is * in the middle of a word.

"...if th*e stack"

Needs to be:

" ... if the stack"


p437 (author): exercise 2

The code in this exercise is not formatted properly. Do the following: 1 put a blank line after the typedef) 2 align interest under amount in the line above 3 align the comment so that it starts three spaces beyond the end of the longest line 4 in the comment itself, remove the extra blanks at the beginning and end

Needs to be:

      typedef   float   DOLLARS;

      int main(void)
      {
         DOLLARS   amount = 100.00,
                   interest = 0.07 * amount;
         {                                         /* new block */
            float   DOLLARS;
            DOLLARS = amount + interest;
            printf("DOLLARS = %.2f\n", DOLLARS);
         }
         return 0;
      }


p438 (author): exercise 3

Correct a misspelling by changing bight to bite.

Needs to be:

      string   a[] = {"I", "like", "to", "fight,"},
               b[] = {"pinch,", "and", "bite."};


p439 (author): exercise 6

The code in the middle is not formatted correctly.

         typedef   double   dbl;         /* create an abbreviation */
         typedef   dbl      (*PFDD)(dbl); 
                               /* ptr to fct of dbl returning dbl */

Needs to be:

         typedef   double   dbl;            /* create an abbreviation */
         typedef   dbl      (*PFDD)(dbl);   /* ptr to fct taking dbl
                                               and returning a dbl */


p443 (author): lines 12 and 13: Concatenate the two lines to get

   
printf("x.a = %d   x.b = %d   x.c = %d\n", x.a, x.b, x.c);


p449 (author): line -8

After the two #include lines, there should be a blank line.

Needs to be:

      #include <stdio.h >
      #include <stdlib.h >

      typedef   char   DATA;           /* will use char in examples */

      struct linked_list {
         DATA                 d;
         struct linked_list   *next;
      };

      typedef   struct linked_list   ELEMENT;
      typedef   ELEMENT              *LINK;


p463 (author): line -13

This line needs to be indented more. After this has been done, the comments will lineup on the right.

Needs to be:

for (i = 0; str[i] != '\0'; ++i) {
   if (!full(&s))
      push(str[i], &s);                 /* push a char on the stack */


p465 (author): picture at top

In the picture at the top of the page: 1 all the underbar lines are too close 2 all the * symbols are just a little too high 2 the second column [or column pair] from the left has an underbar that is too centered and too short 3 the symbol * is missing in the third column pair from the right.

Needs to be:

         3
      *  2
      +  9
      ----


p467 (author): line 12

The lines after the first two case labels need to be indented properly. More precisely, after the first case label, two lines need to be indented, and after the second case label, 14 lines need to be indented.

Needs to be:

      int evaluate(stack *polish)
      {
         data    d, d1, d2;
         stack   eval;

         initialize(&eval);
         while (!empty(polish)) {
            d = pop(polish);
            switch (d.kind) {
            case value:
               push(d, &eval);
               break;
            case operator:
               d2 = pop(&eval);
               d1 = pop(&eval);
               d.kind = value;         /* begin overwriting d */
               switch (d.u.op) {
               case '+':
                  d.u.val = d1.u.val + d2.u.val;
                  break;
               case '-':
                  d.u.val = d1.u.val - d2.u.val;
                  break;
               case '*':
                  d.u.val = d1.u.val * d2.u.val;
               }
               push(d, &eval);
            }
         }
         d = pop(&eval);
         return d.u.val;
      }


p469 (author): lines 7 and 8

Line 7 is missing a quote character at the end of the line. Also, these two lines should be concatenated.

 b1 = (boolean) ((c1 = *p) == '+' || c1 == '-
                     || c1 == '*');

Needs to be:

 b1 = (boolean) ((c1 = *p) == '+' || c1 == '-' || c1 == '*');


p469 (author): line 1

The indentation is wrong in the code. After proper indentation, the comments should lineup on the right.

Needs to be:

      /*
      // First process the string and push data on tmp.
      */
      while (*p != '\0') {
         while (isspace(*p) || *p == ',')
            ++p;
         b1 = (boolean) ((c1 = *p) == '+' || c1 == '-' || c1 == '*');
         b2 = (boolean) ((c2 = *(p + 1)) == ',' || c2 == '\0');
         if (b1 && b2) {
            d.kind = operator;
            d.u.op = c1;
         }
         else {
            d.kind = value;
            assert(sscanf(p, "%d", &d.u.val) == 1);
         }
         if (!full(&tmp))
            push(d, &tmp);                   /* push data on tmp */
         while (*p != ',' && *p != '\0')
            ++p;
      }
      /*
      // Now pop data from tmp and push on stk.
      */
      while (!empty(&tmp)) {
         d = pop(&tmp);                     /* pop data from tmp */
         if (!full(stk))
            push(d, stk);                    /* push data on stk */
      }


p470 (author): line -10

Two blank lines are missing in the output, one at the top and one at the bottom.

Needs to be:

      Polish expression: 13, 4, -, 2, 3, *, +

      stack count:  7     kind: value        val: 13
      stack count:  6     kind: value        val:  4
      stack count:  5     kind: operator      op:  -
      stack count:  4     kind: value        val:  2
      stack count:  3     kind: value        val:  3
      stack count:  2     kind: operator      op:  *
      stack count:  1     kind: operator      op:  +
      stack count:  0

      Polish evaluation: 15


p476 (author): line 5

In the picture of the general tree at the top of the page, interchange the letters g and h.


p477 (author): line -2

In the picture of the binary tree at the bottom of the page, interchange the letters J and H.


p478 (author): line -4

      BTREE new_node()

Needs to be:

      BTREE new_node(void)


p479 (author): line -12

The line of code after the return is not indented properly.

Needs to be:

      /* Create a linked binary tree from an array. */

      BTREE create_tree(DATA a[], int i, int size)
      {
         if (i = size)
            return NULL;
         else
            return (init_node(a[i],
                    create_tree(a, 2 * i + 1, size),
                    create_tree(a, 2 * i + 2, size)));
      }


p480 (author): line 6

In the picture of the general tree and associated list structure near the top of the page, interchange the letters g and h.


p481 (author): line 6

      GTREE new_gnode()

Needs to be:

      GTREE new_gnode(void)


p481 (author): line -13

Replace the code near the bottom of the page.

Needs to be:

      t[0] = init_gnode('a', 1, NULL);
      t[1] = init_gnode('b', 2, NULL);
      t[1] - sib = init_gnode('f', 6, NULL);
      t[1] - sib - sib = init_gnode('h', 8, NULL);
      t[2] = init_gnode('c', 3, NULL);
      t[2] - sib = init_gnode('d', 4, NULL);
      t[2] - sib - sib = init_gnode('e', 5, NULL);
      t[3] = NULL;
      t[4] = NULL;
      t[5] = NULL;
      t[6] = init_gnode('g', 7, NULL);
      t[7] = NULL;
      t[8] = NULL;


p489 (author): exercise 29

Remove the symbols (c) from the end of the line; that is "2 count the number of nodes having a particular value, say 'b' (c)"

Needs to be:

"2 count the number of nodes having a particular value, say 'b'"


p498 (author): line -10

A semicolon is missing at the end of the line.

      double   x = 0.123456789

Needs to be:

      double   x = 0.123456789;


p502 (author): lines -6 and -5

There should be a blank line just before the scanf() statement.

Needs to be:

      int    i;
      char   c;
      char   string[15];

      scanf("%d , %*s %% %c %5s %s", &i, &c, string, &string[5]);


p525 (author): line 10

Lines not indented properly.

Needs to be:

      int main(void)
      {
         int    a[N], i;

         srand(time(NULL));
         for (i = 0; i < N; ++i)
            a[i] = rand() % 10000;
         quicksort(a, a + N - 1);
         for (i = 0; i  a[i + 1]) {
               printf("SORTING ERROR - bye!\n");
               exit(1);
            }
         return 0;
      }


p546 (author): line 5

Remove the extra left paren.

      if (strcmp(mode, "w") == 0 && (access(fname, F_OK) == 0) {

Needs to be:

      if (strcmp(mode, "w") == 0 && access(fname, F_OK) == 0) {


p546 (author): lines 9 and 10

These lines need to be indented properly.

Needs to be:

      FILE *cfopen(char *fname, char *mode)
      {
         char   reply[2];
         FILE   *fp;

         if (strcmp(mode, "w") == 0 && (access(fname, F_OK) == 0) {
            printf("\nFile exists.  Overwrite it?  ");
            scanf("%1s", reply);
            if (*reply != 'y' && *reply != 'Y') {
               printf("\nBye!\n\n");
               exit(1);
            }
         }
         fp = gfopen(fname, mode);
         return fp;
      }


p547 (author): exercise 15

The sentence in parentheses in this exercise needs to be reworded.

(All the ones we tried could not.)

Needs to be:

(A few years ago, all the ones we tried could not, but now they can.)


p547 (author): line -2

Rewrite line -2, and put a blank line between lines -2 and -1.

Needs to be:

      int   a = 1, b = 2, c = 3;

      printf("a%nb%nc%n %d %d %d\n", &a, &b, &c, a, b, c);


p549 (author): exercise 22

Move the line at the bottom of page 549 to the top of page 550. This will simulate a blank line in the right place.


p559 (author): line 8

The indentation is wrong.

Needs to be:

if (sscanf(argv[i], "%d", &value) == 1)

sum += value;


p560 (author): line 5

Put a blank line after line 5.

Needs to be:

      The parent process will be overlaid.
      You have a choice.
      Input 1 or 2: 1

      C:\CENTER\PGM1.EXE: a b c


p562 (author): lines 10 and some beyond: The indentation, starting with line 10, is wrong.

Needs to be:

int main(void)
{
   int   a[N][N] = {{1, 1, 1}, {2, 2, 2}, {3, 3, 3}},
         i, row_sum, sum = 0,
         pd[2];                             /* pipe descriptors */

   if (pipe(pd) == -1)                         /* create a pipe */
      error_exit("pipe() failed");
   for (i = 0; i < N; ++i)
      if (fork() == 0) {                       /* child process */
         row_sum = add_vector(a[i]);
         if (write(pd[1], &row_sum, sizeof(int)) == -1)
            error_exit("write() failed");
         return;                           /* return from child */
      }
   for (i = 0; i < N; ++i) {
      if (read(pd[0], &row_sum, sizeof(int)) == -1)
         error_exit("read() failed");
      sum += row_sum;
   }
   printf("Sum of the array = %d\n", sum);
   return 0;
}

p563 (author): line 10

The indentation is wrong.

Needs to be:

      if (fork() == 0) {                    /* child process */
         row_sum = add_vector(a[i]);
         if (write(pd[1], &row_sum, sizeof(int)) == -1)
            error_exit("write() failed");
         return;                        /* return from child */
      }


p565 (author): line -14

The return statement is indented too far.

Needs to be:

signal(SIGINT, cntrl_c_handler);
   for (i = 0; i < 46; ++i)
	 printf("fib(%2d) = %d\n", i, fib(i));
   return 0;
}


p569 (author): line 10

The break statement needs to be indented further.

Needs to be:

if (fork() == 0)
   break;


p574 (author): line 13

The printf() statement needs to be indented further.

Needs to be:

   for (i = 0; i < n; ++i) {
       for (j = 0; j < n; ++j)
	    printf("%7.1f", a[i][j]);
	 putchar('\n');
    }


p575 (author): line -5

Spacing on variable names does not line up.

Needs to be:

int        n;
double  *v;


p577 (author): line 11

The a[i][j] statement needs to be indented further.


p578 (author): line 14

Line up the comments on the right.

Needs to be:

   p = malloc(m * n * sizeof(elem));  /* get space all at once    */
   a = malloc(m * sizeof(row));
    --a;                                    /* offset the pointer */
   for (i = 1; i <= m; ++i)
      a[i] = p + ((i - 1) * n) - 1;
   return a;
}

void release_matrix_space(matrix a)
{
	   elem *   p;
	
	   p = (elem *) a[1] + 1;    /* base address of the array */
	   free(p);
	   free(a + 1);
	}


p578 (author): line -7

In function release_matrix_space(), the space for a has not been released. Add the following line after line -7: free(a + 1);

Needs to be:

      void release_matrix_space(matrix a)
      {
         elem *   p;

         p = (elem *) a[1] + 1;       /* base address of the array */
         free(p);
         free(a + 1);
      }


p579 (author): line 4

words above picture: The words "The four shaded areas are identified" are wrong.

Needs to be:

"The two shaded areas near the top are identified, and the two shaded areas near the bottom also are identified."


p586 (author): exercise 4

In the code, change fork to fork().

Needs to be:

      if (fork() == 0)
         execl("/usr/bin/date", "date", 0);


p587 (author): exercise 10

The last line of the code in this exercise is wrong.

Needs to be:

      for (i = 0; i < 3; ++i)
         a[i] = calloc(c, sizeof(double));
      .....                                    /* fill the matrix a[][] */
      tr = trace(a, 3);


p590 (author): line 19

The line beginning sum += ... needs to be indented further.

Needs to be:

for (j = 0; j < N; ++j)    /* N is hardwired in the body */
   sum += a[i][j];


p590 (author): line -2

Move the comment to the top of the next page. Put the comment in the following style and incorporate the changes indicated:

Needs to be:

      /*
      // Sun Microsystems RPC code.
      // compile with cc pgc.c -lrpcsvc
      */


p591 (author): line 4

Rewrite the comment.

Needs to be:

      /*
      // Poll the host.
      */


p591 (author): line 9

The code indention for the arguments is wrong.

Needs to be:

stat = callrps(host, RSTATPROG, RSTATVERS_TIME,
               RSTATPROC_STATS,
               xdr_void, 9, s\xdr_statstime, &result_stats);

Also, the comment on line -6 is wrong. Write it as follows: /* polled machine */


p596 (Jack Weinstein): line -6

The keyword const is now in C so that it can no longer be considered new.

"the keyword const is nee in C++. It replaces ...

Needs to be:

"the keyword const replaces ...


p607 (Jack Weinstein): line -1

len needs to account for the terminating \0 and thus should be one less than the number of characters allocated.

string() {len = 255; s = new char [255]; }

Needs to be:

string() {len = 254; s = new char [255]; }


p614 (Jack Weinstein): line 15

The type of n passed to the function needs to be declared.

void init(complex c[], stack<complex>& stk, n)

Needs to be:

void init(complex c[], stack<complex>& stk, int n)


p621 (author): exercise 7

The printout at the top is wrong:

Needs to be:

      i      i * i     square root     i * i * i
      ------------------------------------------
      1          1     1.00000                 1
      2          4     1.41421                 8
      .....


p621 (author): line 10

Put a blank line after the declaration in exercise 8.

Needs to be:

   int temp;

   temp = *i;

p629 (Joel J. Ding) ):line 05 Incorrect function definition:

public String toString(
return (name + " age is " + age +
" sex is " + gender );

needs to be

public String toString()
{ return (name + " age is " + age +
" sex is " + gender ); }


p630 (Joel J. Ding) assignGender() takes a character argument.

p1.assignGender(false);

needs to be

p1.assignGender('M');

 

 

Put a blank line after the declaration in exercise 8.

Needs to be:

   int temp;

   temp = *i;


p688 (Qai Keung Yeung) line 14

Missing the definition of iteration statement

Needs to be:

expression_statement  ::=  expression  opt ;
iteration_statement   ::=  for statement   
| while statement
| do statement