C: Interpretation of the array of function pointers and driver tables

Source: Internet
Author: User

Previous section.

First, let's take a look at the example of using this function pointer array.


[Cpp] # include <stdio. h>
# Include <stdlib. h>
 
 
Int Sum (int a, int B)
{
Return a + B;
}
 
Int Sub (int a, int B)
{
Return a-B;
}
 
Typedef int (* pfFun) (int, int );
 
Int TestFun (int a, int B, pfFun pf)
{
Int I = 0;
I = pf (a, B );
Return I;
}
 
Int main (int argc, char * argv [])
{
Int iTmp = 0;

PfFun pf [] = {Sum, Sub};/* defines and a function pointer array, which contains two elements and initializes it to Sum and Sub function address */

ITmp = TestFun (20, 10, pf [0]);
Printf ("Tmp is: % d \ n", iTmp );

ITmp = TestFun (20, 10, pf [1]);
Printf ("Tmp is: % d \ n", iTmp );

System ("PAUSE ");

Return 0;
}
# Include <stdio. h>
# Include <stdlib. h>


Int Sum (int a, int B)
{
Return a + B;
}

Int Sub (int a, int B)
{
Return a-B;
}

Typedef int (* pfFun) (int, int );

Int TestFun (int a, int B, pfFun pf)
{
Int I = 0;
I = pf (a, B );
Return I;
}

Int main (int argc, char * argv [])
{
Int iTmp = 0;
 
PfFun pf [] = {Sum, Sub};/* defines and a function pointer array, which contains two elements and initializes it to Sum and Sub function address */
 
ITmp = TestFun (20, 10, pf [0]);
Printf ("Tmp is: % d \ n", iTmp );
 
ITmp = TestFun (20, 10, pf [1]);
Printf ("Tmp is: % d \ n", iTmp );
 
System ("PAUSE ");
 
Return 0;
}
Run:


[Plain]
Tmp is: 30
Tmp is: 10
Press any key to continue...
Tmp is: 30
Tmp is: 10
Press any key to continue...

With the above concept, let's take a look at the use of the driver table through another instance. The following small program should be written by almost every programmer, a program that does not consider the accuracy of addition, subtraction, multiplication, division, as follows:


[Cpp]
# Include <stdio. h>
# Include <stdlib. h>
 
/* Addition */
Int Sum (int a, int B)
{
Return a + B;
}
 
/* Subtraction */
Int Sub (int a, int B)
{
Return a-B;
}
 
/* Multiplication */
Int Multi (int a, int B)
{
Return a * B;
}
 
/* Division */
Int Division (int a, int B)
{
Return (B = 0 )? 0: (a/B );
}
 
/* Operation code */
Typedef enum _ ENOPCODE
{
OPCODE_ADD = 0,/* Add */
OPCODE_SUB,/* Minus */
OPCODE_MULTI,/* multiply */
OPCODE_DIVISION,/* Division */
OPCODE_BUTT
} EnOpCode;
 
/* Use the Switch-case statement */
Int GetOpResultBySwitch (int a, int B, enOpCode enOp)
{
Int iTmp = 0;

Switch (enOp)
{
Case OPCODE_ADD:
ITmp = Sum (a, B );
Break;

Case OPCODE_SUB:
ITmp = Sub (a, B );
Break;

Case OPCODE_MULTI:
ITmp = Multi (a, B );
Break;

Case OPCODE_DIVISION:
ITmp = Division (a, B );
Break;
Default:
ITmp =-1;
}

Return iTmp;
}
 
Int main (int argc, char * argv [])
{
Int iTmp = 0;
Int a = 10;
Int B = 30;
 
ITmp = GetOpResultBySwitch (a, B, OPCODE_ADD );
 
Printf ("Tmp is: % d \ n", iTmp );

System ("PAUSE ");
Return 0;
}
# Include <stdio. h>
# Include <stdlib. h>

/* Addition */
Int Sum (int a, int B)
{
Return a + B;
}

/* Subtraction */
Int Sub (int a, int B)
{
Return a-B;
}

/* Multiplication */
Int Multi (int a, int B)
{
Return a * B;
}

/* Division */
Int Division (int a, int B)
{
Return (B = 0 )? 0: (a/B );
}

/* Operation code */
Typedef enum _ ENOPCODE
{
OPCODE_ADD = 0,/* Add */
OPCODE_SUB,/* Minus */
OPCODE_MULTI,/* multiply */
OPCODE_DIVISION,/* Division */
OPCODE_BUTT
} EnOpCode;

/* Use the Switch-case statement */
Int GetOpResultBySwitch (int a, int B, enOpCode enOp)
{
Int iTmp = 0;

Switch (enOp)
{
Case OPCODE_ADD:
ITmp = Sum (a, B );
Break;

Case OPCODE_SUB:
ITmp = Sub (a, B );
Break;

Case OPCODE_MULTI:
ITmp = Multi (a, B );
Break;

Case OPCODE_DIVISION:
ITmp = Division (a, B );
Break;
Default:
ITmp =-1;
}

Return iTmp;
}

