--------- ch2/pay.c :------------------------- CUT HERE ----
#include <stdio.h>

#define FICA_PERCENTAGE 0.0765

/************************************************************/
/* This program reads in a worker's total hours and hourly  */
/* rate of pay, and calculates the worker's gross and       */
/* net pay by deducting the required FICA contributions.    */
/************************************************************/

main()
{
  int hours_worked;
  float hourly_rate, gross_pay, net_pay, fica_deduction;

/************************************************************/
/* Read in hours worked and hourly rate of pay.             */
/************************************************************/

  printf("Simple Payroll Program:\n");
  printf("-----------------------\n\n");
  printf("Enter the number of hours worked: ");
  scanf("%d", &hours_worked);
  printf("Enter the hourly rate of pay: ");
  scanf("%f", &hourly_rate);

/************************************************************/
/* Calculate and print gross pay and net pay.               */
/************************************************************/

  gross_pay = hours_worked * hourly_rate;
  fica_deduction = gross_pay * FICA_PERCENTAGE;
  net_pay = gross_pay - fica_deduction;

  printf("\nHours Worked:   %d\n", hours_worked);
  printf("Hourly Rate:    $%5.2f\n", hourly_rate);
  printf("Gross Pay:      $%5.2f\n", gross_pay);
  printf("FICA Deduction: $%5.2f\n", fica_deduction);
  printf("Net Pay:        $%5.2f\n", net_pay);
  return 0;
}
--------- ch3/travel.c :------------------------- CUT HERE ----
#include <stdio.h>

#define MINS_PER_HOUR 60

/***********************************************************/
/*  This program reads in the distance to be covered on a  */
/*  trip, our average speed, and our departure time.       */
/*  It calculates and prints our travel time and estimated */
/*  arrival time.                                          */
/***********************************************************/

main()
{
  int depart_hours, depart_mins, hours, mins, arrival_hours,
      arrival_mins;
  float distance, speed, travel_time; 

/***********************************************************/
/* Read in the distance, speed, and departure time.        */
/* Departure time is in the form hh:mm.                    */
/***********************************************************/

  printf("Travel calculation program:\n\n");
  printf("Distance to be traveled (miles): ");
  scanf("%f", &distance);
  printf("Speed of travel (mph): ");
  scanf("%f", &speed);
  printf("Departure (military) time (hh:mm): ");
  scanf("%d:%d", &depart_hours, &depart_mins);

/***********************************************************/
/*  Calculate travel time and arrival time.                */
/***********************************************************/

  travel_time = distance / speed;
  hours = travel_time;
  mins = (travel_time - hours) * MINS_PER_HOUR;
  arrival_hours = (depart_hours + hours
                  + (depart_mins + mins) / MINS_PER_HOUR) % 24;
  arrival_mins =  (depart_mins + mins) % MINS_PER_HOUR; 

/***********************************************************/
/*  Print results.                                         */
/***********************************************************/

  printf("\nDistance: %5.2f miles.\n", distance);
  printf("Speed: %5.2f mph.\n", speed);
  printf("Departure time: %.2d:%.2d.\n",
          depart_hours, depart_mins);
  printf("Travel time: %.2d:%.2d.\n", hours, mins);
  printf("Arrival time: %.2d:%.2d.\n",
          arrival_hours, arrival_mins);
  return 0;
}
--------- ch5/grades.c :------------------------- CUT HERE ----
#include <stdio.h>

#define TRUE 1
#define FALSE 0
#define HW_PERC 0.15
#define FIN_PERC 0.25

/**************************************************/
/* This program allows the user to perform grade  */
/* calculations, based on the following:          */
/*                                                */
/*   Three homework assignments, each worth 15%.  */
/*   Two midterm examinations, each worth 15%.    */
/*   One final exam, worth 25%.                   */
/*                                                */
/* The program calculates any one of these items, */
/* or the final grade, in terms of the other six. */
/*                                                */
/**************************************************/

main()
{
  int choice, hw1_flag = TRUE, hw2_flag = TRUE,
     hw3_flag = TRUE, mt1_flag = TRUE, mt2_flag = TRUE,
     fin_flag = TRUE, grd_flag = TRUE;
  float homework_1, homework_2, homework_3,
    midterm_1, midterm_2, final_exam, final_grade;

/**************************************************/
/* Print menu and obtain user choice for the item */
/* to be calculated.                              */
/**************************************************/

  printf("Grade Calculation Program\n\n");
  printf("Please select the item to be calculated:\n");
  printf("  (you'll be asked to enter the others).\n\n");
  printf("Homework #1: (1)\n");
  printf("Homework #2: (2)\n");
  printf("Homework #3: (3)\n");
  printf("Midterm  #1: (4)\n");
  printf("Midterm  #2: (5)\n");
  printf("Final Exam : (6)\n");
  printf("Final Grade: (7)\n\n");
  printf("Please enter your choice: ");
  scanf("%d", &choice);
  if ((choice < 1) || (choice > 7)) {
    printf("Incorrect Choice !\n");
    return 1;
  }

/**************************************************/
/* Input all items except the one chosen.         */
/**************************************************/

  printf("You have chosen to calculate ");
  switch (choice) {
    case 1: hw1_flag = FALSE;
            printf("Homework 1."); break;
    case 2: hw2_flag = FALSE;
            printf("Homework 2."); break;
    case 3: hw3_flag = FALSE;
            printf("Homework 3."); break;
    case 4: mt1_flag = FALSE;
            printf("Midterm 1."); break;
    case 5: mt2_flag = FALSE;
            printf("Midterm 2."); break;
    case 6: fin_flag = FALSE;
            printf("the Final Exam."); break;
    case 7: grd_flag = FALSE;
            printf("the Final Grade."); break;
  }
  printf("\nYou'll now be asked to enter the other items.\n\n");

  if (hw1_flag) {
    printf("Please Enter Homework #1: ");
    scanf("%f", &homework_1);
  }
  if (hw2_flag) {
    printf("Please Enter Homework #2: ");
    scanf("%f", &homework_2);
  }
  if (hw3_flag) {
    printf("Please Enter Homework #3: ");
    scanf("%f", &homework_3);
  }
  if (mt1_flag) {
    printf("Please Enter Midterm #1: ");
    scanf("%f", &midterm_1);
  }
  if (mt2_flag) {
    printf("Please Enter Midterm #2: ");
    scanf("%f", &midterm_2);
  }
  if (fin_flag) {
    printf("Please Enter Final Exam: ");
    scanf("%f", &final_exam);
  }
  if (grd_flag) {
    printf("Please Enter Final Grade: ");
    scanf("%f", &final_grade);
  }

/**************************************************/
/* Calculate and print the item chosen.           */
/**************************************************/

  switch (choice) {
    case 1:
      homework_1 = (final_grade -
        (homework_2 + homework_3 + midterm_1 + midterm_2) * HW_PERC
         - final_exam * FIN_PERC) / HW_PERC;
      printf("Homework #1 = %5.2f\n", homework_1);
      break;
    case 2:
      homework_2 = (final_grade -
        (homework_1 + homework_3 + midterm_1 + midterm_2) * HW_PERC
         - final_exam * FIN_PERC) / HW_PERC;
      printf("Homework #2 = %5.2f\n", homework_2);
      break;
    case 3:
      homework_3 = (final_grade -
        (homework_1 + homework_2 + midterm_1 + midterm_2) * HW_PERC
         - final_exam * FIN_PERC) / HW_PERC;
      printf("Homework #3 = %5.2f\n", homework_3);
      break;
    case 4:
      midterm_1 = (final_grade -
        (homework_1 + homework_2 + homework_3 + midterm_2) * HW_PERC
         - final_exam * FIN_PERC) / HW_PERC;
       printf("Midterm #1 = %5.2f\n", midterm_1);
       break;
    case 5:
      midterm_2 = (final_grade -
        (homework_1 + homework_2 + homework_3 + midterm_1) * HW_PERC
         - final_exam * FIN_PERC) / HW_PERC;
       printf("Midterm #2 = %5.2f\n", midterm_2);
       break;
    case 6:
      final_exam = (final_grade -
        (homework_1 + homework_2 + homework_3 + midterm_1 + midterm_2)
        * HW_PERC ) / FIN_PERC;
      printf("Final Exam = %5.2f\n", final_exam);
      break;
    case 7:
       final_grade =
       (homework_1 + homework_2 + homework_3 + midterm_1 + midterm_2)
       * HW_PERC + final_exam * FIN_PERC;
       printf("Final Grade = %5.2f\n", final_grade);
       break;
  }
  return 0;
}
--------- ch6/amort.c :------------------------- CUT HERE ----
#include <stdio.h>

/************************************************************/
/* This program reads in a loan amount, an interest rate,   */
/* and a monthly payment, and prints an amortization table, */
/* listing the loan balance at the end of each period.      */
/************************************************************/

main()
{
  float balance, interest, payment;
  int i;

/************************************************************/
/* Read in balance, interest rate, and payment.             */
/************************************************************/

  printf("Amortization Table Program:\n\n");
  printf("Enter starting balance: ");
  scanf("%f", &balance);
  printf("Enter interest rate: ");
  scanf("%f", &interest);
  printf("Enter monthly payment: ");
  scanf("%f", &payment);

/************************************************************/
/* Loop to calculate and print the remaining balance at     */
/* the end of each period.                                  */
/************************************************************/

  i = 0;
  printf("\nAmortization Table:\n\n");
  printf("Period    Balance\n");
  printf("-------------------\n");
  while (balance > 0) {
    i++;
    balance = balance + (balance * interest / 12) - payment;
    printf("%5d  %10.2f\n", i, balance);
  }
  return 0;
}
--------- ch6/knight.c :------------------------- CUT HERE ----
#include <stdio.h>

#define NROWS 8
#define NCOLS 8
#define FALSE 0
#define TRUE  1

main()
{
  int knight_row, knight_col;
  int line, row, col, i, j;
  int filled;

  printf("Chess Knight Program\n");

  /*********************************/
  /* Read knight_row, knight_col   */
  /* until they are both in range. */
  /*********************************/

  do {
    printf("Enter knight's coordinates: ");
    scanf("%d %d", &knight_row, &knight_col);
  } while ((knight_row < 1) || (knight_row > NROWS) ||
           (knight_col < 1) || (knight_col > NCOLS));

  /*********************************/
  /* Print 2 * NROWS + 1 rows      */
  /*********************************/

  for (line = 1; line <= 2 * NROWS + 1; line++) {
    row = line / 2;
    if (line % 2 != 0) {
      /**********************************************/
      /* Odd line number: print one row of +---+'s  */
      /**********************************************/
      printf("+");
      for (col = 1; col <= NCOLS; col++)
        printf("---+");
      printf("\n");
    }
    else {
      /**********************************************/
      /* Even line number: print one row of vertical*/
      /* bars, with '*'s and a K where appropriate. */
      /**********************************************/
      printf("|");
      for (col = 1; col <= NCOLS; col++) {
        filled = FALSE;

        /********************************************/
        /*   If a K belongs here, print it.         */
        /********************************************/
        if ((row == knight_row) && (col == knight_col)) {
          printf(" K |");
          filled = TRUE;
          continue;
        }

        /********************************************/
        /*   If a '*' belongs here, print it.       */
        /********************************************/
        for (i = -2; i <= 2; i++) {
          for (j = -2; j <= 2; j++) {
            if ((i == j) || (i == -j) || (i == 0) || (j == 0)) continue;
            if ((knight_row + i == row) && (knight_col + j == col)) {
              printf(" * |");
              filled = TRUE;
            }
          }
        }

        /*********************************************/
        /*  Print a vertical bar if slot not filled.  */
        /*********************************************/
        if (!filled) printf("   |");
      }
      printf("\n");
    }
  }
  return 0;
}
--------- ch7/wac.c :------------------------- CUT HERE ----
#include <stdio.h>
#include <ctype.h>

#define IN_WORD     1
#define OUT_WORD    2
#define IN_COMMENT  3

/**************************************************************/
/* Description: Program that loops to process all input       */
/* characters. Letters are formed into words while delimiters */
/* are ignored. Any invalid characters encountered are        */
/* reported as errors. Also ignored are any comments, denoted */
/* by a slash, up to the eol. Invalid characters within       */
/* comments are ignored, and do not produce an error message. */
/*                                                            */
/* The program itself is organized based on a finite-state    */
/* automaton structure, shown in the table below.             */
/*                                                            */
/* Note the abbreviations:                                    */
/*                                                            */
/* ch: inchar                                                 */
/* nc: number of chars                                        */
/* nw: number of words                                        */
/* nl: number of lines                                        */
/* st: state                                                  */
/*                                                            */
/**************************************************************/
/* Input       IN_WORD        OUT_WORD       IN_COMMENT       */
/* char                                                       */
/*------------------------------------------------------------*/
/* letter      putchar(ch)    putchar(ch)    nc++             */
/*   or        nc++           nc++           st=IN_COMMENT    */
/* digit       st=IN_WORD     st=IN_WORD                      */
/*------------------------------------------------------------*/
/* .,:;[]{}()  putchar(\n)    nc++           nc++             */
/* etc.        nc++ nw++      st=OUT_WORD    st=IN_COMMENT    */
/*             st=OUT_WORD                                    */
/*------------------------------------------------------------*/
/*   \n        putchar(\n)    nc++           nc++             */
/*             nc++ nw++ nl++ nl++           nl++             */
/*             st=OUT_WORD    st=OUT_WORD    st=OUT_WORD      */
/*------------------------------------------------------------*/
/*    /        putchar(\n)    nc++           nc++             */
/*             nc++ nw++      st=IN_COMMENT  st=IN_COMMENT    */
/*             st=IN_COMM                                     */
/*------------------------------------------------------------*/
/*   all       putchar(\n)    ERROR          nc++             */
/*  others     ERROR          nc++           st=IN_COMMENT    */
/*             nw++ nc++      st=OUT_WORD                     */
/*             st=OUT_WORD                                    */
/**************************************************************/

