Friday 21 January 2011

Kernighan & Ritchie

Many years ago I taught myself how to program in the C programming language - after I had played with BASIC and got fed up with FORTRAN. I  used a couple of books to learn about C and a couple of compilers.  Kernighan & Ritchie was the best book, followed closely by The C Book by Mike Banahan (I also remember that there was a really good thick volume on Turbo C by the gloriously named Herb Schildt).  Learning C was a great lesson in logical thinking. Breaking down a problem into the discrete logical steps required for a successful programme is both rigorously analytical and curiously creative and liberating.  I would recommend it to anyone.


I went on to write quite a few programmes, some of them were deliberately tiny and others  quite complex and powerful. Much of the time I spent on my PhD was in writing C code to implement the maths I wanted to apply to data. 


The C Book is HERE to download and no doubt K&R is still available. 





Below is a function that was at the heart of a programme to calculate the Fractal dimension of a stream of data from a flame detector. At the time I was really proud of it - it was written in 1993.  


void calc_fr(int ndata,int data[],int wid[],int dig,int len,FILE *fp)

{
float tal[13];
struct cover cov[15];
div_t xtil,ytil;
int loop,dp,c,curr_d,w,idata;

xtil=div(ndata,len);     /* Calculate number loops to run */
loop=xtil.quot;          /* loop is number of loops       */

idata=data[1];               /* Data value */
for(w=0;w<=dig;w++) tal[w]=0;   /* reset tally to zero     */
for(w=0;w<=dig;w++)
    {
    ytil=div(idata,wid[w]);
    cov[w].hi=cov[w].lo=ytil.quot;
    }
curr_d=1;
for(dp=1;dp<=loop;dp++)   /* Main loop */
    {
    for(c=1;c<len;c++)
{
curr_d++;
idata=data[curr_d];            /* Get next data point */
for(w=0;w<=dig;w++)            /* For each tile width */
   {
   xtil=div(c,wid[w]);        /* Calculate x direction tile */
   ytil=div(idata,wid[w]);    /* Calculate y direction tile */
   cov[w].lo=(int) min(cov[w].lo,ytil.quot);
   cov[w].hi=(int) max(cov[w].hi,ytil.quot);
   if(xtil.rem==0)
{
tal[w]=tal[w]+(cov[w].hi-cov[w].lo)+1;
cov[w].hi=cov[w].lo=ytil.quot;
}
   }
}
    data_out(fp,wid,tal,dig);       /* Calc slope and results  */
    for(w=0;w<=dig;w++) tal[w]=0;   /* reset tally to zero     */
    }
    printf("\nFinished...\n");
}


Kernighan and Ritchie had a refreshing and very straightforward style. In the second edition, where they expanded on the material that had been developed as part of the ANSI C standard they state that;

We have tried to retain the brevity of the first edition. C is not a big language, and it is not well served by a big book. We have improved the exposition of critical features, such as pointers, that are central to C programming. We have refined the original examples, and have added new examples in several chapters. For instance, the treatment of complicated declarations is augmented by programs that convert declarations into words and vice versa. As before, all examples have been tested directly from the text, which is in machine-readable form.

The most famous programme described by K&R is hello.c - which just prints out the text "hello, world" to the terminal. It is the K&R example of a minimal working C program. Almost all computer programming handbooks use a similar programme as a  conventional first programme.