Int main (int argc, char * argv [])
{
Int iTmp = 0;
Int a = 10;
Int B = 30;

ITmp = GetOpResultBySwitch (a, B, OPCODE_ADD );

Printf ("Tmp is: % d \ n", iTmp );
 
System ("PAUSE ");
Return 0;
}
The program looks clear, but if you want to extend the function, you will find that you need to add more case statements. Remember that the maximum number of cases in ansi c is 256, for the moment, no matter what the value is, from the Code itself, the increasing number of cases makes the complexity of the circle constantly increasing, and the difficulty of program maintenance increases.

In this case, you can consider using the method of driving the table. Also, let's take a look at the implementation. Please pay attention to the GetOpResultByTable function.


[Cpp]
# Include <stdio. h>
# Include <stdlib. h>
 
/* Addition */
Int Sum (int a, int B)
{
Return a + B;
}
 
/* Subtraction */
Int Sub (int a, int B)
{
Return a-B;
}
 
/* Multiplication */
Int Multi (int a, int B)
{
Return a * B;
}
 
/* Division */
Int Division (int a, int B)
{
Return (B = 0 )? 0: (a/B );
}
 
/* Define the function pointer */
Typedef int (* pfFun) (int, int );
 
/* Operation code */
Typedef enum _ ENOPCODE
{
OPCODE_ADD = 0,/* Add */
OPCODE_SUB,/* Minus */
OPCODE_MULTI,/* multiply */
OPCODE_DIVISION,/* Division */
OPCODE_BUTT
} EnOpCode;
 
/* Use drive table computing */
Int GetOpResultByTable (int a, int B, enOpCode enOp)
{
If (OPCODE_BUTT = enOp)
{
Return-1;
}
PfFun pf [OPCODE_BUTT] = {Sum, Sub, Multi, Division };
Return pf [enOp] (a, B );

}
 
Int main (int argc, char * argv [])
{
Int iTmp = 0;
Int a = 10;
Int B = 30;
 
ITmp = GetOpResultByTable (a, B, OPCODE_ADD );
Printf ("Tmp is: % d \ n", iTmp );

System ("PAUSE ");
Return 0;
}
# Include <stdio. h>
# Include <stdlib. h>

/* Addition */
Int Sum (int a, int B)
{
Return a + B;
}

/* Subtraction */
Int Sub (int a, int B)
{
Return a-B;
}

/* Multiplication */
Int Multi (int a, int B)
{
Return a * B;
}

/* Division */
Int Division (int a, int B)
{
Return (B = 0 )? 0: (a/B );
}

/* Define the function pointer */
Typedef int (* pfFun) (int, int );

/* Operation code */
Typedef enum _ ENOPCODE
{
OPCODE_ADD = 0,/* Add */
OPCODE_SUB,/* Minus */
OPCODE_MULTI,/* multiply */
OPCODE_DIVISION,/* Division */
OPCODE_BUTT
} EnOpCode;

/* Use drive table computing */
Int GetOpResultByTable (int a, int B, enOpCode enOp)
{
If (OPCODE_BUTT = enOp)
{
Return-1;
}
PfFun pf [OPCODE_BUTT] = {Sum, Sub, Multi, Division };
Return pf [enOp] (a, B );

}

Int main (int argc, char * argv [])
{
Int iTmp = 0;
Int a = 10;
Int B = 30;

ITmp = GetOpResultByTable (a, B, OPCODE_ADD );
Printf ("Tmp is: % d \ n", iTmp );
 
System ("PAUSE ");
Return 0;
}
The implementation is quite simple. If other operations and other functions are added, only the pf array needs to be extended. The complexity of the program loop does not increase as the number of functions increases, which reduces the maintenance cost.

 


Appendix: Concept of circle complexity, from Baidu Encyclopedia: http://baike.baidu.com/view/3553594.htm


Circle complexity
Concept
The so-called circle complexity is a measure of the Code complexity. The Chinese name is the circle complexity. In the concept of software testing, the circle complexity is used to measure the complexity of a module's decision structure. The number is represented by the number of independent current paths, that is, the minimum number of paths required for testing to prevent errors reasonably. The large complexity indicates that the program code may be of low quality and difficult to test and maintain. Based on experience, the possible errors of the program are highly correlated with the complexity of the circle ".

 

Computing
The calculation method is simple. The formula is V (G) = e-n + 2. E indicates the number of edges in the control flow diagram and n indicates the number of nodes in the control flow diagram. In fact, there is a more intuitive way to calculate the complexity of the circle, because the complexity of the circle reflects the number of "judgment conditions", so the complexity of the circle is actually equal to the number of judgment nodes plus 1, that is, the number of regions in the control flow chart. The calculation formula is as follows: V (G) = number of regions = number of decision nodes + 1. H r0U & T # @-g o, J o114943 for multi-branch CASE structure or IF-ELSEIF-ELSE structure, pay special attention to the statistical determination of the number of nodes, it is required to count all the actual number of judgment nodes, that is, each ELSEIF statement and each CASE statement, should be regarded as a judgment node. It is easy to identify the nodes in the control flow diagram of the module. Therefore, when calculating the circle complexity V (G) for the control flow diagram of the program, it is best to use the first formula, that is, V (G) = e-n + 2. When the control flow diagram of the module is used, you can directly count and determine the number of nodes, which is simpler.

 

 

From Socrates Column

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.