main()
{
  int inchar;
  int nchars = 0, nwords = 0, nlines = 0;
  int state;
  state = OUT_WORD;    /* initial state */
 
  /************************************************************/
  /* Loop through input file, reading one character at a time.*/
  /************************************************************/

  while ((inchar = getchar()) != EOF) {
    nchars++;
    /************************************************/
    /* Check if inchar is a letter or digit.        */
    /************************************************/
    if (isalnum(inchar))
      switch (state)  {
        case IN_WORD: case OUT_WORD:
          putchar(inchar);
          state = IN_WORD;
          break;
        case IN_COMMENT:
          break;
      }

    /************************************************/
    /* Check if inchar is punctuator, space, or tab.*/
    /************************************************/
    else if ((inchar == ',') || (inchar == '.') || (inchar == ':') ||
             (inchar == ';') || (inchar == '_') || (inchar == '"') ||
             (inchar == '-') || (inchar == '?') || (inchar == '!') ||
             (inchar == '(') || (inchar == ')') || (inchar == '{') ||
             (inchar == '}') || (inchar == '[') || (inchar == ']') ||
             (inchar == ' ') || (inchar == '\t'))
      switch (state) {
        case IN_WORD:
          putchar('\n');
          nwords++;
        case OUT_WORD:
          state = OUT_WORD;
          break;
        case IN_COMMENT:
          break;
      }

    /************************************************/
    /* Check if inchar is new-line.                 */
    /************************************************/
    else if ((inchar == '\n'))
      switch (state) {
        case IN_WORD:
          putchar('\n');
          nwords++;
        case OUT_WORD: case IN_COMMENT:
          nlines++;
          state = OUT_WORD;
          break;
      }

    /************************************************/
    /* Check if inchar begins a comment.            */
    /************************************************/
    else if ((inchar == '/'))
      switch (state) {
        case IN_WORD:
          putchar('\n');
          nwords++;
        case OUT_WORD: case IN_COMMENT:
          state = IN_COMMENT;
          break;
      }

    /************************************************/
    /* Anything else must be an invalid character.  */
    /************************************************/
    else
      switch (state)  {
        case IN_WORD:
          putchar('\n');
          nwords++;
        case OUT_WORD:
          printf("ERROR!!! Illegal character (%c).\n", inchar);
          state = OUT_WORD;
          break;
        case IN_COMMENT:
          break;
      }
  }

  printf("\n\nNumber of characters: %d\n", nchars);
  printf("Number of words:      %d\n", nwords);
  printf("Number of lines:      %d\n", nlines);
  return 0;
}
--------- ch8/bubsort.c :------------------------- CUT HERE ----
#include <stdio.h>

#define MAXARRAY 100

main()
{
  int a[MAXARRAY];
  int last, index, top, temp;

  /*********************************************************/
  /* Read numbers into the array until a -1 appears.       */
  /* Check the array index so it doesn't go out of bounds. */
  /*********************************************************/
  index = 0;
  printf("Bubble Sort Program.\n");
  printf("Please enter integers, ending with -1\n");
  do {
    scanf("%d", &temp);
     if (index >= MAXARRAY) {
       printf("EXCEEDED ARRAY SIZE of %d!\n\n", MAXARRAY);
       break;
     } else {
       a[index] = temp;
       index++;
     }
  } while (temp != -1);

  last = index - 1;

  /*********************************************************/
  /* Print out the numbers that were read in.              */
  /*********************************************************/
  printf("NUMBERS READ IN: (%d)", last);
  for (index = 0; index < last; index++) {    
     if (index % 10 == 0) printf("\n");
     printf("%5d", a[index]);
  }
  printf("\n\n");

  /*********************************************************/
  /* PERFORM THE BUBBLE SORT.                              */
  /*********************************************************/
  for (top = last - 1; top >= 1; top--)
    for (index = 0; index < top; index++)
      if (a[index] > a[index + 1]) {
        temp = a[index];
        a[index] = a[index + 1];
        a[index + 1] = temp;
      }

  /*********************************************************/
  /* Print out the sorted numbers.                         */
  /*********************************************************/
  printf("SORTED NUMBERS:  (%d)", last);
  for (index = 0; index < last; index++) {    
     if (index % 10 == 0) printf("\n");
     printf("%5d", a[index]);
  }
  printf("\n\n");

  return 0;
}
--------- ch8/large.c :------------------------- CUT HERE ----
#include <stdio.h>

#define MAXSIZE 3000
#define MAXFACT 1000
#define FALSE 0
#define TRUE  1  

/****************************************************/
/* Program to calculate the factorial of MAXFACT.   */
/****************************************************/

main()
{
  int large[MAXSIZE] = {0};
  int n, index, carry, product, last_digit, line_counter, panic;

  panic = FALSE;
  large[0] = 1;
  last_digit = 0;

  /***************************************************/
  /*  Process each value of n, from 1 to MAXFACT.    */
  /***************************************************/
  for (n = 1; n <= MAXFACT; n++) {

    /*************************************************/
    /*  Calculate digits 1 through 'last_digit'      */
    /*************************************************/
    carry = 0;
    for (index = 0; index <= last_digit; index++) {
      product = large[index] * n + carry;
      large[index] = product % 10;
      carry = product / 10;
    }

    /*************************************************/
    /*  Take the carry past 'last_digit';  strip the */
    /*  digits off 'carry' until it becomes zero.    */
    /*  Careful: here we can exceed the array bounds.*/
    /*************************************************/
    while (carry) {
      /***********************************************/
      /* Peel the least significant digit off carry, */ 
      /* place it in large[index], and increment     */
      /* 'index'. If index goes out of bounds, print */
      /* an error message and break out of the loop. */
      /***********************************************/
      large[index] = carry % 10;
      carry = carry / 10;
      index++;
      if (index >= MAXSIZE) {
        printf("OUT OF SPACE\n");
        panic = TRUE;
        break;  
      }
    }
    last_digit = index - 1;

    if (panic) break;  

    /*************************************************/
    /*  Print large number at 50 digits per line.    */
    /*************************************************/
    line_counter = 0;
    printf("%d! has %d digits:\n", n, last_digit + 1);
    for (index = last_digit; index >= 0; index--) {
      printf("%1d", large[index]);
      line_counter++;
      if (line_counter % 50 == 0) printf("\n");
    }
    printf("\n\n");

  }
  return 0;
}
--------- ch9/plot.c :------------------------- CUT HERE ----
#include <stdio.h>
#include <math.h>

#define MAX_COLUMNS 60

float xl, xu, delta, ymin, ymax;

void print_header();
void get_domain_parameters();
void calculate_min_max();
void print_plot_header();
void print_plot_footer();
void print_plot();

main()
{
  print_header();
  get_domain_parameters();
  calculate_min_max();
  print_plot();
  return 0;
}

void print_header()
{
  printf("\n==============================================\n");
  printf("            Sine Function Plotting Program\n");
  printf("==============================================\n");
  printf("\n");
}

void get_domain_parameters()
{
  printf("Please enter lower bound for domain: ");
  scanf("%f", &xl);
  printf("Please enter upper bound for domain: ");
  scanf("%f", &xu);
  printf("Please enter interval over domain: ");
  scanf("%f", &delta);

  printf("\nYou entered the following domain parameters:\n");
  printf(" ===========================================\n");
  printf("    Lower bound for domain: %f\n", xl);
  printf("    Upper bound for domain: %f\n", xu);
  printf("    Increment value       : %f\n", delta);
  printf(" ===========================================\n\n");
}

void calculate_min_max()
{
  float x, y;

  ymin = sin(xl);
  ymax = sin(xl);
  for (x = xl; x <= xu; x += delta) {
    y = sin(x);
    if (y < ymin) ymin = y;
    if (y > ymax) ymax = y;
  }
}

void print_plot_header()
{
  printf("    %3.1f", ymin);
  printf("                           %3.1f", (ymin + ymax) / 2);
  printf("                            %3.1f\n", ymax);
  printf("      +");
  printf("-----------------------------+");
  printf("------------------------------+\n");
}

void print_plot_footer()
{
  printf("      +");
  printf("-----------------------------+");
  printf("------------------------------+\n");
  printf("    %3.1f", ymin);
  printf("                           %3.1f", (ymin + ymax) / 2);
  printf("                            %3.1f\n", ymax);
}

void print_plot()
{
  int scale_index, i, previous;
  float x;
  char A[MAX_COLUMNS];

  for (i = 0; i < MAX_COLUMNS; i++)
    A[i] = ' ';
  x = xl;
  previous = 0;
  print_plot_header();

  /*************************************************************/
  /* Loop through values of x in the domain, in incs of delta  */
  /*************************************************************/
  while (x <= xu) {

    /***********************************************************/
    /* Calculate scale_index: number of spaces to the left of  */
    /* the asterisk. Keep track of previous location of the    */
    /* asterisk. In each iteration, place a space in the       */
    /* previous location, and an asterisk in the current one.  */
    /***********************************************************/
    scale_index = (sin(x) - ymin) * MAX_COLUMNS / (ymax - ymin) - 0.5; 
    A[previous] = ' ';
    A[scale_index] = '*';
    previous = scale_index;
    printf("%5.2f |", x);
    for (i = 0; i < MAX_COLUMNS; i++)
      putchar(A[i]);
    printf("|\n");
    x = x + delta;
  }
  print_plot_footer();
}
--------- ch9/sort.c :------------------------- CUT HERE ----
#include <stdio.h>

#define ARRAY_SIZE 30

int get_input(int a[]);
void print_array(int a[], int n);
int max(int a[], int n);
void sort(int a[], int n);

main()
{
  int n;
  int a[ARRAY_SIZE];

  n = get_input(a);
  print_array(a, n);
  sort(a, n);
  print_array(a, n);
  return 0;
}

int get_input(int a[])
{
  int index = 0, temp;

  printf("Please enter integers, ending with -1.\n");
  do {
    scanf("%d", &temp);
     if (index >= ARRAY_SIZE) {
       printf("EXCEEDED ARRAY SIZE of %d!\n\n", ARRAY_SIZE);
       break;
     } else {
       a[index] = temp;
       index++;
     }
  } while (temp != -1);

  return index - 1; 
}

void print_array(int a[], int n)
{
  int i;

  printf("Array a:\n");
  printf("   +----+\n");
  for (i = 0; i < n; i++)
    printf("%3d|%4d|\n", i, a[i]);
  printf("   +----+\n");
}

int max(int a[], int n)
{
  int max_value, max_index = 0, i;

  max_value = a[max_index];
  for (i = 0; i <= n; i++)
    if (a[i] > max_value) {
      max_value = a[i];
      max_index = i;
    }
  return max_index;
}

void sort(int a[], int n)
{
  int largest, temp;

  if (n <= 1) return;
  largest = max(a, n - 1);
  temp = a[largest];
  a[largest] = a[n - 1];
  a[n - 1] = temp;
  sort(a, n - 1);
}
--------- ch10/sets.c :------------------------- CUT HERE ----
#include <stdio.h>

#define MAX_SET_SIZE 50
#define TRUE  1
#define FALSE 0

void create_set(int a[]);
void read_set(int a[]);
void print_set(int a[]);
void union_set(int a[], int b[], int c[]);
void intersect_set(int a[], int b[], int c[]);
void enter_set(int v, int a[]);
int  element_of(int v, int a[]);

main()
{
  int a[MAX_SET_SIZE];
  int b[MAX_SET_SIZE];
  int c[MAX_SET_SIZE];

  read_set(a);
  read_set(b);

  printf("Set A: ");
  print_set(a);
  printf("Set B: ");
  print_set(b);
  union_set(a, b, c);
  printf("Set C: Union of A and B: ");
  print_set(c);
  intersect_set(a, b, c);
  printf("Set C: Intersection of A and B: ");
  print_set(c);
  return 0;
}

void create_set(int a[]) 
{
  a[0] = 0;
}

void read_set(int a[])
{
  int value;

  create_set(a);
  printf("Enter set values, ending with -1.\n");
  scanf("%d", &value);
  while (value != -1) {
    enter_set(value, a);
    scanf("%d", &value);
  }
}

void print_set(int a[])
{
  int i;

  printf("{");
  if (a[0] >= 1) printf("%d", a[1]);
  for (i = 2; i <= a[0]; i++)
    printf(",%d", a[i]);
  printf("}\n");
}

void union_set(int a[], int b[], int c[])
{
  int i;

  create_set(c);
  for (i = 1; i <= a[0]; i++)
    enter_set(a[i], c);
  for (i = 1; i <= b[0]; i++)
    enter_set(b[i], c);
}

void intersect_set(int a[], int b[], int c[])
{
  int i;

  create_set(c);
  for (i = 1; i <= a[0]; i++) 
    if (element_of(a[i], b))
      enter_set(a[i], c);
}

void enter_set(int v, int a[])
{
  if (a[0] == MAX_SET_SIZE)
    printf("MAX SET SIZE EXCEEDED\n");
  else if (!element_of(v, a)) {
    a[0]++;
    a[a[0]] = v;
  }
}

int element_of(int v, int a[])
{
  int i;

 for (i = 1; i <= a[0]; i++)
   if (a[i] == v) return TRUE;
 return FALSE;
}
--------- ch11/complex.c :------------------------- CUT HERE ----
#include <stdio.h>

/*---------------------------------------------------------------*/
/* This program adds, subtracts, or multiplies complex numbers.  */
/* In all the functions below, r represents the real component   */
/* and i represents the imaginary component.                     */
/*---------------------------------------------------------------*/

void add(float r1, float i1, float r2, float i2,
         float *r3, float *i3);
void subtract(float r1, float i1, float r2, float i2,
              float *r3, float *i3);
void multiply(float r1, float i1, float r2, float i2,
              float *r3, float *i3);
void read_nums(float *r1, float *i1, float *r2, float *i2);
void read_num(float *r, float *i);
void print_complex(float r, float i);

main()
{
  float r1, r2, r3, i1, i2, i3;
  char c;

  printf("COMPLEX NUMBER ARITHMETIC PROGRAM:\n\n");
  while (1) {
    printf("1) Add two complex numbers\n");
    printf("2) Subtract two complex numbers\n");
    printf("3) Multiply two complex numbers\n");
    printf("4) Quit\n\n");
    printf("Choose an option (1 - 4): ");
    scanf("%c", &c);
    switch (c) {
      case '1':
        read_nums(&r1, &i1, &r2, &i2);
        add(r1, i1, r2, i2, &r3, &i3);
        print_complex(r3, i3);
        break;
      case '2':
        read_nums(&r1, &i1, &r2, &i2);
        subtract(r1, i1, r2, i2, &r3, &i3);
        print_complex(r3, i3);
        break;
      case '3':
        read_nums(&r1, &i1, &r2, &i2);
        multiply(r1, i1, r2, i2, &r3, &i3);
        print_complex(r3, i3);
        break;
      case '4':
        return 0;
    }
  }
  return 0;
}

