4.6. Instructiunea while

2019/02/11 in Programare in C

Instructiunea while are formatul:

while(expresie)
instructiune

Primul rand din acest format constituie antetul instructiunii while, iar instructiune este corpul ei.

La intalnirea acestei instructiuni intai se evalueaza expresia din paranteze. Daca ea are valoarea adevarat, atunci se executa instructiune. Apoi se revine la punctul in care se evalueaza din nou valoarea expresiei dintre paranteze. In felul acesta, corpul ciclului se executa atat timp cat expresia din antetul ei este diferita de 0. In momentul in care expresie are valoarea zero, se trece la instructiunea urmatoare instructiunii while.

Corpul instructiunii while poate sa nu se execute niciodata. Intr-adevar, daca expresie are valoarea 0 de la inceput, atunci se trece la instructiunea urmatoare instructiunii while fara a executa niciodata corpul instructiunii respective.

Corpul instructiunii while este o singura instructiune, care poate fi compusa. In felul acesta, avem posibilitatea sa executam repetat mai multe instructiuni grupate intr-o instructiune compusa.

Corpul instructiunii while poate fi o alta instructiune while sau sa fie o instructiune compusa care sa contina instructiuni while. In acest caz se spune ca instructiunile while sunt imbricate.

Instructiunea din corpul unei instructiuni while poate sa defineasca un alt mod de executie a instructiunii while decat cel indicat mai sus. Astfel, ea poate realiza terminarea instructiunii while fara a se mai ajunge la evaluarea expresiei din antetul ei. De exemplu, daca in corpul unei instructiuni while se apeleaza functia exit, atunci se va termina executia ciclului while, deoarece se intrerupe chiar executia programului.

Despre instructiunea while se spune ca este o instructiune ciclica.

Exercitii:

4.9. Sa se scrie un program care calculeaza si afiseaza valoarea polinomului:

p(x) = 3x2 - 7x - 10

pentru

x = 1, 2,..., 10

Programul de fata realizeaza un proces de calcul care consta din evaluarea si afisarea valorii expresiei:

3*x*x - 7*x - 10

pentru cele 10 valori ale lui x. Pentru o valoare a lui x, acest lucru se realizeaza prin intermediul instructiunii de apel:

printf("x = %d\tp(x) = %d\n", x, 3*x*x - 7*x - 10);

Rezulta ca aceasta instructiune trebuie sa se execute repetat pentru x = 1, 2,..., 10. In acest scop, initial vom atribui lui x valoarea 1:

x = 1;

Apoi vom utiliza o instructiune while care sa permita executia repetata a instructiunii de apel a functiei printf de mai sus.

Deoarece lui x i s-a atribuit deja valoarea 1, rezulta ca la prima executie a acestei instructiuni se calculeaza p(1). Pentru ca la a doua executie a ei sa se calculeze p(2), este necesar sa se mareasca valoarea lui x cu 1. Aceasta se poate realiza folosind instructiunea expresie:

x++;

Cu alte cuvinte, este suficient sa se execute repetat secventa de instructiuni:

printf("x = %d\tp(x) = %d\n", x, 3*x*x - 7*x - 10);
x++;

x avand initial valoarea 1. Aceasta secventa formeaza corpul ciclului. De aceea, ea va fi inclusa intre acolade pentru a forma o singura instructiune compusa.

Deoarece ultima executie a secventei de mai sus are loc cand x = 10, rezulta ca ea se va repeta atata timp cat x <= 10.

In concluzie, procesul de calcul ce urmeaza a fi realizat il putem descrie astfel:

  1. x = 1;
  2. atat timp cat x <= 10 se executa:
    • afiseaza pe x si pe p(x);
    • incrementeaza pe x.
#include <stdio.h>

main()
{
    int x;

    x = 1;
    while ( x <= 10 ) {
       printf("x = %d\tp(x) = %d\n", x, 3*x*x - 7*x - 10);
       x++;
    }
}

Observatie:

Limbajul C permite scrierea de programe compacte. De exemplu, secventa de mai sus poate fi compactata folosind expresia:

++x <= 10;

In felul acesta se elimina instructiunea expresie

x++;

din corpul ciclului.

