Sunday, October 30, 2011

One Dicey Issue of Loop Control Structure in C programing

Consider the following function calls:

#include <conio.h>
clrscr ( ) ;
gotoxy ( 10, 20 ) ;
ch = getch ( a ) ;

Here we are calling three standard library functions. Whenever we call the library functions we must write their prototype before making the call. This helps the compiler in checking whether the values being passed and returned are as per the prototype declaration. But since we don’t define the library functions (we merely call them) we may not know the prototypes of library functions. Hence when the library of functions is provided a set of ‘.h’ files is also provided. These files contain the prototypes of library functions. But why multiple files? Because the library functions are divided into different groups and one file is provided for each group. For example, prototypes of all input/output functions are provided in the file ‘stdio.h’, prototypes of all mathematical functions are provided in the file ‘math.h’, etc.
On compilation of the above code the compiler reports all errors due to the mismatch between parameters in function call and their corresponding prototypes declared in the file ‘conio.h’. You can even open this file and look at the prototypes. They would appear as shown below:

void clrscr( ) ;
void gotoxy ( int, int ) ;
int getch( ) ;

Now consider the following function calls:

#include <stdio.h>
int i = 10, j = 20 ;
printf ( "%d %d %d ", i, j ) ;
printf ( "%d", i, j ) ;

The above functions get successfully compiled even though there is a mismatch in the format specifiers and the variables in the list. This is because printf( ) accepts variable number of arguments (sometimes 2 arguments, sometimes 3 arguments, etc.), and even with the mismatch above the call still matches with the prototype of printf( ) present in ‘stdio.h’. At run-time when the first printf( ) is executed, since there is no variable matching with the last specifier %d, a garbage integer gets printed. Similarly, in the second printf( ) since the format specifier for j has not been mentioned its value does not get printed.

Calling Convention of C programing Loop Control Structure

Calling convention indicates the order in which arguments are passed to a function when a function call is encountered. There are two possibilities here:
 
(a) Arguments might be passed from left to right.
(b)Arguments might be passed from right to left.
C language follows the second order.
Consider the following function call:
fun (a, b, c, d ) ;

In this call it doesn’t matter whether the arguments are passed from left to right or from right to left. However, in some function call the order of passing arguments becomes an important consideration. For example:
int a = 1 ;
printf ( "%d %d %d", a, ++a, a++ ) ;
It appears that this printf( ) would output 1 2 3.
This however is not the case. Surprisingly, it outputs 3 3 1. This is because C’s calling convention is from right to left. That is, firstly

1 is passed through the expression a++ and then a is incremented to 2. Then result of ++a is passed. That is, a is incremented to 3 and then passed. Finally, latest value of a, i.e. 3, is passed. Thus in right to left order 1, 3, 3 get passed. Once printf( ) collects them it prints them in the order in which we have asked it to get them printed (and not the order in which they were passed). Thus 3 3 1 gets printed.

Scope Rule of Functions of C programing Loop Control Structure

Look at the following program
main( )
{
int i = 20 ;
display ( i ) ;
}
display ( int j )
{
int k = 35 ;
printf ( "\n%d", j ) ;
printf ( "\n%d", k ) ;
}
of i is known only to the function main( ) and not to any other function. Similarly, the variable k is local to the function display( ) and hence it is not available to main( ). That is why to make the value of i available to display( ) we have to explicitly pass it to display( ). Likewise, if we want k to be available to main( ) we will have to return it to main( ) using the return statement. In general we can say that the scope of a variable is local to the function in which it is defined.
In this program is it necessary to pass the value of the variable i to the function display( )? Will it not become automatically available to the function display( )? No. Because by default the scope of a variable is local to the function in which it is defined. The presence

Passing Values between Functions in C programing Loop Control Structure

