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

111

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

Почему переменные не могут быть объявлены в операторе switch? 23 ответа

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

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

Код

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

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

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

Ваш Ответ

3   ответа
138

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

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

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

Кстати, эта странность не так необычна, как вы думаете. В C и 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);

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

В общем, если переменная используется только в пределах одного регистра, то лучше будет заключить в него раздел регистра {} (это позволит избежать случайного повторного использования позже). Если переменная используется снова поздно, тогда действительно имеет смысл объявить ее перед началом оператора switch, поскольку в противном случае она очень тупая. Peter N Lewis
Вау, даже в C # есть проблема. Для простого кодаif (true) int i = 0; Я получаю следующее сообщение об ошибке в Visual Studio еще до компиляции:Embedded statement cannot be a declaration or labeled statement Удивительно mkmurray
Неудивительно. Приятно, что ошибка в C # на самом деле более ясна, чем ошибка gcc. И на самом деле, я не уверен, что классифицировал бы это как «проблему» ... больше намеренно запрещенного синтаксиса. Я предполагаю, что большинство языков на основе C действуют аналогично. Quinn Taylor
Да, я прошу прощения. Я понимаю, почему синтаксис запрещен, поскольку бессмысленно объявлять переменную, которая немедленно теряет область видимости. Однако я скажу еще кое-что, что C # позволяет использовать этот синтаксис, запрещенный здесь, в Objective-C. Это другие операторы (если, иначе, для, while и do), которые получают это сообщение об ошибке. mkmurray
Я решил написать об этом в блоге и даже изучил грамматику C # Language Spec: Murrayon.net / 2009/09 / переменная декларирование-restrictions.html mkmurray
46

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

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. zakdances
@ joel Хороший хак iVela

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