Tinand seama de ordinea operatiilor, expresia ++x <= 10; se evalueaza astfel:

  1. se incrementeaza x;
  2. se compara valoarea incrementata a lui x cu 10.

    Daca aceasta nu-l depaseste pe 10, atunci se executa corpul ciclului, care acum consta numai din apelul functiei printf.

    In caz contrar, se incheie executia ciclului while si prin aceasta se termina si executia programului.

In acest caz, se va schimba atribuirea x = 1; cu x = 0; deoarece executia corpului ciclului incepe dupa incrementarea lui x. Cu alte cuvinte, Programul 062 poate fi scris si:

...
    x = 0;
    while ( ++x <= 10 ) {
       printf("x = %d\tp(x) = %d\n", x, 3*x*x - 7*x - 10);
    }
}

Trebuie mentionat ca expresia x++ <= 10; (cu operatorul de incrementare postfixat) nu realizeaza acelasi lucru.

Intr-adevar, in cazul expresiei ++x <= 10;, atat comparatia, cat si corpul instructiunii while se executa cu valoarea incrementata a lui x.

In cazul expresiei x++ <= 10; comparatia se face cu valoarea neincrementata a lui x, iar corpul ciclului while se executa cu valoarea incrementata a lui x. De aceea, daca x = 10, atunci x++ <= 10; este falsa, deci corpul ciclului nu se mai executa, in schimb x++ <= 10; are valoarea adevarat si se va executa corpul ciclului si pentru x = 11. De aceea, vom obtine o forma corecta a programului daca in antetul ciclului vom folosi expresia x++ < 10;.

4.10. Sa se scrie un program care tabeleaza valorile functiei sin(x) cu pasul de un grad sexagesimal, x apartinand intervalului [0, 360].

Functia sinus poate fi apelata ca functie standard si are prototipul:

double sin(double x);

in fisierul header math.h.

Parametrul x este in radiani.

Daca a este un unghi in grade sexagesimale, atunci el se reprezinta in radiani daca se inmulteste cu factorul PI/180, unde PI=3.141529265...: a*PI/180.

Tabelarea functiei sinus se va realiza conform pasilor:

  1. f = PI/180;
  2. x = 0;
  3. atat timp cat x <= 359, se executa:
    • calculeaza si afiseaza sin(x*f);
    • incrementeaza pe x.
#include <stdio.h>
#include <math.h>
#include <conio.h>

#define PI 3.14159265358979

main()
{
    int x;
    double f;

    f = PI / 180;
    x = -1;
    while ( ++x <= 359 ) {
       printf("sin(%d) = %.16f\n", x, sin(x*f));
       if ((x+1)%23 == 0) {
        printf("actionati o tasta pentru a continua\n");
        getch();
       }
    }
}

Observatie: Valorile functiei sinus se afiseaza cate una pe linie, de aceea programul afiseaza 360 de linii.

In astfel de situatii se pune problema blocarii executiei unui program dupa ce acesta a afisat un ecran de rezultate. Pentru a realiza acest lucru se poate utiliza functia getch in momentul in care se doreste sa se analizeze datele afisate in fereastra utilizator.

La apelul functiei getch programul se blocheaza deoarece se asteapta actionarea unei taste si se afiseaza automat fereastra utilizator.

In exemplul de fata vom apela functia getch ori de cate ori programul a afisat 23 de valori ale functiei sinus. Pe linia 24 se va afisa textul: actionati o tasta pentru a continua. Ecranul trebuie blocat dupa apelul functiei printf in momentul in care x + 1 are valorile: 23, 46, 69,... si acest lucru se exprima prin expresia: (x+1)%23 == 0.

Deci functia getch se apeleaza cand expresia de mai sus este adevarata.

4.11. Sa se scrie un program care citeste un sir de intregi separati prin caractere albe si afiseaza suma lor. Dupa ultimul numar se va tasta un caracter alb urmat de un caracter nenumeric (de ex. sfarsitul de fisier <Ctrl>-z, o litera etc.), iar dupa aceasta se va actiona tasta Enter.

Programul de fata are o parte care se executa repetat:

  1. citeste constructia curenta de la intrare
  2. daca la intrare s-a aflat un intreg, atunci acesta se aduna la valoarea unei variabile s si se revine la punctul 1.

Altfel se intrerupe citirea.

De aici rezulta ca initial s trebuie sa aiba valoarea 0.

