Lessons from K&R2

April 25, 2008 at 4:21 pm | Posted in Programming | Leave a comment
Tags: ,

Since last month I am solving problems of K&R2 [1] . 1st I learned C from it. Due to my background in C++ it took only 1 month to finish the book, though I solved only the 50-60% of the problems that were useful to me at present time.I think K&R2 is book for a beginner to C but you should touch it only if you have written around 10,000 lines of real-life code, otherwise your will brain will get fried like mine. It is book which has many pieces of good advices and authors will say one thing at one time without repeating it, it is dense and has lots of insights that almost everyone will overlook at 1st reading, some things clear up only after reading it 2-3 times. When I begin to solve the C problems 1st time my head hurt a lot. I was in pain and struggled with the book a lot. Now I see, authors demand some sort of experience with real-life of code, experience with the code not only written by oneself but also to grasp the ideas embedded when you look at code written by other programmers and be able differentiate between good and bad. I have read many books during my graduation and even after that but never came across such succinct and solid descriptions of a language and its features and use and the expertise of the authors about the very general ideas of understanding and solving problems using their special tool. I am quite amazed at the capability, skill and boundaries of their thinking.

I have solved some trivial but important problems. Most recent of them is sorting the user input and printing it but using the pointers to lines to sort the input lines rather than sorting the lines themselves. This is originally the K&R2’s idea [2] but I have not looked at the solution provided by clc-wiki [3] yet. I solved it on my own with the help of comp.lang.c I will provide the code here, which is in very basic form. It is not an advanced piece of code that will handle every real-life situation. I am posting it here to expand on the mental map or better a Mental-Framework that is beginning to form in my mind on problem solving using C. I am putting it down here for you to read, in 3 steps :). You can find the discussion I did on comp.lang.c archives. For USENET archives, you can use Google Groups which offer the best collection of archives and worst User-Interface ever invented. Mind you, the code here is pretty raw and rudimentary and is here only to flash a light on what I have learned in my 28 days with K&R2.

 

/*    write a program to read a set of lines from input and sort them
 * and then print them.
 *
 * version 2.0
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

enum MAXLINES { ARR_SIZE = 100, STR_SIZE = 1000 };

char*  arr_of_ptr[ARR_SIZE];

int readlines(  char**, const int );
void printlines( char** );
int p_strcmp( const void*, const void* );

/* main() will simply call the other functions to do the job */
int main( void )
{
  const int read_num = readlines( arr_of_ptr, STR_SIZE );

  if( read_num )
    {
      qsort( arr_of_ptr, read_num, sizeof( char* ), p_strcmp );
      printlines( arr_of_ptr );
    }

  return 0;
}

/* 1) read lines till we get the NULL,
 * 2) store those lines into an array of characters,
 * 3) pointer of arry of pointers <arr_of_ptr> will point to the
 *    individual elements of array of characters.
 *
 */

int readlines( char* arr_of_ptr[], const int max )
{
  char *p, **p_arrptr;
  int num_lines, size_arr;
  char temp_arr[STR_SIZE];

  num_lines = 0;
  p_arrptr = arr_of_ptr;

  while( fgets(temp_arr, max, stdin) && num_lines < max )
    {
      size_arr = strlen( temp_arr ) + 1;
      if( (p = malloc( size_arr * sizeof( char ))) )
	{
	  strcpy( p, temp_arr );
	  *p_arrptr++ = p;
	  ++num_lines;
	}

    }

  return num_lines;
}

/* it will simply print the lines pointed to by the elements of
 * array of pointers <arr_of_ptr>.
 *
 */
void printlines( char* arr_of_ptr[] )
{
  printf("\n-------------------------\n");
  while( *arr_of_ptr )
    {
      printf("%s", *arr_of_ptr++ );
    }
}

/* compare 2 strings using pointers */
int p_strcmp( const void* pv1, const void* pv2 )
{
    return strcmp( *(char* const*)pv1, *(char* const*)pv2 );
}

 