The functions that we have used so far haven’t been very flexible. We call them and they do what they are designed to do. Like our mechanic who always services the motorbike in exactly the same way, we haven’t been able to influence the functions in the way they carry out their tasks. It would be nice to have a little more control over what functions do, in the same way it would be nice to be able to tell the mechanic, “Also change the engine oil, I am going for an outing”. In short, now we want to communicate between the ‘calling’ and the ‘called’ functions.
The mechanism used to convey information to the function is the ‘argument’. You have unknowingly used the arguments in the printf( ) and scanf( ) functions; the format string and the list of variables used inside the parentheses in these functions are arguments. The arguments are sometimes also called ‘parameters’.
Consider the following program. In this program, in main( ) we receive the values of a, b and c through the keyboard and then output the sum of a, b and c. However, the calculation of sum is done in a different function called calsum( ). If sum is to be calculated in calsum( ) and values of a, b and c are received in main( ), then we must pass on these values to calsum( ), and once calsum( ) calculates the sum we must return it from calsum( ) back to main( ).

/* Sending and receiving values between functions */
main( )
{
int a, b, c, sum ;
printf ( "\nEnter any three numbers " ) ;
scanf ( "%d %d %d", &a, &b, &c ) ;
sum = calsum ( a, b, c ) ;
printf ( "\nSum = %d", sum ) ;
}
calsum ( x, y, z )
int x, y, z ;
{
int d ;
d = x + y + z ;
return ( d ) ;
}

And here is the output...
Enter any three numbers 10 20 30
Sum = 60
There are a number of things to note about this program:

(a) In this program, from the function main( ) the values of a, b and c are passed on to the function calsum( ), by making a call to the function calsum( ) and mentioning a, b and c in the parentheses:
sum = calsum ( a, b, c ) ;
In the calsum( ) function these values get collected in three variables x, y and z:
calsum ( x, y, z )
int x, y, z ;

(b) The variables a, b and c are called ‘actual arguments’, whereas the variables x, y and z are called ‘formal arguments’. Any number of arguments can be passed to a function being called. However, the type, order and number of the actual and formal arguments must always be same
Instead of using different variable names x, y and z, we could have used the same variable names a, b and c. But the compiler would still treat them as different variables since they are in different functions.

(c) There are two methods of declaring the formal arguments. The one that we have used in our program is known as Kernighan and Ritchie (or just K & R) method.
calsum ( x, y, z )
int x, y, z ;
Another method is,
calsum ( int x, int y, int z )
This method is called ANSI method and is more commonly used these days.

(d) In the earlier programs the moment closing brace ( } ) of the called function was encountered the control returned to the calling function. No separate return statement was necessary to send back the control.
This approach is fine if the called function is not going to return any meaningful value to the calling function. In the above program, however, we want to return the sum of x, y and z. Therefore, it is necessary to use the return statement.
The return statement serves two purposes:
(1) On executing the return statement it immediately transfers the control back to the calling program.
(2) It returns the value present in the parentheses after return, to th3e calling program. In the above program the value of sum of three numbers is being returned

(e) There is no restriction on the number of return statements that may be present in a function. Also, the return statement need not always be present at the end of the called function. The following program illustrates these facts.
fun( )
{
char ch ;
printf ( "\nEnter any alphabet " ) ;
scanf ( "%c", &ch ) ;
if ( ch >= 65 && ch <= 90 )
return ( ch ) ;
else
return ( ch + 32 ) ;
}
In this function different return statements will be executed depending on whether ch is capital or not.

(f) Whenever the control returns from a function some value is definitely returned. If a meaningful value is returned then it should be accepted in the calling program by equating the called function to some variable. For example,
sum = calsum ( a, b, c ) ;

(g) All the following are valid return statements.
return ( a ) ;
return ( 23 ) ;
return ( 12.34 ) ;
return ;
In the last statement a garbage value is returned to the calling function since we are not returning any specific value. Note that in this case the parentheses after return are dropped.

(h) If we want that a called function should not return any value, in that case, we must mention so by using the keyword void as shown below.
void display( )
{
printf ( "\nHeads I win..." ) ;
printf ( "\nTails you lose" ) ;
}

(i) A function can return only one value at a time. Thus, the following statements are invalid.
return ( a, b ) ;
return ( x, 12 ) ;
There is a way to get around this limitation, which would be discussed later in this chapter when we learn pointers.

(j) If the value of a formal argument is changed in the called function, the corresponding change does not take place in the calling function. For example,
main( )
{
int a = 30 ;
fun ( a ) ;
printf ( "\n%d", a ) ;
}
fun ( int b )
{
b = 60 ;
printf ( "\n%d", b ) ;
}
The output of the above program would be:
60
30
Thus, even though the value of b is changed in fun( ), the value of a in main( ) remains unchanged. This means that when values are passed to a called function the values present in actual arguments are not physically moved to the formal arguments; just a photocopy of values in actual argument is made into formal arguments

