Chapter 9. Structures and Unions

Home

                       

PROGRAM 91 : fruit_veget.c

#include <stdio.h>

int main(void)
{
  struct fruit {
    char *name;
    int calories;
  };

  struct vegetable {
    char *name;
    int calories;
  };

  struct fruit a;
  struct vegetable b;

  a.name = "apple";
  a.calories = 153;
  b.name = "broccoli";
  b.calories = 79;
  printf("%s%s%s%d%s%s%s%d%s",
    "---\n"
    "Fruit:\n"
    " name: ", a.name, "\n"
    " calories: ", a.calories, "\n"
    "\n"
    "---\n"
    "Vegetable:\n"
    " name: ", b.name, "\n"
    " calories: ", b.calories, "\n"
    "\n");
  return 0;
}

 

PROGRAM 92 : casanova.c

#include <stdio.h>

struct student {
  char *last_name;
  int student_id;
  char grade;
};

int main(void)
{
  struct student tmp, *p = &tmp;

  tmp.grade = 'A';
  tmp.last_name = "Casanova";
  tmp.student_id = 910017;
  printf("%s%12s%12s\n%s%12d%12d\n%s%12c%12c\n\n",
    "---\n"
    "The information will be listed twice:\n"
    "\n"
    "Last name:", p -> last_name, (*p).last_name,
    "Sudent ID:", p -> student_id, (*p).student_id,
    " Grade:", p -> grade, (*p).grade);
  return 0;
}

PROGRAM 931 :main.c

#include "class_info.h"

int main(void)
{
  int cnt;
  int i;
  struct student tmp;
  struct student class[CLASS_SIZE];

  tmp.grade = 'A';
  tmp.last_name = "Casanova";
  tmp.student_id = 910017;
  class[0] = tmp;
  tmp.grade = 'F';
  tmp.last_name = "Superman";
  tmp.student_id = 910018;
  class[1] = tmp;
  tmp.grade = 'C';
  tmp.last_name = "Wonderwoman";
  tmp.student_id = 910019;
  class[2] = tmp;
/*
// Enter nothing for the remainder of the class.
*/
  for (i = 3; i < CLASS_SIZE; ++i) {
    class[i].grade = ' ';
    class[i].last_name = "";
    class[i].student_id = 0;
  }
  cnt = fail(class);
  printf("Number of failing grades: %d\n", cnt);
  return 0;
}

PROGRAM 932 : fail.c

/*
// Count the failing grades
*/

#include "class_info.h"

int fail(struct student class[])
{
  int i, cnt = 0;

  for (i = 0; i < CLASS_SIZE; ++i)
    cnt += class[i].grade == 'F';
  return cnt;
}

PROGRAM 933 : class_info.h

#include <stdio.h>

#define CLASS_SIZE 100

struct student {
  char *last_name;
  int student_id;
  char grade;
};

int fail(struct student class[]);

PROGRAM 941 : complex.h

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

#define MAXLINE 100
#define MAXSTRING 100

enum no_yes {no, yes};

typedef const char cchr;
typedef double dbl;
typedef enum no_yes no_yes;

struct complex {
  dbl re; /* real part */
  dbl im; /* imag part */
};

typedef struct complex complex;

void add(complex *a, complex *b, complex *c);
void error_exit_not_a_complex_number(cchr *s);
void error_exit_too_many_numbers(cchr *line);
no_yes get_complex_number(complex *z, cchr *s);
no_yes get_from_user(complex *a, complex *b);
void mult(complex *a, complex *b, complex *c);
cchr * skip_number(cchr *p);
void wrt(char *s, complex z);

PROGRAM 942 : main.c

#include "complex.h"

int main(void)
{
  complex a, b, z, w;

  printf("%s",
    "---\n"
    "Complex arithemtic will be performed\n"
    "on a and b, two complex numbers.\n"
    "\n");
  for ( ; ; ) {
    printf("Input a and b: ");
    if (get_from_user(&a, &b) == no)
      break;
    putchar('\n');
    add(&z, &a, &b); /* z = a + b */
    mult(&w, &a, &b); /* w = a * b */
    wrt("a", a);
    wrt("b", b);
    putchar('\n');
    wrt("a + b", z);
    wrt("a * b", w);
    putchar('\n');
  }
  printf("\nBye!\n\n");
  return 0;
}

