跳转表¶
指针数组¶
- 是一个数组
- 数组的每个元素:指针
eg:
ps:数组指针:首先是一个指针,指针指向的是一个数组
函数指针¶
- 是一个指针
- 指向的是某个函数(即存储函数地址)
eg:
- 指针p指向函数参数列表为(int, int)的函数
- 函数返回值为int
函数指针数组¶
综上:
- 是一个数组
- 数组的每个元素存放的元素类型是函数地址(指向某个函数的指针)
- 每个元素指向的函数的参数列表都是(int, int)
- 每个元素指向的函数的返回值都是int
跳转表实现¶
- 使用switch:但代码过于冗余
- 定义一个函数指针数组,实现根据输入不同的参数调用某个特定的函数
C++不支持可变长数组,所以以下编码是不通过的:
example.cpp
#ifndef _EXAPLE_H_
#define _EXAPLE_H_
#include <inttypes.h>
#include <unordered_map>
#include <cstring>
#include <iostream>
using namespace std;
unordered_map<int, string> testmap = {
{1, "test1"},
{2, "test2"},
{3, "test3"}};
struct project
{
char *signame;
uint32_t sigval;
};
class solveTest
{
public:
solveTest() = default;
const uint32_t getIdx(const string str);
const string gettest(uint32_t idx, project *pro);
void getSolve(const string str);
// jump teble
void(*funcArr[])() = {test1,
test2,
test3};
private:
void test1() { cout << "this is test1." << endl; }
void test2() { cout << "this is test2." << endl; }
void test3() { cout << "this is test3." << endl; }
};
const uint32_t solveTest::getIdx(const string str)
{
if (!str.size() || str.size() != 5)
{
cout << "input string error." << endl;
return -1;
}
char *tmp = const_cast<char *>(str.c_str());
return tmp[4] - '0';
}
void solveTest::getSolve(const string str)
{
funcArr[getIdx(str)]();
}
const string solveTest::gettest(uint32_t idx, project *pro)
{
string ret;
if (!pro)
{
cout << "project is null." << endl;
}
else
{
if (testmap.find(idx) != testmap.end())
{
ret = testmap[idx];
}
}
return ret;
}
#endif
main.cpp
#include "example.hpp"
#include <iostream>
int main(int argc, char** argv){
solveTest st;
std::cout<<"test1 get index: "<<st.getIdx("test1")<<std::endl;
st.getSolve("test1");
return 0;
}
C语言实现¶
example.h
#pragma once
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <inttypes.h>
typedef struct
{
const char *signame;
uint32_t sigval;
} project;
void test1()
{
printf("this is test1.\n");
}
void test2()
{
printf("this is test2.\n");
}
void test3()
{
printf("this is test3.\n");
}
// jump table
void (*funcArr[])() = {test1, test2, test3};
void getTest(project *pro, const char *tn)
{
if (pro == NULL || tn == NULL)
return;
pro->signame = tn;
uint32_t i = 0;
if (*(tn + 5) != '\0')
return;
const char* cmp = "test";
if (strncmp(cmp, tn, 4) == 0)
{
funcArr[*(tn + 4) - '0' - 1]();
return;
}
printf("input str error!\n");
}
main.c
#include <string.h>
#include "example.h"
int main(int argc, char **argv)
{
project p;
getTest(&p, "test1");
printf("p->signame: %s\n", p.signame);
getTest(&p, "test2");
printf("p->signame: %s\n", p.signame);
getTest(&p, "test3");
printf("p->signame: %s\n", p.signame);
return 0;
}
cmake_minimum_required(VERSION 3.10)
project(main)
set(CMAKE_C_FLAGS "-g")
include_directories("./example.h")
set(SOURCE_FILE main.c)
add_executable(${PROJECT_NAME} ${SOURCE_FILE})
运行结果: