Topic : C Lessons
Author : Christopher Sawtell
Page : << Previous 8  Next >>
Go to page :


to the language.

  enum spectrum { red, orange, yellow, green, blue, indigo, violet } colour;

   In this construct the first symbol is given the value of 0 and for each
   following symbol the value is incremented. It is however possible to assign
   specific values to the symbols like this:

  enum tub
  { anorexic = 65,
    slim = 70,
    normal = 80,
    fat = 95,
    obese = 135
    };


   Some compilers are bright enough to detect that it is an error if an
   attempt is made to assign a value to an enum variable which is not in
   the list of symbols, on the other hand many are not. Take care! In
   practice there is little difference between the enum language construct
   and a number of define statements except perhaps aesthetics. Here is
   another trivial program which demonstrates the use of enum and a
   pre-initialised array.

#include <stdio.h>

enum spectrum { red, orange, yellow, green, blue, indigo, violet } colour;

char *rainbow[] = { "red", "orange", "yellow", "green",
                    "blue", "indigo", "violet" };

main()
{
  for ( colour = red; colour <= violet; colour++ )
  {
    printf ( "%s ", rainbow[colour]);
    }
  printf ( "\n" );
  }


   The output of which is ( not surprisingly ):

red orange yellow green blue indigo violet

   One quite advanced use of initialised arrays and pointers is the jump or
   dispatch table. This is a efficient use of pointers and provides a very much
   better ( In my opinion ) method of controlling program flow than a maze
   of case or ( heaven forbid ) if ( ... ) goto statements.

   Please cut out this program, read and compile it.
   ------------------------------------------------------------------------

char *ident = "@(#) tellme.c - An example of using a pointer to a function.";

#include <stdio.h>
#include <math.h>
#include <sys/errno.h>


/*
These declarations are not in fact needed as they are all declared extern in
math.h. However if you were to use routines which are not in a library and
therefore not declared in a '.h' file you should declare them. Remember you
MUST declare external routines which return a type other than the int type.

extern double  sin ();
extern double  cos ();
extern double  tan ();
extern double atof ();
*/

struct table_entry
{
  char *name;                        /* The address of the character string. */
  double (*function)();   /* The address of the entry point of the function. */
  };

typedef struct table_entry TABLE;

double help ( tp )
TABLE *tp;
{ printf ( "Choose one of these functions:- " );
  fflush ( stdout );
  for ( ; tp -> name; tp++ ) printf ( "%s ", tp -> name );
  printf ( "\nRemember the input is expressed in Radians\n" );
  exit ( 0 );
  return ( 0.0 );  /* Needed to keep some nit-picking dumb compilers happy! */
  }

/*
* This is the array of pointers to the strings and function entry points.
* Is is initialised at linking time. You may add as many functions as you
* like in here PROVIDED you declare them to be extern, either in some .h
* file or explicitly.
*/

TABLE interpretation_table [ ] =
{
  { "sin",  sin  },
  { "tan",  tan  },
  { "cos",  cos  },
  { "help", help },
  {  NULL,  NULL }               /* To flag the end of the table. */
  };

char *output_format = { "\n %s %s = %g\n" };
extern int errno;
extern void perror();

main( argc, argv )
int argc;
char **argv;
{
  TABLE *tp;
  double x, answer;

  if ( argc > 3 )
  {
    errno = E2BIG;
    perror ( "tellme" );
    exit ( -1 );
    }

  for (;;)                  /* This is the way to set up a continuous loop. */
  {
    for ( tp = interpretation_table;
          ( tp -> name && strcmp ( tp -> name, argv[1] ));
          tp++
    )  ;                      /* Note use of empty for loop to position tp. */

    if ( tp -> function == help ) (*tp -> function )( interpretation_table );
    if ( tp -> name == NULL )
    {
      printf ( "Function %s not implemented yet\n", argv[1] );
      exit ( 1 );
      }
    break;                     /* Leave the loop. */
    }

  x = atof ( argv[2] );        /* Convert the character string to a double. */
  answer = ( *tp -> function )( x );/* Execute the desired function.        */
  printf ( output_format,      /* Pointer to printf()'s format string.      */
           argv[1],            /* Pointer to the name of the function.      */
           argv[2],            /* Pointer to the input number ascii string. */
           answer              /* Value ( in double floating point binary ) */
           );
  }



Lesson 4.

The operators of the language.

        I have mentioned that 'C' is a small language with most of the heavy
work
being done by explicit calls to library functions. There is however a rich
mix of intrinsic operators which allow you to perform bit level operations,
use pointers, and perform immediate operations on varables. In other words,
most of a machine's instruction set is able to be used in the object program.
At the time when 'C' was designed and first written these were unique for
a high level language.

  Lets start with a discussion about precedence.

        This really means that the compiler puts invisable parentheses into
your expression. Casting your mind back to Arithmetic in the primary school
I expect you remember the nmemonic "My Dear Aunt Sally". The 'C' language
does as well! So the following expression is correct

        15 + 4 * 11 = 59

        The compiler has rendered the expression as:

        15 + ( 4 * 11 ) = 59

        Now the 'C' language has a much larger collection of operators than
just
Multiply Divide Add Subtract, in fact much too big to try to remember the
precedence of all of them. So my recomendation is to ALWAYS put in the
parentheses, except for simple arithmetic. However, for the sake of
completeness as much as anything else, here is the list.

        First up come what are called the primary-expression operators:

                ()    Function.
                []    Array.
                .     struct member ( variable ).
                ->    struct member ( pointer ).

         The unary operators:

        

Page : << Previous 8  Next >>