I'm no physicist, just a tourist.
I would think a struct representing the atom's electron configuration would be a start. An example might be
Code:
struct
{
char name[ 25 ]; // or however you like to store the element's name
int e1s, e2s, e2p, e3s, e3p, e4f; // just an example
};
Now, this would only suffice if you interpret zero in each shell as empty, and applied a count in each of these. Instead, you might prefer something like:
Code:
struct shell
{
char shell; // or however you like to store the allowed state identifiers
int quantity;
};
struct element
{
char name[ 25 ];
shell * states;
int statecount;
};
The idea here being to create an array of states, the size of which is indicated in statecount, so you can loop through the states to inquire about each one.
This can be extrapolated into the electron configuration of molecules with different notations for each "shell" or "state".
This idea also allows for quick "switching" on states, if that applies to computational chemistry, as that appears to be your goal. That is
Code:
for an element * e;
for a shell of e, say
shell * s = e->states;
switch( s->shell )
{
case 's':
case 'p':
}
I've not filled out the switch.
If 's' and 'p' aren't sufficient information (as I said, I'm not a chemist either), then other related information might be grouped to form enough information, such that instead of name of the "shell" as a character, an enumeration of all the permutations that describe this would instead by given to the struct shell for use in the switch, which determines a choice of behavior (functions to call) based on this information.
Typically, if I recall, you want to quickly access the outer shell, as in:
Code:
shell * outershell = e->states[ statecount - 1 ];
If statecount is initialized to zero for an "empty" element, the incremented as states are added in the initialization of the element, then the last shell in states is statecount - 1;
A quick check on the atomic number or weight, if I recall from my chemistry class of 30 years ago - which is outdated knowledge now (we were taught about valence in those days)...
Code:
for an element * e;
int weight = 0;
for( int i=0; i < e->statecount; ++i )
{
weight += e->states[ i ].quantity;
}
Which, of course, may also be a member of "element" which I didn't put there, but as I understand it, a weight in "element" wouldn't account for ions.
Then, you might consider:
Code:
struct atom
{
element e;
atom * links;
int atomcount;
};
struct molecule
{
char name[25]; // though you may need this to be dynamic, names can be quite long
atom * root;
int atomcount;
};
The idea here is unclear to me because I don't know how you need to visualize the connectivity of atoms in a molecule. I'm not sure if you consider a "root" to a molecule. In your depiction of water, it seems logical to think of oxygen as the root owning two hydrogen atoms, but perhaps that view is unwarranted.
However, what is clear to me is that a molecule struct makes sense as both a header and container of the atoms. It describes the name of the molecule, and whatever other data is generally applicable to the molecule as a whole, then you need a collection of atoms.
Atoms may also hold a collection of atoms, creating chains of connectivity relating to the organization of the molecule. At first it might seem that molecules can hold other molecules, and perhaps that's a valid visualization of the concept - in which case you might also or instead hold a pointer to a list of molecules instead of just a list of atoms.
Still, the idea is that a hierarchical ownership applies, and there must be some kind of "root" to the ownership, even if that root is chosen arbitrarily. It might help if I understood the nature and extent (and more about) the modeling of chemistry you require.
There's a chapter yet for me to write on how to allocate and free these structures, but I must admit I'm a C++ developer, not a C developer - though I wrote in C for years (from '81) until C++ become available ( in '87 ). At this point my C skills are rusty enough that I have trouble reaching for C solutions easily. There's so much that I want to reach for that isn't available to me in C that I have to stop and think carefully.
There may also be information required in the table of elements that describe what can happen to an atom, for there to be useful modeling of their behavior in the presence of bonds to other atoms, possibly reactions with other molecules (if you're going there), etc.
As for representation....
If, in the case of water, you assumed oxygen were the root, you'd have what is basically a classic recursive algorithm for the display as "lines" of depth in the recursion through the hierarchical connections in the structs I've shown.
However, molecules do exhibit "shapes" that don't easily conform to this simple notion, and so you'd really want some kind of graphical display, or at the very least, control of placement (print something at location x,y) in order to adequately display something like a benzine molecule.
Which, again reaching back to memory of a class or two from 30 years ago, requires a little care in the modeling of data structure I've shown above - you must avoid circular references.
What that means is that since benzine's connect in a ring, the "last" in a series of connections would "want" to connect back to the first one. This would require a touch of finesse.
In the struct I listed above, the "next" in a hierarchical chain has no typification. It is always a "next" - and if connected into a circle, creates a problem for freeing the memory. You'd never really know when to stop, and create a crash.
It would probably suffice to hold a boolean that indicates of the connection is hard or soft. A hard connection indicates that, with respect to ownership or other loop processing, the next entry in the list must be followed.
A soft connection indicates that the next entry is actually a circular connection - the point at which the connection became a circle, and as such, in some loops and certainly in deallocation routines, is a link that should not be followed - processing should conclude. in drawing, however, it indicates that while you should draw the connection from "this" to the next atom, that's the end of the loop.
I'm sure there's more, this is a stream of consciousness post, and while I find the topic intriguing, it's late and I'll need to read more on chemistry to really know what I'm talking about.