#include #include #include #include #define MaxName (20) /* element or compound */ #define MaxSym (5) /* chemical symbol */ const double CritMass = 1.0e-7; /* common to elements and compounds */ typedef struct basics { double mass; char name[ MaxName + 1 ]; char symbol[ MaxSym + 1 ]; } Basics; /* chemical elements */ typedef struct element { double aWgt; /* atomic weight */ Basics basics; } Element; /* chemical compounds */ typedef struct compound { double mWgt; /* molecular weight */ Basics basics; } Compound; void print_basics( const Basics* b ), report( const char* msg, const Compound* c, const Element* e1, const Element* e2 ), set_basics( Basics* b, const char* name, const char* symbol, const double mass ), make_element( Element* e, const char* name, const char* symbol, const double aWgt, const double mass ), make_compound( Compound* c, const char* name, const char* symbol, const double mWgt, const double mass ), update_compound( Element* el, int v1, Element* e2, int v2, Compound* c ); main() { Element oxygen, hydrogen; Compound water; make_element( &oxygen, "Oxygen", "O", 16, 17 ); make_element( &hydrogen, "Hydrogen", "H", 1, 3 ); make_compound( &water, "Water", "H2O", 18., 0.5 ); report( "Initial", &water, &hydrogen, &oxygen ); update_compound( &hydrogen, -1, &oxygen, 2, &water ); report( "Final", &water, &hydrogen, &oxygen ); return EXIT_SUCCESS; } /* Print name, chemical symbol, and mass. */ void print_basics( const Basics* b ) { printf( "\t%s (%s): %.2f grams\n", b -> name, b -> symbol, b -> mass ); } /* Print basic fields and atomic or molecular weight. */ void report( const char* msg, const Compound* c, const Element* e1, const Element* e2 ) { printf( "\n%s reactants and product:\n", msg ); print_basics( &e1 -> basics ); print_basics( &e2 -> basics ); print_basics( &c -> basics ); } /* Set name, symbol, and mass. */ void set_basics( Basics* b, const char* name, const char* symbol, const double mass ) { strcpy( b -> name, name ); strcpy( b -> symbol, symbol ); b -> mass = mass; } /* Set atomic weight and basic fields. */ void make_element( Element* e, const char* name, const char* symbol, const double aWgt, const double mass ) { e -> aWgt = aWgt; set_basics( &e -> basics, name, symbol, mass ); } /* Set molecular weight and basic fields. */ void make_compound( Compound* c, const char* name, const char* symbol, const double mWgt, const double mass ) { c -> mWgt = mWgt; set_basics( &c -> basics, name, symbol, mass ); } /* Add elements to existing compound by computing * -- which element has excess amount * -- depletion of reactants * -- amount of product generated */ void update_compound( Element* e1, int v1, /* valence */ Element* e2, int v2, /* valence */ Compound* c ) { double m1, /* molecules in 1st element */ m2, /* molecules in 2nd element */ mR; /* molecules reacted */ /* Return if insufficient elements to make compound. */ if ( fabs( e1 -> basics.mass * e2 -> basics.mass ) <= CritMass ) return; /* Get absolute values for valences. */ v1 = abs( v1 ); v2 = abs( v2 ); /* Get number of molecules. */ m1 = e1 -> basics.mass / e1 -> aWgt; m2 = e2 -> basics.mass / e2 -> aWgt; /* More of 1st element than 2nd element? */ if ( m1 / v2 > m2 / v2 ) { /* if so, compute excess of 1st element */ mR = m2 / v1; m1 -= mR * v2; e1 -> basics.mass = m1 * e1 -> aWgt; e2 -> basics.mass = 0.0; } else { /* compute excess of 2nd element */ mR = m1 / v2; m2 -= mR * v1; e2 -> basics.mass = m2 * e2 -> aWgt; } /* Update compound. */ c -> basics.mass = c -> basics.mass + mR * c -> mWgt; }