Un intreg se citeste folosind functia scanf. Daca notam cu i variabila careia i se atribuie intregul citit, atunci la citirea unui intreg, expresia: scanf("%d", &i) == 1 are valoarea adevarat. Deci valoarea lui i trebuie adunata la s atata timp cat expresia de mai sus este adevarata. Expresia de mai sus se utilizeaza in antetul instructiunii while, iar corpul ciclului se compune din instructiunea: s = s + i;.

#include <stdio.h>

main()
{
    int i, s;

    s = 0;
    while (scanf("%d", &i) == 1) {
      s += i;
      printf("suma = %d\n", s);
    }
}

4.12. Sa se scrie un program care citeste un intreg n care apartine intervalului [0, 170], calculeaza si afiseaza n!.

Avem:

n! = 1*2*3*...*(n-1)*n

pentru n>0, si 0! se considera egal cu 1.

Acest de calcul implica un proces ciclic:

  1. f = f*i;
  2. i = i + 1;

unde notam cu f produsul factorial. Aceasta secventa se executa repetat atat timp cat i <= n este adevarata.

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

main()
{
    int n, i;
    double f;

    printf("valoarea lui n:");
    if (scanf("%d", &n) != 1) {
        printf("nu s-a tastat un intreg\n");
        exit(1);
    }
    if (n < 0 || n > 170) {
        printf("n nu apartine intervalului [0, 170]\n");
        exit(1);
    }
    f = 1.0;
    i = 2;
    while ( i <= n )
        f = f*i++;
    printf("n = %d\tn! = %g\n", n, f);
}

4.13. Sa se scrie un program care citeste componentele a doi vectori x si y, calculeaza si afiseaza valoarea produsului lor scalar.

Daca vectorul x are componentele: x1, x2,..., xn iar y: y1, y2,..., yn atunci produsul lor scalar se defineste prin suma de produse:

(x, y) = x1*y1 + x2*y2 +...+ xn*yn

Componentele celor doi vectori se tasteaza in urmatoarea ordine:

x1 y1
x2 y2
...
xn yn

Pe randul care urmeaza dupa ultima pereche se poate tasta o litera, un caracter special care nu intra in compunerea unui numar sau sfarsitul de fisier.

#include <stdio.h>

main()
{
    double x, y, prodscal;
    int i;

    prodscal = 0.0;
    printf("componentele lui x si y:\n");
    i = 0;
    while (scanf("%lf %lf", &x, &y) == 2) {
        printf("x[%d]\ty[%d]:", i+1, i+1);
        prodscal += x*y;
        i++;
        printf("numarul componentelor vectorilor este: %d\n", i);
        printf("produsul scalar al lui x si y este: %g\n", prodscal);
    }
}

4.14. Sa se scrie un program care citeste fara ecou caractere imprimabile si le afiseaza ca si caractere minus (-). Programul se intrerupe la tastarea unui caracter care nu apartine codului ASCII.

La realizarea programului vom folosi functiile getch si putch.

Functia getch returneaza codul ASCII al caracterului citit sau ) daca se citeste un caracter care nu apartine codului ASCII. Expresia c = getch() atribuie variabilei c codul ASCII al caracterului citit. Se vor recodifica prin - numai caracterele imprimabile, adica de cod ASCII din intervalul [32, 126]. Restul caracterelor se neglijeaza. Daca c are ca valoare codul caracterului citit, atunci instructiunea:

if (c <= 32 && c >= 126)
putch('-');

permite afisarea caracterului respectiv ca si caracter minus, daca acesta este imprimabil; altfel el este neglijat. Aceasta instructiune se executa repetat, cat timp se tasteaza un caracter care apartine codului ASCII. De aceea, ea va forma corpul unui ciclu while.

In antetul acestui ciclu vom folosi instructiunea c = getch(), care este diferita de 0 (adevarata) pentru caracterele codului ASCII si 0 (falsa) pentru restul caracterelor.

#include <conio.h>

main()
{
    int c;

    while (c = getch())
        if (c >= 32 && c <= 126)
    putch('-');
}

4.15. Sa se scrie un program care apeleaza functia putch cu valorile codului ASCII extins.

Codul ASCII extins cuprinde valorile intregi din intervalul [0, 255].

Pe o linie se va afisa valoarea codului urmata de imaginea corespunzatoare afisat prin functia putch. Ecranul se blocheaza dupa 23 de linii afisate si pe linia urmatoare se afiseaza mesajul:

pentru a continua actionati o tasta

