#include #include #include #include /* Goal want a program with different kinds of shapes, circles, rectangles, squares, triangles, etc. with common operations area, circumference, distanceto, etc. want to consider all as shapes. Want a structure (array) consisting of "shapes:" some circles, some rectangles. Want to, for example, calculate total area of all shapes. */ #define CIRCLE 1 #define RECTANGLE 2 struct shape { char type; int x, y; }; typedef struct shape shape; struct circle { char type; int x, y; int radius; }; typedef struct circle circle; struct rectangle { char type; int x, y; int width; int height; }; typedef struct rectangle rectangle; circle* make_circle(int x, int y, int r) { circle* c= (circle*)malloc(sizeof(circle)); c->type = CIRCLE; c->x = x; c->y = y; c->radius = r; return c; } rectangle* make_rectangle(int x, int y, int w, int h) { rectangle* r = (rectangle*)malloc(sizeof(rectangle)); r->type = RECTANGLE; r->x = x; r->y=y; r->width=w; r->height=h; return r; } // no overloading in C double area_circle(circle* c) { return M_PI * c->radius * c->radius; } double circumference_circle(circle* c) { return M_PI * c->radius * 2; } double area_rectangle(rectangle *r) { return r->width * r->height; } double circumference_rectangle(rectangle *r) { return r->width*2 + r->height*2; } double distance(shape* c1, shape *c2) { int dx = c1->x - c2->x; int dy = c1->y - c2->y; return sqrt(dx*dx + dy*dy); } // can I have distance between rectangle and circle (should) double area(shape* s) { if (s->type==CIRCLE) return area_circle((circle*)s); else return area_rectangle((rectangle*)s); } // setup dispatch vector: typedef double (*shapefun)(shape*); shapefun circ_fun[] = {(shapefun)circumference_circle, (shapefun)circumference_rectangle}; double circumference(shape* s) { return circ_fun[s->type](s); } // currently, no relationship at all between different kinds of shapes. // can't create typed structure containing both. int main() { circle* c1 = make_circle(4,5,6); rectangle* r1 = make_rectangle(5,6,7,87); double d = distance((shape*)c1, (shape*)r1); // type casting needed to establish relationship between circle and shape. // create an array of shapes: rectangle *r2 = make_rectangle(4,3,2,1); circle *c2 = make_circle(4,7,6); shape* S[] = {(shape*)c1, (shape*)r1, (shape*)c2, (shape*)r2}; shape *s; // how much memory to allocate? // stack allocation requires the compile to calculate sizeof(shape) // FIRST REALIZATION: NEED DYNAMIC MEMORY ALLOCATION char input; printf("what kind of shape do you want?"); scanf("%c",&input); if (input == 'c') s = (shape*)make_circle(5,5,67); else s = (shape*)make_rectangle(6,4,3,2); // want to calculate total area of all shapes in S: double totalarea = 0; //for(int i=0;i<4;i++) area += ... // can't even write this code. info doesn't exist. // SECOND REALIZATION: NEED DYNAMIC TYPE INFORMATION. // static typing not enough for(int i=0;i<4;i++) { totalarea += area(S[i]); } // THIRD REALIZATION: need dynamic dispatch printf("aread = %f\n", totalarea); return 0; }