void add(float r1, float i1, float r2, float i2,
         float *r3, float *i3)
{
  *r3 = r1 + r2;
  *i3 = i1 + i2;
}

void subtract(float r1, float i1, float r2, float i2,
              float *r3, float *i3)
{
  *r3 = r1 - r2;
  *i3 = i1 - i2;
}

void multiply(float r1, float i1, float r2, float i2,
              float *r3, float *i3)
{
  *r3 = r1 * r2 - i1 * i2;
  *i3 = ((r1 * i2) + (r2 * i1));
}

void read_nums(float *r1, float *i1, float *r2, float *i2)
{
  printf("Reading the first number ...\n");
  read_num(r1, i1);
  printf("Reading the second number ...\n");
  read_num(r2, i2);
}

void read_num(float *r, float *i)
{
  printf("Please type the real component: ");
  /* r and i are pointers; the & operator is unnecessary */
  scanf("%f", r);
  printf("\n");
  printf("Please type the imaginary component: ");
  scanf("%f", i);
  printf("\n");
}

void print_complex(float r3, float i3)
{
  printf("The operation yields %6.3f + %6.3fi\n\n", r3, i3);
}
--------- ch12/matrix.c :------------------------- CUT HERE ----
#include <stdio.h>

#define N 3

void multiply(int *mat1, int *mat2, int *mat3);
void fill_zero(int *mat);
void read_matrix(int *mat);
void print_matrix(const int *mat);

main()
{
  int mat1[N][N];
  int mat2[N][N];
  int mat3[N][N];

  printf("MATRIX MULTIPLICATION PROGRAM:\n\n");

  fill_zero(mat1[0]);
  fill_zero(mat2[0]);
  fill_zero(mat3[0]);

  printf("Reading the first matrix ...\n");
  read_matrix(mat1[0]);
  printf("Reading the second matrix ...\n");
  read_matrix(mat2[0]);

  multiply(mat1[0], mat2[0], mat3[0]);

  printf("The resulting matrix is:\n");
  print_matrix(mat3[0]);
  return 0;
}

void multiply(int *mat1, int *mat2, int *mat3)
{
  int row1, col2;
  int *p1row, *p1, *p2, *p3;

  /* traverse all of mat3  */
  for (p3 = mat3; p3 < mat3 + N * N; p3++) {
    /* Get the current row number  */
    row1 = (p3 - mat3) / N;
    /* Get the current col number */
    col2 = (p3 - mat3) % N;
    /* Pointer to first row, current column in mat2*/
    p2 = mat2 + col2;
    /* Pointer to start of current row in mat1 */
    p1row = mat1 +row1 * N;

    /* Traverse the current row */
    for (p1 = p1row; p1 < p1row + N; p1++){
      /* Multiply values from mat1 and mat2; */
      /*  Add result to position in mat3.    */
      *p3 += *p1 * *p2;
      /* Move pointer in mat2 to next row. */
      p2 += N;
    }
  }
}

void read_matrix(int *mat)
{
  int i;

  for (i = 0; i < N * N; i++) {
    printf("Please type the element in row %d, column %d: ",
            i / N + 1, i % N +1);
    scanf("%d", mat++);
  }
  printf("\n\n");
}  

void print_matrix(const int *mat)
{
  int i, j;

  for (i = 0; i < N; i++) {
    for (j = 0; j < N; j++)
      printf("%3i  ", *mat++);
    printf("\n");
  }
}

void fill_zero(int *mat)
{
  int i;

  for (i = 0; i < N * N; i++)
    *mat++ = 0;
}
--------- ch13/indented.indenter.c :------------------------- CUT HERE ----
#include <stdio.h>
#include <string.h>

#define LINE_SIZE 512
#define TAB '\t'

/********************************************************/
/* This program indents the source text of a C program. */
/* It requires that every bracket ('{') be the first    */
/* non-space character in the line. Lines of maximum   */
/* length 512 can be handled. The number of characters  */
/* to indent is taken as a program parameter.           */
/********************************************************/

void remove_spaces(char *s);
void add_spaces(char *s, int curr_indent);

main(int argc, char *argv[])
{
  int curr_indent = 0, indent;
  char line[LINE_SIZE];
  
  if (argc != 2)
  {
    printf("INDENTER needs an integer value\n");
  }
  else
  {
    indent = argv[1][0] - '0';
    while (gets(line) > 0)
    {
      remove_spaces(line);
      switch (line[0])
      {
        case '\n': break;
        case '{' :
        {
          add_spaces(line, curr_indent);
          curr_indent +=  indent;
          break;
        }
        case '}' :
        {
          curr_indent -= indent;
          add_spaces(line, curr_indent);
          break;
        }
        default  :
        {
          add_spaces(line, curr_indent);
        }
      }
      puts(line);
    }
  }
  return 0;
}

void remove_spaces(char *s)
{
  int i = 0;
  char p[LINE_SIZE]; 
  
  strcpy(p, "");
  strcpy(p, s);
  while ((p[i] == ' ') || (p[i] == TAB)) 
  {
    i++;
  }
  strcpy(s, &p[i]);
}

void add_spaces(char *s, int curr_indent)
{
  char p[LINE_SIZE];
  int i = 0;
  
  strcpy(p, "");
  while (i++ < curr_indent)
  {
    strcat(p, " ");
  }
  strcat(p, s);
  strcpy(s, p);
}
--------- ch13/indenter.c :------------------------- CUT HERE ----
#include <stdio.h>
#include <string.h>

#define LINE_SIZE 512
#define TAB '\t'

/********************************************************/
/* This program indents the source text of a C program. */
/* It requires that every bracket ('{') be the first    */
/* non-space character in the line. Lines of maximum    */
/* length 512 can be handled. The number of characters  */
/* to indent is taken as a program parameter.           */
/********************************************************/

void remove_spaces(char *s);
void add_spaces(char *s, int curr_indent);

main(int argc, char *argv[])
 {
    int curr_indent = 0, indent;
    char line[LINE_SIZE];

 if (argc != 2)
  {
  printf("INDENTER needs an integer value\n");
 }
 else
 {
   indent = argv[1][0] - '0';
  while (gets(line) > 0)
  {
   remove_spaces(line);
   switch (line[0])
    {
    case '\n': break;
    case '{' :
    {
      add_spaces(line, curr_indent);
        curr_indent +=  indent;
        break;
    }
    case '}' :
    {
       curr_indent -= indent;
        add_spaces(line, curr_indent);
      break;
    }
    default  :
    {
          add_spaces(line, curr_indent);
        }
   }
   puts(line);
  }
}
return 0;
}

void remove_spaces(char *s)
{
  int i = 0;
  char p[LINE_SIZE]; 

 strcpy(p, "");
   strcpy(p, s);
 while ((p[i] == ' ') || (p[i] == TAB)) 
   {
  i++;
 }
 strcpy(s, &p[i]);
}

void add_spaces(char *s, int curr_indent)
{
 char p[LINE_SIZE];
   int i = 0;

 strcpy(p, "");
while (i++ < curr_indent)
 {
  strcat(p, " ");
  }
 strcat(p, s);
 strcpy(s, p);
}
--------- ch14/stacks1.c :------------------------- CUT HERE ----
/*************************************************************/
/* This program implements one STACK, with basic operations  */
/* push, pop, and init.                                      */
/* The operations are implemented via macros to contrast     */
/* their performance versus functions.                       */
/*************************************************************/

#include <stdio.h>
#include <time.h>        /* to access the internal clock */

#define MAX_STACK_SIZE 1024
#define count(s) s[0]
     /* s[0] contains the current number of elements  */

#define init(s) \
  do { \
    for (i = 1; i < MAX_STACK_SIZE; i++) \
      s[i] = 0; \
    count(s) = 0; \
  } while (0)

#define push(e, s) \
  do { \
    if (count(s) < stack_size) \
      s[stack_size - count(s)++] = e; \
    else \
      printf("Stack's full.\n"); \
  } while (0);

#define pop(e, s) \
  do { \
    if (count(s) == 0) \
      printf("The stack is empty.\n"); \
    else \
      e = s[stack_size - (count(s)--) + 1]; \
  } while (0)

main()
{
  int i, e, stack_size;
  int s[MAX_STACK_SIZE];
  clock_t first_tick;

  printf("Enter number of values to be reversed: ");
  scanf("%d", &stack_size);
  if (stack_size > MAX_STACK_SIZE) {
    printf("Maximum stack size allowed is %d.\n",
            MAX_STACK_SIZE - 1);
    exit(1);
  }
  first_tick = clock();
  init(s);
  for (i = 1; i <= stack_size; i++)
    push(i, s);
  printf("The reversed list is :\n");
  for (i = 1; i <= stack_size; i++) {
     pop(e, s);
     printf("%d, ", e);
  }
  printf("\n");
  printf("Elapsed time: %d\n", (int)(clock() - first_tick));
  return 0;
}
--------- ch14/stacks2.c :------------------------- CUT HERE ----
/*************************************************************/
/* This program implements one STACK, with basic operations  */
/* push, pop, and init.                                      */
/* The operations are implemented via functions to contrast  */
/* their performance versus macros.                          */
/*************************************************************/

#include <stdio.h>
#include <time.h>     /* to access the internal clock */

#define MAX_STACK_SIZE 1024
#define count(s) s[0]
      /* s[0] contains the current number of elements */

int stack_size = 0;

void init(int *s);
void push(int e, int *s);
int  pop(int *s);

main()
{
  int i, e;
  int s[MAX_STACK_SIZE];
  clock_t first_tick;

  printf("Enter number of values to be reversed: ");
  scanf("%d", &stack_size);
  if (stack_size > MAX_STACK_SIZE) {
    printf("Maximum stack size allowed is %d.\n",
             MAX_STACK_SIZE - 1);
    exit(1);
  }
  first_tick = clock();
  init(s);
  for (i = 1; i <= stack_size; i++) 
    push(i, s);
  printf("The reversed list is:\n");
  for (i = 1; i <= stack_size; i++) {
     e = pop(s);
     printf("%d, ", e);
  }
  printf("\n");
  printf("Elapsed time: %d.\n", (int)(clock() - first_tick));
  return 0;
}

void init(int *s)
{
  int i;

  for (i = 1; i < MAX_STACK_SIZE; i++)
    s[i] = 0;
  count(s) = 0;
}

void push(int e, int *s)
{
  if (count(s) < stack_size)
    s[stack_size - count(s)++] = e;
  else
    printf("Stack is full.\n");
}

int pop(int *s)
{
  if (count(s) == 0) {
    printf("The stack is empty.\n");
    exit(1);
  } else
    return (s[stack_size - count(s)-- + 1]);
}
--------- ch14/stacks3.c :------------------------- CUT HERE ----
/*************************************************************/
/* This program implements one STACK, with basic operations  */
/* push, pop, and init.                                      */
/* The operations are implemented via macros, using macros   */
/* to allow stack elements to be of various types.           */
/*************************************************************/

#include <stdio.h>

#define MAX_STACK_SIZE 12
#define FALSE 0
#define TRUE  1

#define INT   TRUE
#define CHAR  FALSE
#define FLOAT FALSE
#define count(s) s[0]

#if INT
  #define TYPE int
#elif  FLOAT
  #define TYPE float
#else
  #define TYPE char
#endif

int stack_size = 0;
void init(TYPE *s);
void push(TYPE e, TYPE *s);
TYPE pop(TYPE *s);

main(int argc, char *argv[])
{
  TYPE e;
  int i;
  TYPE s[MAX_STACK_SIZE];

  printf("Enter number of values to be reversed: ");
  scanf("%d", &stack_size);
  if (stack_size > MAX_STACK_SIZE) {
    printf("Maximum stack size allowed is %d.\n",
             MAX_STACK_SIZE - 1);
    exit(1);
  }
  printf("This program reverses a list of values of type ");
  #if INT
     printf("int.");
  #elif  FLOAT
     printf("float.");
  #else
     printf("char.");
  #endif
  printf("\n\n");

  init(s);
  for (i = 0; i < stack_size; i++) {
    printf("Enter value #%1d: ", i);
    #if INT
       scanf("%d", &e);
    #elif  FLOAT
       scanf("%f", &e);
    #else
       scanf(" %c", &e);
    #endif
    push(e, s);
  }
  for (i = 1; i <= stack_size; i++) {
    e = pop(s);
    #if INT
       printf("%d,", e);
    #elif FLOAT
      printf("%6.3f,", e);
    #else
       printf("%c,", e);
    #endif
  }
  printf("\n");
  return 0;
}

void init(TYPE *s) {
  int i;

  for (i = 1; i < MAX_STACK_SIZE; i++)
    s[i] = 0;
  count(s) = 0;
}

void push(TYPE e, TYPE *s) {
  if (count(s) < stack_size)
    s[stack_size - (int)count(s)++] = e;
  else 
    printf("The Stack is full.\n");
}

TYPE pop(TYPE *s) {
  if (count(s) == 0) {
    printf("The Stack is empty.\n");
    exit(1);
  }
  else
    return (s[stack_size - (int)(count(s)--) + 1]);
}
--------- ch15/bool/bool.h :------------------------- CUT HERE ----
/**********************/
/*    bool.h          */
/**********************/

#ifndef BOOL_H
#define BOOL_H

#define TRUE 1
#define FALSE 0

typedef int Bool;

extern Bool i_exist;

int logical_and(Bool a, Bool b);
void print_bool(Bool b);

#endif
--------- ch15/bool/booltest.c :------------------------- CUT HERE ----
/*************************/
/*    booltest.c         */
/*************************/

#include <stdio.h>
#include "bool.h"

main()
{
  Bool a = TRUE;
  Bool b = FALSE;

  print_bool(logical_and(a, b));
  print_bool(i_exist);
  return 0;
}
--------- ch15/bool/Makefile :------------------------- CUT HERE ----
bool:	booltest.o bool.o
	gcc -Wall -o bool booltest.o bool.o

bool.o:	bool.c
	gcc -Wall -c bool.c

booltest.o: booltest.c
	gcc -Wall -c booltest.c

clean:	
	rm -f *.o bool
--------- ch15/bool/bool.c :------------------------- CUT HERE ----
/**********************/
/*      bool.c        */
/**********************/

#include <stdio.h>
#include "bool.h"

Bool logical_and(Bool a, Bool b) 
{
  return (a && b);
}