Insight (1) In C, a program is executed by calling a function named main. Every C program must have a main function, you can’t compile a C program without main. To a programmer, main is the collection of steps used to solve the problem at hand. Steps are quite specific to the problems at hand but the concepts used are quite, by far, the very fundamental ideas on which the problem-solving in C is based. I call it the basic structure of solution you will finally get when you have solved the problem. It just calls other pieces of abstraction (known as functions, don’t confuse them with the functions of Haskell Language. C is Procedural programming language, so I better call these abstractions as procedures) to finish the work, except that it does not do much (though It can do everything other procedures do)

Those fundamental-concepts, the basic pattern for solving the specific problem at hand will teach you and give you an insight into the ideas like efficiency, maintainability, readability of code and also the elegance that is used to manage the code. By efficiency, I not only mean to get the program to be efficient, I also mean that you will try to understand why the efficiency is needed at some places and why you should not worry much about it at other places. By maintainability, I not only mean that you are one who will maintain it for over a longer period of time like 10 years (if you are lucky enough to have a successful product 😉 ) and you will be able to understand the code step by step after just after 6 months, that is readability, I mean that if you are not here and some other person or a team of programmers want to read it, or say, by the grace of devil your boss wants to read it, but that does not matter because he will not even able to differentiate between Arrays and Pointers :D. So at that time, that team must be able to comprehend it. Most of the programmers must be able to jot-down the description of the pattern o the structure of the solution to the problem by just browsing your code for some time. They must be able to make mental-picture of what you have done and also they must be able to comprehend the design-errors you made during your time ;). By Elegance, I mean your code must be structured properly in different, well formed pieces that solve the problem neatly and that takes us to 2nd insight…

Insight (2) We use Data-Structures and operations on those Data-Structures to write different parts of code. The choice and use of operations on Data-Structures will make or break your program. While a good choice leads to well-formed code, a bad-choice will beautifully lead to a mess you will not be able to comprehend that why you used a particular Data-Structures at one place and some different one at the another. Fortunately, understanding the use of Data-Structures in any language require you to learn the language by heart, I mean you must love it, thats what I have felt. If you like coding then you are very lucky man because no one wants to go to the job on Monday with half-eyes closed. Programming is kind of profession which requires creativity, you will hit different things each day and you create solutions every day, different solutions and you will also get amazed at the fact that different programmers solve problems in different ways, the ways that never came to your mind. At every touch with the code you will be blessed with something you never came across. That is the power of our profession. We don’t do rotten work everyday, our brains are not rotten and if you think so then you are not doing programming. If you are not willing to spend next 4 years of your life in just understanding the very basic of programming (I repeat, only the basics, no fancy stuff yet) , you better find some thing else to work on. Sell Loans, become a share broker and make a lot of money or even own a gas-station, that will give you a heck lot of money than doing programming. Programming is for people for whom the code and their lives are all alike. You and the code are one identity, not two. Just remember, choice of Data-Structures and choice of the operations on them will make or break your life, oops! I meant, will make or break your program 🙂

Insight (3) Using the facilities from Standard-Library is a very good idea, better idea is to learn from their design and use the reasoning that gave them birth. Dissolved in them is the expertise and experience of many years of work that had gone into their creation. Using them will keep your code clean and easier to manage. Standard-Libraries are here for some reason and some are not here for some other reasons. Use them and understand theose reasons, thats all I will say for now. Rest needs more experience on my side.

 

[1] http://en.wikipedia.org/wiki/The_C_Programming_Language_(book)

[2] K&R2, section 5.6, page 107

[3] http://clc-wiki.net/wiki/K&R2_solutions

 

 

Copyright © 2008, Arnuld Uttre, #331/type-2/sector-1, Naya Nangal, Distt. – Ropar, Punjab (INDIA) – 140126

Verbatim copying and distribution of this entire article are permitted worldwide, without royalty, in any medium, provided this notice, and the copyright notice, are preserved.

Advertisements

Leave a Comment »

RSS feed for comments on this post. TrackBack URI

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Create a free website or blog at WordPress.com.
Entries and comments feeds.

%d bloggers like this: