c 开关和跳转表

2024-01-01

据我了解,c/c++ 中的 switch 语句有时会编译为跳转表。 我的问题是,有什么经验法则可以保证这一点吗?

就我而言,我正在做这样的事情:

enum myenum{
MY_CASE0= 0,
MY_CASE0= 1, 
.
.
.
};

switch(foo)
{
  case MY_CASE0:
  //do stuff
  break;
  case MY_CASE1:
  //do stuff
  break;
 .
 .
 .
}

我按顺序涵盖了从 1 到 n 的所有情况。可以安全地假设它将编译为跳转表吗? 原来的代码又长又乱if else声明,所以至少我获得了一些可读性。


一个好的编译器可以并且将会在跳转表、链式 if/else 或组合之间进行选择。设计不良的编译器可能不会做出这样的选择,甚至可能为开关块生成非常糟糕的代码。但任何像样的编译器都应该为开关块生成有效的代码。时间

这里的主要决策因素是,当数字相距很远时,编译器可能会选择 if/else [并且不是简单地(例如除以 2、4、8、16、256 等)更改为更接近的值],例如

 switch(x)
 {
    case 1:
     ...
    case 4912:
     ...
    case 11211:
     ...
    case 19102:
     ...
 }

需要至少 19102 * 2 字节的跳转表。

另一方面,如果数字很接近,编译器通常会使用跳转表。

即使它是一个if/else设计类型,它通常会进行“二分搜索” - 如果我们采用上面的例子:

 if (x <= 4912)
 {
     if (x == 1)
     {
        ....
     }
     else if (x == 4912)
     {
         .... 
     }
 } else {
     if (x == 11211)
     {
         ....
     }
     else if (x == 19102)
     {
         ...
     }
 }

如果我们有很多情况,这种方法会嵌套得很深,人类可能会在三到四个深度后迷失方向(记住每个如果从范围中间的某个点开始),但它减少了log2(n) 的测试次数,其中 n 是选择数。这肯定比简单的方法有效得多

if (x == first value) ... 
else if (x == second value) ... 
else if (x == third value) ... 
..
else if (x == nth value) ... 
else ... 

如果将某些值放在 if-else 链的开头,这可能会稍微好一些,但前提是您可以在运行代码之前确定最常见的值。

如果性能对您的案例至关重要,那么您需要对两种替代方案进行基准测试。但我的猜测是,仅将代码编写为开关将使代码更加清晰,同时运行速度至少同样快,甚至更快。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