void print_bool(Bool b)
{
  printf("%s\n", (b ? "TRUE" : "FALSE"));
}

Bool i_exist = TRUE;
--------- ch15/sets/Makefile :------------------------- CUT HERE ----
testset:	testset.o set.o commandline.o menu.o
	gcc -Wall -o testset menu.o testset.o set.o commandline.o
testset.o:	testset.c commandline.h set.h bool.h
	gcc -Wall -c testset.c
commandline.o: commandline.c commandline.h
	gcc -Wall -c commandline.c
set.o: set.c set.h
	gcc -Wall -c set.c
menu.o:	menu.c menu.h
	gcc -Wall -c menu.c
clean:
	rm -f *.o testset
--------- ch15/sets/commandline.h :------------------------- CUT HERE ----
/**************************************/
/*      File: commandline.h           */
/**************************************/
#ifndef COMMAND_LINE_H
#define COMMAND_LINE_H

char *program_argument(char *flag, char *name, int argc, char *argv[]);
int program_flag(char *flag, int argc, char *argv[]);
void commandline(int argc, char *argv[]);

#endif
--------- ch15/sets/menu.c :------------------------- CUT HERE ----
/*******************************/
/*      File: menu.c           */
/*******************************/

#include <stdio.h>
#include "bool.h"
#include "set.h"
#include "menu.h"

void main_menu_loop()
{
  int done, user_choice;
  int a[MAX_SET_SIZE];
  int b[MAX_SET_SIZE];
  int c[MAX_SET_SIZE];

  done = FALSE;
  while (!done) {
    printf("SET MANIPULATION PROGRAM:\n\n");
    printf("Main Menu:\n");
    printf("1. Union of sets.\n");
    printf("2. Intersection of sets.\n");
    printf("3. Difference between sets.\n");
    printf("4. Quit this program.\n\n");
    printf("Your selection (by number): ");
    scanf("%d", &user_choice);
    switch (user_choice) {
      case 1:
        read_sets(a, b);
        union_set(a, b, c);
        printf("Set C: Union of A and B:\n");
        print_set(c);
        break;
      case 2:
        read_sets(a, b);
        intersect_set(a, b, c);
        printf("Set C: Intersection of A and B:\n");
        print_set(c); 
        break;
      case 3:
        read_sets(a, b);
        difference_set(a, b, c);
        printf("Set C: Difference between A and B:\n");
        print_set(c); 
        break;
      case 4:
        done = TRUE;
        printf("Bye!\n");
        break;
      default:
        printf("INVALID MENU SELECTION\n\n");
    }
  }
}
--------- ch15/sets/set.c :------------------------- CUT HERE ----
/******************************/
/*      File: set.c           */
/******************************/

#include <stdio.h>
#include "bool.h"
#include "set.h"

void create_set(int a[])
{
  a[0] = 0;
}

void read_set(int a[])
{
  int value;

  create_set(a);
  printf("Enter set values, end with -1.\n");
  scanf("%d", &value);
  while (value != -1) {
     enter_set(value, a);
     scanf("%d", &value);
  }
}

void read_sets(int a[], int b[])
{
  read_set(a);
  read_set(b);
  printf("Set A:\n");
  print_set(a);
  printf("Set B:\n");
  print_set(b);
}

void print_set(int a[])
{
  int i;

  printf("{");
  for (i = 1; i <= a[0]; i++) {
    printf("%d", a[i]);
    if (i < a[0]) printf(", ");
    if (i % elements_per_line == 0)
      printf("\n");
  }
  printf("}\n");
}

void union_set(int a[], int b[], int c[])
{
  int i;

  create_set(c);
  for (i = 1; i <= a[0]; i++)
    enter_set(a[i], c);
  for (i = 1; i <= b[0]; i++)
    enter_set(b[i], c);
}

void intersect_set(int a[], int b[], int c[])
{
  int i;

  create_set(c);
  for (i = 1; i <= a[0]; i++) 
    if (element_of(a[i], b))
      enter_set(a[i], c);
}

void difference_set(int a[], int b[], int c[])
{
  int i;

  create_set(c);
  for (i = 1; i <= a[0]; i++) 
    if (!element_of(a[i], b))
      enter_set(a[i], c);
}

void enter_set(int v, int a[])
{
  if (a[0] == MAX_SET_SIZE)
    printf("MAX SET SIZE EXCEEDED\n");
  else if (!element_of(v, a)) {
    a[0]++;
    a[a[0]] = v;
  }
}

Bool element_of(int v, int a[])
{
  int i;

  for (i = 1; i <= a[0]; i++)
    if (a[i] == v) return TRUE;
  return FALSE;
}
--------- ch15/sets/bool.h :------------------------- CUT HERE ----
/*******************************/
/*      File: bool.h           */
/*******************************/
#ifndef BOOL_H
#define BOOL_H

#define TRUE 1
#define FALSE 0

typedef int Bool;

#endif
--------- ch15/sets/menu.h :------------------------- CUT HERE ----
/*******************************/
/*      File: menu.h           */
/*******************************/

#ifndef MENU_H
#define MENU_H

void main_menu_loop();

#endif
--------- ch15/sets/set.h :------------------------- CUT HERE ----
/******************************/
/*      File: set.h           */
/******************************/

#ifndef SET_H
#define SET_H

#include "bool.h"
#define MAX_SET_SIZE 50

int elements_per_line;
void create_set(int a[]);
void read_set(int a[]);
void read_sets(int a[], int b[]);
void print_set(int a[]);
void union_set(int a[], int b[], int c[]);
void intersect_set(int a[], int b[], int c[]);
void difference_set(int a[], int b[], int c[]);
void enter_set(int v, int a[]);
Bool element_of(int v, int a[]);

#endif
--------- ch15/sets/testset.c :------------------------- CUT HERE ----
/**********************************/
/*      File: testset.c           */
/**********************************/
#include <stdio.h>
#include "bool.h"
#include "commandline.h"
#include "set.h"
#include "menu.h"

main(int argc, char *argv[])
{
  commandline(argc, argv);
  main_menu_loop();
  return 0;
}
--------- ch15/sets/commandline.c :------------------------- CUT HERE ----
/**************************************/
/*      File: commandline.c           */
/**************************************/

#include "commandline.h"
#include "set.h"

char *program_argument(char *flag, char *name, int argc, char *argv[])
{
  int position = program_flag(flag, argc, argv);
  if (position)
    return (argv[position + 1]);
  else
    return name;
}

int program_flag(char *flag, int argc, char *argv[])
{
  int index = 0;
  char *base;
  char *fl;

  while (index < argc) {
    base = argv[index];
    fl = flag;
    while ((*base == *fl) & (*fl != '\0')) {
      base++;
      fl++;
    }
    if (*base == *fl)
      return index;
    else
      index++;
  }
  return 0;
}

int str_to_int(char *s)
{
  int i = 0;
  char c;

  while ((c = *s++) != '\0')
    i = i * 10 + c - '0';
  return i;
}

void commandline(int argc, char *argv[])
{
  elements_per_line =
    str_to_int(program_argument("-p", "20", argc, argv));
}
--------- ch16/bank.short.c :------------------------- CUT HERE ----
#include <stdio.h>
#include <string.h>

typedef struct {
  char name[20];
  int type;
  float balance;
} Bank_account;

Bank_account make_account(const char *name, int type, float balance);
void print_account(Bank_account b);

main()
{
  Bank_account account1, account2;

  account1 = make_account("John Smith", 1, 23.50);
  account2 = make_account("Mary Jones", 2, 18.23);
  print_account(account1);
  print_account(account2);
  return 0;
}

Bank_account make_account(const char *name, int type, float balance)
{
  Bank_account b;

  strcpy(b.name, name);
  b.type = type;
  b.balance = balance;
  return b;
}

void print_account(Bank_account b)
{
  printf("%s: ", b.name);
  printf("%s account has a balance of ",
         (b.type == 1) ? "savings" : "checking");
  printf("%5.2f\n", b.balance);
}

--------- ch16/bank/Makefile :------------------------- CUT HERE ----
bank:	bank.o account.o
	gcc -Wall bank.o account.o -o bank
bank.o:	bank.c
	gcc -c -Wall bank.c
account.o:	account.c
	gcc -c -Wall account.c

clean:	
	rm -f *.o
--------- ch16/bank/account.h :------------------------- CUT HERE ----
/********************************/
/*          account.h           */
/********************************/

#ifndef ACCOUNT_H
#define ACCOUNT_H

#include <stdio.h>

typedef enum {SAVINGS, CHECKING} Account_type;

/* savings account */
struct saving {
  int interest;       /* Interest paid      */
  float max_withdraw; /* Maximum withdrawal */
};

/* checking account */
struct check {
  float max_overdraw; /* Maximum overdraft permitted */
  float overdraw;     /* Current overdraft */
  float interest;     /* Interest charged on overdrawn amount  */
};

typedef struct {
  int number;        /* Account number */
  Account_type type; /* Savings or checking */
  float balance;     /* Account balance */
  union {
    struct saving s; /* savings account, or */
    struct check c;  /* checking account   */
  } item;
} Account;

void clear_accounts(Account bank[], int max_accounts);
void insert_account(Account bank[], int max_accounts);
void transactions(Account bank[], int max_accounts);

#endif
--------- ch16/bank/account.c :------------------------- CUT HERE ----
/********************************/
/*          account.c           */
/********************************/
#include "account.h"

void clear_accounts(Account bank[], int max_accounts)
{
  int i;

  for (i = 0; i < max_accounts; i++)
    bank[i].number = -1;
    /* -1 indicates an available cell */
}

void display_account(Account bank[], int account)
{
  if (bank[account].type == SAVINGS)
    printf("SAVINGS ACCOUNT #%d\n", bank[account].number);
  else
    printf("CHECKING ACCOUNT #%d\n", bank[account].number);

  printf("Balance: $%5.2f\n", bank[account].balance);

  if (bank[account].type == SAVINGS) {
    printf("Maximum daily withdrawal: $%5.2f\n",
             bank[account].item.s.max_withdraw);
    printf("Interest earned: %d\n", bank[account].item.s.interest);

  } else {   /* CHECKING  */
    printf("Amount currently overdrawn: $%5.2f\n",
             bank[account].item.c.overdraw);
    if (bank[account].item.c.overdraw !=
        bank[account].item.c.max_overdraw)
      printf("You can overdraw yourself by $%5.2f\n",
               bank[account].item.c.max_overdraw -
               bank[account].item.c.overdraw);
    printf("Interest charged for overdrawing: $%5.2f\n",
             bank[account].item.c.interest);
  }
}

void deposit(Account bank[], int account)
{
  float amount;

  printf("Deposit Amount? ");
  scanf("%f", &amount);
  if (bank[account].type == SAVINGS)
    bank[account].balance += amount;
  else if (bank[account].item.c.overdraw == 0)
    bank[account].balance += amount;
  else if (amount > bank[account].item.c.overdraw) {
    bank[account].balance = amount - bank[account].item.c.overdraw;
    bank[account].item.c.overdraw = 0;
  } else
    bank[account].item.c.overdraw -= amount;
}

void withdraw(Account bank[], int account)
{
  float amount;

  printf("Withdrawal amount ? ");
  scanf("%f", &amount);
  if (bank[account].type == SAVINGS)
    if ((bank[account].balance >= amount) &&
            (bank[account].item.s.max_withdraw >= amount))
       bank[account].balance -= amount;
     else
       printf("We cannot satisfy your request. "
              "Please check your balance.\n");

  else               /* CHECKING  */
    if (bank[account].item.c.overdraw == 0 && bank[account].balance > 0)
      if (amount <= bank[account].balance)
         bank[account].balance -= amount;
      else     /* withdrawal will cause overdraw */
        if (amount <= (bank[account].balance +
                      (bank[account].item.c.max_overdraw -
                       bank[account].item.c.overdraw))) {
          bank[account].item.c.overdraw = amount -
                 bank[account].balance + bank[account].item.c.overdraw;
          bank[account].balance = 0;
        } else   /* withdrawal exceeds max_overdraw */
           printf("We cannot satisfy your request. "
                     "Please check your balance\n");
    else       /* account already overdrawn  */
      if (amount <= (bank[account].item.c.max_overdraw -
                     bank[account].item.c.overdraw))
        /* withdrawal still covered under max_overdraw */
        bank[account].item.c.overdraw += amount;
      else  /* withdrawal exceeds max_overdraw */
        printf("We cannot satisfy your request. "
                "Please check your balance\n");
}

void transactions(Account bank[], int max_accounts)
{ 
  int account, choice = 1;

  printf("Account number: ");
  scanf("%d", &account);
  if (account >= 0 && account < max_accounts)
    if (bank[account].number != -1)
      do {
        display_account(bank, account);
        printf("\n\n1. Make a deposit\n");
        printf("2. Make a withdrawal\n");
        printf("3. Close your account\n");
        printf("4. Exit\n\n");
        printf("Please choose an option: ");
        scanf("%d", &choice);
        switch (choice) {
          case 1:
            deposit(bank, account);
            break;
          case 2:
            withdraw(bank, account);
            break;
          case 3:
            bank[account].number = -1;
            printf("Your account has been terminated.\n");
            printf(" We'll keep your balance as a fee "
                    "for services rendered\n");
            choice = 4;
            break;
          case 4:
            printf("Thanks for preferring us!\n\n");
            break;
          default:
            printf("Sorry. That's not an option.\n\n");
        }
      } while (choice != 4);
    else
      printf("Account not open.\n");
  else
    printf("Invalid account number\n");
}

void get_initial_deposit(Account bank[], int account)
{
  float amount;

  printf("Initial deposit? ");
  scanf("%f", &amount);
  bank[account].balance = amount;
}

void open_savings(Account bank[], int account)
{
  bank[account].type = SAVINGS;
  get_initial_deposit(bank, account);
  /* The initial deposit determines the interest */
  if (bank[account].balance > 100000) {
    bank[account].item.s.interest = 30;
    bank[account].item.s.max_withdraw = bank[account].balance / 15;
  } else if (bank[account].balance > 50000) {
    bank[account].item.s.interest = 20;
    bank[account].item.s.max_withdraw = bank[account].balance / 10;
  } else {
    bank[account].item.s.interest = 10;
    bank[account].item.s.max_withdraw = bank[account].balance / 5;
  }
}

