In depth analysis of C transition table and transformation table

  • 2020-04-02 00:53:13
  • OfStack

Personal implementation examples:

#include <stdio.h>
#include <string.h>
#define M 4
int add(int a, int b);
int sub(int a, int b);
int mul(int a, int b);
int div(int a, int b);
int (*oper_func[])(int, int) = {
 add, sub, mul, div
};
char oper_sequence[M][10] = {
 "add", "sub", "mul", "div"
};
int main()
{
 char oper[10];
 int seq;
 int a,b;
 int result;
 int i;
 printf("Operator:");
 scanf("%s",oper);
 printf("a:");
 scanf("%d",&a);
 printf("b:");
 scanf("%d",&b);
 for(i=0; i<M; i++)
 {
  if(strncmp(oper_sequence[i], oper, 3) == 0)
   seq = i;
 }
 result = oper_func[seq](a, b);
 printf("result is %d/n", result);
 return 0;
}
int add(int a, int b)
{
 return a+b;
}
int sub(int a, int b)
{
 return a-b;
}
int mul(int a, int b)
{
 return a*b;
}
int div(int a, int b)
{
 return a/b;
}

< < C and pointer > > The original:
Jump table
The transition table is best explained by an example. The following code snippet is taken from a program that implements a pocket calculator. The rest of the program has read in two Numbers (op1 and op2) and an operator (oper). The following code tests the operators and finally decides which function to call.
The switch (oper)
{
  Case the ADD:     Result = add (op1, op2); Break;
  Case SUB:       Result = sub (op1, op2); Break;
  Case the MUL:       Result = the mul (op1, op2); Break;
  Case DIV:         Result = div (op1, op2); Break;
  .
}
For a fancy calculator with hundreds of operators, this switch statement would be very long. Why call a function to perform these operations? It is a good design to separate the specific operation from the code that selects the operation. More complex operations will certainly be implemented as independent functions, since their length may be very long. But even simple operations can have side effects, such as saving a constant value for later operations.
To use the switch statement, the code representing the operator must be an integer. If they are consecutive integers starting from zero, we can use the transform table to accomplish the same task. The transform table is an array of function Pointers.
Creating a transformation table requires two steps. First, declare and initialize an array of function Pointers. The only thing to take care of is to make sure that the prototypes of these functions appear before the declaration of the array.
Double the add (double, double);
Double sub (double, double);
Double the mul (double, double);
Double div (double, double);
Double (* oper_func []) (double, double) = {the add, sub, the mul, div,... };
The correct order in which the function names in the list are initialized depends on the integer code used in the program to represent each operator. This example assumes that ADD is 0, SUB is 1, MUL is 2, and so on.
The second step is to replace the entire switch statement with the following statement!
Result = oper_func [oper] (op1, op2);
Oper selects the correct function pointer from the array, which is executed by the function call operator.

Related articles: