Объявление переменных внутри оператора switch

Я увидел несколько ответов на эту проблему, и я понял - вы не можете объявлять и присваивать переменные внутри switch. Но мне интересно, правильно ли указано следующее: "

error: ожидаемое выражение перед 'int'

код:

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

Почему бы поставить вызов NSLog() до того, как он не приведет к ошибкам?

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

Ответы

Ответ 1

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

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


Edit:

Кстати, эта причуда не так уж необычна, как вы думаете. В C и Java также запрещено использовать объявление локальной переменной как одиночный оператор (значение "не окружено фигурными скобками" ) в для, , а или do или даже в if и else. (На самом деле это рассматривается в головоломке № 55 "Java Puzzlers" , о котором я очень рекомендую.) Я думаю, что мы вообще не пишем таких ошибок, потому что не имеет смысла объявлять переменную как единственное утверждение в таких контекстах При конструкциях switch/ case некоторые люди опускают фигурные скобки, так как оператор break является критическим оператором для потока управления.

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

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

Ответ 2

Я столкнулся с этой проблемой раньше и пришел к выводу, что вы просто помещаете код внутри блока.

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

Ответ 3

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

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