void open_checking(Account bank[], int account)
{
  bank[account].type = CHECKING;
  bank[account].item.c.overdraw = 0;
  get_initial_deposit(bank, account);
  if (bank[account].balance > 100000) {
    bank[account].item.c.max_overdraw = bank[account].balance / 15;
    bank[account].item.c.interest = 23.5;
  } else if (bank[account].balance > 50000) {
    bank[account].item.c.max_overdraw = bank[account].balance / 10;
    bank[account].item.c.interest = 17.5;
  } else {
    bank[account].item.c.max_overdraw = bank[account].balance / 5;
    bank[account].item.c.interest = 8.5;
  }
}

void insert_account(Account bank[], int max_accounts)
{
  int account, choice;

  /*  Find first unoccupied account */
  for (account = 0; bank[account].number != -1 &&
       account < max_accounts; account++);

  if (account == max_accounts)
    printf("Sorry, we have our hands full at the moment!");
  else {
    bank[account].number = account;
    printf("Your account number is: %d\n\n", account);
    printf("What kind of account do you wish?\n\n");
    printf("1. Savings account\n");
    printf("2. Checking account\n\n");
    printf("Please choose an option: ");
    scanf("%d", &choice);
    switch (choice) {
      case 1:
        open_savings(bank, account);
        break;
      case 2:
        open_checking(bank, account);
        break;
      default:
         printf("Sorry. That's not a option\n");
    }
  }
}
--------- ch16/bank/bank.c :------------------------- CUT HERE ----
/********************************/
/*           bank.c             */
/********************************/
#include <stdio.h>
#include "account.h"

#define MAX_ACCOUNTS 25

main()
{
  int choice;
  Account bank[MAX_ACCOUNTS];

  clear_accounts(bank, MAX_ACCOUNTS);

  printf("      ALMOST A BANK!\n\n");
  printf("We'll keep your money safe\n");
  printf("  (at least for a while)");
  do {
    printf("\n\n1. Create a new account.\n");
    printf("2. Transact on an existing account.\n");
    printf("3. Exit.\n\n");
    printf("Please choose an option: ");
    scanf("%d", &choice);
    switch (choice) {
      case 1:
        insert_account(bank, MAX_ACCOUNTS);
        break;
      case 2:
        transactions(bank, MAX_ACCOUNTS);
        break;
      case 3:
        printf("It has been a pleasure serving you!\n");
        break;
      default :
        printf("Sorry. That's not an option\n");
    }
  } while (choice != 3);
  return 0;
}
--------- ch17/sets/Makefile :------------------------- CUT HERE ----
sets:	sets.o node.o
	gcc sets.o node.o -o sets
sets.o:	sets.c
	gcc -c -Wall sets.c
node.o:	node.c
	gcc -c -Wall node.c

clean:
	rm -f *.o
--------- ch17/sets/node.c :------------------------- CUT HERE ----
/*************************/
/*       node.c          */
/*************************/
#include <stdio.h>
#include <stdlib.h>
#include "node.h"

void insert(Node **set, int elem)
{ 
  Node *new_node;

  if ((*set) == NULL)  /* the set is empty */
    if (((*set) = malloc(sizeof(Node))) != NULL) {
      (*set)->elem = elem;
      (*set)->next = NULL;
    }
    else {
      printf("Error in malloc - Function insert\n");
      exit(0);
    }
  else {   /* The set's not empty */
    new_node = *set;

    /* First we search for elem in the set */
    while ((new_node->next != NULL) && (new_node->elem != elem))
      new_node = new_node->next;
      
    if (new_node->elem != elem) { /* elem isn't in the set: add it */
      if ((new_node->next = malloc(sizeof(Node))) != NULL) {
        /* New element successfully created */
        new_node->next->elem = elem;
        new_node->next->next = NULL;
      }
      else {
        /* New element couldn't be created */
        printf("Error in malloc - Function insert\n");
        exit(0);
      }
    }
  }
}

void insert_prompt(Node **set, int n) 
{
  int elem;

  printf("\nElement you wish to add to set %1d: ", n);
  scanf("%d", &elem);
  insert(set, elem);
  printf("\nSet %1d is now:\n", n);
  print(*set);
}

void delete(Node **set, int n)
{
  Node *previous, *current;
  int elem;

  printf("\nSet %1d is:\n", n);
  print(*set);
  printf("\nElement you wish to delete from set %1d: ", n);
  scanf("%d", &elem);

  if ((*set)->elem == elem) {
    /* The first element is being deleted */
    current = *set;
    *set = (*set)->next;
    free(current);
  }
  else {
    /* Search the list */
    previous = *set;
    current = previous->next;
    while (current != NULL && current->elem != elem) {
      /* Search for elem, or end of list */
      previous = current;
      current = current->next;
    }

    if (current == NULL) return;  /* never found it */
    if (current->elem == elem) {
      /* found elem in current, so bypass it */
      previous->next = current->next;
      free(current);
    }
  }
  printf("\nSet %1d now is:\n", n);
  print(*set);
}

void done(Node **set)
{
  Node *current, *previous;

  current = *set;
  while (current != NULL) {
    /* Haven't reached the end of the list */
    previous = current;
    current = current->next;
    free(previous);
  }
  *set = NULL;
}


Node *sunion(Node *set1, Node *set2)
{
  Node *result, *current;

  result = NULL;
  current = set1;
  /* Insert all elements of set 1 */
  while (current != NULL) {
    insert(&result, current->elem);
    current = current->next;
  }

  /* Insert all elements of set 2 */
  current = set2;
  while (current != NULL) {
    insert(&result, current->elem);
    current = current->next;
  }
  return result;
}

void print(Node *set)
{
  Node *current;

  if (set == NULL)
    printf("The set is empty.\n");
  else {
    current = set;
    while (current != NULL) {
      printf("%d", current->elem);
      if (current->next != NULL)
        printf(", ");
      current = current->next;
    }
   printf("\n");
  }
}

int cardinality(Node *set)
{
  Node *current;
  int i;

  i = 0;
  current = set;
  while (current != NULL) {
    i++;
    current = current->next;
  }
  return i;
}

int locate(Node *set, int elem)
{
  Node *current;

  current = set;
  while (current != NULL && current->elem != elem)
    current = current->next;
  return (current != NULL);
}

Node *intersection(Node *set1, Node *set2)
{
  Node *result, *current;

  result = NULL;
  current = set1;
  while (current != NULL) {
    if (locate(set2, current->elem))
      insert(&result, current->elem);
    current = current->next;
  }
  return result;
}

Node *get_set(int n)
{
  int i, nelems;
  Node * set;

  printf("Reading Set %1d\n", n);
  set = NULL;
  printf("How many elements will the set have? ");
  scanf("%d", &nelems);
  for (i = 1; i <= nelems; i++)
    insert_prompt(&set, n);
  printf("\n");
  return set;
}

--------- ch17/sets/node.h :------------------------- CUT HERE ----
/*************************/
/*       node.h          */
/*************************/
#ifndef NODE_H
#define NODE_H

struct node {
  int elem;
  struct node *next;
};
typedef struct node Node;

void insert_prompt(Node **set, int n);
void insert(Node **set, int elem);
void delete(Node **set, int elem);
void done(Node **set);
void print(Node *set);
int cardinality(Node *set);
int locate(Node *set, int elem);
Node *sunion(Node *set1, Node *set2);
Node *intersection(Node *set1, Node *set2);
Node *get_set(int n);

#endif
--------- ch17/sets/sets.c :------------------------- CUT HERE ----
/*******************************************************************/
/* This program will implement sets, with the following operations:*/
/* union, intersection, and cardinality. Operations for            */
/* creating, destroying, and printing the sets are also available. */
/* The sets are implemented as linked lists.                       */
/*******************************************************************/

#include <stdio.h>
#include "node.h"

main()
{
  int choice;
  Node *set1, *set2;

  printf("SET MANIPULATION PROGRAM:\n");
  printf("Insert, Delete, Union and Intersect two sets\n\n");
  set1 = get_set(1);
  set2 = get_set(2);
  choice = 0;
  while (choice != 8) {
    printf("\nMENU:\n-----\n");
    printf("1. Add an element to Set 1\n");
    printf("2. Add an element to Set 2\n");
    printf("3. Delete an element from Set 1\n");
    printf("4. Delete an element form Set 2\n");
    printf("5. View the cardinality of the sets\n");
    printf("6. View the union of the sets\n");
    printf("7. View the intersection of the sets\n");
    printf("8. Exit\n\n");
    printf("Please choose an option: ");
    scanf("%d", &choice);
    switch (choice) {
      case 1:
        insert_prompt(&set1, 1);
        break;
      case 2:
        insert_prompt(&set2, 2);
        break;
      case 3:
        delete(&set1, 1);
        break;
      case 4:
        delete(&set2, 2);
        break;
      case 5:
        printf("\nThe cardinality of Set 1 is %d.", cardinality(set1));
        printf("\nThe cardinality of Set 2 is %d.\n", cardinality(set2));
        break;
      case 6:
        printf("\nThe union of the sets is:\n");
        print(sunion(set1, set2));
        break;
      case 7:
        printf("\nThe intersection of the sets is:\n");
        print(intersection(set1, set2));
        break;
      case 8:
        printf("\nBye!\n\n");
        break;
      default:
        printf("I'm sorry. That's not a valid option.\n");
        choice = 0;
    }
  }
  done(&set1);
  done(&set2);
  return 0;
}
--------- ch17/integration/integration.c :------------------------- CUT HERE ----
#include <stdio.h>
#include <stdlib.h>
#include <math.h>

float integrate(float func(float x),
                float low, float high, int n);

float func0(float x); /* sine (x)   */
float func1(float x); /* cosine x)  */
float func2(float x); /* tan (x)    */
float func3(float x); /* x*x        */
float func4(float x); /* sqrt (x)   */

main()
{
  float high, low;
  int choice, npoints;
  float (*vec[5])(float);

  vec[0] = func0;
  vec[1] = func1;
  vec[2] = func2;
  vec[3] = func3;
  vec[4] = func4;

  printf("NUMERIC INTEGRATION PROGRAM\n\n");
  choice = 0;
  while (choice != 6) {
    printf("1. Sine.\n");
    printf("2. Cosine.\n");
    printf("3. Tangent.\n");
    printf("4. Square.\n");
    printf("5. Square root.\n");
    printf("6. Exit.\n\n");
    printf("Please choose one: ");
    scanf("%d", &choice);
    if ((choice > 6) || (choice <= 0))
      printf("\nSorry, that's not an option.\n");
    else if (choice != 6) {
      printf("\nPlease enter the interval's lower limit: ");
      scanf("%f", &low);
      printf("\nPlease enter the interval's upper limit: ");
      scanf("%f", &high);
      npoints = -1;
      while (npoints < 0) {
        printf("\n\nHow many subintervals ? ");
        scanf("%d", &npoints);
        if (npoints < 0)
          printf("\nMust have a positive number !\n\n");
      }
      printf("The result is : %f.\n\n",
              integrate(vec[choice-1], low, high, npoints));
    }
  }
  printf("Bye!\n\n");
  return 0;
}

float integrate (float func (float x),
                 float low, float high, int n)
{
  int i;
  float x, width, sum;

  sum = 0;
  width = (high - low) / n;
  x = low + width / 2;
  for (i = 0; i < n; i++) {
    sum = sum + func(x) * width;
    x = x + width;
  }
  return sum;
}

float func0(float x)
{
  return sin(x);
}

float func1(float x)
{ 
  return cos(x);
}

float func2(float x)
{
  return sin(x) / cos(x);
}

float func3(float x)
{
  return x * x;
}

float func4(float x)
{
  return sqrt(x);
}
--------- ch18/sample1.c :------------------------- CUT HERE ----
#include <stdio.h>

float func0(float p) { return p; }
float func1(float p) { return p * 2.0; }
float func2(float p) { return p * p; }
float f_func0(int i, float (*func)(float));
float f_func1(int i, float (*func)(float));
float f_func2(int i, float (*func)(float));

main()
{
  float (*vec[3])(float) = {func0, func1, func2};
  float (*f_vec[3])(int, float (*func)(float)) =
           {f_func0, f_func1, f_func2};

  printf("%5.2f\n", vec[0](3.0));   
  printf("%5.2f\n", f_vec[2](4, func1));
  printf("%5.2f\n", f_vec[2](4, func2));
  return 0;
}

float f_func0(int i, float (*func)(float))
{
  return func(i);
}

float f_func1(int i, float (*func)(float))
{
  return func(func(i));
}

float f_func2(int i, float (*func)(float))
{
  return func(func(func(i)));
}
--------- ch18/sample2.c :------------------------- CUT HERE ----
#include <stdio.h>

typedef float Func(float);
typedef Func *Func_ptr;
typedef Func_ptr Vec_func[3];

Func func0, func1, func2;

typedef float F_func(int, Func_ptr);
typedef F_func *F_func_ptr;
typedef F_func_ptr Vec_f_func[3];

F_func f_func0, f_func1, f_func2;

main()
{
  Vec_func vec = {func0, func1, func2};
  Vec_f_func f_vec = {f_func0, f_func1, f_func2};

  printf("%5.2f\n", vec[0](3.0));   
  printf("%5.2f\n", f_vec[2](4, func1));
  printf("%5.2f\n", f_vec[2](4, func2));
  return 0;
}

float func0(float p) { return p; }
float func1(float p) { return p * 2.0; }
float func2(float p) { return p * p; }

float f_func0(int i, float (*func)(float))
{
  return func(i);
}

float f_func1(int i, float (*func)(float))
{
  return func(func(i));
}

float f_func2(int i, float (*func)(float))
{
  return func(func(func(i)));
}

--------- ch18/sample3.c :------------------------- CUT HERE ----
#include <stdio.h>

typedef void Func(void);
typedef Func *Func_ptr;
typedef Func_ptr Vec_func[3];

Func func0, func1, func2;

typedef void F_func(Vec_func v_func);
typedef F_func *F_func_ptr;
typedef F_func_ptr V_f_func[3];

F_func f_func0, f_func1, f_func2;

main()
{
  Vec_func vec = {func0, func1, func2};
  V_f_func vec2 = {f_func0, f_func1, f_func2};

  vec[0]();
  vec2[1](vec);
  return 0;
}

void func0() { printf("func0\n"); }
void func1() { printf("func1\n"); }
void func2() { printf("func2\n"); }

void f_func0(Vec_func v_func)
{
  v_func[0]();
}

