Reviewing 'C' - Part 2

| Intro. | Part 0 | Part-1 | Part-2 | Part-3 | Part-4 | Part-5 |

A construct is an arrangement of key words that provide a behavior.  Loop and branch constructs are based on a logical result.  The while loop constructs repeat instructions in a code block, branch constructs select a code block to execute.

Looping Constructs

There are three loop constructs available to the 'C' programmer. 

First consider the while construct.  As illustrated earlier in the program intest.c, as long as the Boolean test expression is true, the corresponding block of code will repeatedly execute.  Each time the code block executes, is referred to as an iteration.  The following is the general outline of the while loop.  The LOGICAL_STATEMENT produces a single true/false result.  The block statements are executed for as long as the logical statement is true.
while( LOGICAL_STATEMENT )
{
  BLOCK_STATEMENTS;
}
The do-while construct is similar, but is guaranteed to perform at least one iteration.  In the following example the do-while loop tests for the initial condition, but produces non-trivial results.  The line numbers are not part of the program, the line numbers are only inserted for your reference.  Predict the final value of n when the loop exits.
00 /********************************
01  * dowhile.c - Your-name-here
02  * Just a simple demonstration
03  *******************************/
04 #include <stdio.h>
05 int main()
06 {
07   int i = 1, n = 0;
08
09   do {
10     n++; i <<= 1;
11     i &= 0x0F;
12   } while (i != 0);
13
14   printf("Final n = %d\n",n);
15   return 0;
16 }

The for loop construct is equivalent to a special case of the while loop. The for construct is shorthand for the following code outline. 

INIT;
while ( LOGIC ) 
{
  // lines of 'C' code
  BLOCK_STATEMENTS;
  ADVANCE;
}

The INIT statement initializes an index variable.  The LOGICAL statement produces a true or false result, if true the code block is executed.  One block statement somehow advances the index variable.  The following is the outline of the corresponding  for loop construct.

for( INIT; LOGICAL; ADVANCE ) 
{
  // lines of 'C' code
  BLOCK_STATEMENTS;
}

The following program uses a for loop construct to add the integers from 1 to 5.

00 /******************************
01  * sum5.c - Your-name-here
02  * Form sum from one to five
03  *****************************/
04 #include <stdio.h>
05 int main()
06 {
07   int i, sum;
08
09   sum = 0;
10   for (i = 1; i <= 5; i++)
11   {
12     sum += i;
13   }
14   printf("Sum equals %d\n",sum);
15
16   return 0;
17 }

The keyword continue is used in a loop construct to provide a mechanism to jump to the start of the next iteration.  The keyword break is used to immediately exit from a loop construct. 

If Type Constructs

The following outline describes one form of a conditional test.  If the TEST_EXPRESSION evaluates to true then the code in BLOCK1 is executed.  In handling such an expression, 'C' treats the value zero as false and any non-zero value as true.  An example of such a test expression is A > 0, which returns a non-zero value if A is larger than zero.

if (TEST_EXPRESSION)
{
  BLOCK1;
}

The keyword else is used to introduce a second block of code, executed if TEST_EXPRESSION evaluates to false.

if (TEST_EXPRESSION)
{
  BLOCK1;
}
else
{
  BLOCK2;
}

It is not unusual to follow the else keyword immediately with another test, such a construct is referred to as IF - ELSE IF - ELSE.  In such an arrangement the test expressions are examined in the order given.  Having the else keyword alone at the end ensures that one code block will be executed.

if (TEST_EXPRESSION_1)
{
  BLOCK1;
}
else if (TEST_EXPRESSION_2)
{
  BLOCK2;
}
else
{
  BLOCK3;
}

Prime Factors Example

The following example makes use of a number of topics discussed so far.  The line numbers are inserted only to help in our discussion.  To understand why the program produces only a list of prime factors, just work through an example on paper and see what happens.

00 /***************************************************
01  * primes.c - Jonathan Hill
02  * Produce prime factors of a positive number
03  **************************************************/
04 #include <stdlib.h>
05 #include <stdio.h>
06 int main()
07 {
08   int i, val;
09   printf("-- Prime Factor Producer --\n");
10   printf("Enter a positive integer value: ");
11   scanf("%d", &val);
12
13   // Test if the number is zero or negative
14   if (val <= 0) {
15     printf("%d is not a positive integer\n", val);
16     exit(0);
17   }
18
19   // One is infinitely divisible into all numbers
20   else if (val == 1) {
21     printf("1 is divisible by itself\n");
22     exit(0);
23   }
24
25   // Repeatedly divide out the divisible primes
26   for (i = 2; i <= val; i++) {
27     while (val % i == 0) {
28       printf("%d\n",i);
29       val /= i;
30     }
31   }
32   printf("Done!\n");
33   return 0;
34 }

