在switch语句中声明变量[重复]

Posted

技术标签:

【中文标题】在switch语句中声明变量[重复]【英文标题】:Declaring variables inside a switch statement [duplicate] 【发布时间】:2010-11-16 21:38:38 【问题描述】:

我看到了这个问题的一些答案,我明白了——你不能在 switch 中声明和分配变量。但我想知道以下在抛出错误时是否正确

错误:'int'之前的预期表达式

代码:

switch (i) 
    case 0:
        int j = 1;
        break;

为什么要在没有错误之前调用NSLog()

switch (i) 
    case 0:
        NSLog(@"wtf");
        int j = 1;
        break;

【问题讨论】:

这已经被(至少)问过两次:***.com/questions/92396/…***.com/questions/1115304/… 没错,但这两个问题仍然悬而未决。我认为让这个单独存在没有问题 - 无需投票关闭它...... Adam,虽然另一篇文章回答了错误,但它没有解决将表达式作为第一个调用实际上可以避免错误的事实。奎因在这里回答了一些问题。 【参考方案1】:

如果您按照语言的语法进行操作,您实际上可以在开关中声明变量。您收到错误是因为“case 0:”是一个标签,在 C 中,将 declaration 作为标签后的第一条语句是非法的 - 请注意,编译器需要一个 expression ,例如方法调用、普通赋值等(虽然可能很奇怪,但这是规则。)

当你把 NSLog() 放在首位时,你就避免了这个限制。您可以将 case 的内容括在 大括号中以引入范围块,或者您可以将变量声明移到 switch 之外。您选择哪个是个人喜好问题。请注意,在 大括号中声明的变量仅在该范围内有效,因此使用它的任何其他代码也必须出现在这些大括号内。


编辑:

顺便说一句,这种怪癖并不像您想象的那么罕见。在 C 和 Java 中,在 forwhile 中使用局部变量声明作为单独的语句(意思是“不被大括号包围)也是非法的do 循环,甚至在 ifelse 子句中。(事实上,这在我强烈推荐的 "Java Puzzlers" 的谜题 #55 中有所介绍。 ) 我认为我们通常不会一开始就编写此类错误,因为在此类上下文中将变量声明为唯一语句没有什么意义。使用 switch / case 构造,不过,有些人省略了大括号,因为 break 语句是控制流的关键语句。

要查看编译器是否合适,请将这个可怕的、毫无意义的 sn-p 复制到您的 (Objective-)C 代码中:

if (1)
    int i;
else
    int i;
for (int answer = 1; answer <= 42; answer ++)
    int i;
while (1)
    int i;
do
    int i;
while (1);

还有另一个原因总是使用 大括号来分隔此类构造的主体。 :-)

【讨论】:

一般情况下,如果变量只在单个 case 中使用,那么将 case 部分包含在 中会更好(避免以后意外重用)。如果以后再次使用该变量,那么在 switch 语句开始之前声明它确实更有意义,因为否则它非常迟钝。 哇,C# 也有问题。对于简单的代码if (true) int i = 0;,我什至在编译之前就在 Visual Studio 中收到以下错误消息:Embedded statement cannot be a declaration or labeled statement Amazing. 不足为奇。很高兴来自 C# 的错误实际上比 gcc 错误更清楚一些。实际上,我不确定我是否会将其归类为“问题”……更多的是故意禁止的语法。我猜大多数基于 C 的语言的行为类似。 是的,我很抱歉。我理解为什么禁止使用该语法,因为声明一个将立即失去作用域的变量是没有意义的。然而,我还要说一件事,C# 允许这种在 Objective-C 中被禁止的开关语法。收到此错误消息的是其他语句(if、else、for、while 和 do)。 我实际上决定写博客,甚至调查了 C# Language Spec 语法:murrayon.net/2009/09/variable-declaration-restrictions.html【参考方案2】:

我之前遇到过这个问题,结论是你只是把代码放在一个块里。

switch (i) 
case 0:
    
        int j = 1;
        break;
    

【讨论】:

【参考方案3】:

我使用的另一个简单解决方法是在声明之前添加一个空表达式(分号)。这避免了将变量范围限制在代码块中(或者有些 case 语句带有代码块,有些则没有)。

switch (i) 
    case 0:;
        int j = 1;
        break;

【讨论】:

这给了我default 案例的错误:Switch case is in protected scope.

以上是关于在switch语句中声明变量[重复]的主要内容,如果未能解决你的问题,请参考以下文章

在switch中的case语句中声明变量会被提前

如何在将成为全局的 if/switch 语句中声明一个变量?

现代c++实践:变量声明强化,竟然可以在if/switch中定义变量!

我可以使用带有两个变量的 case/switch 语句吗?

js的一些编码问题

switch语句用法规则