2012-03-16 2 views
2

Код:Переменная Определение Игнорирование в C

int main() 
{ 
    int a=1; 
    switch(a) 
    { 
    int b=20; 

    case 1: 
    printf("b is %d\n",b); 
    break; 

    default: 
    printf("b is %d\n",b); 
    break; 
    } 
    return 0; 
} 

Выход: Он печатает некоторое значение для мусора б , когда делает заявление о б здесь имеет место Почему б не инициализирован 20 здесь ???

+2

Не инициализируйте b там. –

+0

@ 0A0D Это не дубликат этого вопроса. Инициализация находится в другой части коммутатора (внутри корпуса), и верхний проголосовавший ответ здесь не применяется. – Paulpro

+0

@ 0A0D: Нет, это не дубликат этого вопроса. Ответ на это - это синтаксическая ошибка, чтобы следовать метке case с объявлением переменной. В то время как это связано с тем, что переключатель вызывает пропущен код инициализации. – JeremyP

ответ

8

Поскольку память будет выделена для int b, но когда приложение будет запущено, «b = 20» никогда не будет оценено.

Это потому, что switch -statement будет прыгать вниз либо case 1: или default:, пропуская заявление в вопросе - таким образом b будет неинициализированным и неопределенное поведение вызывается.


Следующие два вопроса (с их принятыми ответами) будет даже дальнейшей помощи в ваших поисках в поисках ответов:


Включение ваших предупреждений компилятора/ошибки на более высоком уровне, мы надеемся предоставить вам эту информацию при попытке скомпилировать источник.

Ниже приведено описание gcc;

foo.cpp:6:10: error: jump to case label [-fpermissive] 
foo.cpp:5:9: error: crosses initialization of 'int b' 

так int a всегда будет 1 (один), он всегда будет прыгать здесь.

Наиболее релевантные из двух ссылок, ответы на которые мне предоставлены.

2

switch непосредственно переходит на case 1:, не выполняя задание.

2

Предположительно потому, что switch функционирует как goto - если a == 1, он подскакивает прямо case 1: и обходит инициализацию b.

То есть: Я знаю, что switch прыгает прямо на метку case, но я очень удивлен, что компилятор не жалуется на пропущенную инициализацию.

0

Поскольку эта линия никогда не была достигнута. Когда C обращается к заявлению switch(a), он переходит к case, который соответствует условию переменной, которую вы включаете. Утверждение, которое инициализирует b, ни в одном из случаев.Я предполагаю, что компилятор может свободно писать 20 в местоположение, но язык не требует этого, и в этом случае это не так: он также может оставить инициализацию до тех пор, пока она фактически не выполнит назначение.

3

Операторы-переключатели оценивают только часть кода внутри них, и вы не можете поместить код вверху и ожидать, что он будет оцениваться каждым компонентом case. Вам нужно поставить b инициализацию выше в программе над оператором switch. Если вам действительно нужно сделать это на месте, сделайте это в отдельный набор фигурных скобок:

Код:

int main() 
{ 
    int a=1; 
    /* other stuff */ 
    { 
    int b=20; 
    switch(a) 
    { 

     case 1: 
     printf("b is %d\n",b); 
     break; 

     default: 
     printf("b is %d\n",b); 
     break; 
    } 
    } 
    /* other stuff... */ 
    return 0; 
} 
1

Это очень плохая идея для инициализации B по утверждению переключателя и вне сазе. Чтобы понять, что здесь происходит, вы должны знать, что коммутатор делает переход к правильному аргументу case/default.

1

потому что при выполнении оператора switch (a) управление переходит непосредственно к оператору case 1: без выполнения оператора int b = 20, поэтому он дает значение мусора в качестве ответа. Если u хочет напечатать a, то либо u должен инициализировать в случае, когда 1: блок или u должны инициализироваться перед оператором switch (a).

Смежные вопросы