c 开关和跳转表 的相关文章

  • 是否可以使静态控件透明?

    我正在尝试实现一个静态控件 该控件刷新 更改文本 以响应每秒发生一次的某个事件 由于我不想每秒绘制整个客户区域 所以我决定使用静态控件 现在的问题是父窗口被蒙皮 这意味着它有自定义位图作为背景 而静态控件没有适应 所以我正在寻找使静态控件的
  • 根据当前文化调用不同(本地化)视图

    我在用着LocalizationAttribute它实现了ActionFilterAttribute本地化视图 我简单地说 Localize 在控制器上 我使用 LocalizeStrings resx 文件根据当前线程上的语言进行应用 一
  • 以 ISO 8601 格式输出日期

    如何在 C 中获取以下格式的日期 2016 04 26T19 50 48Z include
  • OWIN AuthenticationOptions 在 mvc5 应用程序中运行时更新

    Hi 情况如下 我在 iis 7 上有一个带有 Identity 2 的 MVC 5 应用程序 该应用程序为多个网站提供服务 主机名是某些网站的关键 网站 另一个网站 等等 我决定在我的所有网站上使用谷歌外部登录 每个网站都应该是带有个人
  • 以编程方式更改 Excel 中的字体(Trebuchet MS、Calibari)C#

    我目前正在使用一个 C 应用程序 该应用程序有一个将生成 Excel 文件的类 一切都很顺利 Excel 工作表上填充的数据具有 Times New Roman 字体 我想将其更改为其他字体 Calibari 我怎样才能以编程方式做到这一点
  • 运行时两个注册之间的简单注入器基于动态上下文的注入

    我有一个使用 Simple Injector 进行命令处理程序注册的中介应用程序 并且注入和处理程序均已设置并完美运行 class DoWashingCommandHandler IRequestHandler
  • 在宏中使用 # [重复]

    这个问题在这里已经有答案了 请解释一下代码 include
  • 用 C# 中的字典中的值替换字符串中的单词

    我有一个简单的dictionary像这样 var fruitDictionary new Dictionary
  • 错误 C2065:'cout':未声明的标识符

    我正在处理我的编程作业的 驱动程序 部分 但我不断收到这个荒谬的错误 错误 C2065 cout 未声明的标识符 我什至尝试过使用std cout但我收到另一个错误 IntelliSense 命名空间 std 没有成员 cout 当我宣布u
  • MVVM 同步集合

    是否有一种标准化方法可以将 Model 对象集合与 C 和 WPF 中匹配的 ModelView 对象集合同步 我正在寻找某种类 可以使以下两个集合保持同步 假设我只有几个苹果 并且可以将它们全部保存在内存中 换句话说 我想确保如果我将 A
  • 如果 .txt 文件不存在,则创建一个,如果存在则追加新行

    我想创建一个 txt 文件并写入它 如果该文件已经存在 我只想添加更多行 string path E AppServ Example txt if File Exists path File Create path TextWriter t
  • Excel 2007 中的数值 - 底层 xml 文件中的表示与存储

    这个问题与 NET和OpenXml有关 我已经阅读了以下文章 它有很好的解释 但没有回答我的问题 Excel 2007 中数值的可视化与底层 xml 文件不一致 https stackoverflow com questions 58594
  • 内存不足异常

    我正在使用 C 和 asp net 开发一个网络应用程序 我一直收到内存不足的异常 该应用程序的作用是从数据源读取一堆记录 产品 可能是数百 数千 通过向导中的设置处理这些记录 然后使用处理的产品信息更新不同的数据源 虽然有多个 DB 类
  • 嘲笑会员用户

    我目前正在开发一个 asp net mvc 2 应用程序 它使用默认的 SqlMembershipProvider 进行身份验证 我已经实现了一个控制器方法 通过调用读取当前用户的 ProviderUserKeyMembership Get
  • 如何在 Windows 8.1 上打开多个 Visual Studio 窗口? [关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 我使用的是 Windows 7 我能够启动多个 Visual Studio 并同时工作 现在我有 Windows 8 1 操作系统 每当我
  • 如何通过 Excel 互操作对象自动调整列大小?

    下面是我用来将数据加载到 Excel 工作表中的代码 但我希望在加载数据后自动调整列的大小 有谁知道自动调整列大小的最佳方法 using Microsoft Office Interop public class ExportReport
  • 如何进行平衡组捕获?

    假设我有这个文本输入 tes tR R abc aD mnoR xyz 我想提取 ff 输出 R abc R xyz D mnoR xyz R R abc aD mnoR xyz 目前 我只能使用平衡组方法提取组内的内容 如中所示msdn
  • 矩阵行列式算法 C++

    我是编程新手 我一直在寻找一种找到矩阵行列式的方法 我在网上找到了这段代码 但我很难理解这里的算法 我对递归的基础没有问题 但继续和主循环我很难理解 非常感谢任何可以向我解释该算法的人 int determ int a MAX MAX in
  • PC 上 XNA 中的信箱和缩放

    有没有一种方法可以让我基本上以 1080p 或 720p 作为默认分辨率来开发 XNA 游戏 然后根据设置的分辨率将游戏中的所有内容缩放到适当的大小 而不必在每个 Sprite 中设置缩放因子Draw 方法 我的想法是 我可以基于 1080
  • Task.Delay 到底是如何工作的?

    他们说 Task Delay 是一个异步 Thread Sleep 为了测试这一点 我写了下面的代码 我希望立即打印 One 然后 3 秒后将打印结果变量 15 2 秒后 将打印 Two 但似乎并非如此 一 不会立即打印 3 秒后打印 On

随机推荐

  • JavaScript 对数组进行排序

    我的数组未正确排序 有人可以让我知道我做错了什么吗 sortArray new Array hello Link to Google zFile aFile sort array if dir asc sortArray sort func
  • 找到顶点的边(多边形)的最佳算法

    我有大量的顶点 其中一些是边缘 一些是多余的 形状内部 我想删除它们 我能想到的最简单的算法是一一检查它们是否撞到了其他人形成的形状 但这应该是一个非常慢的算法 我考虑从边缘选择一个 每个示例中距原点最远的一个 并计算从这一点开始的最长路径
  • 为什么Python在for和while循环之后使用'else'?

    我理解这个结构是如何工作的 for i in range 10 print i if i 9 print Too big I m giving up break else print Completed successfully 但我不明白
  • 制作嵌套在其他显示对象中的显示对象的视觉克隆,并将克隆添加到相同位置、旋转等的舞台层中

    我希望能够获取嵌套在其他对象中的 DisplayObject 的副本转变的DisplayObjects 旋转 缩放 拉伸的对象 并能够将其标记回相同的视觉位置 但在舞台层上 本质上 能够创建嵌套 DisplayObject 的克隆 但能够将
  • Python: int(3.0) = 2

    观察下面的python程序 def goo y x y float y x float x yup y x 1 x yup str yup yup yup split decimal yup 1 decimal float decimal
  • 数据库管理系统通常绕过文件系统,这是真的吗?

    我对典型数据库管理系统绕过文件系统的一般理解是否正确 据我所知 他们管理自己的磁盘空间 并将实际数据和索引系统 如 B 树 直接写入磁盘块 绕过文件系统的任何中间帮助 这假设 root 将向数据库用户提供直接读取和写入磁盘块的权限 在 Li
  • 在 SR-IOV 虚拟功能 (VF) NIC 之间转发数据包

    我有一个支持 Intel SR IOV 的 Intel 82599ES 10G NIC 我已成功创建了 8 个虚拟功能 VF 并将其分配给 2 个 qemu kvm VM 每个 VM 2 个 VF 两台虚拟机都使用分配的 VF 运行 DPD
  • 学习汇编,代码有问题吗?

    jmp start Draws a horiz and vert line startaddr dw 0a000h start of video memory colour db 1 start mov ah 00 mov al 19 in
  • SQlite 时差使用函数 strftime 和日期并使用触发器在插入时更新

    我想要两个时间戳之间的差异 例如 Endtime strftime Y m d H M S now localtime firsttime strftime Y m d H M S 2012 01 27 02 34 56 即如果我的第一次是
  • 选择要安装的包 - 安装按钮呈灰色

    我正在尝试使用 sdk 管理器安装一组软件包 但即使选择 全部接受 后 安装 按钮仍然呈灰色 我可以看到一些文字说 这个包依赖于 缺少 SDK 平台 Android API 17 但不知道我需要做什么来安装 缺少 SDK 平台 Androi
  • 何时应在函数返回值上使用 std::move? [复制]

    这个问题在这里已经有答案了 在这种情况下 struct Foo Foo meh return std move Foo 我很确定此举是不必要的 因为新创建的Foo将是一个 x 值 但在这样的情况下该怎么办呢 struct Foo Foo m
  • Guice 最佳实践和反模式

    我不确定这个问题是否有价值 但是是否有任何特定于的最佳实践和反模式谷歌指南 https github com google guice 请将任何通用 DI 模式定向至这个问题 https stackoverflow com q 168255
  • Javascript - XMLHttpRequest 如何同时发送多个请求?

    我遇到了一个非常超自然的问题 我正在尝试实现一个购物车 其中我在客户端存储了 cookie 以识别已订购的商品 ID 及其数量 当我加载结帐 HTML 页面时 我会读取 cookie 并逐个获取项目 id 然后 对于每个项目 id 我将向我
  • 如何注册网络 python 包安装的入口点?

    我有一个用户环境 其中大多数 python 软件包都安装在网络共享上 并可通过PYTHONPATH环境变量 Python本身仍然安装在本地 其中一些软件包需要注册 setuptools切入点 http pythonhosted org se
  • git 子模块分支是否与主项目的分支一起切换?

    最近我开始了解 git 子模块 它们似乎是自给自足的项目 拥有自己的 git 结构和分支 当我切换主项目的分支时 这是否也会切换子模块的分支 git 如何处理这种情况 我最近遇到类似的问题 https stackoverflow com a
  • 使用 Javascript 关闭 iPhone 视频播放器

    我有一个带有多个 html5 标签的网页 为用户提供了许多他们可以选择播放的视频的海报 缩略图 当用户触摸其中一个时 iPhone 视频播放器就会打开并播放视频 我希望能够在视频播放完毕后自动关闭视频播放器并将用户返回到缩略图 我已经为 结
  • 为什么使用 Url.Content 来引用资源?

    在我遇到的几乎每个 ASP NET MVC 示例中 我总是看到网址内容用于引用 CSS JavaScript 和图像 没有人解释过为什么要使用它 有谁愿意解释一下吗 这样做有什么不好 img src Content Img MyImage
  • 无法将 iOS 自定义框架添加到 KMM(Kotlin 多平台)模块(未找到 cinteropXXXIosArm64 FAILED 模块)

    我正在开发一个 iOS 应用程序 它使用 Kotlin Native 共享模块 这个Kotlin Native共享模块 利用了自主开发的iOS框架 这在过去非常有效 但现在我正在尝试将我的项目升级为最新版本的 Kotlin Native 此
  • React,webpack:避免导入语句中的“..”

    我目前正在学习 React 因此正在学习 es6 es7 和 webpack 来自主要Python背景的我对导入语句的文件夹敏感路径声明感到恼火 即使用 在进口声明中 这意味着如果我将文件移动到不同的目录 我需要更改文件中声明的导入语句 P
  • c 开关和跳转表

    据我了解 c c 中的 switch 语句有时会编译为跳转表 我的问题是 有什么经验法则可以保证这一点吗 就我而言 我正在做这样的事情 enum myenum MY CASE0 0 MY CASE0 1 switch foo case MY