Please send all questions & assignments to:
dsolarek@eng.utoledo.edu

 

C
Introduction and Overview

Flow Control

A program consists of a number of statements which are usually executed in normal top-to-bottom order. Programs can be much more powerful if we control the order in which statements are execute. This section will discuss the use of control statements in C that allow you to:
  • select between optional sections of a program
  • repeat sections of the program

The if statement

The if statement has the same function as in other programming languages. It has three basic forms. The first form, shown below, is sometimes called the "guarded if" because the condition "guards" the statement which it proceeds ... selectively controlling its execution. The basic syntax for the guarded if is:
 if (expression)
   statement
An example of how this form might be used is illustrated below:
 if (temperature < 0)
   print("Frozen\n");
The seconf form of the if statement is the tradational if-then-else structure. The syntax for the if-then-else form is:
 if (expression)
   statement1
 else
   statement2
The following example shows how this form might appear in a practical program:
 if (result >= 45)
   printf("Pass\n");
 else
   printf("Fail\n");
For more than a single statement, use the curly brackets ( { } ) to block statements:
 if (result >= 45)
 {
   printf("Passed\n");
   printf("Congratulations\n")
 }
 else
 {
   printf("Failed\n");
   printf("Good luck in the resits\n");
 }
The third form of the if statement is the if-then-else-if-else form. The syntax of this form is:
 if (expression)
   statement1
 else if (expression)
   statement2
 else
   statement3
An example of the if-then-else-if-else form is illustrated below:
 if (result >= 75)
   printf("Passed: Grade A\n");
 else if (result >= 60)
   printf("Passed: Grade B\n");
 else if (result >= 45)
   printf("Passed: Grade C\n");
 else
   printf("Failed\n");
Care must be taken to assure that these "nested" if statements select the appropriate alternative.

The switch Statement

This is another form of the multi way decision. It is well structured, but can only be used in certain cases where;
  • Only one variable is tested, all branches must depend on the value of that variable. The variable must be an integral type. (int, long, short or char).
  • Each possible value of the variable can control a single branch. A final, catch all, default branch may optionally be used to trap all unspecified cases.
Here is an example. This is a function which converts an integer into a vague description. It is useful where we are only concerned in measuring a quantity when it is quite small.
estimate(number)
int number;
/* Estimate a number as none, one, two, several, many */
{
  switch(number)
  {
    case 0 :
      printf("None\n");
      break;
    case 1 :
      printf("One\n");
      break;
    case 2 :
      printf("Two\n");
      break;
    case 3 :
    case 4 :
    case 5 :
      printf("Several\n");
      break;
    default :
      printf("Many\n");
      break;
  }
}

Loops

C gives you a choice of three types of loops, while, do while and for.
  • The while loop keeps repeating an action until an associated test returns false. This is useful where the programmer does not know in advance how many times the loop will be traversed.
  • The do while loops is similar, but the test occurs after the loop body is executed. This ensures that the loop body is run at least once.
  • The for loop is frequently used, usually where the loop will be traversed a fixed number of times. It is very flexible, and novice programmers should take care not to abuse the power it offers

The while Loop

The basic looping mechanism in C is the while loop. The while loop repeats a statement until the test at the top proves false.

The general form of the while loop is shown below:

 while (expression)
 {
   statements
 }
Its meaning of this syntax is:
  • evaluate the expression
  • if its value is true (i.e., not zero) do the statement, and repeat
Because the expression is tested before the statement is executed, the statement part can be executed zero times, which is often desirable.

Here is an example of the while loop:

 /* This is an example of a "while" loop */

 void main()
 {
 int count;
   count = 0;
   while (count < 6) {
      printf("The value of count is %d\n", count);
      count = count + 1;
   }
 }

The do-while Loop

The general form of the do-while loop is shown below:
 do 
 { 
   statement(s)
 } 
 while (conditional statement ); 
Repeats the section inside the braces while the condition at the bottom is satisfied.
 printf("Type in the grid coordinates.\n");
 printf("(-1 to end)\n");
 do
 {
   gets(line);
   sscanf("%d %d",&easting,&northing);
 }
 while (easting != -1); 
