c - 是否有使用不带大括号的 switch 语句的有用案例?

标签 c language-lawyer

在 H&S5 中,我遇到了不使用大括号的“最奇怪”的 switch 语句(8.7.1,第 277 页)。
这是示例:

switch (x)
    default:
    if (prime(x))
        case 2: case 3: case 5: case 7:
            process_prime(x);
    else
        case 4: case 6: case 8: case 9: case 10:
            process_composite(x);

这个想法似乎是为了避免 prime(x) 对最常见的小数的开销。

当我看到那个语句时,我对缺少的大括号感到困惑,但是检查官方语法( C1X pre-standard ,6.8.4,第 147 页),语法是正确的:switch 语句在switch 表达式和右括号。

但在我的编程实践中,我再也没有遇到过这样奇怪的 switch 语句(我不想在代码中看到任何我必须负责的语句),但我开始想:

你们有没有人知道这样一个 switch 表达式,一个不使用大括号但仍然有意义的表达式?不仅仅是 switch (i);(这是合法的,而是一个 NOP),而是使用至少两个具有某种有用目的的 case 标签?

最佳答案

如果您在宏中使用控制结构,switch 而不是 if 会派上用场,因为它没有悬空的 else 问题。

#define DEBUG_PRINT(...) switch (!debug_mode) case 0: fprintf(__VA_ARGS__)

这样,如果该宏的用户将其置于附加条件中,您就不会感到惊讶

if (unclear) DEBUG_PRINT(stderr, "This is really %unclear\n", unclear);
else {
 // do something reasonable here
}

这样的调试宏具有始终被编译(然后最终被优化掉)的优势。因此,调试代码必须在程序的整个生命周期内保持有效。

另请注意,switch 不使用 {} 很重要,否则 if/else 示例不会要么工作。所有这些都可以通过其他方式实现(if/else(void)0do/while 技巧),但这个是最我知道方便。

不要误会我的意思,我并不是说每个人都应该在宏中使用控制结构,您当然应该知道自己在做什么。但在某些情况下这是合理的。

关于c - 是否有使用不带大括号的 switch 语句的有用案例?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8118009/

相关文章:

c - "warning: ' 结构矩阵 ' declared inside parameter list [enabled by default]"和错误 : conflicting types for 'scanToken'

c++ - 对象是否在初始化列表的末尾完全构造?

c++ - [over.load]/1 下面突出显示的句子是什么意思?

c - int main() { }(没有 "void")在 ISO C 中有效且可移植吗?

c - 在C中通过引用递归传递字符串

编译 linux 内核的一小部分(即几个文件)

c++ - std::is_unsigned<bool>::value 定义是否明确?

c++ - 为什么别名声明不是有效的初始化语句 (/simple-declaration)?

使用 GNU make 和 Microsoft Visual Studio 编译器编译 .obj 文件中的所有 .c 文件

c - 我的单链表代码有什么问题?