L указывает целочисленный тип, а не двойной, чем стандартный числовой класс.
> str(1)
num 1
> str(1L)
int 1
Case
операторы [только 115] маркируют . Это означает, что компилятор интерпретирует это как переход непосредственно к маркировке. В C++ проблемой здесь является один из объема. Ваши фигурные скобки определяют объем как все в switch
оператор. Это означает, что Вас оставляют с объемом, где переход будет выполнен далее в код, пропускающий инициализацию. Корректный способ обработать это состоит в том, чтобы определить объем, характерный для того case
оператор, и определить Вашу переменную в нем.
switch (val)
{
case VAL:
{
// This will work
int newVal = 42;
break;
}
case ANOTHER_VAL:
...
break;
}
Я полагаю, что текущий вопрос, это - оператор, был пропущен, и Вы пытались использовать var в другом месте, это не будет объявлено.
newVal существует во всем объеме переключателя, но только инициализируется, если конечность VAL поражена. При создании блока вокруг кода в VAL, это должно быть в порядке.
Новые переменные могут быть decalared только в области действия блока. Необходимо записать что-то вроде этого:
case VAL:
// This will work
{
int newVal = 42;
}
break;
, Конечно, newVal только имеет объем в фигурных скобках...
С наилучшими пожеланиями, Ralph
Если бы Ваш код говорит "интервал newVal=42", тогда Вы обоснованно ожидали бы, что newVal никогда не является неинициализированным. Но если Вы goto по этому оператору (который является тем, что Вы делаете) тогда это точно, что происходит - newVal, в объеме, но не был присвоен.
, Если, именно это Вы действительно означали происходить тогда, язык требует для создания его явным путем высказывания "интервала newVal; newVal = 42";. иначе можно ограничить объем newVal к единственному случаю, который более вероятен, что Вы хотели.
Это может разъяснить вещи, если Вы рассматриваете тот же пример, но с "интервалом константы newVal = 42";
Я просто хотел подчеркнуть тонкий точка . Конструкция переключателя создает целый, объем гражданина первого класса. Таким образом, возможно объявить (и инициализировать) переменная в операторе переключения перед первой маркировкой случая, без дополнительная пара скобки:
switch (val) {
/* This *will* work, even in C89 */
int newVal = 42;
case VAL:
newVal = 1984;
break;
case ANOTHER_VAL:
newVal = 2001;
break;
}
Рассмотрите:
switch(val)
{
case VAL:
int newVal = 42;
default:
int newVal = 23;
}
В отсутствие операторов завершения, иногда newVal объявляется дважды, и Вы не знаете, делает ли он до времени выполнения. Мое предположение - то, что ограничение из-за этого вида беспорядка. Каков объем newVal был бы? Соглашение продиктовало бы, что будет весь блок переключателя (между фигурными скобками).
я не программист на C++, но в C:
switch(val) {
int x;
case VAL:
x=1;
}
Хорошо работает. Объявление переменной в блоке переключателя прекрасно. При объявлении после того, как защита случая не.
Можно объявить переменные в операторе переключения при запуске нового блока:
switch (thing)
{
case A:
{
int i = 0; // Completely legal
}
break;
}
причина относится к выделению (и исправление) пространство на стеке для устройства хранения данных локальной переменной (переменных).
Попробуйте это:
switch (val)
{
case VAL:
{
int newVal = 42;
}
break;
}
Мой любимый злой прием переключателя должен использовать если (0) для перескакивания через нежелательную маркировку случая.
switch(val)
{
case 0:
// Do something
if (0) {
case 1:
// Do something else
}
case 2:
// Do something in all cases
}
, Но очень злой.
Большинство ответов до сих пор является неправильным, с одной стороны: Вы можете объявлять переменные после оператора выбора, но Вы не можете инициализировать их:
case 1:
int x; // Works
int y = 0; // Error, initialization is skipped by case
break;
case 2:
...
, Как ранее упомянуто, хороший путь вокруг этого состоит в том, чтобы использовать фигурные скобки для создания объема для случая.
Вы не можете сделать этого, потому что case
маркировки являются на самом деле просто точками входа в содержание блока.
Это наиболее ясно проиллюстрировано устройство Вареного пудинга . Вот некоторый код из Википедии:
strcpy(char *to, char *from, size_t count) {
int n = (count + 7) / 8;
switch (count % 8) {
case 0: do { *to = *from++;
case 7: *to = *from++;
case 6: *to = *from++;
case 5: *to = *from++;
case 4: *to = *from++;
case 3: *to = *from++;
case 2: *to = *from++;
case 1: *to = *from++;
} while (--n > 0);
}
}
Уведомление, как case
маркировки полностью игнорируют границы блока. Да, это является злым. Но это - то, почему Ваш пример кода не работает. При переходе к case
маркировка совпадает с использованием goto
, таким образом, Нельзя перепрыгнуть через локальную переменную с конструктором.
, Поскольку несколько других плакатов указали, необходимо вставить собственный блок:
switch (...) {
case FOO: {
MyObject x(...);
...
break;
}
...
}
Целый оператор переключения находится в том же объеме. Для обхождения его сделайте это:
switch (val)
{
case VAL:
{
// This **will** work
int newVal = 42;
}
break;
case ANOTHER_VAL:
...
break;
}
Примечание скобки.
Хорошо. Просто для уточнения это строго не имеет никакого отношения к объявлению. Это имеет отношение только к "перепрыгиванию через инициализацию" (C++ ISO '03 6.7/3)
, Много сообщений здесь упомянуло, что перепрыгивание через объявление может привести к переменной "не быть объявленным". Это не верно. Объект POD может быть объявлен без инициализатора, но он будет иметь неопределенное значение. Например:
switch (i)
{
case 0:
int j; // 'j' has indeterminate value
j = 0; // 'j' initialized to 0, but this statement
// is jumped when 'i == 1'
break;
case 1:
++j; // 'j' is in scope here - but it has an indeterminate value
break;
}
то, Где объект является не-POD или агрегировал компилятор неявно, добавляет инициализатор, и таким образом, не возможно перепрыгнуть через такое объявление:
class A {
public:
A ();
};
switch (i) // Error - jumping over initialization of 'A'
{
case 0:
A j; // Compiler implicitly calls default constructor
break;
case 1:
break;
}
Это ограничение не ограничено оператором переключения. Это - также ошибка использовать 'goto' для перепрыгивания через инициализацию:
goto LABEL; // Error jumping over initialization
int j = 0;
LABEL:
;
Немного мелочи - то, что вот в чем разница между C++ и C. В C это не ошибка перепрыгнуть через инициализацию.
, Поскольку другие упомянули, решение состоит в том, чтобы добавить вложенный блок так, чтобы время жизни переменной было ограничено маркировкой отдельного случая.
Весь раздел переключателя является единственным контекстом объявления. Вы не можете объявить переменную в операторе выбора как этот. Попробуйте это вместо этого:
switch (val)
{
case VAL:
{
// This will work
int newVal = 42;
break;
}
case ANOTHER_VAL:
...
break;
}
Пока ответы были для C ++.
Для C ++ вы не можете перепрыгнуть через инициализацию. Вы можете в C. Однако в C объявление не является оператором, и за метками case должны следовать операторы.
Итак, допустимый (но уродливый) C, недопустимый C ++
switch (something)
{
case 1:; // Ugly hack empty statement
int i = 6;
do_stuff_with_i(i);
break;
case 2:
do_something();
break;
default:
get_a_life();
}
И наоборот, в C ++ объявление является оператором, поэтому следующий код является допустимым C ++, недопустимым C
switch (something)
{
case 1:
do_something();
break;
case 2:
int i = 12;
do_something_else();
}