void f_func1(Vec_func v_func)
{
  v_func[0]();
  v_func[1](); 
}

void f_func2(Vec_func v_func)
{
  v_func[0]();
  v_func[1]();
  v_func[2]();
}
--------- ch19/point/Makefile :------------------------- CUT HERE ----
testpoint:	testpoint.o point.o
	gcc -Wall testpoint.o point.o -o testpoint
testpoint.o:	testpoint.c
	gcc -c -Wall testpoint.c
point.o:	point.c
	gcc -c -Wall point.c

clean:
	rm -f *.o testpoint
--------- ch19/point/point.h :------------------------- CUT HERE ----
/****************/
/*    point.h   */
/****************/

#ifndef POINT_H
#define POINT_H

typedef struct {
  float x;
  float y;
} Pointstruct;

typedef Pointstruct *Point;
Point create_point();
void set_x(Point p, float x);
void set_y(Point p, float y);
void print_point(Point p);

#endif
--------- ch19/point/testpoint.c :------------------------- CUT HERE ----
#include "point.h"

main()
{
  Point p;

  p = create_point();
  set_x(p, 3.4);
  set_y(p, 5.6);
  print_point(p);
  return 0;
}
--------- ch19/point/point.c :------------------------- CUT HERE ----
/***************/
/*   point.c   */
/***************/

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

Point create_point()
{
  return malloc(sizeof(Pointstruct));
}

void set_x(Point p, float x)
{
  p->x = x;
}

void set_y(Point p, float y)
{
  p->y = y;
}

void print_point(Point p)
{
  printf("Point p = (%f,%f)\n", p->x, p->y);
}
--------- ch19/complex/complex.cc :------------------------- CUT HERE ----
#include <stream.h>

class Complex {
private:
  float real;
  float imag;
public:
  Complex(float x, float y);
  void print();
  Complex operator+(Complex c);
};

Complex::Complex(float x=0.0, float y=0.0)
{
   real = x; imag = y;
}

void Complex::print()
{
   cout << "(" << real << "+" << imag << "i)" << endl;
}

Complex Complex::operator+(Complex c)
{
  Complex result;

  result.real = real + c.real;
  result.imag = imag + c.imag;
  return result;
}

main()
{
  Complex a(1.2, 3.4), b(5.6), c;

  a.print();
  b.print();
  c = a + b;
  c.print();
  return 0;
}
--------- ch19/stack/stack.c :------------------------- CUT HERE ----
#include <stdio.h>             
#define STACK_SIZE 10          
                               
struct stack {                 
                               
 int items[STACK_SIZE];        
 int sp;                       
};                             
typedef struct stack Stack;    
                               
                               
void initialize(Stack* s)      
{                              
 s->sp=-1;                     
}                              
                               
void push(Stack* s, int i)     
{                              
 s->items[++s->sp]=i;          
}                              
                               
int pop(Stack *s)              
{                              
 return s->items[s->sp--];     
}                              
                               
                               
void print(const Stack* s)     
{                              
 int i;                        
                               
 printf("Stack:\n");           
 for (i=0;i<=s->sp;i++)        
  printf("%d ",s->items[i]);   
 printf("\n");                 
}                              
                               
main()                         
{                              
 Stack s;                      
 int i;                        
                               
 initialize(&s);               
 push(&s, 1);                  
 push(&s, 2);                  
 print(&s);                    
 i=pop(&s);                    
 print(&s);                    
 return 0;                     
}                              
--------- ch19/stack/stack.cc :------------------------- CUT HERE ----
#include <iostream.h>
const int STACK_SIZE = 10;
                                  
class Stack {
private:
 int items[STACK_SIZE];
 int sp;
public:

 void print(void);

 Stack()
 {
  sp=-1;
 }

 void Stack::operator<<(int i)
 {
  items[++sp]=i;
 }

 void Stack::operator>>(int& i)
 {
  i=items[sp--];
 }
};

void Stack::print(void)
{
 int i;

 cout << "Stack:\n";
 for (i=0;i<=sp;i++)
  cout << items[i] << " ";
 cout << "\n";
 };

main()
{
 Stack s;
 int i;


 s << 1;
 s << 2;
 s.print();
 s >> i;
 s.print();
 return 0;
}
--------- ch19/car/Makefile :------------------------- CUT HERE ----
car:	carmain.o car.o
	gcc -Wall carmain.o car.o -o car
carmain.o:	carmain.c car.h
	gcc -Wall -c carmain.c
car.o:	car.c	car.h
	gcc -Wall -c car.c

clean:
	rm -f *.o car
--------- ch19/car/car.c :------------------------- CUT HERE ----
/*********************/
/*       car.c       */
/*********************/
#include <stdio.h>
#include "car.h"

void start_car(Car *c)
{
  c->direction = 'N';
  c->ignition_on = 1;
}

void forward(Car c)
{
  printf("Going Forward. Heading %c.\n", c.direction);
}

void uturn(Car *c)
{
  switch (c->direction) {
    case 'N':
      c->direction = 'S';
      break;
    case 'S':
      c->direction = 'N';
      break;
    case 'E':
      c->direction = 'W';
      break;
    case 'W':
      c->direction = 'E';
      break;
  }
  printf("Making U turn. Now heading %c.\n", c->direction);
}

void left(Car *c)
{
  switch (c->direction) {
    case 'N':
      c->direction = 'W';
      break;
    case 'S':
      c->direction = 'E';
      break;
    case 'E':
      c->direction = 'N';
      break;
    case 'W':
      c->direction = 'S';
      break;
  }
  printf("Turning Left. Now heading %c.\n", c->direction);
}

void right(Car *c)
{
  switch (c->direction) {
    case 'N':
      c->direction = 'E';
      break;
    case 'S':
      c->direction = 'W';
      break;
    case 'E':
      c->direction = 'S';
      break;
    case 'W':
      c->direction = 'N';
      break;
  }
  printf("Turning Right. Now heading %c.\n", c->direction);
}

int running(Car c)
{
  return c.ignition_on;
}

void stop(Car *c)
{
   printf("Car stopped.\n");
   c->ignition_on = 0;
}
--------- ch19/car/car.h :------------------------- CUT HERE ----
/**********************/
/*        car.h       */
/**********************/

#ifndef CAR_H
#define CAR_H

typedef struct {
  char direction;  /* 'N', 'S', 'E', 'W'  */
  int ignition_on;
} Car;

void start_car(Car *c);
void forward(Car c); 
void uturn(Car *c);
void left(Car *c); 
void right(Car *c); 
int running(Car c);
void stop(Car *c);

#endif
--------- ch19/car/carmain.c :------------------------- CUT HERE ----
#include <stdio.h>
#include "car.h"

main()
{
  char choice;
  Car c;

  start_car(&c);
  printf("Please type the correct key for each operation:\n");
  printf("(f)orward, (u)turn, (l)eft, (r)ight, (s)top\n");
  forward(c);
  while (running(c)){
    scanf(" %c", &choice);
    switch (choice){
      case 'r':
        right(&c);
        break;
      case 'l':
        left(&c);
        break;
      case 'f':
        forward(c);
        break;
      case 'u':
        uturn(&c);
        break;
      case 's':
        stop(&c);
        break;
      default :
        printf("Not an allowed operation.\n");
        break;
    }
  }
  return 0;
}
--------- ch20/hamming.c :------------------------- CUT HERE ----
/**************************************************/
/* Implementation of Hamming codes: single error  */
/* detection and correction in a transmitted word */
/**************************************************/
#include <stdio.h>
#include <stdlib.h>

#define BIT(word, i) (((word) & 1 << (i)) >> (i))

void gen_error(unsigned int *word);
void encode(unsigned int *word);
unsigned int decode(unsigned int *word);
void print_bits(unsigned int word);

main()
{
  unsigned int word, error;
  char c;

  printf("HAMMING CODES PROGRAM\n");
  while (1) {
    printf("Enter to continue, `q' to quit:");
    scanf("%c", &c);
    if (c == 'q')
      break;
    word = rand() & 0x00ff;  /* An 8-bit word */
    printf("Data Word:                ");
    print_bits(word);   
    encode(&word);
    printf("Hamming encoded word:     ");
    print_bits(word);
    gen_error(&word);
    printf("Word with random error:   ");
    print_bits(word);
    error = decode(&word);
    if (!error)
      printf("No error!\n");
    else {
      printf("Error at bit %u!\n", error);
      printf("        Corrected word:   ");
      print_bits(word);
    }
  }
  return 0;
}

void gen_error(unsigned int *word)
{
/******************************/
/*  produce the error         */
/******************************/
  unsigned int err, loc;

  err = rand() % 2;       /* error bit */
  loc = rand() % 12;
  err <<= loc;    /* in random location */
  *word ^=  err;
}

void encode(unsigned int *word)
{
/*********************/
/* Hamming encoding  */
/*********************/
  unsigned int checkbit;

  checkbit = BIT(*word, 7) ^ BIT(*word, 6) ^ BIT(*word, 4) ^
             BIT(*word, 3) ^ BIT(*word, 1);
  *word |= checkbit << 11;
  checkbit = BIT(*word, 7) ^ BIT(*word, 5) ^ BIT(*word, 4) ^
             BIT(*word, 2) ^ BIT(*word, 1);
  *word |= checkbit << 10;
  checkbit = BIT(*word, 6) ^ BIT(*word, 5) ^ BIT(*word, 4) ^
             BIT(*word, 0);
  *word |= checkbit << 9;
  checkbit = BIT(*word, 3) ^ BIT(*word, 2) ^ BIT(*word, 1) ^
             BIT(*word, 0);
  *word |= checkbit << 8;
}

unsigned int decode(unsigned int *word)
{
  unsigned int checkbit, error = 0;
  unsigned int permute[13] = {0,11,10,7,9,6,5,4,8,3,2,1,0};

  checkbit = BIT(*word, 11) ^ BIT(*word, 7) ^ BIT(*word, 6) ^
             BIT(*word, 4)  ^ BIT(*word, 3) ^ BIT(*word, 1);
  error |= checkbit << 0;
  checkbit = BIT(*word, 10) ^ BIT(*word, 7) ^ BIT(*word, 5) ^
             BIT(*word, 4)  ^ BIT(*word, 2) ^ BIT(*word, 1);
  error |= checkbit << 1;
  checkbit = BIT(*word, 9) ^ BIT(*word, 6) ^ BIT(*word, 5) ^
             BIT(*word, 4) ^ BIT(*word, 0);
  error |= checkbit << 2;
  checkbit = BIT(*word, 8) ^ BIT(*word, 3) ^ BIT(*word, 2) ^
             BIT(*word, 1) ^ BIT(*word, 0);
  error |= checkbit << 3;

  error = permute[error];
  if (error)
    *word ^= 1 << error;
  return error;
}

void print_bits(unsigned int word) 
{
  int j;

  printf("%4u: ", word);
  for (j = 11; j >= 0; j--)
    printf("%u", (word >> j) & 1 );
  printf("\n");
}
--------- ch21/offset.c :------------------------- CUT HERE ----
#include <stdio.h>
#include <stddef.h>

main()
{
  struct s {
    char a;
    char *b[4];
    float c;
  };

  printf("Size of a: %lu. Offset of a: %lu.\n",
          (unsigned long) sizeof(char),
          (unsigned long) offsetof(struct s, a));
  printf("Size of b: %lu. Offset of b: %lu.\n",
          (unsigned long) sizeof(char *[4]),
          (unsigned long) offsetof(struct s, b));
  printf("Size of c: %lu. Offset of c: %lu.\n",
          (unsigned long) sizeof(float),
          (unsigned long) offsetof(struct s, c));

  printf("Size of s: %lu.\n",
          (unsigned long) sizeof(struct s));
  return 0;
}
--------- ch22/bank/account.c :------------------------- CUT HERE ----
/********************************/
/*          account.c           */
/********************************/
#include "account.h"

void load_bank(const char *f_name, Account bank[], int max_accounts)
{
  FILE *fp;
  int i;

  if ((fp = fopen(f_name, "r")) == NULL)
    /* If null, just clear the array */
    for (i = 0; i < max_accounts; i++)
      bank[i].number = -1;
      /* -1 indicates an available cell */
  else {
    /* Read the array from the file */
    i = 0;
    while (1) {
      if (fscanf(fp, "%d", &bank[i].number)!=1)
        break;
      if (bank[i].number == -1) continue;
      if (fscanf(fp, "%d%f", &bank[i].type, &bank[i].balance)!=2)
        break;
      if (bank[i].type == SAVINGS) {
        if (fscanf(fp, "%d%f", &bank[i].item.s.interest,
          &bank[i].item.s.max_withdraw)!=2)
          break;
      }
      else {
        if (fscanf(fp, "%f%f%f", &bank[i].item.c.max_overdraw,
          &bank[i].item.c.overdraw, &bank[i].item.c.interest)!=3)
          break;
      }
      i++;
    }
    for (; i < max_accounts; i++)
       bank[i].number = -1;
    fclose(fp);
  }
}

void save_bank(const char *f_name, Account bank[], int max_accounts)
{
  FILE *fp;
  int i = 0;

  if ((fp = fopen(f_name, "w")) == NULL)
    printf("Unable to open file for saving\n\n");
  else {
    /* Write the array to the file */
    while (i < max_accounts) {
      fprintf(fp, "%d\n", bank[i].number);
      if (bank[i].number != -1) {
        fprintf(fp, "%d %f ", bank[i].type,
                              bank[i].balance);
        if (bank[i].type == SAVINGS)
           fprintf(fp, "%d %f\n", bank[i].item.s.interest,
                                  bank[i].item.s.max_withdraw);
        else
           /* checking account */
           fprintf(fp, "%f %f %f\n", bank[i].item.c.max_overdraw,
                                     bank[i].item.c.overdraw,
                                     bank[i].item.c.interest);
      }
      i++;
    }
    fclose(fp);
  }
}

void display_account(Account bank[], int account)
{
  if (bank[account].type == SAVINGS)
    printf("SAVINGS ACCOUNT #%d\n", bank[account].number);
  else
    printf("CHECKING ACCOUNT #%d\n", bank[account].number);

  printf("Balance: $%5.2f\n", bank[account].balance);

  if (bank[account].type == SAVINGS) {
    printf("Maximum daily withdrawal: $%5.2f\n",
            bank[account].item.s.max_withdraw);
    printf("Interest earned: %d\n", bank[account].item.s.interest);

  } else {   /* CHECKING  */
    printf("Amount currently overdrawn: $%5.2f\n",
            bank[account].item.c.overdraw);
    if (bank[account].item.c.overdraw !=
        bank[account].item.c.max_overdraw)
      printf("You can overdraw yourself by $%5.2f\n",
               bank[account].item.c.max_overdraw -
               bank[account].item.c.overdraw);
    printf("Interest charged for overdrawing: $%5.2f\n",
             bank[account].item.c.interest);
  }
}