Switch Construct

The type of if-else statement chain, where a variable is successively compared against different values in search of a match, is so commonly used that the switch construct is developed.  The general format is as follows.  The dots indicates where extra lines may be inserted.  The value in expression may be a variable or an expression that produces a simple value.

switch ( expression )
{
  case VALUE1:
    program-statements
    break;

  case VALUE2:
    program-statements
    break;

  · · ·

  case VALUEN:
    program-statements
    break;

  default:
    program-statements
    break;
}

If a case is found that matches the value of expression, the program statements that follow the case statement are executed.  The break statement signals the end of each case, exiting the switch construct.  A case not terminated with a break statement will lead to the case that follows it, thus both cases are executed.  Thus two cases can share one block of code.  If there is no match, code following the special optional case called default is executed.

RPN Calculator Example

The following examples uses a switch contruct, if-else constructs, simple input and output commands, and a bunch of the operators that we have discussed.  The program reads in a string of characters and uses the first character in the string in a switch construct.  The preprocessor directive define assigns the value 4 to the symbols MAXDEPTH.

00 /***************************************************************
01  * rpn1.c
02  * A simple RPN style calculator.  A given value is pushed onto
03  * the stack.  An operation removes two values and pushes the
04  * result.  'c' clears the stack and 'e' exits the program.
05  **************************************************************/
06 #include <stdio.h>
07 #include <stdlib.h>
08 #define  MAXDEPTH 4
09 int main()
10 {
11   double stack[MAXDEPTH];
12   int   ix, item = -1, done = 0;
13   char  buff[18];
14
15   printf("+ adds, - subtracts, e exits, c clears\n");
16   while(!done) {
17     scanf("%16s",buff);
18     switch(buff[0]) {
19
20     case 'e':  // exit command
21       done = 1;
22       break;
23
24     case 'c':  // clear command
25       item = -1;
26       break;
27
28     case '+':
29       printf("Add\n");
30       if (item > 0) {
31         stack[item - 1] = stack[item - 1] + stack[item];
32         item--; }
33       else {
34         printf("** Requires two items on the stack\n");}
35       break;
36 
37     case '-':
38       printf("Subtract\n");
39       if (item > 0) {
40         stack[item - 1] = stack[item - 1] - stack[item];
41         item--; }
42       else {
43         printf("** Requires two items on the stack\n");}
44       break;
45
46     default: // Push a value
47       if (item < MAXDEPTH - 1) {
48       stack[++item] = atof(buff); }
49       else {
50         printf("Stack Overflow\n");}
51       break;
52     } // end of switch
53
54     // display the stack
55     for (ix = item; ix >= 0; ix--) {
56       printf("%f\n", stack[ix]);
57     }
58     printf("--------\n");
59   }
60   return 0;
61 } 

The atof( ) is used to convert a number given in ASCII form, to double floating point number format. This program has two curious effects, first the input string is limited to 16 characters.  A number longer than 16 characters will be interpreted as two numbers. Second, an invalid entry may be interpreted as the value zero.

Conditional Evaluation

In 'C', logical expressions are evaluated only as far as necessary, to produce a result.  This property is exploited to condition the evaluation of an expression.  If the expression to the left of a logical-OR ( || ) is true, the right side is not evaluated and the result is true.  Conversely, if the expression to the left of a logical-AND ( && ) is false, the right side is not evaluated, and the result is false

flag && (valx = flag);

If flag is non-zero, its value is assigned to valx.

Homework Problems:

  1. Enter and compile the example dowhile.c.  For homework insert your name in the source code, produce the source code and the program results.  Provide a brief explanation why the numerical result is correct.

  2. Enter and compile the example sum5.c.  For homework insert your name in the source code, produce the source code and the program results.  Provide a brief explanation why the numerical result is correct.

  3. Consider the primes.c program listed above.  To illustrate how the program produces the list of prime factors for the decimal number 60, make a table with columns for the program line number, the value in i, and the value in val.  For the given line, the table lists values just before the line executes.  Start your table at program line 14 and use a pair of question marks to indicate values that are not known.

  4. Examine the program rpn1.c closely.  Write new cases for division '/' and multiplication '*'.  For homework submit a printout of the program, with the new cases inserted.


Please Let me know that you read my web pages.

This supplemental set of notes is written for the computer engineering students at the University of Hartford.  Copyright is reserved by the author, but copies of this document may be made for educational use as-is, provided that this statement remains attached.  The author welcomes corrections, comments, and constructive criticism. 
Original Author: Jonathan Hill jmhill@hartford.edu
Copyright Date: Sun Jan 26 14:50:06 EST 2003
Last revised: Mon Feb 26 01:06:07 EST 2007