如何在 C 中有条件地分支到算术运算或查找表给出的标签

Posted

技术标签:

【中文标题】如何在 C 中有条件地分支到算术运算或查找表给出的标签【英文标题】:How to branch conditionally in C to a label given by an arithmetic operation or lookup table 【发布时间】:2022-01-23 01:19:48 【问题描述】:

而不是写一个ifswitchstatement,像这样:

if (a == 1)
    <some code here 1>
else if (a == 2)
    <some code here 2>
else if (a == 3)
    <some code here 3>

我想运行这样的东西:

l[1] = here1;
l[2] = here2;
l[3] = here3;

goto l[a];

here1:
    <some code here 1>
here2:
    <some code here 2>
here3:
    <some code here 3>

在 C 中可以做到这一点吗?

【问题讨论】:

你想要一个switch 声明。 @dbush,抱歉之前的评论,我发现这个answer 告诉我switch 的性能可能与下面答案中的标签和值一样好,将尝试一些性能测量检查它。谢谢。 哦,在那个问题中,有一个answer 提到了这个paper,似乎编译器遇到switch 时所做的事情要复杂得多,有很多可能的实现,从简单的条件分支到跳转表到超优化。无论如何,我必须检查性能。 我强烈怀疑这会成为性能瓶颈。通常,编写可读的代码并相信编译器会根据需要进行优化。仅当您的速度明显放缓时才手动优化。 条件达到数百个cases,这不是微不足道的,因为它应该在各种平台上运行,并且受制于一些不同的编译器,比如除了GCC之外的ICC,所以它不仅仅是简单的测试,也许我应该通过编译器选项提供两种实现,并让用户决定。 【参考方案1】:

不,它不是,但有一个 GCC 扩展。 https://gcc.gnu.org/onlinedocs/gcc/Labels-as-Values.html#Labels-as-Values.

所以你的代码是:

void *l[3] = &&here1, &&here2, &&here2;

goto *l[a];

here1:
    <some code here 1>
here2:
    <some code here 2>
here3:
    <some code here 3>

【讨论】:

哦,这很酷,会试一试。根据你的提示,我发现了这个answer,这启发了@dbush 的评论。 而且似乎ICC也实现了labels as values。 @Arc 我在那边少了一个小*。修复。不要盲目复制我的代码,也要复制错字,失败然后投反对票。而且,根据我的经验,如果您想以特定顺序遍历标签,标签作为值是可用的。这不是常见的需求,但如果使用得当,标签和标签作为值可以解决许多代码可读性问题。 嗨@ShambhavGautam,我绝不会因此而投反对票,您的回答非常有用,您及时更正了。

以上是关于如何在 C 中有条件地分支到算术运算或查找表给出的标签的主要内容,如果未能解决你的问题,请参考以下文章

没有条件、循环和算术运算符的 C 中的阶乘

Java NO.2

shell算术运算和文件测试及多分支if语句

c语言设计一个简单的计算器程序

C语言逻辑运算符和if语句

逆波兰算术表达式 C语言