Dupa actionarea unei taste ecranul se deblocheaza si se afiseaza un nou set de imagini s.a.m.d..

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

main()
{
    int c;

    c = -1;
    while ( ++c <= 255 ) {
        printf("cod: %4d\t", c);
        putch(c);
        putchar('\n');
        if ( (c + 1) % 22 == 0 ) {
            printf("pentru a continua actionati o tasta\n");
            getch();
        }
    }
}

4.16. Sa se scrie un program care citeste rezultatele unor masuratori:

x1, x2, ...,xn

calculeaza si afiseaza:

Daca notam cu meda media aritmetica a masuratorilor, atunci abaterea patratica este radacina patrata din expresia:

[(x1-meda)2 + (x2-meda)2 + ...+ (xn-meda)2] / N

unde: N - este n sau n - 1. Numitorul se ia egal cu n - 1 cand n este relativ mic.

De obicei: N = n - 1 pentru n < 30

si

N = n pentru n >= 30.

Evident, n >= 2.

Deoarece pentru calculul abaterii patratice este nevoie de masuratorile x1, x2, ..., xn, cat si de media lor aritmetica, programul va trebui sa le pastreze intr-un tablou unidimensional, pe care il notam cu x.

Vom presupune ca exista cel mult 500 de masuratori: n <= 500

Media geometrica se calculeaza prin extragerea radacinii de ordinul ng din produsul celor ng masuratori pozitive dintre cele n masuratori citite.

Setul de masuratori sunt date flotante in simpla precizie si se considera terminat daca se tasteaza un caracter nenumeric.

Programul listeaza masuratorile citite, cate 5 pe un rand. De asemenea, programul se blocheaza dupa afisarea a 23 de linii cu masuratori.

#define MAXMAS 500
#define LIMNUMIT 30
#define APEL printf("masuratoarea a %d-a: ", n + 1)

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

main()
{
    float x[MAXMAS];
    double meda, medg, ap;
    int n, ng, i;

    n = ng = 0;
    meda = 0;
    medg = 1.0;
    APEL;

    /*
    - se citesc masuratorile;
    - se insumeaza;
    - se inmultesc cele pozitive.
    */
    while (scanf("%f", &x[n]) == 1) {
        meda += x[n];
        if (x[n] > 0) {
            medg *= x[n];
            ng++;
        }
    n++;
    APEL;
    }
    if ( n < 1 ) {
        printf("nu s-a tastat nicio masuratoare\n");
        exit(1);
    }
    /*calculeaza media aritmetica*/
    meda /= n;

    /*calculeaza media geometrica*/
    if ( ng < 2 ) {
        printf("nu exista nici 2 masuratori pozitive\n");
        medg = -1.0;
    }
    else
        medg = pow(medg, 1.0/ng);
    if ( n > 1) {
    /*calculeaza abaterea patratica*/
        ap = 0.0;
        i = 0;
        while ( i < n ) {
            ap += (x[i] - meda)*(x[i] - meda);
            i++;
        }
        if ( n < LIMNUMIT)
            ap /= n - 1;
        else
            ap /= n;
        }
    else {
        printf("nu exista nici 2 masuratori\n");
        ap = -1;
    }
    /*listeaza masuratorile, cate 5 pe un rand*/
    i = 0;
    while ( i < n ) {
        printf("x[%d]=%g%c", i+1, x[i], i%5==4 || i==n-1 ? '\n' : ' ');
        i++;
        if ( i%(5*23) == 0 ) {
            printf("pentru a continua actionati o tasta\n");
            getch();
        }
    }
    /*afiseaza mediile si abaterea patratica*/
    printf("media aritmetica = %g\n", meda);
    if (medg != -1.0)
        printf("media geometrica = %g\n", medg);
    if ( n > 1 )
        printf("abaterea patratica = %g\n", sqrt(ap));
}

Observatii:

1. Pentru a afisa masuratorile cate 5 pe un rand s-a apelat functia printf folosind trei specificatori de format in parametrul de control:

"x[%d] = %d%c"

Parametrul corespunzator lui %d este i + 1. Acesta defineste numarul de ordine al masuratorii curente.

Parametrul corespunzator lui %g este x[i] si reprezinta valoarea masuratorii curente.

Dupa specificatorul %g urmeaza specificatorul %c, a carui parametru defineste caracterul care se afiseaza dupa valoarea masuratorii curente. Acest caracter poate fi spatiu (' ') sau caracterul de rand nou ('\n').

