<<Pagina Materiale

 
 
 Instructiuni 
Instructiunea expresie

Sintaxa:

   expresie; // a se observa faptul ca orice instructiune expresie se termina cu ;

Expresia este evaluata cu efect lateral, deci de regula instructiunea expresie este o atribuire ( expresie in care apare unul sau mai multi operatori de atribuire ) sau un apel de functie - vezi definitia expresiei.

Exemple:

    int a,b,c,m,n,p=2;
  // liniile de mai jos reprezinta instructiuni expresie
    scanf("%d",&a); // apel de functie, valoarea returnata nu este folosita
    b=5;
    c=a>b?a:b;
    n=printf("%d %d %d\n",a,b,c); //valoarea returnata este memorata in n
    p=a*b/c;
    p++;
    m=p+=5;
    a+b; // valoarea expresiei nu este folosita - apare un avertisment ( warning ) la compilare:
       // Code has no effect

Instructiunea expresie are ca echivalent ( mai slab ) in Pascal instructiunea de atribuire ( var:=expr ). In Pascal instructiunile se separa prin ; pe cand in C se termina, lucru care se pare duce la un numar mai mic de erori in compilare. Un bloc de atribuire dintr-o schema logica se codifica printr-o intructiune expresie.

Sus
Instructiunea compusa (bloc )

Pe parcursul elaborarii programelor, intervin situatii cand sintaxa impune folosirea unei singure instructiuni, iar codificarea necesita prezenta mai multora - instructiunile se intercaleaza intre acolade, formand o instructiune compusa.

Sintaxa:

  {
      declaratii_variabile_locale_blocului // optionale
    instructiuni
    }

Observatii:

  • Corpul oricarei functii este un bloc;
  • Instructiunile unui bloc pot fi de orice tip, deci si alte instructiuni bloc; instructiunile bloc pot fi deci incuibate;
  • Un bloc corespunde structurii de control secventa de la schemele logice;
  • O instructiune bloc poate sa nu contina nici o declaratie sau instructiune intre acolade; in general un astfel de bloc poate apare in faza de punere la punct a programului ( functii cu corp vid );
  • Daca un bloc contine doar instructiuni expresie, el se poate inlocui cu o instructiune expresie in care expresiile initiale se separa prin operatorul secvential , ; exemplu:

  • Blocul:
          {
            a++;
            c=a+ --b;
            printf("%d\n",c);
      }
  este echivalent cu instructiunea expresie:
          a++,c=a+ --b,printf("%d\n",c);
Sus
Instructiunea vida

Se utilizeaza cand sintaxa impune prezenta unei instructiuni, iar codificarea nu cere nici una.

Sintaxa:

    ;

Sus
Instructiunea de decizie

Sintaxa:

    if(expresie)         sau        if(expresie)
       instructiune1                  instructiune
   else
       instructiune2

Semantica:
Se evalueaza expresie; daca valoarea ei este adevarat ( diferita de 0 ) se executa instructiune1, altfel, daca exista ramura else, se executa instructiune2.

Observatii:

  • Instructiunea corespunde structurii de control selectie din schemele logice;
  • Pentru ca programele scrise se fie cat mai clare este bine ca instructiunile corespunzatoare lui if si else sa fie scrise decalat fata de cuvintele cheie;
  • Instructiunea corespunzatoare valorii adevarat sau fals, poate fi orice instructiune C:
    • daca instructiunea corespunzatoare valorii adevarat este o instructiune expresie, simbolul ; apare in fata cuvantului cheie else
    • instructiunea bloc ( atunci cand trebuie executate mai multe prelucrari )
    • o alta instructiune de decizie - deci instructiunile if-else pot fi incuibate; fiecare else corespunde if-ului anterior cel mai apropiat, fara pereche.
Exemplu:

//  urmatoarele trei secvente echivalente verifica daca trei valori pot reprezenta lungimile laturilor unui triunghi
 

