首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >跳转表是如何工作的?

跳转表是如何工作的?
EN

Stack Overflow用户
提问于 2012-12-22 07:40:35
回答 5查看 1.4K关注 0票数 1

在以下文档中,第4-5页:

http://www.open-std.org/jtc1/sc22/wg21/docs/ESC_Boston_01_304_paper.pdf

代码语言:javascript
复制
typedef int (* jumpfnct)(void * param); 
static int CaseError(void * param) 
{ 
  return -1; 
} 
static jumpfnct const jumptable[] = 
{ 
  CaseError, CaseError, ... 
  . 
  . 
  . 
  Case44,    CaseError, ... 
  . 
  . 
  . 
  CaseError, Case255 
}; 
  result = index <= 0xFF ? jumptable[index](param) : -1;

它比较了IF-ELSE和SWITCH,然后介绍了这个“跳表”。显然,它是这三种方法中实现速度最快的。它到底是什么?我看不出它是怎么工作的?

EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2012-12-22 07:46:58

跳转表是一种将一些输入整数映射到操作的方法。这是因为您可以使用输入整数作为数组的索引。

代码设置了一个指向函数的指针数组。然后,您的输入整数用于选择这些函数指针中的一个。一般来说,它看起来像是指向函数CaseError的指针。然而,每隔一段时间,它都会是一个不同的函数。

它的设计目的是为了

代码语言:javascript
复制
  jumptable[62] = Case62;
  jumptable[95] = Case95;
  jumptable[35] = Case35;
  jumptable[34] = CaseError; /* For example... and so it goes on */

因此,选择正确的函数调用是恒定的时间...使用if-elses和select,选择正确函数所需的时间取决于输入的整数...假设编译器本身没有优化select到跳转表...如果它是针对嵌入式代码的,那么这种优化可能已经被禁用了……你得去检查一下。

一旦找到了正确的函数指针,最后一行简单地调用它:

代码语言:javascript
复制
result = index <= 0xFF ? jumptable[index](param) : -1;

变成了

代码语言:javascript
复制
result = index <= 0xFF  /* Check that the index is within
                           the range of the jump table */

         ? jumptable[index](param) /* jumptable[index] selects a function
                                      then it gets called with (param) */

         : -1; /* If the index is out of range, set result to be -1
                  Personally, I think a better choice would be to call
                  CaseError(param) here */
票数 3
EN

Stack Overflow用户

发布于 2012-12-22 07:58:27

Jumpfnct是指向函数的指针。Jumptable是由多个jumpfncts组成的数组。这些函数可以通过引用它们在数组中的位置来调用。

例如,jumptable0将执行第一个函数,传递参数。jumptable1将执行第二个函数,依此类推。

如果你不了解函数指针,你就不应该使用这个技巧。它们非常方便,在一个狭窄的领域内。

当你所做的是在大量类似的函数调用之间切换时,它是非常快和空间有效的。您正在添加switch语句不一定具有的函数调用开销,因此它可能并不适用于所有情况。如果你的代码是这样的:

代码语言:javascript
复制
switch(x) {
  case 1:
    function1();
    break;
  case 2:
    function2();
    break;
...
}

跳转表可能是一个很好的替代方案。但是,如果您的开关是这样的:

代码语言:javascript
复制
switch(x) {
  case 1:
    y++;
    break;
  case 1023:
    y--;
    break;
...
}

这可能不值得去做。

我把它们用在了一个玩具FORTH语言解释器中,在那里它们是无价的,但在大多数情况下,你不会看到让它们值得使用的速度优势。如果它们能让你的程序逻辑更清晰,而不是为了优化,那就使用它们。

票数 2
EN

Stack Overflow用户

发布于 2012-12-22 07:45:34

此跳转表通过其索引返回指向函数的指针。定义该表的方式是,无效索引指向返回一些无效代码的函数(如本例中的-1 ),有效索引指向需要调用的函数。

施工

代码语言:javascript
复制
jumptable[index]

返回指向函数的指针,并调用此函数

代码语言:javascript
复制
jumptable[index](param)

其中param是一些自定义参数。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/13998591

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档