Pe primul rand se afiseaza valorile:

x[0] x[1] x[2] x[3] x[4]

deci, dupa masuratorile de indice 0, 1, 2, 3, 4 se afiseaza un spatiu, iar dupa x[4] urmeaza caracterul rand nou.

Analog, pe al doilea rand se afiseaza valorile:

x[5] x[6] x[7] x[8] x[9]

deci, dupa masuratorile de indice 5, 6, 7, 8, 9 se afiseaza un spatiu, iar dupa x[9] urmeaza caracterul rand nou.

In general, pe un rand se afiseaza valorile:

x[5k] x[5k + 1] x[5k + 2] x[5k + 3] x[5k + 4]

Se observa ca dupa o masuratoare de indice 5k + 4 urmeaza caracterul de rand nou, iar in rest urmeaza spatiu.

Un indice i este de forma 5k + 4, daca restul impartirii lui i la 5 este egal cu 4, adica daca expresia:

i%5 == 4

este adevarata.

De asemenea, dupa ultima masuratoare se va afisa caracterul de rand nou, adica daca:

i == n - 1

are valoarea adevarat.

Rezulta ca afisarea caracterului de rand nou se va face numai atunci cand expresia:

i%5 == 4 || i == n - 1

este adevarata. In rest se afiseaza un caracter spatiu. Aceasta situatie se reprezinta simplu prin expresia conditionala:

i%5 == 4 || i == n - 1 ? '\n' : ' '

Acest lucru demonstreaza odata in plus, facilitatile mari oferite de expresiile conditionale la compactarea programelor.

2. Pentru a calcula radicalul de ordinul ng din medg se apeleaza functia pow cu parametrul medg si 1.0/ng.

Functia pow are prototipul:

double pow(double x, double y);

si returneaza pe x la puterea y. In cazul de fata 1.0/ng are tipul double deoarece 1.0 este o constanta de tip double. Trebuie mentionat ca expresia 1/ng are valoarea zero (impartire de intregi cu ng>1) deci este necesara utilizarea constantei 1.0. Apelul functiei pow returneaza pe medg la puterea 1.0/ng, adica radical de ordinul ng din medg.

4.17. Sa se scrie un program care citeste un cuvant (succesiune de caractere diferite de caracterele albe) si afiseaza prefixele si sufixele lui diferite de el insusi.

Fie cuvantul:

c+t*f

atunci prefixele acestui cuvant, diferite de el insusi sunt:

In mod analog, sufixele aceluiasi cuvant sunt:

Se presupune ca un cuvant nu depaseste 70 de caractere.

Programul peste eventualele caractere albe care preced cuvantul de prelucrat. Apoi citeste caracterele din compunerea cuvantului si le pastreaza ca elemente ale unui tablou t.

Cuvantul se termina la:

Caracterele se citesc folosind macroul getchar. Acesta se apeleaza prin expresia de atribuire:

c = getchar()

care atribuie lui c codul ASCII al caracterului citit. Pentru a avansa peste caracterele albe este necesar sa stabilim daca codul atribuit lui c este codul spatiului, al tabulatorului sau al caracterului de rand nou. Expresia:

(c = getchar()) == ' '

compara codul caracterului citit cu cel al spatiului si are valoarea adevarat, daca s-a citit un spatiu si fals in caz contrar.

In mod analog, pentru caracterele tabulator si newline se folosesc expresiile:

c == '\t'

si

c == '\n'

Rezulta ca, daca se citeste un caracter alb, atunci este adevarata una dintre cele trei expresii de mai sus, ceea ce conduce la faptul ca expresia:

(1)

(c == getchar()) == ' ' || c == '\t' || c == '\n'

este adevarata daca si numai daca se citeste un caracter alb.

De aici, rezulta ca pentru a avansa peste caracterele albe vom utiliza un ciclu while care se va executa atat timp cat expresia (1) este adevarata. Deci, antetul ciclului este:

while((c == getchar()) == ' ' || c == '\t' || c == '\n')

Deoarece acest ciclu nu are altceva de realizat decat sa avanseze peste spatii albe, corpul lui se compune din instructiunea vida.

Citirea caracterelor cuvantului de la intrare se face tot printr-o instructiune while. De data aceasta, ciclul while se executa atata timp cat expresia (1) este falsa, nu s-a intalnit sfarsitul de fisier (EOF) si nici nu s-au citit inca 70 de caractere.