The do-while loop should be used when
  • a loop counter is not needed
  • the code within the loop must be executed at least once regardless of the condition
 /* This is an example of a do-while loop */

 void main()
 {
 int i;
   i = 0;
   do {
      printf("The value of i is now %d\n", i);
      i = i + 1;
   } while (i < 5);
 }

The for Loop

The basic form of the for loop is shown below:
 for (initialise; conditional expression; action) 
 { 
   statement  
 } 
The section between the braces (which should be indented) is repeated several times depending on the three elements of the for loop. For Example:
 for(count=0; count<16; count++)
 {
   printf("%d ",count);
 }
Example:
 /* This is an example of a for loop */

 void main()
 {
   int index;
   for(index=0; index<6; index=index+1)
     printf("The value of the index is %d\n", index);
 }
Here is a program to calculate the factorial of a number (6 in this example):
 /* Program to find factorial of 6 */ 
 #include   
 #define VALUE 6  
 int i,j;
 void main()  
 {
   j=1;
   for (i=1; i<=VALUE; i++)      
     j=j*i;
   printf("The factorial of %d is %d\n",VALUE,j);
 } 
The following programs fills an array with randum numbers and then sorts them into numeric order.
 #include   
 #define MAX 10  
 int a[MAX]; 
 int rand_seed=10;  
 int rand() /* returns random number between 0 and 32767.*/
 { 
   rand_seed = rand_seed * 1103515245 +12345;    
   return (unsigned int)(rand_seed / 65536) % 32768;
 }
 void main()
 {    
   int i,t,x,y;
   /* fill array */
   for (i=0; i a[y+1])        
        {  
          t=a[y];  
          a[y]=a[y+1];  
          a[y+1]=t;        
        } 
   /* print sorted array */    
   printf("--------------------\n");    
   for (i=0; i < MAX; i++)      
     printf("%d\n",a[i]); 
 }

break and continue statements

The following two statements are used in loop control.
  • break exits the innermost current loop
  • continue starts the next iteration of the loop
Use of the break statement provides an early exit from a while or for loop. For example:
 while (i<N)
 {
   if (a[i]==0) break;
   sum += a[i];
 }
The continue statement is similar to break but is encountered less frequently. It only works within loops where its effect is to force an immediate jump to the loop control statement.
  • In a while loop, jump to the test statement
  • In a do while loop, jump to the test statement
  • In a for loop, jump to the test, and perform the iteration
Like a break, continue should be protected by an if statement.
 /*
  Program#ifcontinue.c
  A simple program to show the use of the continue statement
 */

 #include 
 main()
 {
   int x;
   for (x=0; x<=100; x++)
   {
     if (x%2) continue;
     printf("%d\n" , x);
   }
 }
Here is another example where we read in integer values and process them according to the following conditions. If the value we have read is negative, we wish to print an error message and abandon the loop. If the value read is great than 100, we wish to ignore it and continue to the next value in the data. If the value is zero, we wish to terminate the loop.
 while (scanf("%d", &value ) == 1 && value != 0)
 { 
   if (value < 0)
   {
     printf("Illegal value\n");
     break;
     /* Abandon the loop */
   }
   if (value > 100)
   {
     printf("Invalid value\n");
     continue;
     /* Skip to start loop again */
   }
   /* Process the value read,
      guaranteed between 1 and 100 */
      ...;
      ...;
 } /* end while value != 0 */

Functions

Statements are the basic building blocks for all C programs. However, in order to easily create even moderately complex programs, you need to use bigger blocks. In C, as in other programming languages, these bigger blocks are called functions.

Most languages let you create procedures or functions, or both. C allows only functions, although you can create procedures by making functions that return nothing. C functions can accept an unlimited number of parameters. As mentioned in the introduction, they cannot be nested. In general, C does not care in what order you put your functions in the program.

Functions have a basic structure. Their format is

 ret_dt  funct_name  (arguments, arguments)
 data_type_declarations_of_arguments;
 {
   function_body
 }
It is worth noting that a ret_dt (return data type)is assumed to be type int unless otherwise specified, thus the programs we have seen so far imply that main() returns an integer to the operating system.

