4.12. Instructiunea switch

2019/02/17 in Programare in C

Instructiunea switch permite realizarea structurii selective. Aceasta este o generalizare a structurii alternative si a fost introdusa de C. A. R. Hoare. Ea poate fi realizata prin instructiuni if imbricate. Utilizarea instructiunii switch face ca programul sa fie mai clar decat daca se utilizeaza varianta cu instructiuni if imbricate.

Structura selectiva, in forma in care a fost ea acceptata de catre adeptii programarii structurate, se realizeaza in limbajul C cu ajutorul urmatorului format al instructiunii switch:

switch(expresie){
 case c1:
   sir_1
   break;
 case c2:
   sir_2
   break;
...
 case cn:
   sir_n
   break;
 default:
   sir
}

unde:

c1, c2, ..., cn sunt constante;
sir_1, sir_2, ..., sir_n sunt succesiuni de instructiuni.

Instructiunea switch cu formatul definit mai sus se executa astfel:

  1. Se evalueaza expresia din parantezele rotunde;
  2. Se compara pe rand valoarea expresiei cu valorile constantelor c1, c2, ..., cn;
    • daca valoarea expresiei coincide cu una din constante, sa zicem cu ci, atunci se executa secventa sir_i, apoi se trece la instructiunea urmatoare instructiunii switch, adica la cea aflata dupa acolada inchisa care termina instructiunea switch;
    • daca valoarea respectiva nu coincide cu niciuna din constantele c1, c2, ..., cn, atunci se executa succesiunea de instructiuni sir si apoi se trece la instructiunea urmatoare instructiunii switch.

Exista cazuri cand nu se doreste sa se ajunga la instructiunea urmatoare instructiunii switch, atunci cand succesiunea de instructiuni selectata pentru executie (sir_i sau sir) va defini ea insasi un alt mod de continuare a executiei programului (de ex. executia instructiunii de revenire dintr-o functie, saltul la o instructiune etichetata, etc.).

Succesiunile sir, sir_1, sir_2, ..., sir_n se numesc alternativele instructiunii switch.

Alternativa sir este optionala, deci intr-o instructiune switch, secventa:

default:
sir

poate fi absenta.

In acest caz, daca valoarea expresiei nu coincide cu valoarea niciuneia dintre constantele c1, c2, ..., cn, atunci instructiunea switch nu are niciun efect si se trece la executia instructiunii urmatoare.

Instructiunea switch de mai sus este echivalenta cu urmatoarea instructiune switch imbricata:

if(expresie == c1)
  sir_1
else
  if(expresie == c2)
    sir_2
  else
    if(expresie == c3)
      sir_3
    else
      if
      ...
      else
        if(expresie == cn)
          sir_n
        else
          sir

Instructiunea break de la sfarsitul fiecarei alternative, dupa secventele sir, sir_1, sir_2, ..., sir_n, permite ca la intalnirea ei sa se treaca la executia instructiunii urmatoare instructiunii switch. Se spune ca instructiunea break permite iesirea din instructiunea switch.

Instructiunea break poate fi utilizata numai in corpurile ciclurilor si in alternativele intructiunii switch.

Prezenta ei la sfarsitul fiecarei alternative a instructiunii switch nu este obligatorie. In cazul cand instructiunea break este absenta la sfarsitul unei alternative, dupa executia succesiunii de instructiuni din compunerea alternativei respective se va trece la executia succesiunii de instructiuni din alternativa urmatoare a aceleiasi instructiuni switch.

Astfel, daca o instructiune switch are formatul:

switch(expresie){
  case c1:
    sir_1
  case c2:
    sir_2
}

atunci ea este echivalenta cu urmatoarea secventa:

if(expresie == c1){
  sir_1
  sir_2
} else
    if(expresie == c2)
      sir_2
}

Exercitii:

4.25. Sa se scrie un program care citeste o cifra din intervalul [1, 7] si afiseaza denumirea zilei din saptamana corespunzatoare cifrei respective (1 - luni, 2 - marti etc.).

#include <stdio.h>
#include <stdlib.h>

main()
{
    int i;
    char t[255];

    do {
        puts("Tastati o cifra din intervalul [1, 7]: ");
        if(gets(t) == NULL) {
            puts("s-a tastat EOF");
            exit(1);
        }
    if (sscanf(t, "%d", &i) == 1 && i > 0 && i < 8)
            break;
        puts("nu s-a tastat o cifra din intervalul [1, 7]");
    } while (1);
    switch (i) {
        case 1:
            puts("luni");
            break;
        case 2:
            puts("marti");
            break;
        case 3:
            puts("miercuri");
            break;
        case 4:
            puts("joi");
            break;
        case 5:
            puts("vineri");
            break;
        case 6:
            puts("sambata");
            break;
        case 7:
            puts("duminica");
            break;
    }
}

4.26. Sa se scrie un program care citeste constructii de forma op1 op op2, unde:

op1 si op2 sunt intregi de tip long;
op este unul din caracterele: +, -, * sau /.

si afiseaza valoarea expresiei citite.

Operatia de impartire este impartirea intreaga.

Acest program simuleaza un calculator rudimentar de birou.

#include <stdio.h>
#include <stdlib.h>

main()
{
    long op1, op2, rez;
    char op;
    char t[255];

    for( ; ; ){
        do {
            printf("tastati expresia: op1opop2: ");
            if (gets(t) == NULL)
                exit(0);
            if (sscanf(t, "%ld %c %ld", &op1, &op, &op2) == 3)
                break;
            printf("expresie eronata\n");
        } while (1);
        switch(op) {
            case '+':
                rez = op1 + op2;
                break;
            case '-':
                rez = op1 - op2;
                break;
            case '*':
                rez = op1 * op2;
                break;
            case '/':
                if (op2 == 0) {
                    printf("divizor nul\n");
                    rez = 0;
                }
                else
                    rez = op1 / op2;
                    break;
            default:
                printf("operator eronat\n");
                rez = 0;
        }
        printf("op1 = %ld op = %c op2 = %ld rez = %ld\n", op1, op, op2, rez);
    }
}

Programul de fata permite evaluarea mai multor expresii separate prin caractere albe. El se intrerupe la intalnirea sfarsitului de fisier (<Ctrl> - Z).

4.13. Instructiunea goto