Why Use Functions ? in C programing Loop Control Structure

Why write separate functions at all? Why not squeeze the entire logic into one function, main( )? Two reasons:

(a)  Writing functions avoids rewriting the same code over and over. Suppose you have a section of code in your program that calculates area of a triangle. If later in the program you want to calculate the area of a different triangle, you won’t like it if you are required to write the same instructions all over again. Instead, you would prefer to jump to a ‘section of code’ that calculates area and then jump back to the place from where you left off. This section of code is nothing but a function.

(b)  Using functions it becomes easier to write programs and keep track of what they are doing. If the operation of a program can be divided into separate activities, and each activity placed in a different function, then each could be written and checked more or less independently. Separating the code into modular functions also makes the program easier to design and understand.

What is the moral of the story? Don’t try to cram the entire logic in one function. It is a very bad style of programming. Instead, break a program into small units and write functions for each of these isolated subdivisions. Don’t hesitate to write functions that are called only once. What is important is that these functions perform some logically isolated task.

What is a Function of : C programing The Loop Control Structure

A function is a self-contained block of statements that perform a coherent task of some kind. Every C program can be thought of as a collection of these functions. As we noted earlier, using a function is something like hiring a person to do a specific job for you. Sometimes the interaction with this person is very simple;
sometimes it’s complex.

Suppose you have a task that is always performed exactly in the same way—say a bimonthly servicing of your motorbike. When you want it to be done, you go to the service station and say, “It’stime, do it now”. You don’t need to give instructions, because the mechanic knows his job. You don’t need to be told when the job is done. You assume the bike would be serviced in the usual way, the mechanic does it and that’s that.
Let us now look at a simple C function that operates in much the same way as the mechanic. Actually, we will be looking at two things—a function that calls or activates the function and the function itself.
main( )
{
      message( ) ;
      printf ( "\nCry, and you stop the monotony!" ) ;
}
message( )
{
      printf ( "\nSmile, and the world smiles with you..." ) ;
}

And here’s the output...

Smile, and the world smiles with you...
Cry, and you stop the monotony!

Here, main( ) itself is a function and through it we are calling the function message( ). What do we mean when we say that main( ) ‘calls’ the function message( )? We mean that the control passes to the function message( ). The activity of main( ) is temporarily suspended; it falls asleep while the message( ) function wakes up and goes to work. When the message( ) function runs out of statements to execute, the control returns to main( ), which comes to life again and begins executing its code at the exact point where it left off. Thus, main( ) becomes the ‘calling’ function, whereas

main( )
{
      message( ) ;
      printf ( "\nCry, and you stop the monotony!" ) ;
}
message( )
{
      printf ( "\nSmile, and the world smiles with you..." ) ;
}

And here’s the output...

Smile, and the world smiles with you...
Cry, and you stop the monotony!

Here, main( ) itself is a function and through it we are calling the function message( ). What do we mean when we say that main( ) ‘calls’ the function message( )? We mean that the control passes to the function message( ). The activity of main( ) is temporarily suspended; it falls asleep while the message( ) function wakes up and goes to work. When the message( ) function runs out of statements to execute, the control returns to main( ), which comes to life again and begins executing its code at the exact point where it left off. Thus, main( ) becomes the ‘calling’ function, whereasmessage( ) becomes the ‘called’ function
.
If you have grasped the concept of ‘calling a function you are prepared for a call to more than one function. Consider the following example:

main( )
{
      printf ( "\nI am in main" ) ;
      italy( ) ;
      brazil( ) ;
      argentina( ) ;


becomes the ‘called’ function.
If you have grasped the concept of ‘calling’ a function you are prepared for a call to more than one function. Consider the following example:

main( )
{
      printf ( "\nI am in main" ) ;
      italy( ) ;
      brazil( ) ;
      argentina( ) ; 
}
italy( ) 
{
      printf ( "\nI am in italy" ) ;

}
brazil( ) 
{
      printf ( "\nI am in brazil" ) ; 
}
argentina( ) 
{
      printf ( "\nI am in argentina" ) ;
}

The output of the above program when executed would be as
under:

I am in main
I am in italy 
I am in brazil 
I am in argentina 

From this program a number of conclusions can be drawn:

−  Any C program contains at least one function.

−  If a program contains only one function, it must be main( ).

−  If a C program contains more than one function, then one (and only one) of these functions must be
main( ), because program execution always begins with main( ).

−  There is no limit on the number of functions that might be present in a C program.

−  Each function in a program is called in the sequence specified by the function calls in main( )

−  After each function has done its thing, control returns to main( ).When main( ) runs out of function calls, the program ends.

As we have noted earlier the program execution always begins with main( ). Except for this fact all C functions enjoy a state of perfect equality. No precedence, no priorities, nobody is nobody’s
boss. One function can call another function it has already called but has in the meantime left temporarily in order to call a third function which will sometime later call the function that has calledit, if you understand what I mean. No? Well, let’s illustrate with an example.

main( )
{
      printf ( "\nI am in main" ) ;
      italy( ) ;
      printf ( "\nI am finally back in main" ) ;
}
italy( ) 
{
      printf ( "\nI am in italy" ) ;
      brazil( ) ;
      printf ( "\nI am back in italy" ) ;
}
brazil( ) 
{
      printf ( "\nI am in brazil" ) ; 
      argentina( ) ;
}
argentina( ) 
{
      printf ( "\nI am in argentina" ) ;
}

And the output would look like..
I am in main
I am in italy 
I am in brazil 
I am in argentina 
I am back in italy 
I am finally back in main

Here, main( ) calls other functions, which in turn call still other functions. Trace carefully the way control passes from one function to another. Since the compiler always begins the program
execution with main( ), every function in a program must be called directly or indirectly by main( ). In other words, the main( ) function drives other functions. Let us now summarize what we have learnt so far.

(a)  C program is a collection of one or more functions.

(b)  A function gets called when the function name is followed by a semicolon. For example,

 main( )
{
     argentina( ) ;
}

(c)  A function is defined when function name is followed by a pair of braces in which one or more statements may be present. For example,

 argentina( )

 statement 1 ;
 statement 2 ;
 statement 3 ;

(d)  Any function can be called from any other function. Even main( ) can be called from other functions. For example,

 main( )
{
     message( ) ;
}
message( )
{
     printf ( "\nCan't imagine life without C" ) ;
     main( ) ; 

}

(e)  A function can be called any number of times. For example,

 main( ) 
{
     message( ) ;
     message( ) ;
}
message( )
{
     printf ( "\nJewel Thief!!" ) ;
}

(f)  The order in which the functions are defined in a program and the order in which they get called need not necessarily be same. For example,

 main( )
{
     message1( ) ;
     message2( ) ;
}
message2( )
{
     printf ( "\nBut the butter was bitter" ) ;
}
message1( )
{
     printf ( "\nMary bought some butter" ) ;
}

 Here, even though message1( ) is getting called before message2( ), still, message1( ) has been defined after message2( ). However, it is advisable to define the functions in the same order in which they are called. This makes the program easier to understand.

(g)  A function can call itself. Such a process is called ‘recursion’. We would discuss this aspect of C functions later in this chapter. 

(h)  A function can be called from other function, but a function cannot be defined in another function. Thus, the following program code would be wrong, since argentina( ) is being defined inside another function, main( ).

main( )
{
     printf ( "\nI am in main" ) ;
 argentina( )
 {
           printf ( "\nI am in argentina" ) ;
 }
}

(i)  There are basically two types of functions:

 Library functions Ex. printf( ), scanf( ) etc. User-defined functions Ex. argentina( ), brazil( ) etc.

 As the name suggests, library functions are nothing but commonly required functions grouped together and stored in what is called a Library. This library of functions is present on the disk and is written for us by people who write compilers for us. Almost always a compiler comes with a library of standard functions. The procedure of calling both types of functions is exactly same.

C programing The Loop Control Structure Summary:

(a)  When we need to choose one among number of alternatives, a switch statement is used.
(b)  The  switch  keyword is followed by an integer or an expression that evaluates to an integer.  
(c)  The  case  keyword is followed by an integer or a character constant. 
(d)  The control falls through all the cases unless the break statement is given.
(e)  The usage of the goto keyword should be avoided as it usually violets the normal flow of execution.