Saturday, December 10, 2011

C programming lecture 3


Now that we have covered the basic concepts of C programming, we can briefly discuss the process of compilation.
Compilation is basically translation ­­ a computer program called the compiler takes our C source code and translates it into the binary language used by computers. Of course, it is more complicated than that; but the basic idea applies.
To those new to programming, this seems fairly simple. A naive compiler might read in every
source file, translate everything into machine code, and write out an executable. This could work but
has two serious problems. First, for a large project, the computer may not have enough memory to
read
 all of the source code at once. Second, if you make a change to a single source file, you would
rather not have to recompile the entire application. To deal with these problems, compilers break
their job down into steps; for each source file (each .c file), the compiler reads the file, reads the
files it #includes, and translates it to machine code. The result of this is an "object file" (.o).
Once every object file is made, a "linker" collects all of the object files and writes the actual
program. This way, if you change one source file, only that file needs to be recompiled and then the
application needs to be re­linked.
Without going into the painful details, it can be beneficial to have a superficial understanding of the compilation process, and here we will briefly discuss it:
Preprocessor
In this stage the "preprocessor directives" are dealt with. These include #includes, macros, and #pragma compiler settings. The result of the preprocessor is a text string.




Syntax Checking
This step ensures that the code is valid and will sequence into an executable program.
Object Code
The compiler produces a machine code equivalent of the source code that can then be linked into
the
 final program. This step ensures that the code is valid and will sequence into an executable
program.
Linking
Linking combines the separate object codes into one complete program by integrating libraries and
the
 code into the final executable format.  Compilin |Error handling 
C Structure and Style
This is a basic introduction to producing effective code structure in the C Programming Language.
It is designed to provide information on how to effectively use Indentation, Comments, and other
elements
 that will make your C code more readable. It is not a tutorial on actually programming in