if(a<b+c && b<a+c && c<a+b)
    puts("pot fi laturile unui triunghi");
else
    puts("nu pot fi laturile unui triunghi");
if(a<b+c && b<a+c && c<a+b)
    ; //pentru cond adev nu se executa nimic, deci apare instr vida
else
    printf("nu ");
puts("pot fi laturile unui triunghi");
if(!(a<b+c && b<a+c && c<a+b))  // sau if(a>=b+c || b>=a+c || c>=a+b)
    printf("nu ");
puts("pot fi laturile unui triunghi");
Sus
Instructiunea de ciclare cu test initial

Sintaxa:

     while(expresie)
        instructiune

Semantica:
Se evalueaza expresie; daca valoarea ei este adevarat ( diferita de 0 ) se executa instructiune, dupa care se evalueaza din nou expresie; daca valoarea este 0, se trece la instructiunea urmatoare. Deci instructiune, care este corpul ciclului, se executa atat timp cat expresie este adevarata, deci de 0 sau mai multe ori.

Observatii:

  • In general expresie contine variabile care se modifica in instructiune, astfel incat expresie sa devina falsa, deci ciclarea sa nu se faca infinit;
  • In unele programe se poate sa apara
    while(1)
       instructiune
          corpul ciclului poate sa contina o instructiune de iesire din ciclu, altfel tastarea Ctrl/Break intrerupe programul;
  • Orice program C poate fi scris folosind instructiunile prezentate pana acum; urmatoarele doua instructiuni de ciclare sunt derivate din cea cu test initial;
  • Instructiunea while corespunde structurii ciclu cu test initila de la schemele logice.
Aplicatii:
  • 1.Secvente echivalente care citesc cu validare o variabila - in urma citirii, variabila trebuie sa apartina intervalului [inf,sup]:
putchar(':');
scanf("%d",&var);
while(var<inf || var>sup){ //valoare invalida, se reia citirea
  putchar(':');
  scanf("%d",&var);
}
while(putchar(':'),scanf("%d",&var),var<inf || var>sup);
for(;putchar(':'),scanf("%d",&var),var<inf || var>sup;);
do{
  putchar(':');
  scanf("%d",&var);
}while(var<inf || var>sup);
  • 2.Se citesc de la tastatura intregi, pana la introducerea lui CTRL/Z. Sa se determine si sa se tipareasca urmatoarele informatii:
    • numarul de valori citite
    • media aritmetica a valorilor
    • numarul de valori pozitive
    • valoarea minima.
#include <stdio.h>
#include <conio.h>
#define MAX 32767 //0x7fff
void main(void){
  //var locale
  int curent,ind/*preia val returnata de scanf*/,contor,contor_poz,min; 
  float med_aritm; long suma; //pentru a nu apare depasire
  //initializari                        //*
  contor=contor_poz=suma=0;min=MAX;
  //prima citire
  putchar(':');ind=scanf("%d",&curent);   //1
  while(ind!=EOF){             //2
   //prelucrarea valorii din curent
    contor++;
    suma+=curent;
    if(curent>0)contor_poz++;
    if(curent<min)min=curent;
   //citirea unei noi valori
    putchar(':');ind=scanf("%d",&curent); //3
  }//while                       //**
  //tiparire rezultate
  if(contor){
    med_aritm=suma/(float)contor;
    printf("S-au citit %d intregi, dintre care %d pozitive, cu media \
aritm %f, minimul %d\n",contor,contor_poz,med_aritm,min);
  }//if
  else
    puts("Nici o valoare prelucrata");
  getch();
}//main

