5.10. Instrucţiunea break
Formatul instrucţiunii este următorul:
break;
De obicei instrucţiunea break se foloseşte pentru a ieşi dintr-un ciclu. Dacă există mai multe cicluri imbricate instrucţiunea break va trece controlul la ciclul de nivel imediat superior (deci imbricarea rămâne, nu se iese din toate ciclurile). O altă utilizare este în instrucţiunea switch, după cum am observat în paragraful anterior.
Un alt exemplu de utilizare frecventă este ieşirea dintr-un ciclu infinit de forma:
for ( ; ; )
{. . .
if (exp) break;
. . .
}
5.11. Instrucţiunea continue
Formatul instrucţiunii este următorul:
continue;
Efectul:
-
în ciclurile while şi do-while ea realizează saltul la evaluarea expresiei care decide asupra continuării ciclului;
-
în ciclul for ea realizează saltul la pasul de reiniţializare.
Observaţie:
1o. Instrucţiunea continue se utilizează numai în corpul unui ciclu, permiţând, după caz, să se treacă la pasul următor al ciclului sau să se iasă din ciclu.
5.12. Instrucţiunea goto
Conform principiilor programării structurate instrucţiunea goto nu ar fi necesară. Dar ea a fost introdusă în limbaj, deoarece, în anumite cazuri, se dovedeşte a fi utilă, asigurând o flexibilitate mai mare în programare. De multe ori ieşirea dintr-un ciclu imbricat în alte cicluri se realizează mai simplu cu ajutorul instrucţiunii goto. În lipsa ei ar trebui să folosim mai mulţi indicatori şi teste asupra valorilor acestora pentru ieşirea din ciclu. Saltul făcut de goto se face la o instrucţiune care este prefixată de o etichetă.
Prin etichetă vom înţelege un nume urmat de caracterul “:”. Etichetele sunt locale unei funcţii.
Instrucţiunea goto are următorul format:
goto eticheta;
Efectul:
-
se realizează saltul la instrucţiunea prefixată de eticheta al cărei nume se află scris după cuvântul cheie goto.
5.13. Apelul şi revenirea dintr-o funcţie
5.13.1. Apelul unei funcţii
În limbajul C funcţiile sunt de două tipuri:
-
funcţii care returnează o valoare la revenirea din ele;
-
funcţii care nu returnează nici o valoare la revenirea din ele.
O funcţie care nu returnează nici o valoare la revenirea din ea se apelează printr-o instrucţiune de apel. Ea are următorul format:
nume (lista_parametrilor_efectivi); (*)
unde:
-
nume este numele funcţiei;
-
lista_parametrilor_efectivi este fie vidă, fie se compune din una sau mai multe expresii separate prin virgulă.
Instrucţiunea de apel este un caz particular al instrucţiunii expresie. Parametrii efectivi (de la apel) trebuie să corespundă cu cei formali (de la definirea funcţiei) prin ordine, tip şi număr.
În cazul în care o funcţie returnează o valoare, ea poate fi apelată fie printr-o instrucţiune de apel, fie sub forma unui operand al unei expresii.
Observaţii:
1o. Dacă nu dorim să utilizăm valoarea returnată de funcţia respectivă, apelul se face printr-o instrucţiune de apel.
2o. Dacă dorim să utilizăm valoarea returnată de funcţie, vom folosi apelul funcţiei drept operand într-o expresie, operandul având formatul (*).
Exemple de apeluri de funcţii folosite până acum sunt apelurile funcţiilor standard printf, scanf, getchar şi putchar. Funcţiile printf şi putchar au fost apelate prin instrucţiuni de apel, valorile returnate de ele nefiind utilizate. În schimb funcţiile scanf şi getchar au fost apelate în ambele moduri, atât prin instrucţiuni de apel, cât şi ca operanzi în diferite expresii.
5.13.2. Prototipul unei funcţii
O funcţie poate fi apelată dacă ea este definită în fişierul sursă înainte de a fi apelată. După cum am prezentat în lecţia 1 nu întotdeauna este posibil acest lucru şi în astfel de cazuri apelul funcţiei trebuie să fie precedat de prototipul ei.
Prototipul unei funcţii are ca scop să informeze compilatorul despre:
-
tipul valorii returnate de funcţie;
-
tipurile parametrilor.
În felul acesta, la apelul unei funcţii, compilatorul poate face teste cu privire la tipul expresiilor care reprezintă parametrii efectivi, precum şi unele conversii necesare asupra valorii returnate de funcţie.
Observaţii:
1o. Tipurile parametrilor pot să lipsească. În acest caz, compilatorul nu controlează tipurile parametrilor efectivi, singura informaţie conţinută de prototip fiind tipul valorii returnate de funcţia respectivă.
2o. Absenţa atât a prototipului unei funcţii, cât şi a definiţiei funcţiei înainte de a fi apelată este posibilă; în acest caz se presupune că funcţia returnează o valoare de tip int.
3o. În practică se recomandă utilizarea prototipurilor pentru toate funcţiile înainte de a fi apelate. În acest scop, ele vor fi scrise la începutul fişierelor sursă.
Formatele posibile ale unui prototip sunt:
formatul 1: tip nume (lista_declaratiilor_de_parametri);
formatul 2: tip nume (lista_ tipurilor_parametrilor);
formatul 3: tip nume (void);
formatul 4: tip nume ();
Formatul 2 este cel mai utilizat. Formatul 3 se poate folosi pentru orice funcţie care nu are parametri. Formatul 4 se poate folosi pentru orice funcţie la al cărei apel nu se doresc teste referitoare la tipul parametrilor efectivi.
Funcţiile din biblioteca standard a limbajului C au prototipurile definite în fişierele de tip .h.
5.13.3. Apel prin valoare şi apel prin referinţă
La apelul unei funcţii, fiecărui parametru formal i se atribuie valoarea parametrului efectiv care-i corespunde. Deci, la apelul unei funcţii se transferă valorile parametrilor efectivi. Din această cauză se spune că apelul este prin valoare (call by value). În anumite limbaje de programare, la apel nu se transferă valorile parametrilor efectivi ci adresele acestora. În acest caz se spune că apelul este prin referinţă (call by refference).
Între cele două tipuri de apeluri există o diferenţă esenţială şi anume: în cazul apelului prin valoare funcţia apelată nu poate modifica parametrii efectivi din funcţia apelantă, neavând acces la ei. În cazul apelului prin referinţă, funcţia apelată, dispunând de adresele parametrilor efectivi, îi poate modifica.
În limbajul C apelul se realizează implicit prin valoare. În cazul că un parametru este numele unui tablou atunci transferul se realizează prin referinţă deoarece numele unui tablou este un pointer şi conţine adresa primului element al tabloului. Transferul prin referinţă se realizează cu ajutorul variabilelor de tip pointer şi cu ajutorul operatorului de adresă (&).
5.13.4. Revenirea dintr-o funcţie
Revenirea dintr-o funcţie se poate face în două moduri:
-
la întâlnirea instrucţiunii return;
-
după execuţia ultimei sale instrucţiuni, adică a instrucţiunii care precede acolada închisă ce termină corpul funcţiei respective.
Instrucţiunea return are două formate:
return; sau return expresie;
Primul format se utilizează când funcţia nu returnează o valoare, iar cel de-al doilea când funcţia returnează o valoare. În acest ultim caz, funcţia returnează valoarea expresiei specificate.
Observaţie:
1o. Când revenirea se face după execuţia ultimei instrucţiuni a funcţiei nu se returnează o valoare; revenirea în acest caz, se face ca şi cum acolada închisă de la sfârşitul corpului funcţiei ar fi precedată de instrucţiunea return.
Exemplu: vom da un exemplu de apel al funcţiei care determină rădacina pătratică dintr-un număr nenegativ.
#include
double radacina_2 (double); // prototipul functiei
void main (void) // functia principala care citeste d
// si afiseaza radacina patrata din d
{ double d;
clrscr(); // sterge ecranul
if (scanf (“%lf”,&d) != 1 || d<0)
printf (“numarul dat este eronat\n”);
else
printf (“d=%f, radacina patrata = %.10g\n”, d, radacina_2(d));
#define EPS 1e-10
double radacina_2 (double x)
{ double x1,x2,y;
x2 = 1.0;
do { x1 = x2;
x2 = 0.5 *(x1+x/x1); // formula de iteratie
if ((y=x2-x1) < 0) y = -y;
}
while (y >= EPS);
return x2;
}
Observaţie:
1o. Limbajul C dispune de o bibliotecă matematică în care sunt incluse o serie de funcţii pentru calculul valorilor funcţiilor elementare. Există o funcţie numită sqrt (cu prototipul double sqrt (double);). Fişierul care conţine biblioteca matematică se numeşte math.h şi trebuie inclus în fişierul sursă de lucru dacă se doreşte utilizarea funcţiilor definite în el.
Dostları ilə paylaş: |