no_yes get_complex_number(complex *z, cchr *s)
{
  cchr* p;
  dbl x;
  dbl y;

  assert(strlen(s) > 0);
  assert(!isspace(*s));
  assert(!isspace(*(s + strlen(s) - 1)));
/*
// Try to pick up the first number.
*/
  if (sscanf(s, "%lf", &x) != 1) {
/*
// There is no first number; look for +i, -i, or i.
*/
    if (strcmp(s, "+i") == 0 || strcmp(s, "i") == 0) {
      z -> re = 0.0;
      z -> im = 1.0;
      return yes;
    }
    if (strcmp(s, "-i") == 0) {
      z -> re = 0.0;
      z -> im = -1.0;
      return yes;
    }
  }
/*
// We have a number; is it by itself?
*/
  p = skip_number(s);
  if (*p == '\0') {
    z -> re = x;
    z -> im = 0.0;
    return yes;
  }
  if (strcmp(p, "i") == 0) {
    z -> re = 0.0;
    z -> im = x;
    return yes;
  }
/*
// Try to pick up the second number.
*/
  if (sscanf(p, "%lf", &y) != 1) {
/*
// There is no second number; look for +i or -i.
*/
    if (strcmp(p, "+i") == 0) {
      z -> re = x;
      z -> im = 1.0;
      return yes;
    }
    if (strcmp(p, "-i") == 0) {
      z -> re = x;
      z -> im = -1.0;
      return yes;
    }
  }
/*
// We have the second number; it should be followed by i.
*/
  p = skip_number(p);
  if (strcmp(p, "i") == 0) {
    z -> re = x;
    z -> im = y;
  return yes;
  }
/*
// If we get this far, there is trouble.
*/
  error_exit_not_a_complex_number(s);
  return no;
}

no_yes get_from_user(complex *a, complex *b)
{
  char line[MAXLINE];
  char s1[MAXSTRING];
  char s2[MAXSTRING];
  cchr *p;
  char *val;

  val = fgets(line, MAXLINE, stdin);
  assert(val != NULL);
/*
// Skip white space.
*/
  for (p = line; isspace(*p); ++p)
    ;
/*
// Check for "bye", "exit", of "quit".
*/
  if (*p == 'b' || *p == 'e' || *p == 'q')
    return no;
/*
// Get the first string from the line.
*/
  if (sscanf(p, "%s", s1) != 1)
    return no;
/*
// Skip over the first string.
*/
  p += strlen(s1);
/*
// Skip white space.
*/
  for ( ; isspace(*p); ++p)
    ;
/*
// Get the second string from the line.
*/
  if (sscanf(p, "%s", s2) != 1)
    return no;
/*
// Skip over the second string.
*/
  p += strlen(s2);
/*
// Skip white space.
*/
  for ( ; isspace(*p); ++p)
    ;
/*
// Check for anything else on the line.
*/
  if (*p != '\0')
    error_exit_too_many_numbers(line);
/*
// Get the complex numbers a and b.
*/
  if (get_complex_number(a, s1) == no)
    return no;
  if (get_complex_number(b, s2) == no)
    return no;
  return yes;
}

void wrt(char *s, complex z)
{
  printf(" %5s = %+.3f%+.3f*i\n", s, z.re, z.im);
}

void add(complex *a, complex *b, complex *c) /* a = b + c */
{
  a -> re = b -> re + c -> re;
  a -> im = b -> im + c -> im;
}

void mult(complex *a, complex *b, complex *c) /* a = b * c */
{
  a -> re = (b -> re) * (c -> re) - (b -> im) * (c -> im);
  a -> im = (b -> re) * (c -> im) + (b -> im) * (c -> re);
}