ANSI C varies slightly in the way that functions are declared. Its format is

 ret_dt funct_name (dt variable_name, dt variable_name, .. )
 {
   function_body
 }
This permits type checking by utilizing function prototypes to inform the compiler of the type and number of parameters a function accepts. When calling a function, this information is used to perform type and parameter checking.

ANSI C also requires that the ret_dt for a function which does not return data must be type void. The default ret_dt is assumed to be integer unless otherwise specified, but must match that which the function declaration specifies.

A simple function is,

 void print_message( void )
 {
   printf("This is a module called print_message.\n");
 }
Note the function name is print_message. No arguments are accepted by the function, this is indicated by the keyword void in the accepted parameter section of the function declaration. The ret_dt is void, thus data is not returned by the function.

An ANSI C function prototype for print_message() is,

 void print_message( void );
Function prototypes are listed at the beginning of the source file.

The program below illustrates the use of a function to calculate the factorial of a number.

 #include <stdio.h>

 int fact(int i)
 {
   int j,k;
       j=1;
   for (k=2; k<=i; k++)
   {
     j=j*k;
   }
   return j;
 }

 int main()
 {
   printf("%d\n",fact(1));
   printf("%d\n",fact(2));
   printf("%d\n",fact(3));
   printf("%d\n",fact(4));
   printf("%d\n",fact(5));
   return 0;
 }
Create a file for this program on the class server, and name it fact1.c. If you compile and run this program, you should see:
 et105:~/c$ fact1
 1
 2
 6
 24
 120
 et105:~/c$
The above example is not the first function that we have encountered in C as the "main" program we have been using all along is technically a function, as is the "printf" function. The "printf" function is a library function that was supplied with your compiler.

For user-defined functions, it is considered good form to use function prototypes for all functions in your program. A prototype declares the function name, its parameters, and its return type to the rest of the program. To understand why function prototypes are useful, enter the following code into a file on the class server, compile and run it:

 #include <stdio.h>

 /* function prototype for add */
 int add (int,int);

 int main()
 {
   printf("%d\n",add(3,5));
   return 0;
 }

 int add(int i, int j)
 {
   return i+j;
 }
Or, for our factorial example:
 #include <stdio.h>

 /* function prototype for fact */
 int fact (int);

 int main()
 {
   printf("%d\n",fact(1));
   printf("%d\n",fact(2));
   printf("%d\n",fact(3));
   printf("%d\n",fact(4));
   printf("%d\n",fact(5));
   return 0;
 }

 int fact(int i)
 {
   int j,k;
       j=1;
   for (k=2; k<=i; k++)
   {
     j=j*k;
   }
   return j;
 }
Here is another example which uses several functions:
 #include <stdio.h>
 int sum; /* This is a global variable */

 int header();
 int square(int);
 int ending();

 int main()
 {
   int index;
   header();   /* This calls the function named header */
   for (index=1; index<=10; index++)
   {
     square(index); /* This calls the square function */
   }
   ending();        /* This calls the ending function */
   return 0;
 }

 int header()   /* This is the function named header */
 {
   sum = 0;   /* Initialize the variable "sum" */
   printf("This is the header for the square program:\n\n");
   return 0;
 }

 int square(int number)   /* This is the square function */
 {
   int numsq;
   numsq = number * number;  /* This produces the square */
   sum += numsq;
   printf("The square of %d is %d\n",number,numsq);
   return 0;
 }

 int ending()   /* This is the ending function */
 {
   printf("\nThe sum of the squares is %d\n",sum);
   return 0;
 }
The following shows the output generated when this program is executed:
 et105:~/c$ sumsq
 This is the header for the square program:

 The square of 1 is 1
 The square of 2 is 4
 The square of 3 is 9
 The square of 4 is 16
 The square of 5 is 25
 The square of 6 is 36
 The square of 7 is 49
 The square of 8 is 64
 The square of 9 is 81
 The square of 10 is 100

 The sum of the squares is 385
 et105:~/c$
    Click on the button at left to return to the calling page.

 

There have been visitors since 11/26/2003

Added to the Web: December 9, 1999.
Last updated: December 9, 1999.
Web page design by Dan Solarek.

http://cset.sp.utoledo.edu/cset4250/