Structures

(read ch. 9)

C structs are like records in other programming languages. The associate a group of variables (possibly of different types) that are somehow related.

Example: a struct representing a book might relate string variables author, title and publisher; and an integer variable number of pages. In C, this struct type could be defined as follows:

#define AUTHLEN 41
#define TITLELEN 81
#define PUBLEN 81

typedef char authtype[AUTHLEN];
typedef char titletype[TITLEN];
typedef char pubtype[PUBLEN];

typedef struct {
   authtype author;
   titletype title;
   pubtype publisher;
   int numpages;} bookrec;

Here, author, title, publisher and numpages are called the fields of the struct. Type bookrec is now the type of such structs. A variable thetext of type bookrec is declared as follows:

bookrec thetext;

Like arrays, a variable of a struct type can be initialized when (and only when) it is declared:

bookrec thetext = {"Barrett and Wagner",
                   "C and UNIX",
                   "John Wiley and Sons",
                   446};

The order of the initial values must match the order of the fields in the type definition.

Each field of a struct variable can be referred to by the variable name followed by . followed by the field name. Examples (given the previous declaration of thetext):

  /* print the number of pages */
  printf("This book has %d pages.\n", thetext.numpages);

  /* change the number of pages */
  thetext.numpages = 448;

  /* read in a new publisher */
  scanf("%s", thetext.publisher);

  /* read in a new number of pages */
  scanf("%d", &thetext.numpages);

Note how addresses are handled here.

Example: a function to print a bookrec:

void printbook(bookrec book) {
  printf("Author: %s\n", book.author);
  printf("Title: %s\n", book.title);
  printf("Publisher: %s\n", book.publisher);
  printf("Number of pages: %d\n", book.numpages);
}

Return to Table of Contents

Structs and Functions

Functions can take structs as parameters and return structs as results.

Example: a program that handles structs representing points in the real plane

#include <stdio.h>

typedef struct {
  double x;
  double y;
  } point;

point newpoint(void);
void printpoint(point);

main() {
  
  point p;
  p = newpoint();
  printpoint(p);
}

point newpoint(void) {
  /* return an initialized point */

  point tp;

  tp.x = 0;
  tp.y = 0;

  return (tp);
}

void printpoint(point tp) {
  /* print a point */

  printf("The point value is: (%lf, %lf).\n", tp.x, tp.y);
}

Structs are passed by value by default, so a function that needs to change some field(s) of a struct must have a parameter of type address of struct.

Example: a function to set the x field of a point

void setx(point *paddr, double newval) {
  /* set the x field to newval */

  (*paddr).x = newval;
}

Note that we first get the value at the address of the struct, and then refer to the field. C also provides the -> operator to refer to fields of a struct parameter that has been passed by address:

void setx(point *paddr, double newval) {
  /* set the x field to newval */

  paddr->x = newval;
}

Example: see ~taw2/pub/struct.c

Return to Table of Contents

Nested Structs

Structs can:

Example. The following makes librarytype the type of arrays of bookrecs (a library of books):

#define AUTHLEN 41
#define TITLELEN 81
#define PUBLEN 81
#define LIB_MAX 100

typedef char authtype[AUTHLEN];
typedef char titletype[TITLEN];
typedef char pubtype[PUBLEN];

typedef struct {
   authtype author;
   titletype title;
   pubtype publisher;
   int numpages;} bookrec;

typedef bookrec librarytype[LIB_MAX];


/* some expressions using this type */

/* declare a variable of type librarytype */

librarytype library;

/* how many pages does the third book
   in the library have? */

printf("Number of pages: %d\n", library[2].numpages);

/* add 5 pages to the 10th book in the library */

library[9].numpages += 5;

/* read in a new author for the second 
   book in the library */

scanf("%s", library[1].author);

Example: see ~taw2/pub/library.c

Return to Table of Contents

Other Declaration Methods

Structs can be declared without using a typedef by using a tagname that appears between struct and {.

Example:

struct point {
  double x;
  double y;
  };

Here, point is the tagname. To use this struct type, the keyword struct must be used with it in declarations and prototypes.

Examples:

struct point point1, point2;

void setx(struct point *paddr);

This syntax is will be useful in the future. A typedef can still be used along with this way of defining struct types:

typedef struct point pointtype;

makes struct point and pointtype equivalent type names.

Return to Table of Contents