knking.com -- Programming Language Books and Training

 C C++ Java

Books by K. N. King

Home
Books by K. N. King
Short courses
Recommended books
Recommended links
FAQ

C Programming: A Modern Approach (Second Edition)

Chapter 17

Answers to Selected Exercises

2. [was #2; modified]

char *duplicate(const char *s)
{
  char *temp = malloc(strlen(s) + 1);

  if (temp == NULL)
    return NULL;

  strcpy(temp, s);
  return temp;
}

5. [was #6] (b) and (c) are legal. (a) is illegal because it tries to reference a member of d without mentioning d. (d) is illegal because it uses -> instead of . to reference the c member of d.

7. [was #8] The first call of free will release the space for the first node in the list, making p a dangling pointer. Executing p = p->next to advance to the next node will have an undefined effect. Here's a correct way to write the loop, using a temporary pointer that points to the node being deleted:

struct node *temp;

p = first;
while (p != NULL) {
  temp = p;
  p = p->next;
  free(temp);
}

8. [was #10; modified]

#include <stdbool.h>   /* C99 only */
#include <stdio.h>
#include <stdlib.h>
#include "stack.h"

struct node {
  int value;
  struct node *next;
};

struct node *top = NULL;

void make_empty(void)
{
  struct node *temp;

  while (top != NULL) {
    temp = top;
    top = top->next;
    free(temp);
  }
}

bool is_empty(void)
{
  return top == NULL;
}

bool push(int i)
{
  struct node *new_node;

  new_node = malloc(sizeof(struct node));
  if (new_node == NULL)
    return false;

  new_node->value = i;
  new_node->next = top;
  top = new_node;

  return true;
}

int pop(void)
{
  struct node *temp;
  int i;

  if (is_empty()) {
    printf("*** Stack underflow; program terminated. ***\n");
    exit(EXIT_FAILURE);
  }

  i = top->value;
  temp = top;
  top = top->next;
  free(temp);

  return i;
}

15. [was #12] The output of the program is

Answer: 3

The program tests the values of f2(0), f2(1), f2(2), and so on, stopping when f2 returns zero. It then prints the argument that was passed to f2 to make it return zero.

17. [was #14] Assuming that compare is the name of the comparison function, the following call of qsort will sort the last 50 elements of a:

qsort(&a[50], 50, sizeof(a[0]), compare);

Answers to Selected Programming Projects

1. [was #4]

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

#define NAME_LEN 25
#define INITIAL_PARTS 10

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

struct part *inventory;
int num_parts = 0;      /* number of parts currently stored */
int max_parts = INITIAL_PARTS;   /* size of inventory array */

int find_part(int number);
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.                          *
 **********************************************************/
int main(void)
{
  char code;

  inventory = malloc(max_parts * sizeof(struct part));
  if (inventory == NULL) {
    printf("Can't allocate initial inventory space.\n");
    exit(EXIT_FAILURE);
  }

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

/**********************************************************
 * find_part: Looks up a part number in the inventory     *
 *            array. Returns the array index if the part  *
 *            number is found; otherwise, returns -1.     *
 **********************************************************/
int find_part(int number)
{
  int i;

  for (i = 0; i < num_parts; i++)
    if (inventory[i].number == number)
      return i;
  return -1;
}

/**********************************************************
 * 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 or the  *
 *         database is full.                              *
 **********************************************************/
void insert(void)
{
  int part_number;
  struct part *temp;

  if (num_parts == max_parts) {
    max_parts *= 2;
    temp = realloc(inventory, max_parts * sizeof(struct part));
    if (temp == NULL) {
      printf("Insufficient memory; can't add more parts.\n");
      return;
    }
    inventory = temp;
  }

  printf("Enter part number: ");
  scanf("%d", &part_number);
  if (find_part(part_number) >= 0) {
    printf("Part already exists.\n");
    return;
  }

  inventory[num_parts].number = part_number;
  printf("Enter part name: ");
  read_line(inventory[num_parts].name, NAME_LEN);
  printf("Enter quantity on hand: ");
  scanf("%d", &inventory[num_parts].on_hand);
  num_parts++;
}

/**********************************************************
 * 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)
{
  int i, number;

  printf("Enter part number: ");
  scanf("%d", &number);
  i = find_part(number);
  if (i >= 0) {
    printf("Part name: %s\n", inventory[i].name);
    printf("Quantity on hand: %d\n", inventory[i].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)
{
  int i, number, change;

  printf("Enter part number: ");
  scanf("%d", &number);
  i = find_part(number);
  if (i >= 0) {
    printf("Enter change in quantity on hand: ");
    scanf("%d", &change);
    inventory[i].on_hand += change;
  } 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)
{
  int i;

  printf("Part Number   Part Name                  "
         "Quantity on Hand\n");
  for (i = 0; i < num_parts; i++)
    printf("%7d       %-25s%11d\n", inventory[i].number,
           inventory[i].name, inventory[i].on_hand);
}

2. [was #16]

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

#define NAME_LEN 25
#define MAX_PARTS 100

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

int num_parts = 0;   /* number of parts currently stored */

int find_part(int number);
void insert(void);
void search(void);
void update(void);
void print(void);
int compare_parts(const void *p, const void *q);

/**********************************************************
 * 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.                          *
 **********************************************************/
int main(void)
{
  char code;

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

/**********************************************************
 * find_part: Looks up a part number in the inventory     *
 *            array. Returns the array index if the part  *
 *            number is found; otherwise, returns -1.     *
 **********************************************************/
int find_part(int number)
{
  int i;

  for (i = 0; i < num_parts; i++)
    if (inventory[i].number == number)
      return i;
  return -1;
}

/**********************************************************
 * 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 or the  *
 *         database is full.                              *
 **********************************************************/
void insert(void)
{
  int part_number;

  if (num_parts == MAX_PARTS) {
    printf("Database is full; can't add more parts.\n");
    return;
  }

  printf("Enter part number: ");
  scanf("%d", &part_number);
  if (find_part(part_number) >= 0) {
    printf("Part already exists.\n");
    return;
  }

  inventory[num_parts].number = part_number;
  printf("Enter part name: ");
  read_line(inventory[num_parts].name, NAME_LEN);
  printf("Enter quantity on hand: ");
  scanf("%d", &inventory[num_parts].on_hand);
  num_parts++;
}

/**********************************************************
 * 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)
{
  int i, number;

  printf("Enter part number: ");
  scanf("%d", &number);
  i = find_part(number);
  if (i >= 0) {
    printf("Part name: %s\n", inventory[i].name);
    printf("Quantity on hand: %d\n", inventory[i].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)
{
  int i, number, change;

  printf("Enter part number: ");
  scanf("%d", &number);
  i = find_part(number);
  if (i >= 0) {
    printf("Enter change in quantity on hand: ");
    scanf("%d", &change);
    inventory[i].on_hand += change;
  } else
    printf("Part not found.\n");
}

/**********************************************************
 * print: Sorts the inventory array by part number, then  *
 *        prints a listing of all parts in the database,  *
 *        showing the part number, part name, and         *
 *        quantity on hand.                               *
 **********************************************************/
void print(void)
{
  int i;

  qsort(inventory, num_parts, sizeof(struct part), compare_parts);
  printf("Part Number   Part Name                  "
         "Quantity on Hand\n");
  for (i = 0; i < num_parts; i++)
    printf("%7d       %-25s%11d\n", inventory[i].number,
           inventory[i].name, inventory[i].on_hand);
}

int compare_parts(const void *p, const void *q)
{
  return ((struct part *) p)->number - ((struct part *) q)->number;
}

Copyright © 2008, 1996 W. W. Norton & Company, Inc. All rights reserved.

Google
 
Web knking.com