Exercise 1 page 257 - CBD page 257 - Kurt Nørmark.

Solution index                   Textual C program


/* Programmed by Kurt Nørmark, March 2003 */

#include <stdio.h>

enum month {jan = 1, feb, mar, apr, may, jun, jul, 
           aug, sep, oct, nov, dec}; 
typedef enum month month;

month previous_month(month m){
  int result;
  if (m == 1)
     result = 12;
   else 
     result = m - 1;

  return (month)result;
}  

void prnt_month(month m){
  switch (m) {
    case jan: printf("January");
       break;
    case feb: printf("February");
       break;
    case mar: printf("March");
       break;
    case apr: printf("April");
       break;
    case may: printf("May");
       break;
    case jun: printf("June");
       break;
    case jul: printf("July");
       break;
    case aug: printf("August");
       break;
    case sep: printf("September");
       break;
    case oct: printf("October");
       break;
    case nov: printf("November");
       break;
    case dec: printf("December");
       break;
  }
}   

int main(void){
  
  month m;
  int i;
  
  for(m = dec, i = 1;  i <= 12; m = previous_month(m), i++){
    prnt_month(m); printf("\n");
  }
}    


enum month {jan = 1, feb, mar, apr, may, jun, jul, 
           aug, sep, oct, nov, dec}; 
typedef enum month month;
We use the type definitions recommended in the book. Thus, we define a new type enum month, and we make a convenient brief notation possible via the typedef. When we mention the type month in the program we refer to the enumeration type month.
 

month previous_month(month m){
  int result;
  if (m == 1)
     result = 12;
   else 
     result = m - 1;

  return (month)result;
}  
We chose an approach where we calculate the previous month, which is the month before another month. Alternatively, we could have used a large switch control structure, to represent kind of a table which maps a month to the previous month.

Instead of attempting some modulo calculation like m % 12 we make a solution where the special case, January, is handled separatly in an if control structure. For months other than January we just subtract one from the month. We use the fact that month values are integers. However, somewhat redundantly, we cast the final result to month. This is not necessary for the program to work. We could also consider to cast the input of the function, m, from month to int, but this is not necessary either, and it would clutter the program.

Please notice that we go for a single return from our functions. In general, this makes it easier to spot what is returned from a function.

 

void prnt_month(month m){
  switch (m) {
    case jan: printf("January");
       break;
    case feb: printf("February");
       break;
    case mar: printf("March");
       break;
    case apr: printf("April");
       break;
    case may: printf("May");
       break;
    case jun: printf("June");
       break;
    case jul: printf("July");
       break;
    case aug: printf("August");
       break;
    case sep: printf("September");
       break;
    case oct: printf("October");
       break;
    case nov: printf("November");
       break;
    case dec: printf("December");
       break;
  }
}   
We see the prnt_month function, which actually prints the full month name of the parameter m. It would have been attractive to use the symbolic enumerator names in the source program, but we cannot get access to these in the running program - unfortunately. Therefore we end up with some tedious programming of 12 cases in the switch. Recall from an earlier lecture that we use break in each of the cases in the switch constrol structure.

Instead of a void function (procedure) that prints the month name it might actually be more convenient to have function that returns the 'print name'. Such a function would return a string, which in C is the type char* (pointer to char).
 

int main(void){
  
  month m;
  int i;
  
  for(m = dec, i = 1;  i <= 12; m = previous_month(m), i++){
    prnt_month(m); printf("\n");
  }
}    
In the main program we are asked to make a table of the month. In my program I print the months in reverse order, in order to illustrate a possible (but not very good) use the function previous_month. In order to terminate the for loop I introduce an integer counter i. You might consider a solution without using i. The program prints the following output:
December
November
October
September
August
July
June
May
April
March
February
January
 


Generated: Wednesday, March 29, 2006, 12:33:29
This program dissection page is generated from an XML-in-LAML source file