Вопрос по variables, switch-statement, objective-c, c, declaration – Объявление переменных внутри оператора switch [duplicate]

111

На этот вопрос уже есть ответ здесь:

Почему можно# переменные должны быть объявлены в операторе swi#ch? 23 ответа

Я видел несколько ответов на этот вопрос, и я понял - вы можете'объявить и назначить переменные внутриswi#ch, Но я'Мне интересно, правильно ли следующее при выдаче ошибки, говоря

ошибка: ожидаемое выражение перед 'INT»

Код:

swi#ch (i) {
    case 0:
        in# j = 1;
        break;
}

Зачем звонитьNSLog() прежде чем это приведет к ошибкам?

swi#ch (i) {
    case 0:
        NSLog(@"w#f");
        in# j = 1;
        break;
}
Это было задано (по крайней мере) дважды, прежде чем:stackoverflow.com/questions/92396/... stackoverflow.com/questions/1115304/... Adam Rosenfield
Правда, но оба эти вопроса все еще открыты. Я нене вижу проблемы с тем, чтобы оставить это в покое - не нужно голосовать, чтобы закрыть его ... Quinn Taylor
Адам, в то время как другой пост отвечает на ошибку, это неt учитывать тот факт, что помещение выражения в качестве первого вызова на самом деле позволит избежать ошибки. Что-то Куинн ответил здесь. dizy

Ваш Ответ

3   ответа
46

и пришел к выводу, что вы просто помещаете код в блок.

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

Можно объявляйте переменные внутри переключателя, если вы делаете это в соответствии с синтаксисом языка. Вы'получаю ошибку, потому что ""case 0: это метка, а в C это 'незаконно иметьдекларация в качестве первого утверждения после метки - обратите внимание, что компилятор ожидаетвыражениетакие как вызов метода, нормальное присваивание и т. д. (хотя это может показаться странным, что 'это правило.)

Когда вы сначала ставите NSLog (), вы избегаете этого ограничения. Вы можете заключить содержимое регистра в фигурные скобки {}, чтобы ввести блок области видимости, или вы можете переместить объявление переменной за пределы переключателя. То, что вы выбираете, зависит от личных предпочтений. Просто имейте в виду, что переменная, объявленная в фигурных скобках {}, действительна только в этой области, поэтому любой другой код, который ее использует, также должен появляться в этих фигурных скобках.

Редактировать:

Кстати, эта причуда нетак необычно, как вы могли подумать. В Си и Java этоТакже недопустимо использовать объявление локальной переменной в качестве оператора lone (что означаетне в окружении брекетов) вза,в то время как, или жеделать петля, или даже весли а такжееще статьи. (На самом деле, это покрыто загадкой № 55 "Java Puzzlers ", что я очень рекомендую.) Я думаю, что мы вообще неДля начала не пишите такие ошибки, потому что не имеет смысла объявлять переменную как единственное утверждение в таких контекстах. Спереключатель /дело конструкции, однако, некоторые люди опускают фигурные скобки, так какперерыв утверждение является критическим утверждением для потока управления.

Чтобы увидеть совпадения компилятора, скопируйте этот ужасный, бессмысленный фрагмент в ваш (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);

Еще одна причина всегда использовать {} фигурные скобки для разделения тела таких конструкций. :-)

обратите внимание, что компилятор ожидает выражение, такое как вызов метода, нормальное присваивание и т. д. (хотя это может показаться странным, что 'это правило.) "->  Я бы спросил "Зачем" это правило наложено! Paul Brewczynski
вау, это странно ... но спасибо! dizy
Я действительно решил написать об этом в блоге и даже изучил грамматику C # Language Spec:murrayon.net/2009/09/variable-declaration-restrictions.html» mkmurray
Да, я прошу прощения. Я понимаю, почему синтаксис запрещен, поскольку бессмысленно объявлять переменную, которая немедленно теряет область видимости. Однако я скажу еще кое-что, что C # позволяет использовать этот синтаксис, запрещенный здесь, в Objective-C. Это's другие операторы (если, иначе, для, while и do), которые получают это сообщение об ошибке. mkmurray
3

который я использую, заключается в добавлении пустого выражения (точка с запятой) перед объявлением. Это позволяет избежать ограничения области действия переменной блоком кода (или иметь некоторые операторы case с кодовыми блоками, а некоторые без).

switch (i) {
    case 0:;
        int j = 1;
        break;
}
Это дает мне ошибку на моемdefault дело:Switch case is in protected scope. zakdances
@joel Хороший хак :) iVela

Похожие вопросы