用c ++编写的数据控制程序

gor*_*lon 5 c++ arrays dictionary list

不确定如何命名这个问题,因为问题本身正在寻找一个我不知道它的名字的结构.

问题是我正在处理控制流程主要取决于数据的程序.

例如,我创建了一个MIPS模拟器,它实现了一个包含50多个指令的列表,每个指令都是单独实现的,所有内容都由一个巨大的开关盒控制

switch (function){ //Function is an int, each function (eg SLL) is 
        case 0:    //associated with one
            if (state->debug_level > 0){
                fprintf(state->debug_out, "SLL\n");
            }
            step_err = SLL(state, rs, rt, rd, sa);
            break;
        case 2:
            if (state->debug_level > 0){
                fprintf(state->debug_out, "SRL\n");
            }
            step_err = SRL(state, rs, rt, rd, sa);
            break;
        case 3:
            if (state->debug_level > 0){
                fprintf(state->debug_out, "SRA\n");
            }
//
Run Code Online (Sandbox Code Playgroud)

我被告知这可以使用函数指针实现,但是这样做我正在寻找的是一种关联任何类型的数据的方式,比如说一个字符串与其他数据,比如一个整数.我知道地图,但不想推回每一对.我正在寻找某种类似数组的语法,我想如果之前看到它可能看起来像这样:

¿type? function_codes[]{
     0, "SLL";
     2, "SRL";
     3, "SRA";
     ...
 }
Run Code Online (Sandbox Code Playgroud)

我不是在寻找这个问题的解决方案,而是一种在数据之间引入快速关系并使用它来修改控制流的通用方法.

在答案后编辑 我实际上在寻找什么,但我不知道确实是地图,但特别是它的初始化语法类似于数组(参见接受的答案).这与函数指针一起使用完成了所需的工作.

Edw*_*ard 4

正如您所猜测的,函数指针实际上是实现此目的的好方法。由于您指定不想使用 Map,因此这就是使用函数指针数组实现基于整数的函数分派的方式。请注意,由于我不知道 MIPS 函数(SLL、SRL 等)的类型签名,因此我使用了虚拟占位符类型名称。

typedef ret_t (*mips_func)(arg1_t, arg2_t, arg3_t, arg4_t, arg5_t);

mips_func function_codes[] = {
    &SLL,
    &SRL,
    &SRA,
    ...
};

//...Later, in the part of your code that used to contain the big switch statement
step_err = (*function_codes[function])(state, rs, rt, rd, sa);
Run Code Online (Sandbox Code Playgroud)

该语法&SLL获取指向函数 SLL 的指针,我假设该函数已经在范围内,因为您可以直接从 switch 语句调用它。

请注意,这假设函数的数字代码是从 0 到 [最大代码值] 的连续整数序列。如果某些数字代码未使用,那么您需要在数组中留下显式间隙(通过在一个或多个条目中放置 NULL 指针)或使用,std::map<int, mips_func>以便您可以使用任意非连续整数值作为函数的键。幸运的是,使用 Map 仍然不需要push_back遍历每个元素,因为 C++ 现在具有初始值设定项列表。使用 Map 的相同代码如下所示:

typedef ret_t (*mips_func)(arg1_t, arg2_t, arg3_t, arg4_t, arg5_t);

std::map<int, mips_func> function_codes = {
    {0, &SLL},
    {2, &SRL},
    {4, &SRA},
    ...
};

//Using the Map looks exactly the same, due to its overloaded operator[]
step_err = (*function_codes[function])(state, rs, rt, rd, sa);
Run Code Online (Sandbox Code Playgroud)