Prima conditie se exprima prin negatia expresiei (1), presupunand ca c contine deja caracterul curent.

(2)

!(c == ' ' || c == '\t' || c == '\n')

Tinand seama de faptul ca expresia !(a || b) este echivalenta cu !a && !b, expresia (2) se poate scrie sub forma:

(3)

!(c == ' ') && !( c == '\t') && !(c == '\n')

Deoarece expresia !(a == b) este echivalenta cu a != b, expresia (3) se poate pune sub o forma mai simpla:

(4)

c != ' ' && c != '\t' && c != '\n'

A doua conditie pentru continuarea ciclului while este ca sa nu se citeasca sfarsitul de fisier. Aceasta inseamna ca expresia:

(5)

c != EOF

trebuie sa fie adevarata.

Daca notam cu i numarul de caractere citite, diferite de caracterele albe, atunci ciclul while continua daca, pe langa conditiile (4) si (5) de mai sus, este adevarata si conditia exprimata prin expresia (6) i < 70 (se presupune ca initial i = 0;)

De aici rezulta ca ciclul while pentru citirea caracterelor cuvantului aflat la intrare se continua atata timp cat expresiile (4), (5) si (6) sunt adevarate, ceea ce se exprima conectand expresiile respective prin operatorul "si logic".

In corpul ciclului se pastreaza codul caracterului citit in tabloul t de tip caracter, se incrementeaza numaratorul de caractere si apoi se citeste caracterul urmator. Aceasta se realizeaza prin instructiunile de atribuire:

t[i++] = c;
c = getchar();

Pentru determinarea prefixelor cuvantului urmarim pasii de mai jos, unde:

i are ca valoare lungimea cuvantului;
j are ca valoare lungimea prefixului curent;
k numara caracterele unui prefix.

  1. j = 1 - primul prefix are lungimea 1;
  2. cat timp j < i se executa:
    2.1. k = 0;
    2.2. cat timp k < j se executa:
      2.2.1. se afiseaza t[k];
      2.2.2. se mareste k cu o unitate.
    2.3. se afiseaza newline deoarece s-au afisat toate caracterele prefixului curent;
    2.4. se mareste j cu o unitate pentru a afisa prefixul urmator.

Pasul 2 se realizeaza prin doua cicluri while imbricate:

while ( j < i) {
k = 0; /*punctul 2.1.*/
while ( k < j) { /*punctul 2.2.*/
    putchar(t[k]); /*punctul 2.2.1.*/
    k++; /*punctul 2.2.2.*/
}
putchar('\n'); /*punctul 2.3.*/
j++; /*punctul 2.4.*/
}

Sufixele se pot determina printr-o secventa analoga. Daca in cazul prefixelor, acestea incep toate cu t[0], in cazul sufixelor, caracterul de inceput este variabil. Astfel, sufixul de lungime 1 contine numai ultimul caracter al cuvantului, deci este t[i-1]. Sufixul de lungime 2 se compune din ultimele doua caractere ale cuvantului: t[i-2] si t[i-1].

In general, sufixul de lungime j se compune din caracterele:

t[i-j], t[i-j+1], ..., t[i-1]

De aceea, in acest caz, variabila k nu se mai initializeaza cu 0, ci cu i-j.

Deoarece toate sufixele au ca ultim caracter pe t[i-1], rezulta ca variabila k variaza cu pasul 1 de la i-j pana la i-1. In rest, secventa pentru determinarea sufixelor este aceeasi cu cea pentru determinarea prefixelor.

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

#define MAX 70


main()
{
    int c, i, j, k;
    char t[MAX];

    while ((c = getchar()) == ' ' || c == '\t' || c == '\n');

    if (c == EOF) {
        printf("cuvant vid\n");
        exit(1);
    }
    i = 0;
    while (c != ' ' && c != '\t' && c != '\n' && c != EOF && i < MAX) {
        t[i++] = c;
        c = getchar();
    }
    j = 1;
    while ( j < i ) {
        k = 0;
        while ( k < j )
            putchar(t[k++]);
        putchar('\n');
        j++;
    }
    j = 1;
    while( j < i ) {
        k = i - j;
        while ( k < i )
            putchar(t[k++]);
        putchar('\n');
        j++;
    }
}

4.7. Instructiunea for