cchr *skip_number(cchr *p)
{
  no_yes found_decimal_point = no;

  assert(!isspace(*p));
  if (*p == '+' || *p == '-')
    ++p;
  if (*p == '.') {
    found_decimal_point = yes;
    ++p;
  }
  while (isdigit(*p))
    ++p;
  if (found_decimal_point == no && *p == '.') {
    ++p;
    while (isdigit(*p))
      ++p;
  }
  if (*p == 'e' || *p == 'E') {
    ++p;
    if (*p == '+' || *p == '-')
      ++p;
    while (isdigit(*p))
      ++p;
  }
  return p;
}
void error_exit_not_a_complex_number(cchr *s)
{
  printf("%s%s%s",
    "\n"
    "---\n"
    "ERROR: Not a complex number:\n"
    "\n"
    " Here is part of what you typed in:\n"
    "\n"
    " ", s, "\n"
    "\n"
    " This string cannot be interpreted as a complex number.\n"
    " Here are some examples of acceptable complex numbers:\n"
    "\n"
    " 1.23+4.567i -0.123 1+i i\n"
    "\n"
    " Only two such numbers can occur on your input line.\n"
    "\n"
    "Bye!\n"
    "\n");
  exit(1);
}

void error_exit_too_many_numbers(cchr *line)
{
  printf("%s%s%s",
    "\n"
    "---\n"
    "INPUT ERROR:\n"
    "\n"
    " Too many numbers on the line or numbers in the wrong format: \n"
    " Here is the line that you typed in:\n"
    "\n"
    " ", line,
    "\n"
    " Here are some examples of acceptable complex numbers:\n"
    "\n"
    " 1.23+4.567i -0.123 1+i i\n"
    "\n"
    " Only two such numbers can occur on your input line.\n"
    "\n"
    "Bye!\n"
    "\n");
  exit(1);
}

 

PROGRAM 95 : union.c

#include <stdio.h>

typedef union int_or_float {
  int i;
  float f;
} number;

int main(void)
{
  number n;

  n.i = 4444;
  printf("i: %10d f: %16.10e\n", n.i, n.f);
  n.f = 4444.0;
  printf("i: %10d f: %16.10e\n", n.i, n.f);
  return 0;
}

 

PROGRAM 961 : check_bit.h

#include <limits.h>
#include <stdio.h>

struct word_bytes {
  unsigned b0 : 8, b1 : 8, b2 : 8, b3 : 8;
};

struct word_bits {
  unsigned
  b0 : 1, b1 : 1, b2 : 1, b3 : 1, b4 : 1, b5 : 1, b6 : 1, 
  b7 : 1, b8 : 1, b9 : 1, b10 : 1, b11 : 1, b12 : 1, b13 : 1,
  b14: 1, b15 : 1, b16 : 1, b17 : 1, b18 : 1, b19 : 1, b20 : 1,
  b21: 1, b22 : 1, b23 : 1, b24 : 1, b25 : 1, b26 : 1, b27 : 1, 
  b28: 1, b29 : 1, b30 : 1, b31;
};

typedef struct word_bytes word_bytes;
typedef struct word_bits word_bits;

union word {
  int i;
  word_bits bit;
  word_bytes byte;
};

typedef union word word;

 

PROGRAM 962 : main.c

#include "check_bits.h"

int main(void)
{
  word w = {0};
  void bit_print(int);

  w.bit.b8 = 1;
  w.byte.b0 = 'a';
  printf("w.i = %d\n", w.i);
  bit_print(w.i);
  putchar('\n');
  return 0;
}


void bit_print(int a)
{
  int i;
  int n = sizeof(int) * CHAR_BIT; /* in limits.h */
  int mask = 1 << (n - 1); /* mask = 100...0 */

  for (i = 1; i <= n; ++i) {
    putchar(((a & mask) == 0) ? '0' : '1');
    a <<= 1;
    if (i % CHAR_BIT == 0 && i < n)
      putchar(' ');
  }
}

 


[Last Update: 2001.5.25] Dongseo University Cyber Campus