我正在编写一个程序,用户可以在开始时设置选项标志。
我的问题是我想根据用户标记调用不同版本的函数,每次我选择调用哪个版本时我都不想做if(flag)
因为我会必须检查我处理的每一行的if()
语句。
这是一个学校项目,所以我试图找到最有效的方法来确定我想要调用哪个函数, and I read
if()`语句很昂贵here。
所以有一种方法可以在开头说明
if(flag)
// use this function the rest of the program
else
// use this other function for the rest of the program
答案 0 :(得分:5)
所以如果有一种方法可以在开始时基本上说if(flag)使用这个函数,那么程序的其余部分就会使用另一个函数来完成程序的其余部分
只需执行以下操作:
void func1() {
// ...
}
void func2() {
// ...
}
int main(int argc, char* argv[]) {
std::function<void()> func;
// Make your decision once:
if(std::string(argv[1]) == "func1") {
func = func1;
}
else if(std::string(argv[1]) == "func2") {
func = func2;
}
// Call func many times
func();
// ...
}
答案 1 :(得分:1)
您可以使用以下函数指针的旧样式数组:
#include <stdio.h>
int sum(int a, int b);
int subtract(int a, int b);
int mul(int a, int b);
int div(int a, int b);
int (*p[4]) (int x, int y);
typedef enum{
SUM=0,
SUB,
MUL,
DIV
}FLAG;
int main(void)
{
int result;
int i, j, op;
p[SUM] = sum; /* address of sum() */
p[SUB] = subtract; /* address of subtract() */
p[MUL] = mul; /* address of mul() */
p[DIV] = div; /* address of div() */
printf("Enter two numbers: ");
scanf("%d %d", &i, &j);
printf("0: Add, 1: Subtract, 2: Multiply, 3: Divide\n");
do {
printf("Enter number of operation: ");
scanf("%d", &op);
} while(op<0 || op>3);
result = (*p[op]) (i, j);
printf("%d", result);
return 0;
}
int sum(int a, int b)
{
return a + b;
}
int subtract(int a, int b)
{
return a - b;
}
int mul(int a, int b)
{
return a * b;
}
int div(int a, int b)
{
if(b)
return a / b;
else
return 0;
}
答案 2 :(得分:0)
执行此类操作的最佳方法是使用模板。您的问题可以被理解为类似于&#34;循环拉出&#34;问题:
void foo(vector v, bool b) {
for (auto e : v) {
// do stuff
if (b) // stuff
else // other stuff
// do more stuff
}
}
分支在循环期间没有变化,但我们一直在打它。令人惊讶地难以重写这一点,特别是如果在分支之前和之后有一堆代码。使用模板,我们可以使用这种方法:
template <bool b>
void foo(vector<double>& v) {
for (auto e : v) {
// do stuff
if (b) // stuff
else // other stuff
// do more stuff
}
}
void foo(vector<double>& v, bool b) {
if (b) foo<true>(v);
else foo<false>(v);
}
在编译器内部,编译器将生成两个版本的foo
,其中一个版本在编译时将bool硬编码为true,另一个版本在编译时硬编码为false。在每种情况下,编译器都可以完全消除分支。然后你只需在调用开始时调度到正确的函数,只分支一次。但是代码的结构完全相同;你只需添加几行代码就不会随着你的循环变得越来越大而增加。