#include<stdio.h>
#include<stdlib.h>
/* I prefer this style of struct definition */
typedef struct {
int len;
} square_t;
typedef struct {
double radius;
} circle_t;
typedef enum {
SQUARE,
CIRCLE
} shape_type_t;
typedef struct {
/* Ordinary C unions are UNSAFE; they do not provide any way to
determine what the type of the current content is. Therefore, we
must keep track of it manually with the 'type' member. */
shape_type_t type;
union {
square_t square;
circle_t circle;
};
} shape_t;
void scale(shape_t *, double);
int main(void) {
shape_t s, *r;
/* s is statically allocated shape */
s.type = SQUARE;
s.square.len = 10;
/* r is 2 dynamically allocated shapes in an array */
r = (shape_t *) malloc(sizeof(shape_t)*2);
if (r == NULL) exit(1); /* always check result of malloc */
r[0].type = CIRCLE;
r[0].circle.radius = 3.14;
r[1].type = SQUARE;
r[1].square.len = 2;
/* function call example */
scale(&s, 2);
free(r);
return 0;
}
void scale(shape_t *p, double factor) {
/* Discriminate type */
if (p->type == SQUARE) {
/* Use pointer-to-struct syntax for access */
p->square.len *= factor;
} else if (p->type == CIRCLE) {
p->circle.radius *= factor;
}
}