What does style look like?
Building on my post on style last week.
So what does "coding style" look like, anyway?
Well, the facile answer is "I know it when I see it". But it's more than that. A good coding style should result in high quality self-documented code that is esthetically pleasing to look at. This is not to reduce the value of external specifications, they are utterly critical to the success of a project, but external specifications serve a different purpose from the code. Neither can function independently.
I thought it might be interesting to see what happens to a single piece of code when you use different styles on it.
For the purposes of illustration, I opened my copy of Robert Sedgewick's "Algorithms in C, 3rd edition" to a random page, and picked the most reasonable example from that page. On that page is the following code:
#include "list.h"main(int argc, char *argv[]) { int i, N = atoi(argv[1]), M = atoi(argv[2]); Node t, x; initNodes(N); for (i = 2, x = newNode(1); i <= N; i++) { t = newNode(i); insertNext(x, t); x = t; } while (x != Next(x)) { for (i = 1; i < M ; i++) x = Next(x); freeNode(deleteNext(x)); } printf("%d\n", Item(x)); }
This is the code as it exists in the book, any errors come from my poor transcription efforts.
Let's see what happens to the code if you apply a couple of different coding styles. Please note: there's no one-true coding style. They're all different, and they all have their advantages.
First up, Hungarian. Hungarian's a structure-neutral coding style, so all I did was to hungarian-ize the variables and functions, without touching the other aspects.
#include "list.h"main(C cArg, SZ rgszArg[]) { I iNode, cNodes = atoi(rgszArg[1]), cNodesToSkip = atoi(rgszArg[2]); PNODE pnodeT, pnodeCur; InitNodes(cNodes); for (iNode = 2, pnodeCur = PnodeNew(1); iNode <= cNodes ; iNode++) { pnodeT = PnodeNew(i); InsertNext(pnodeCur, pnodeT); pnodeCur = pnodeT; } while (pnodeCur != PnodeNext(x)) { for (iNode = 1; iNode < cNodesToSkip ; iNode++) pnodeCur = PnodeNext(pnodeCur); FreeNode(PnodeDeleteNext(pnodeCur)); } printf("%d\n", Item(nodeCur)); }
So what changed? First off, all the built-in types are gone. Hungarian can use them, but not for most reasons. Next, the hungarian types "I", "C", and "SZ" are used to replace indexes, counts and strings. Obviously the C runtime library functions remain the same. Next, I applied the appropriate prefix - i for indices, c for counts, p<type> for "pointer to <type>". The Node type was renamed PNODE, in Hungarian, all types are uppercased. In Hungarian, the name of the routine describes the return value - so a routine that returns a "pointer to foo" is named "Pfoo<something relevent to which pfoo is being returned>".
Looking at the transformation, I'm not sure it's made the code any easier to read, or more maintainable. The next examples will try to improve things.