Programul se mai poate scrie echivalent daca liniile notate cu 1 si 3 dispar, iar 2 va fi de forma ( expresie formata din doua subexpresii, separate de operatorul secvential ):

           while(putchar(':'),scanf("%d",&curent)!=EOF){ //2

Daca enuntul se modifica astfel incat citirea sa se faca pana la introducerea lui 0, care nu se prelucreaza, linia 2 devine:

            while(putchar(':'),scanf("%d",&curent),curent){ //2

Daca enuntul se modifica astfel incat citirea sa se faca pana la introducerea lui CTRL/Z sau 0, care nu se prelucreaza, linia 2 devine:

           while(putchar(':'),scanf("%d",&curent)!=EOF && curent){//2

Sus
Instructiunea de ciclare for

Sintaxa - in dreapta secventa echivalenta care foloseste instructiunea while:
 

 for(expresie1;expresie2;expresie3) 
        instructiune
expresie1;
while(expresie2){
      instructiune
      expresie3;
}

Semantica:
Se evalueaza expresie1 care are rol de initializare; se evalueaza apoi expresie2, cu rol de conditie - daca valoarea ei este adevarat ( diferita de 0 ) se executa instructiune - corpul ciclului, dupa care se evalueaza expresie3, cu rol de actualizare, apoi din nou expresie2; daca valoarea este 0, se trece la instructiunea urmatoare. Deci instructiune se executa atat timp cat expresie2 este adevarata, deci de 0 sau mai multe ori.

Observatii:

  • Instructiunea for permite o scriere mult mai compacta decat celelalte doua instructiuni de ciclare, fiind foarte des utilizata in scrierea programelor;
  • Oricare din cele expresii poate lipsi, dar separatorul ; ramane. Absenta expresie2 echivaleaza cu conditia adevarat, deci 1; in tabelul de mai jos sunt date echivalentele cu instructiunea while, pentru cazuri cand expresii din sintaxa for lipsesc:
for(;expresie;) 
        instructiune
while(expresie)
      instructiune
for(;;) 
        instructiune
while(1)
      instructiune
  • Instructiunea for are ca si caz particular instructiunea de ciclare cu contor - in Pascal instructiunea for are doar aceasta semnificatie:
               for(var_contor=val_initiala;var_contor<=val_finala;var_contor+=increment)
                    instructiune
 
numarul de cicluri fiind (val_finala-val_initiala)/increment
Aplicatii:
  • 1.Folosind instructiunea for, programul anterior devine - modificari apar in secventa marcata //* //** - a se observa ca fiecare expresie din for este formata din mai multe, separate prin operatorul secvential:
#include <stdio.h>
#include <conio.h>
#define MAX 32767 //0x7fff
void main(void){
  //var locale
  int curent,ind/*preia val returnata de scanf*/,contor,contor_poz,min; 
  float med_aritm; long suma; //pentru a nu apare depasire
                    //*
  for(contor=contor_poz=suma=0,min=MAX;putchar(':'),scanf("%d",&curent)!=EOF;
      contor++,suma+=curent){
    if(curent>0)contor_poz++;
    if(curent<min)min=curent;
  }//for         //**
  //tiparire rezultate
  if(contor){
    med_aritm=suma/(float)contor;
    printf("S-au citit %d intregi, dintre care %d pozitive, cu media aritm\  %f, minimul %d\n",contor,contor_poz,med_aritm,min);
  }//if
  else
    puts("Nici o valoare prelucrata");
  getch();
}//main
  • 2.Pentru un intreg n strict pozitiv citit de la tastatura, sa se calculeze expresiile:
    • suma primilor n intregi
    • factorial de n
    • puterea n a lui n.
    A se observa la rularea programului depasirile care apar ( 6^6 depaseste domeniul intreg  ) si sa se faca modificarile necesare pentru calcularea corecta a expresiilor; sa se observe valorile lui n pentru care apar depasiri la declararea variabilelor de calcul de tip int ( 6^6), long ( 12^12 ), float, double.
     
    #include <stdio.h>
    #include <conio.h>
    void main(void){
      //var locale
      int n,contor,suma,factorial,putere;
      //citire n cu validare
      while(printf("n="),scanf("%d",&n),n<=0);
      //calcul expresii
      for(suma=0,contor=factorial=putere=1;contor<=n;contor++){
        suma+=contor;
        factorial*=contor;
        putere*=n;
      }//for 
      //tiparire rezultate
      printf("suma=%d,fact=%d,putere=%d\n",suma,factorial,putere);
      getche();
    }//main


    //instructiunea for se mai poate scrie - cu corpul vid:
    for(suma=0,contor=factorial=putere=1;contor<=n;suma+=contor,factorial*=contor,
                                                   putere*=n, contor++);
    Sa se modifice programul astfel incat sa se citeasca o secventa de intregi pentru care sa se calculeze expresiile.
  • 3.Sa se tipareasca in binar numerele intregi citite - oprirea programului se face cu CTRL/Z.
#include <stdio.h>
#include <conio.h>
void main(void){
 int numar,rang,dim=sizeof(numar)*8/*numar biti*/,masca=1;
 while(1){
 printf("numar=");scanf("%d",&numar);
 for(rang=dim-1;rang>=0;rang--)
   putchar(numar&masca<<rang?'1':'0'); //tip bit de la pozitia rang
 putchar('\n');
}
Sus
Instructiunea de ciclare cu test final

Sintaxa - in dreapta secventa echivalenta care foloseste instructiunea while:
 

do 
     instructiune
while(expresie);
instructiune
while(expresie)
      instructiune

Semantica:
Se executa instructiune - corpul ciclului, apoi se evalueaza expresie care are rol de conditie - daca valoarea ei este adevarat ( diferita de 0 ) se executa instructiune , dupa care se evalueaza din nou expresie; daca valoarea este 0, se trece la instructiunea urmatoare. Deci instructiune se executa atat timp cat expresie este adevarata, cel putin o data.

Observatii:

  • Instructiunea do-while se utilizeaza in secventele in care se stie ca o anumita prelucrare trebuie executata cel putin o data - vezi citirea cu validare;
  • Instructiunea echivaleaza cu structura de control ciclu cu test final de la scheme logice;
  • Instructiunea do-while difera de repeat until din Pascal, unde corpul ciclului se executa cat timp o conditie este falsa.
Aplicatie:

Sa se calculeze suma termenilor sirului an=xn/n!, a0=1, pana la insumarea a cel mult nmax termeni sau pana cand diferenta a doi termeni consecutivi este eps. Se vor citi de la tastatura cu validare valorile: x ( 0<x<1 ), nmax ( nmax >=2 ), eps ( 0<eps<1).
Se vor afisa suma calculata, numarul de termeni insumati si diferenta dintre ultimii doi termeni consecutivi.
Se observa ca sirul este descrescator, iar relatia de recurenta este: an=an-1x/n
In rezolvarea acestei aplicatii se utilizeaza instructiunea do-while pentru ca prelucrarea ce formeaza corpul ciclului trebuie executata cel putin o data ( suma se initializeaza cu primul termen si cel putin inca unul mai trebuie adunat, nmax fiind >=2 ).
 

#include <stdio.h> 
#include <conio.h> 

void main(void){ 
  int nmax,rang; 
  float x,eps,suma,termen,termen_ant; /*double pentru precizie mai mare */ 
    //initializari 
  rang=0; 
  suma=termen=0; //suma se initializeaza cu primul termen ( de rang 0 )
    //citiri cu validari
  while(printf("x="), scanf("%f",&x), x<=0 || x>=1); 
  while(printf("nmax="), scanf("%d",&nmax), nmax<2); 
  while(printf("eps="), scanf("%f",&eps), eps<=0 || eps>=1); 
  //calcul suma 
  do{
    termen_ant=termen; //salvare termen in termen_ant
    termen=x*termen_ant/++rang; //calcul cu relatia de recurenta
   //val rang reprezinta numarul de termeni insumati-1
    suma+=termen; //adunarea noului termen
  }while(termen_ant-termen>eps && rang+1<nmax); //continuare daca nici
        // una din conditiile de terminare nu s-a indeplinit 
    //tiparire rezultate
  printf("Suma=%e a rezultat din insumarea a %d termeni,\n",
  suma,rang+1); 
  /* rang+1 termeni pentru ca s-a adunat si cel de rang 0 */ 
  printf("Diferenta ultimilor doi: %e-%e=%e\n",termen_ant,termen, 
           termen_ant-termen); 
  getche(); 

Sus
Instructiunea de iesire din ciclu

Sintaxa:

  break;

Semantica:
Instructiunea break determina iesirea fortata din ciclu, adica iesirea din corpul celei mai apropiate instructiuni while, for,do-while sau switch care o contine si trecerea la executia instructiunii urmatoare.

Observatii:

  • Oricare dintre aceste instructiuni poate contine mai multe instructiuni break;
  • De obicei instructiunea break apare conditionata de un if:
while(expresie){ 
  ...
  if(exprb)break;
  ...
}
for(expresie1;expresie2;expresie3){ 
  ...
  if(exprb)break;
  ...
}
do{ 
  ...
  if(exprb)break;
  ...
}while(expresie);
Sus
Instructiunea de selectie

Sintaxa:

   switch(expresie){      //expresie - de tip intreg, numita expresie selectoare
       case k1:prelucrare1  //k1,k2,...,kn - etichete de tip intreg, distincte
       case k2:prelucrare2  //orice prelucrare consta din 0 sau mai multe instructiuni
        ...
       case kn:prelucraren
       default:prelucrarex  //optional, corespunde multimii de valori diferite de etichete
    }

Semantica:
Se evalueaza expresie; daca se gaseste o eticheta avand valoarea egala cu a expresiei, se executa prelucrarea corespunzatoare acesteia si celelalte, pana la sfarsitul lui switch; daca nici o eticheta nu are valoarea expresiei si exista default, se executa prelucrarex; altfel, se trece la instructiunea urmatoare.

Observatie:

  • Pentru a se executa doar prelucrarea corespunzatoare unei etichete, nu si cele urmatoare, fiecare prelucrare se termina cu instructiunea break:
       switch(expresie){
            case k1:prelucrare1 break;
            case k2:prelucrare2 break;
            ...
            case kn:prelucraren break;
            default:prelucrarex
        }
Gasiti secventa echivalenta instructiunii switch, in care sa se foloseasca doar instructiunea de decizie if-else.

Exemplu:

Urmatorul program executa operatiile unui calculator de buzunar simplu : adunare, scadere, inmultire si impartire a doua numere reale. Se preiau linii de forma :
     numar  operator  numar
si se afiseaza rezultatul calculului matematic. Secventa calculelor se incheie cu CTRL/Z.
 

#include <stdlib.h>
#include <stdio.h>
#define PROMPT ':'

void main(void){
     float a,b,result;
     char oper,eroare;

     while (putchar(PROMPT),(scanf("%f%c%f",&a,&oper,&b)!=EOF)){
           eroare=0;
           switch(oper){
                   case '+': result=a+b; break;
                   case '-': result=a-b; break;
                   case '*': result=a*b; break;
                   case '/': if(b)result=a/b;
                             else {
                                  puts("*** Impartire la 0 ***"); 
                                  eroare=1;
                             }
                             break;
                   default : printf("*** Operator ilegal %c ***\n",
                             oper);
                             eroare=1;
           }//switch
           if(!eroare)
                   printf("rezultatul e %f\n", result);
     }//while
}//main

Sus
Instructiunea de revenire din functie

Sintaxa:

     return;        sau      return expresie;

Semantica:
Se revine din functia care contine instructiunea, in cea apelanta, la instructiunea urmatoare apelului; se returneaza valoarea expresiei pentru cazul al doilea.

Sus
Quiz

Inainte de a trece la Exercitii, incercati sa gasiti raspunsurile corecte la autotestele de mai jos - puteti testa secventele, introducandu-le in mici programe pe care sa le rulati:

1.Daca int crt; care din secventele de mai jos tipareste numerele de la 1 la 10?

for(crt=1;crt<=10;crt++)
      printf("%d\n",crt);

for(crt=0;++crt<=10;printf("%d\n",crt));  //corp vid

crt=0;
    while(crt++<10)
      printf("%d\n",crt);

crt=0;
    do; //corp vid
    while(printf("%d\n",++crt),crt<10);

2.Secventa de mai jos va tipari pe ecran:
int i=4;
switch(--i){
  case 3:putchar('*');
  case 4:putchar('$');
  default:putchar('#');
}

Sus
Exercitii

1.Se citesc de la tastatura perechi de intregi de forma a n, pana la introducerea lui CTRL/Z. Sa se determine si sa se tipareasca urmatoarele informatii:
 -sa se tipareasca in bazele 10, 16, 8 valoarea obtinuta prin setarea/stergerea/complementarea bitului de rang n din a
 -numarul de perechi citite
 -media aritmetica si geometrica a valorilor a
 -numarul de valori a pozitive
 -valoarea minima pentru a
 -numarul de valori a cu bitul de rang 2 setat
 -numarul de valori a care prin impartirea cu 2n conduc la un numar divizibil cu 3 ( impartirea se face prin deplasare la dreapta ).
Sa se modifice programul astfel incat citirea perechilor sa se faca atat timp cat valoarea lui n reprezinta un rang din n ( 0..15 ) - ( vezi aplicatia rezolvata).

2.Se citesc de la tastatura valori reale, pana la introducerea lui CTRL/Z.
Sa se calculeze si sa se afiseze mediile:
- aritmetica
- geometrica ( radicalul de ordin n dintr-un numar x se calculeaza prin apelul functiei pow(x,1.0/n) cu prototipul in math.h )
- armonica  cu relatia n/med_arm=1/val1 + 1/val2 + ... + 1/valn.

3.Sa se calculeze si afiseze rezistentele echivalente pentru legarea in serie, respectiv paralel a celor cu valorile reale introduse de la tastatura si terminate cu CTRL/Z. La introducerea unei valori invalide ( <=0 ) se semnaleaza eroare si se termina programul.

4.Sa se afiseze numerele prime dintre doua valori min si max, citite cu validare, astfel incat min<=max. Analog pentru afisarea tuturor numerol divizibile cu un numar pozitiv citit..

5.Sa se afiseze descompunerea in factori primi ( factorii primi si exponentii ) pentru un numar citit.

6.Pentru doua date citite, in an, luna, zi, sa se afiseze numarul de ani intregi trecuti.

7.Se se determine toate patratele perfecte dintre doua valori citite.

8.Sa se scrie programul care determina daca trei valori reale citite pot fi laturile unui triunghi, in caz afirmativ, afisandu-i aria calculata cu formula lui Heron si determinand daca e echilateral, isoscel sau oarecare.

9.Sa se calculeze valoarea expresiei (n-a)b-n, pentru n variind intre a si b inclusiv; a si b se citesc, astfel incat sa fie pozitivi si b>a. Nu se va utiliza functia pow, ci ridicarea la putere se va realiza prin inmultiri repetate.

10.Sa se afiseze codurile ASCII ale literelor mari si mici.

11.Se considera functia: f(x)=(x^2-9)/(x-1), pentru x<1
                                            x, pentru x>=1 si x<=5
                                            1/(x-5), pentru x>5.
Sa se afiseze valorile functiei f(x) pentru xC[a,b], cu pasul p, numarul punctelor in care x si f(x) sunt de acelasi
semn si media aritmetica a valorilor calculate.a, b si p se citesc de la tastatura, cu validare, astfel incat a<=b.
 

Sus
<<Pagina Materiale


Copyright © 2001-2002. Carmen Holotescu
All rights reserved. Published by Timsoft