void deposit(Account bank[], int account)
{
  float amount;

  printf("Deposit Amount? ");
  scanf("%f", &amount);
  if (bank[account].type == SAVINGS)
    bank[account].balance += amount;
  else if (bank[account].item.c.overdraw == 0)
    bank[account].balance += amount;
  else if (amount > bank[account].item.c.overdraw) {
    bank[account].balance = amount - bank[account].item.c.overdraw;
    bank[account].item.c.overdraw = 0;
  } else
    bank[account].item.c.overdraw -= amount;
}

void withdraw(Account bank[], int account)
{
  float amount;

  printf("Withdrawal amount ? ");
  scanf("%f", &amount);
  if (bank[account].type == SAVINGS)
    if ((bank[account].balance >= amount) &&
            (bank[account].item.s.max_withdraw >= amount))
       bank[account].balance -= amount;
     else
       printf("We cannot satisfy your request. "
              "Please check your balance.\n");

  else               /* CHECKING  */
    if (bank[account].item.c.overdraw == 0 && bank[account].balance > 0)
      if (amount <= bank[account].balance)
         bank[account].balance -= amount;
      else     /* withdrawal will cause overdraw */
        if (amount <= (bank[account].balance +
                      (bank[account].item.c.max_overdraw -
                       bank[account].item.c.overdraw))) {
          bank[account].item.c.overdraw = amount -
                 bank[account].balance + bank[account].item.c.overdraw;
          bank[account].balance = 0;
        } else   /* withdrawal exceeds max_overdraw */
           printf("We cannot satisfy your request. "
                    "Please check your balance\n");
    else       /* account already overdrawn  */
      if (amount <= (bank[account].item.c.max_overdraw -
                     bank[account].item.c.overdraw))
        /* withdrawal still covered under max_overdraw */
        bank[account].item.c.overdraw += amount;
      else  /* withdrawal exceeds max_overdraw */
        printf("We cannot satisfy your request. "
               "Please check your balance\n");
}

void transactions(Account bank[], int max_accounts)
{ 
  int account, choice = 1;

  printf("Account number: ");
  scanf("%d", &account);
  if (account >= 0 && account < max_accounts)
    if (bank[account].number != -1)
      do {
        display_account(bank, account);
        printf("\n\n1. Make a deposit\n");
        printf("2. Make a withdrawal\n");
        printf("3. Close your account\n");
        printf("4. Exit\n\n");
        printf("Please choose an option: ");
        scanf("%d", &choice);
        switch (choice) {
          case 1:
            deposit(bank, account);
            break;
          case 2:
            withdraw(bank, account);
            break;
          case 3:
            bank[account].number = -1;
            printf("Your account has been terminated.\n");
            printf(" We'll keep your balance as a fee "
                   "for services rendered\n");
            choice = 4;
            break;
          case 4:
            printf("Thanks for preferring us!\n\n");
            break;
          default:
            printf("Sorry. That's not an option.\n\n");
        }
      } while (choice != 4);
    else
      printf("Account not open.\n");
  else
    printf("Invalid account number\n");
}

void get_initial_deposit(Account bank[], int account)
{
  float amount;

  printf("Initial deposit? ");
  scanf("%f", &amount);
  bank[account].balance = amount;
}

void open_savings(Account bank[], int account)
{
  bank[account].type = SAVINGS;
  get_initial_deposit(bank, account);
  /* The initial deposit determines the interest */
  if (bank[account].balance > 100000) {
    bank[account].item.s.interest = 30;
    bank[account].item.s.max_withdraw = bank[account].balance / 15;
  } else if (bank[account].balance > 50000) {
    bank[account].item.s.interest = 20;
    bank[account].item.s.max_withdraw = bank[account].balance / 10;
  } else {
    bank[account].item.s.interest = 10;
    bank[account].item.s.max_withdraw = bank[account].balance / 5;
  }
}

void open_checking(Account bank[], int account)
{
  bank[account].type = CHECKING;
  bank[account].item.c.overdraw = 0;
  get_initial_deposit(bank, account);
  if (bank[account].balance > 100000) {
    bank[account].item.c.max_overdraw = bank[account].balance / 15;
    bank[account].item.c.interest = 23.5;
  } else if (bank[account].balance > 50000) {
    bank[account].item.c.max_overdraw = bank[account].balance / 10;
    bank[account].item.c.interest = 17.5;
  } else {
    bank[account].item.c.max_overdraw = bank[account].balance / 5;
    bank[account].item.c.interest = 8.5;
  }
}

void insert_account(Account bank[], int max_accounts)
{
  int account, choice;

  /*  Find first unoccupied account */
  for (account = 0; bank[account].number != -1 &&
       account < max_accounts; account++);

  if (account == max_accounts)
    printf("Sorry, we have our hands full at the moment!");
  else {
    bank[account].number = account;
    printf("Your account number is: %d\n\n", account);
    printf("What kind of account do you wish?\n\n");
    printf("1. Savings account\n");
    printf("2. Checking account\n\n");
    printf("Please choose an option: ");
    scanf("%d", &choice);
    switch (choice) {
      case 1:
        open_savings(bank, account);
        break;
      case 2:
        open_checking(bank, account);
        break;
      default:
         printf("Sorry. That's not a option\n");
    }
  }
}
--------- ch22/bank/bank.c :------------------------- CUT HERE ----
/********************************/
/*           bank.c             */
/********************************/
#include <stdio.h>
#include "account.h"

#define MAX_ACCOUNTS 25
#define FILE_NAME "bank.dat"

main()
{
  int choice;
  Account bank[MAX_ACCOUNTS];

  load_bank(FILE_NAME, bank, MAX_ACCOUNTS);

  printf("      ALMOST A BANK!\n\n");
  printf("We'll keep your money safe\n");
  printf("  (at least for a while)");
  do {
    printf("\n\n1. Create a new account.\n");
    printf("2. Transact on an existing account.\n");
    printf("3. Exit.\n\n");
    printf("Please choose an option: ");
    scanf("%d", &choice);
    switch (choice) {
      case 1:
        insert_account(bank, MAX_ACCOUNTS);
        break;
      case 2:
        transactions(bank, MAX_ACCOUNTS);
        break;
      case 3:
        printf("It has been a pleasure serving you!\n");
        break;
      default:
        printf("Sorry. That's not an option\n");
    }
  } while (choice != 3);
  save_bank(FILE_NAME, bank, MAX_ACCOUNTS);
  return 0;
}
--------- ch22/bank/Makefile :------------------------- CUT HERE ----
bank:	bank.o account.o
	gcc -g -Wall bank.o account.o -o bank
bank.o:	bank.c
	gcc -g -c -Wall bank.c
account.o:	account.c
	gcc -g -c -Wall account.c

clean:	
	rm -f *.o bank
--------- ch22/bank/account.h :------------------------- CUT HERE ----
/********************************/
/*          account.h           */
/********************************/

#ifndef ACCOUNT_H
#define ACCOUNT_H

#include <stdio.h>

typedef enum {SAVINGS, CHECKING} Account_type;

/* savings account */
struct saving {
  int interest;       /* Interest paid.     */
  float max_withdraw; /* Maximum withdrawal */
};

/* checking account */
struct check {
  float max_overdraw; /* Maximum overdraw permitted */
  float overdraw;     /* Current overdraw */
  float interest;     /* Interest charged on overdrawn amount. */
};

typedef struct {
  int number;        /* Account number */
  Account_type type; /* Savings or checking */
  float balance;     /* Account balance */
  union {
    struct saving s; /* savings acount, or */
    struct check c;  /* checking account   */
  } item;
} Account;

void load_bank(const char * f_name, Account bank[], int max_accounts);
void save_bank(const char * f_name, Account bank[], int max_accounts);
void insert_account(Account bank[], int max_accounts);
void transactions(Account bank[], int max_accounts);

#endif
--------- ch22/parts/Makefile :------------------------- CUT HERE ----
all: invent
invent: invent.o readline.o
	gcc -Wall invent.o readline.o -o invent
invent.o: invent.c
	gcc -c -Wall invent.c
readline.o: readline.c
	gcc -c -Wall readline.c

clean:
	rm -f *.o invent


--------- ch22/parts/invent.c :------------------------- CUT HERE ----
#include <stdio.h>
#include "readline.h"

#define NAME_LEN 25
#define FILE_NAME "parts.dat"

struct part {
  int number;
  char name[NAME_LEN+1];
  int on_hand;
};

typedef struct part Part;

int find_part(int number, Part* p);
void insert(void);
void search(void);
void update(void);
void print(void);

/********************************************************** 
 * main: Prompts the user to enter an operation code,     * 
 *       then calls a function to perform the requested   * 
 *       action. Repeats until the user enters the        * 
 *       command 'q'. Prints an error message if the user * 
 *       enters an illegal code.                          * 
 **********************************************************/
main()
{
  char code;

  for (;;) {
    printf("Enter operation code: ");
    printf("(Insert, Search, Update, Print, or Quit): ");
    scanf(" %c", &code);
    while (getchar() != '\n')   /* skips to end of line */
      ;
    switch (code) {
      case 'i': case 'I': insert(); break;
      case 's': case 'S': search(); break;
      case 'u': case 'U': update(); break;
      case 'p': case 'P': print(); break;
      case 'q': case 'Q': return 0;
      default:  printf("Illegal code\n");
    }
  }
  printf("\n");
  return 0;
}

/********************************************************** 
 * find_part: Looks up a part number in the inventory     * 
 *            file. If the part is found, stores the part *
 *            in p, and returns the part's file position. * 
 *            If the part is not found, returns 0.        * 
 **********************************************************/
int find_part(int number, Part* p)
{
  FILE *fp;
  long int file_position;

  if ((fp = fopen(FILE_NAME, "rb")) == NULL)
    return 0;
  while  (fread(p, sizeof(*p), 1, fp) != 0)
    if (p->number == number) {
      file_position = ftell(fp);
      fclose(fp);
      return file_position;
    }
  fclose(fp);
  return 0;  
}

/********************************************************** 
 * insert: Prompts the user for information about a new   * 
 *         part and then inserts the part into the        * 
 *         database. Prints an error message and returns  * 
 *         prematurely if the part already exists.        * 
 **********************************************************/
void insert(void)
{
  FILE *fp;
  Part p;
  int number;

  printf("Enter part number: ");
  scanf("%d", &number);
  if (find_part(number, &p) > 0) {
    printf("Part %d already exists.\n", p.number);
    return;
  }
  p.number = number;
  printf("Enter part name: ");
  read_line(p.name, NAME_LEN);
  printf("Enter quantity on hand: ");
  scanf("%d", &p.on_hand);
  if ((fp = fopen(FILE_NAME, "ab")) == NULL) {
     printf("Can't open file !\n");
     exit(1);
  }
  fwrite(&p, sizeof(p), 1, fp);
  fclose(fp); 
}

/********************************************************** 
 * search: Prompts the user to enter a part number, then  * 
 *         looks up the part in the database. If the part * 
 *         exists, prints the name and quantity on hand;  * 
 *         if not, prints an error message.               * 
 **********************************************************/
void search(void)
{
  Part p;
  int number;

  printf("Enter part number: ");
  scanf("%d", &number);
  if (find_part(number, &p) > 0) {
    printf("Part name: %s\n", p.name);
    printf("Quantity on hand: %d\n", p.on_hand);
  } else
    printf("Part not found.\n");
}

/********************************************************** 
 * update: Prompts the user to enter a part number.       * 
 *         Prints an error message if the part doesn't    * 
 *         exist; otherwise, prompts the user to enter    * 
 *         change in quantity on hand and updates the     * 
 *         database.                                      * 
 **********************************************************/
void update(void)
{
  FILE *fp;
  long  file_position;
  Part p;
  int number, change;

  printf("Enter part number: ");
  scanf("%d", &number);
  if ((file_position = find_part(number, &p)) > 0) {
    printf("Enter change in quantity on hand: ");
    scanf("%d", &change);
    p.on_hand += change;
    if ((fp = fopen(FILE_NAME, "rb+")) == NULL) {
      printf("Can't open file !\n");
      exit(1);
    }
    fseek(fp, file_position - sizeof(p), SEEK_SET);
    fwrite(&p, sizeof(p), 1, fp);
    fclose(fp);
  } else
    printf("Part not found.\n");
}

/********************************************************** 
 * print: Prints a listing of all parts in the database,  * 
 *        showing the part number, part name, and         * 
 *        quantity on hand. Parts are printed in the      * 
 *        order in which they were entered into the       * 
 *        database.                                       * 
 **********************************************************/
void print(void)
{
  FILE *fp;
  Part p;

  if ((fp = fopen(FILE_NAME, "rb")) == NULL) {
    printf("Can't open file !\n");
    return;
  }  
  printf("Part Number   Part Name                  "
         "Quantity on Hand\n");
  while (fread(&p, sizeof(p), 1, fp) != 0)
    printf("%7d       %-25s%11d\n", p.number,
           p.name, p.on_hand);
  fclose(fp); 
}
--------- ch22/parts/readline.c :------------------------- CUT HERE ----
/*********************************************************
 * From C PROGRAMMING: A MODERN APPROACH, by K. N. King  *
 * Copyright (c) 1996 W. W. Norton & Company, Inc.       *
 * All rights reserved.                                  *
 * This program may be freely distributed for class use, *
 * provided that this copyright notice is retained.      *
 *********************************************************/

/* readline.c (Chapter 16, page 345) */

#include <ctype.h>
#include <stdio.h>
#include "readline.h"

int read_line(char str[], int n)
{
  int ch, i = 0;

  while (isspace(ch = getchar()))
    ;

  while (ch != '\n' && ch != EOF) {
    if (i < n)
      str[i++] = ch;
    ch = getchar();
  }

  str[i] = '\0';
  return i;
}
--------- ch22/parts/readline.h :------------------------- CUT HERE ----
/*********************************************************
 * From C PROGRAMMING: A MODERN APPROACH, by K. N. King  *
 * Copyright (c) 1996 W. W. Norton & Company, Inc.       *
 * All rights reserved.                                  *
 * This program may be freely distributed for class use, *
 * provided that this copyright notice is retained.      *
 *********************************************************/

