6.1. Instruciune simpl de decizie Fie urmtoarea problem ce trebuie rezolvat prin intermediul unui program: S se reali:e:e un program care face automat calculul mediei de licen i a mediei generale. Programul primeste trei medii de le examenele de licen si nota primit la susinerea proiectului de stat. El trebuie s calculeze media ntre notele de la examenele de licen, rezultnd o prim medie, care apoi se mediaz cu nota de la proiectul de stat rezultnd media general. Exist o limitare asupra datelor de intrare care trebuie realizat de program si anume dac una din mediile de la examenul de licen este mai mic ca cinci s nu mai realizeze calculul mediilor Iinale si s-l declare pe respectivul candidat respins. O soluie de rezolvare a problemei la nivel de pseudocod arat ca mai jos: include librriile necesare lucrului in mod text void main(void) {//nceput program declar variabilele n1,n2,n3,ns,m1,m2 de tip real, terge ecranul, citete nota1 in variabila n1, citete nota2 in variabila n2, citete nota3 in variabila n3, dac (n1~5) i (n2~5) i (n3~5) atunci { citete nota stat in variabila ns; reali:ea: media m1(n1n2n3)/3, reali:ea: media m2(m3ns)/2, afiea: media de licena m1, afiea: media general m2, } altfel afiea: 'Candidat respins`, ateapt o tast, }// sfarit de program Se observ c a Iost nevoie de o ramiIicare la nivelul procesrii datelor, ramiIicare care apare din nevoile utilizatorului. Este nevoie ca la un moment dat s hotrm moduri multiple de prelucrare pentru acelasi Ilux de date de intrare. n limbajul C pentru a implementa acest tip de decizii a Iost introdus instruciunea if cu sintaxa ca mai jos: if (condiieadevrat) dac condiia este adevrat { execut bloc instruciuni1 execut bloc instruciuni1 altfel } execut bloc instruciuni1 else { execut bloc instruciuni2 }; Sintaxa instruciunii este identic cu pseudocodul, bineneles c se Ioloseste limba englez. Fig. 6.1a. Repre:entarea prin schema logic a instruciunii de deci:ie Fig. 6.1b. Repre:entarea prin schema logic a instruciunii de deci:ie simple n Iigurile 6.1a si 6.1b este prezentat reprezentarea la nivel de schem logic a instruciunii de decizie. Spre deosebire de alte limbaje de programare, cum ar Ii PASCAL de exemplu, limbajul C nu Ioloseste variabile de tip logic pentru rezultatul evalurii unei expresii. Valorile comparate pot rezulta din valoarea returnat de o Iuncie, din cea stocat ntr-o variabil sau direct dat n program. Dac n locul condiiei, n urma evalurii expresiei rezult un numr diIerit de zero, acesta va Ii considerat ca condiie ndeplinit si deci se va executa blocul1 de instruciuni, dac este zero condiia nu este satisIcut atunci se va executa blocul2 de instruciuni. Acest lucru conIer un mare avantaj prin Iaptul c se pot introduce direct expresii matematice sau apeluri de Iuncii ce returneaz rezultate numerice n zona de test a condiiei. Nu ntotdeauna este nevoie de ambele pri ale instruciunii, de exemplu cnd se execut o operaiune numai dac este ndeplinit o anumit condiie. De Iapt structura logic de control ar trebui prevzut si cu o ramur de else dar acest lucru nu ar duce dect la suprancrcarea codului, ceea ce ngreuneaz mult depanarea programului, rezultnd sintaxa prezentat mai jos: if (condiieadevrat) dac condiia este adevrat atunci { execut bloc instruciuni execut bloc instruciuni }; n cazul n care sunt implicate mai multe decizii simple care trebuiesc luate Iuncie de diIerite valori ale unei singure variabile, limbajul este prevzut cu instruciune specializat case.. Discuia acestei instruciuni se va Iace ulterior. Mai jos este prezentat programul corespunztor pseudocodului prezentat anterior. #include <stdio.h> #include <conio.h> void main(void) { float n1,n2,n3,ns,m1,m2; clrscr(); printf(Dati prima nota:); scanf(%f,&n1); printf(\nDati a doua nota:); scanf(%f,&n2); printf(\nDati prima nota:); scanf(%f,&n1); if( (n1>5) && (n2>5) && (n3>5)) { printf(\nDati nota de la stat:); scanf(%f,&ns); m1=(n1+n2+n3)/3; m2=(m3+ns)/2; printf( media de licenta %f, m1); printf( media generala %f,m2); } else printf(Candidat respins); getch(); } Observaii: 1. n aceast Iaz Iaptul c s-a Iolosit o reIerin, pentru citirea unei variabile (vezi &n1) nu poate Ii explicat suIicient si va trebui luat ca atare n cazul citirii variabilelor simple. 2. Operatorul \n` realizeaz un salt la linie nou. 3. Se observ c pe ramura de else nu s-au introdus delimitatorii de bloc (acoladele) pentru c dac acestia nu sunt precizai prima instruciune este automat considerat aparinnd ramurii respective. 4. Pentru programatorii mai avansai: n momentul n care blocul de instruciuni este Iormat dintr-o singur instruciune se poate Iolosi operatorul ? ca n exemplul de mai jos, unde : if(a>b) x=25; else yx=34; poate fi echivalat prin: a>b (x=25) : (y=34); Un alt exemplu de Iolosire a operatorului ? este o linie de cod care calculeaz maximul dintre var1 si var2 si-l depune n variabila max. max=(var1>var2) ? var1 : var2; Mai jos vom prezenta un program simplu cu exemple despre evaluarea unor expresii compuse ntr-un program: void main(void) { int x = 11,y = 11,z = 11; char a = 40,b = 40,c = 40; float r = 12.987,s = 12.987,t = 12.987; if (x v) : -13, /* execuia instruciunii va avea ca efect : -13 */ if (x ~ :) a A, /* execuia instruciunii va avea ca efect a 65 */ if ('(x ~ :)) a B, /* execuia instruciunii nu va avea nici un efect */ if (b c) r 0.0, /* execuia instruciunii va avea ca efect r 0.0 */ if (r ' s) t c/2, /* execuia instruciunii va avea ca efect t 20 */ if (x (r ' s)) : 1000, /* execuia instruciunii va avea ca efect faptul c x va lua valori po:itive iar : 1000 */ if (x v) : 222, /* execuia instruciunii va avea ca efect x v i : 222 */ if (x ' 0) : 333, /* execuia instruciunii va avea ca efect : 333 */ if (x) : 444, /* execuia instruciunii va avea ca efect : 444 */ x = y = z = 77; if ((x v) && (x 77)) : 33, /* execuia instruciunii va avea ca efect z = 33 */ if ((x ~ v) ,, (: ~ 12)) : 22, /* execuia instruciunii va avea ca efect z = 22 */ if (x && v && :) : 11, /* execuia instruciunii va avea ca efect z = 11 */ if ((x 1) && (v 2) && (: 3)) r 12.00, /* execuia instruciunii va avea ca efect x = 1, y = 2, z = 3, r = 12.00 */ if ((x 2) && (v 3) && (: 4)) r 14.56, /* execuia instruciunii nu va avea nici un efect */ if (x == x); z = 27.345; /* z se va modifica ntotdeauna */ if (x ' x) : 27.345, /* v nu se va modifica nici o dat */ if (x 0) : 27.345, /* x va lua valoarea 0 , : va rmane neschimbat */ } 6.2. Instruciune de decizie multipl (selecie) Exist situaii n care rezolvarea unei probleme impune ca o decizie s conduc la execuia a mai mult de dou ramuri de program. Ca exemplu s considerm cazul celei mai simple Iorme de meniu care poate Ii oIerit unui utilizator. Se citeste un numr de la tastatur. Funcie de valoarea dat se poate alege execuia uneia dintre opiunile prezentate utilizatorului. Mai jos este prezentat un meniu simplu folosind metoda pseudocodului. terge ecran afiea: mesaf 'Apas una din taste pentru a alege operaiunea dorit` afiea: mesaf '1- Citire din fiier` afiea: mesaf '2- Scriere in fiier` afiea: mesaf '3- Procesare date` afiea: mesaf '4- afiare grafic re:ultat` citete o tast funcie de tast citit dac e 1 . apelea: funcia de citire din fiier apoi stop dac e 2 . apelea: funcia de scriere in fiier apoi stop dac e 3 . apelea: funcia de procesare date apoi stop dac e 4 . apelea: funcia de afiare grafic a re:ultate apoi stop dac nu e nici unul din numerele de mai sus . afiea: mesaf 'Opiune invalid` Se observ c se poate realiza implementarea si cu instruciuni if dar, acest lucru nu este justiIicat att timp ct avem o instruciune specializat pentru acest tip de situaii. Aceasta este instruciunea case. cu urmtoarea sintax: switch(operand) //funcie de operand { case val1. // dac operandul ia valoarea 1 bloc de instruciuni 1 break; // stop case val2. // dac operandul ia valoarea 2 bloc de instruciuni 2 break; // stop ... case valn. // dac operandul ia valoarea n bloc de instruciuni n break; // stop default . // pentru orice alt valoare bloc de instruciuni ce tratea: restul valorilor ce le poate avea operandul } // stop O Iorm de reprezentare la nivel de schema logic ar Ii cea prezentat n Iigura 6.2. Fig. 6.2. Schema logic pentru repre:entarea unei structuri de selecie multipl Mai jos este prezentat un program care citeste doi operanzi de la tastatur apoi ne permite selecia operaiei matematice ce trebuie realizat ca n Iinal s aIiseze rezultatul. #include <stdio.h> #include <conio.h> void main(void) { int op1, op2; float rez; char oper; clrscr(); printf(Dati primul operand:); scanf(%d,&op1); printf(\nDati al doilea operand:); scanf(%d,&op2); printf(\nSelectionati operatia dorita); oper=getch(); printf(/n1- Adunare); printf(/n2- Scadere); printf(/n3- Inmultire); printf(/n4-Impartire ); switch(oper) { case 1:rez=op1+op2;break; case 2:rez=op1-op2; break; case 3:rez=op1*op2; break; case 4:rez=op1/op2; break; default: clrscr(); printf(Operatie nepermisa); } printf(\nRezultatul este: %d, rez); }