Как работает оператор switch?

Как выполняются инструкции, которые предшествуют любому объявленному тегу case в обработанном блоке switch-case. Пожалуйста, объясните поведение следующих программ.

prog1:

#include<stdio.h>
int main()
{
  switch(1)
  {   
    int i=0; 
    case 1:printf("%d",i);         
  }
getchar();
return 0;
}

Выход: значение мусора.

PROG2:

#include<stdio.h>
int main()
{
  switch(1)
  {  
    printf("Inside Switch");  
    case 1:printf("Case 1\n");      
  }
  printf("Outside Switch");
  getchar();
  return 0;
}

Вывод:

Случай 1

Внешний переключатель.

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

Было бы действительно полезно, если бы кто-нибудь мог подробно объяснить, как процедура switch обрабатывается внутри.

Ответы

Ответ 1

Это лучше всего объясняется цитатами из стандарта c. Я цитирую соответствующие части из стандарта, которые применимы к вашему вопросу здесь.

6.8.4.2 Оператор switch

Параграф 4:

Оператор

A switch приводит к тому, что элемент управления выполняет переход, в или мимо оператора, который является switch тело, в зависимости от значения управляющего выражения, и от наличия default и значения любых меток case на или в корпусе переключателя......

Параграф 2:

Если оператор switch имеет связанную метку case или default в пределах области идентификатор с измененным типом, весь оператор switch должен находиться в пределах область действия этого идентификатора. 154)

FootNote:

154) То есть объявление либо предшествует оператору switch, либо оно следует за последней меткой case или default, связанной с switch, которая находится в блоке, содержащем объявление.

Параграф 7:
ПРИМЕР В фрагменте искусственной программы

switch (expr)
{
    int i = 4;
    f(i);
    case 0:
       i = 17;
       /* falls through into default code */
    default:
       printf("%d\n", i);
}

объект с идентификатором i существует с автоматической продолжительностью хранения (внутри блока), но никогда не инициализируется, и, следовательно, если управляющее выражение имеет ненулевое значение, вызов функции printf будет иметь доступ неопределенное значение. Аналогично, вызов функции f не может быть достигнут.


Вышеупомянутое относится к обоим примерам кода в Вопросе.
Example 1, i имеет значение Неопределенное, поскольку оно никогда не инициализировалось и, следовательно, печатает мусор, Example 2, printf вызов не достигается, потому что элемент управления переходит к соответствующей метке case.

Ответ 2

В принципе, коммутатор действует как goto на соответствующую метку - промежуточные утверждения не выполняются. Определения переменных (которые фактически происходят во время компиляции) происходят, но если они содержат инициализацию, это также пропускается.

Ответ 3

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

ПРИМЕЧАНИЕ: декларация может быть записана там, но нет инструкции (int i; является объявлением, но int я = 10; является объявлением + присваиванием = так что присвоение не будет выполняться там..!)

switch(a)
{
printf("This will never print"); // this will never executed
case 1:
        printf(" 1");
break;

default :
break;
}

см. этот Почему переменные не могут быть объявлены в инструкции switch сразу после этикеток?