/* readline.h (Chapter 16, page 345) */

#ifndef READLINE_H
#define READLINE_H

/**********************************************************
 * read_line: Skips leading white-space characters, then  *
 *            reads the remainder of the input line and   *
 *            stores it in str. Truncates the line if its *
 *            length exceeds n. Returns the number of     *
 *            characters stored.                          *
 **********************************************************/
int read_line(char str[], int n);

#endif
--------- ch23/anagram.c :------------------------- CUT HERE ----
/*********************************************************/
/*                                                       */
/* This program takes two strings as parameters, removes */
/* duplicate characters from them, and determines if the */
/* second string is an anagram of the first.             */
/*                                                       */
/*********************************************************/

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

char *repeat_off(char *str);
int  is_anagram(char *str1, char *str2);

main(int argc, char *argv[])
{
  char *str1, *str2;

  if (argc != 3){
    printf("ANAGRAM needs two strings as parameters.\n");
    printf("Type: ANAGRAM word1 word2\n");
    return 0;
  }
  str1 = repeat_off(argv[1]);
  str2 = repeat_off(argv[2]);

  if (strlen(str1) != strlen(str2))
    printf("NO ANAGRAM.\n");
  else
    if (is_anagram(str1, str2))
      printf("YES, an ANAGRAM.\n");
    else
      printf("NO ANAGRAM.\n");
  return 0;
}

char *repeat_off(char *str)
{
  char *str1, *str2;

  str1 = str;
  while (*str1) {
    str2 = str1 + 1;
    while (*str2)
      if (*str1 != *str2)
        str2++;
      else
        memmove(str2, str2 + 1, strlen(str2));
    str1++;
  }
  return str;
}

int is_anagram(char *str1, char *str2)
{
  while (*str2) {
    if (!strchr(str1, *str2)) return 0;
    str2++;
  }
  return 1;
}
--------- ch23/tokens.c :------------------------- CUT HERE ----
/***********************************************************/
/*                                                         */
/* This program reads a string from the input and prints   */
/* the words in it, each on a separate line. The program   */
/* uses the strtok function to delimit words.              */
/*                                                         */
/***********************************************************/

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

#define MAXLENGTH 1000

main()
{
  char string[MAXLENGTH+1];
  char delims[] = " `~!@#$%^&*()_+|-=\\\"\t\n;:',./<>?";
  int c, i = 0;
  char *p;

  while ((c = getchar()) != EOF)
    if (i < MAXLENGTH)
      string[i++] = c;

  string[i] = '\0';

  p = strtok(string, delims);
  while (p) {
    puts(p);
    p = strtok(NULL, delims);
  }
  return 0;
}
--------- ch24/hash/Makefile :------------------------- CUT HERE ----
all:	hash
hash:	hash.o table.o
	gcc -g -Wall hash.o table.o -o hash
hash.o:	hash.c
	gcc -c -g -Wall hash.c
table.o:	table.c
	gcc -c -g -Wall table.c
clean:	
	rm -f hash.o table.o hash
--------- ch24/hash/table.c :------------------------- CUT HERE ----
/*************************************/
/*  Implementation of ADT Hash Table */
/*************************************/

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <assert.h>
#include <errno.h>
#include "table.h"

static int hash(const char* str);

void initialize(Table tab)
{
  int i;

  for (i = 0; i < MAXBUCKET; i++)
    tab[i] = EMPTYBUCKET;
}

int hash(const char *str)
{
  int res;

  for (res=0; *str != '\n'; str++)
    res ^= (unsigned char) *str;
  return res % MAXBUCKET;
}

void insert(FILE* fptr, Table tab, const char *str, long position)
{
  char str2[MAXLINE+1];
  int index;

  assert((index = hash(str)) >= 0); 
  if (tab[index] == EMPTYBUCKET) {
    tab[index] = position;
    return;
  }
  do {
    errno = 0;
    if (fseek(fptr, tab[index], SEEK_SET)) {
      printf("File error 1, program quits.\n");
      exit(1);
    }
    fgets(str2, MAXLINE, fptr);
    if (strcmp(str, str2) == 0) return;
    index = (index + 1) % MAXBUCKET;
    assert(index >= 0);
  } while (index != EMPTYBUCKET);
  tab[index] = position;
}

void retrieve(FILE* fptr, const Table tab, const char *str)
{
  char str2[MAXLINE+1];
  int index, comparisons = 0, found;

  assert((index = hash(str)) >= 0); 
  do {
    if (tab[index] == EMPTYBUCKET) {
      found = 0;
      break;
    }
    errno = 0;
    if (fseek(fptr, tab[index], SEEK_SET)) {
      printf("File error 2, program quits.\n");
      exit(1);
    }
    fgets(str2, MAXLINE, fptr);
    comparisons++;
    if ((found = (strcmp(str, str2) == 0))) break;
    index = (index + 1) % MAXBUCKET;
  } while (index != EMPTYBUCKET);
  if (found)
     printf(" String found. ");
  else
     printf(" String not found. ");
  printf("Needed %d comparison(s).\n", comparisons);
}

void print(FILE* fptr, const Table tab)
{
  int i;
  char str[MAXLINE+1];
   
  printf("\nHash Table:\n");
  printf("Index   FPOS  String\n");
  printf("-----------------------------\n");
  for (i = 0; i < MAXBUCKET; i++) {
    printf("%4d %6ld: ", i, tab[i]);
    if (tab[i] == EMPTYBUCKET)
      printf("<EMPTY BUCKET>\n");
    else {
      fseek(fptr, tab[i], SEEK_SET);
      fgets(str, MAXLINE, fptr);
      printf("%s", str);
    }
  }
}
--------- ch24/hash/hash.c :------------------------- CUT HERE ----
/*********************************************************/
/* This program stores the position of each string in    */
/* the input file, in a hash table. Efficient retrieval  */
/* of strings can then be performed. The program deals   */
/* with some of the error conditions that may arise,     */
/* using the <errno.h> and <assert.h> libraries.         */ 
/*********************************************************/

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <errno.h>
#include "table.h"


main(int argc, char *argv[]) 
{
  FILE *fptr;
  Table tab;
  char str[MAXLINE+1];
  long position, new_position;

  initialize(tab);
  if (argc < 2) {
    printf("Program requires name of data file.\n");
    exit(1);
  }
  errno = 0;
  if ((fptr = fopen(argv[1], "r")) == NULL) {
    printf("File error 3: Cannot open file %s.\n", argv[1]);
    exit(1);
  }         
  new_position = 0;
  printf("Reading strings from file '%s' ...\n", argv[1]);
  while (1) {
    position = new_position;
    fseek(fptr, position, SEEK_SET);
    if (fgets(str, MAXLINE, fptr) == NULL) break;
    new_position = ftell(fptr);
    insert(fptr, tab, str, position);
  }
  #ifndef NDEBUG
    print(fptr, tab);
  #endif
  while(1) {
    printf("Please enter a string: ");
    if (fgets(str, MAXLINE, stdin) == NULL) break;
    if (str[0] == '\n') break;
    retrieve(fptr, tab, str);
  }
  fclose(fptr);
  return 0;
}
--------- ch24/hash/table.h :------------------------- CUT HERE ----
/*************************************/
/*  table.h   -- ADT Hash Table      */
/*************************************/

#ifndef TABLE_H
#define TABLE_H

#define MAXBUCKET 256  /* Max number of buckets */
#define MAXLINE   100  /* Max number of chars per line */
#define EMPTYBUCKET -1

typedef long Table[MAXBUCKET];

void initialize(Table tab);
void insert(FILE* fptr, Table tab, const char *str, long position);
void retrieve(FILE* fptr, const Table tab, const char *str);
void print(FILE* fptr, const Table tab);

#endif
--------- ch24/file_printer.c :------------------------- CUT HERE ----
#include <stdio.h>
#include <signal.h>
#include <setjmp.h>
#include <string.h>

#define NAME_SIZE 128

jmp_buf env;
FILE *fptr;
void handler(int sig);
void print_file(void);

main()
{
  char name[NAME_SIZE+1], *p;

  setjmp(env);
  while(1) {
    signal(SIGINT, SIG_IGN);
    printf("File: ");
    fgets(name, NAME_SIZE, stdin);
    if ((p = strchr(name, '\n')) != NULL)
        *p = '\0';   
    if (name[0] == '\0') break;
    if ((fptr = fopen(name, "r")) != NULL) {
      signal(SIGINT, handler);
      print_file();
    }
    else
      fprintf(stderr, "Can't open file!\n");
  }
  return 0;
}

void handler(int sig)
{
  fprintf(stderr, "program interrupted !\n");
  fprintf(stderr, "Closing file.\n");
  fclose(fptr);
  longjmp(env, 1);
}

void print_file(void)
{
  int c;

  while ((c = getc(fptr)) != EOF)
    putchar(c);
}
--------- ch25/locale.c :------------------------- CUT HERE ----
#include <locale.h>
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#include <string.h>

#define MAX_NAME 100

void printstring(const char *title, const char *str);
void printchar(const char *title, char c);

main()
{
  struct lconv *p;
  char name[MAX_NAME+1];
  char *temp;

  printf("Please enter name of locale: ");
  fgets(name, MAX_NAME, stdin);
  if ((temp = strchr(name, '\n')) != NULL)
      *temp = '\0';  
  printf("LOCALE is \"%s\"\n", name);
  temp = setlocale(LC_ALL, name);
  if (temp == NULL) {
    printf("That locale is not available.\n");
    exit(1);
  }
  p = localeconv();
  printstring("decimal_point    ", p->decimal_point);
  printstring("thousands_sep    ", p->thousands_sep);
  printstring("grouping         ", p->grouping);
  printstring("int_curr_symbol  ", p->int_curr_symbol);
  printstring("currency_symbol  ", p->currency_symbol);
  printstring("mon_decimal_point", p->mon_decimal_point);
  printstring("mon_thousands_sep", p->mon_thousands_sep);
  printstring("mon_grouping     ", p->mon_grouping);
  printstring("positive_sign    ", p->positive_sign);
  printstring("negative_sign    ", p->negative_sign);

  printchar("int_frac_digits  ", p->int_frac_digits);
  printchar("frac_digits      ", p->frac_digits);
  printchar("p_cs_precedes    ", p->p_cs_precedes);
  printchar("p_sep_by_space   ", p->p_sep_by_space);
  printchar("p_sign_posn      ", p->p_sign_posn);
  printchar("n_cs_precedes    ", p->n_cs_precedes);
  printchar("n_sep_by_space   ", p->n_sep_by_space);
  printchar("n_sign_posn      ", p->n_sign_posn);
  return 0;
}

void printstring(const char *title, const char *str)
{
  printf("%s: \"%s\"\n", title, str);
}

void printchar(const char *title, char c)
{
  printf("%s: ", title);
  if (c == CHAR_MAX)
    printf("UNAVAILABLE\n");
  else
    printf("%d\n", c);
}
--------- ch26/sort.c :------------------------- CUT HERE ----
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <time.h>
#include <string.h>

#define MAX_STR_LEN 30
#define CONVERSION_BASE 10
#define NUMS_PER_LINE 10
#define DEBUG

clock_t before, after;
time_t start_time;

int compare(const void *a, const void *b);
void print_array(int a[], int array_size);
void debug(const char *fname, const char *format, ...);
void check_endptr(const char *endptr);
void report_timing(void);

main()
{
  int i, *a, array_size, max_value;
  char s[MAX_STR_LEN+1];
  char *endptr, *p;

  atexit(report_timing);
  start_time = time(NULL);
  printf("How many random values to sort? ");
  fgets(s, MAX_STR_LEN, stdin);
  if ((p = strchr(s, '\n')) != NULL)
      *p = '\0';      
  array_size = strtol(s, &endptr, CONVERSION_BASE);
  check_endptr(endptr);
  #ifdef DEBUG
    debug("main", "array_size is %d\n", array_size);
  #endif
  a = malloc(sizeof(int) * array_size);

  printf("Largest random value? ");
  fgets(s, MAX_STR_LEN, stdin);
  if ((p = strchr(s, '\n')) != NULL)
      *p = '\0';      
  max_value = strtol(s, &endptr, CONVERSION_BASE);
  check_endptr(endptr);
  #ifdef DEBUG
    debug("main", "max_value is %d\n", max_value);
  #endif
  srand((unsigned)time(NULL));
  for (i = 0; i < array_size; i++) {
    a[i] = rand() % (max_value + 1);
  }
  print_array(a, array_size);
  #ifdef DEBUG
    debug("main", "begin sorting ...\n");
  #endif
  before = clock();
  qsort(a, array_size, sizeof(a[0]), compare);
  after = clock();
  #ifdef DEBUG
    debug("main", "end sorting ...\n");
  #endif
  print_array(a, array_size);
  return 0;
}

int compare(const void *a, const void *b)
{
  int na = *(int *)a;
  int nb = *(int *)b;

  if (na < nb) return -1;
  if (na == nb)
    return 0;
  else
    return 1;
}

void print_array(int a[], int array_size)
{
  int i;

  #ifdef DEBUG
    debug("print_array", "begin printing ...\n");
  #endif
  for (i = 0; i < array_size; i++) {
    if (i % NUMS_PER_LINE == 0)
      printf("\n");
    printf("%4d ", a[i]);
  }
  printf("\n");
  #ifdef DEBUG
    debug("print_array", "end printing ...\n");
  #endif
}

void debug(const char *fname, const char *format, ...)
{
  va_list args;

  printf("DEBUGGING %s: ", fname);
  va_start(args, format);
  vprintf(format, args);
  va_end(args);
}

void check_endptr(const char *endptr)
{
  if (*endptr != '\0') {
    debug("main", "input error: bad character is `%c`\n", *endptr);
    abort();
  }
}

void report_timing(void)
{
  clock_t elapsed;
  time_t t;

  elapsed = after - before;
  printf("Processor time = %6.2f ticks = %.2f seconds\n",
         (double)elapsed, (double)elapsed / CLOCKS_PER_SEC);
  t = time(NULL);
  printf("Elapsed time = %.2f seconds.\n", difftime(t, start_time));
  printf("Program ends: %s", ctime(&t));
}