C.
New programmers will often not see the point in following structure in their programs, because they often think that code is designed purely for the reading by a compiler. This is usually not the case, as well­written code that follows a well­designed structure is usually much easier for programmers (who haven't worked on the code for months) to read, and edit.
In the following sections, we will attempt to explain good programming techniques that will in turn make your programs more effective.
Introduction
The following two blocks of code are essentially the same: Both of them contain exactly the same
code,
 and will compile and execute with the same result; however there is one essential difference.
Which of the following programs do you think is easier to read?
#include  <stdio.h>
int  main()
{printf("Hello,  World!\n");return(0);}

or
#include  <stdio.h>
int  main()
{
printf("Hello,  World!\n"); return(0);
}
The simple use of indents and line breaks can greatly improve the readability of the code; without
making
 any impact whatsoever on how the code performs. By having readable code, it is much
easier
 to see where functions and procedures end, and which lines are part of which loops and





procedures.
This book is going to focus on the above piece of code, and how to improve it. Please note that
during the course of the tutorial, there will be many (apparently) redundant pieces of code added. These are only added to provide examples of techniques that we will be explaining, without
breaking the overall flow of code that the program achieves.
Line Breaks and Indentation
The addition of white space inside your code is arguably the most important part of good code
structure. Effective use of it can create a visual gauge of how your code flows, which can be very important when returning to your code when you want to maintain it.

Line Breaks
Line breaks should be used in three main parts of your code
  After precompiler declarations.
  After new variables are declared.
  Between new paths of code. (i.e. Before the declaration of the function or loop, and after the
     
closing '}' bracket).
The following lines of code have line breaks between functions, but not any indention. Note that we have added line numbers to the start of the lines. Using these in actual code will make your
compiler fail, they are only there for reference in this book.
10      #include  <stdio.h>
20      int  main()
30      {
40      int  i=0;
50      printf("Hello,  World!");
60      for  (i=0;i<1;i++){
70      printf("\n");
80      break;
90      }
100  return(0);
110   }
120

Based on the rules we established earlier, there should now be four line breaks added.
  Between lines 10 and 20, as line 10 is a precompiler declaration
  Between lines 40 and 50, as the block above it contains variable declarations
  Between lines 50 and 60, as it is the beginning of a new path (the 'for' loop)
  Between lines 90 and 100, as it is the end of a path of code
This will make the code much more readable than it was before:
10      #include  <stdio.h>
11
20      int  main()
30      {
40      int  i=0;
41
50      printf("Hello,  World!");
51
60      for  (i=0;i<1;i++){
70      printf("\n");
80      break;
90      }





91
100  return(0);
110   }
120

But this still isn't as readable as it can be.

Indentation
Although adding simple line breaks between key blocks of code can make code marginally easier to
read,
 it provides no gauge of the flow of the program. The use of your tab key can be very useful
now:
 indentation visually separates paths of code by moving their starting points to a new column in
the line. This simple practice will make it much easier to read code. Indentation follows a fairly
simple rule:
  All code inside a new path (i.e. Between the two '{' brackets '}') should be indented by one
     
tab more than the code in the previous path.
So, based on our code from the previous section, there are two paths that require indentation:
  Lines 40 to 100
  Lines 70 and 80
10 #include  <stdio.h>
11
20 int  main()
30 {
40           int  i=0;
41
50           printf("Hello,  World!");
51
60           for  (i=0;i<1;i++){
70                           printf("\n");
80                           break;
90           }
91
100         return(0);
110 }
120
It is now fairly obvious as to which parts of the program fit inside which paths of code. You can tell which parts of the program will loop, and which ones will not. Although it might not be
immediately noticeable, once many nested loops and paths get added to the structure of the
program, the use of indentation can be very important.
NOTE: Many text editors automatically indent appropriately when you hit the enter/return key.
Comments
Comments in code can be useful for a variety of purposes. They provide the easiest way to point out specific parts of code (and their purpose); as well as providing a visual "split" between various parts of your code. Having a good commentary throughout your code will make it much easier to
remember what specific parts of your code do.
Comments in modern flavours of C (and many other languages) can come in two forms:
//Single  Line  Comments

and




/*Multi­Line
Comments*/

Note that Single line comments are only a very recent addition to C, and that some
compilers may not support them. A recent version of GCC will have no problems supporting
them.
This section is going to focus on the various uses of each form of commentary.

Single­line Comments
Single­line comments are most useful for simple 'side' notes that explain what certain parts of the code do. The best places to put these comments are next to variable declarations, and next to pieces of code that may need explanation.
Based on our previous program, there are two good places to place comments
  Line 40, to explain what 'int i' is going to do
  Line 80, to explain why there is a 'break' keyword.
This will make our program look something like

10      #include  <stdio.h>
11
20      int  main()
30      {
40            int  i=0;
41





//Temporary  variable  used  for  'for'  loop.

50           printf("Hello,  World!");

51

60           for  (i=0;i<1;i++){

70                 printf("\n");

80                 break;                              //Exits  'for'  loop.

90           }

91

100         return(0);

110   }

Multi­line Comments
Multi­line comments are most useful for long explanations of code. They can be used as
copyright/licensing notices, and they can also be used to explain the purpose of a path of code. This can be useful in two facets: They make your functions easier to understand, and they make it easier to spot errors in code (if you know what a path is supposed to do, then it is much easier to find the piece of code that is responsible).
As an example, suppose we had a program that was designed to print "Hello, World! " a certain
number of times, on a certain number of lines. There would be many for loops in this program. For this example, we shall call the number of lines i, and the number of strings per line as j.
A good example of a multi­line comment that describes 'for' loop i's purpose would be:
/*  For  Loop  (int  i)
Loops  the  following  procedure  i  times  (for  number  of  lines).    Performs  'for' loop  j  on  each  loop,
and  prints  a  new  line  at  end  of  each  loop.
*/

This provides a good explanation of what 'i's purpose is, whilst not going into detail of what 'j' does. By going into detail over what the specific path does (and not ones inside it), it will be easier to





troubleshoot the path.
Similarly, you should always include a multi­line comment as the first thing inside a function, to explain the name of the function; the input that it will take, how it takes that input; the output; and the overall procedure that the function is designed to perform. Always leave the technical details to the individual code paths inside your program ­ this makes it easier to troubleshoot.
A function descriptor should look something like:
/*  Function  :  int  hworld  (int  i,int  j)
Input         :  int  i  (Number  of  lines),  int  j  (Number  of  instances  per  line)
Output      :  0  (on  success)
Procedure:  Prints  "Hello,  World!"  j  times,  and  a  new  line  to  standard  output over  i  lines.
*/

This system allows for an at­a­glance explanation of what the function should do. You can then go into detail over how each aspect of the program is achieved later on in the program.
Finally, if you like to have aesthetically­pleasing source code, the multi­line comment system allows for the easy addition of starry borders to your comment. These make the comments stand out much more than they would without the border (especially buried deep in source code). They should take a format similar to:
/***************************************
*    This  is  a  multi  line  comment                *
*    That  is  surrounded  by  a                         *
*    Cool,  starry  border!                                   *
***************************************/


Applied to our original program, we can now include a much more descriptive and readable source
code:


10      #include  <stdio.h>
11
20      int  main()
30      {
31
/*******************************************************************************
*****
32        *  Function:  int  main()
*
33        *  Input        :  none
*
34        *  Output     :  Returns  0  on  success
*
35        *  Procedure:  Prints  "Hello,  World!"  and  a  new  line  to  standard  output  then
exits.       *
36
********************************************************************************
****/
40            int  i=0;                                   //Temporary  variable  used  for  'for'  loop.
41
50            printf("Hello,  World!");
51
52            /*  FOR  LOOP  (int  i)
53                  Prints  a  new  line  to  standard  output,  and  exits  */
60            for  (i=0;i<1;i++){
70                  printf("\n");
80                  break;                               //Exits  'for'  loop.





90            }
91
100         return(0);
110   }
This will allow any outside users of the program an easy way to understand what the code does, and how it works. It also prevents confusion with other like­named functions. 

0 comments: