PC Laborator 5: Diferență între versiuni

De la WikiLabs
Jump to navigationJump to search
(Anularea modificării 3364 făcute de Radu Hobincu (Discuție))
 
(Nu s-au afișat 35 de versiuni intermediare efectuate de alți 6 utilizatori)
Linia 5: Linia 5:
* scrie programe în C folosind construcții decizionale.  
* scrie programe în C folosind construcții decizionale.  
    
    
== Structura decizionala ==  
== Structura decizională ==  
    
    
Se întâmplă adesea ca evoluția unui program să depindă de un moment prezent. Acel moment prezent poate lua însă diverse forme, rolul programatorului fiind să conducă execuția programului pe calea corectă, pe baza unor condiții. Apare astfel structura decizionala if, care ramifică evoluția programului în funcție de valoarea de adevăr  a condiției testate.   
Se întâmplă adesea ca evoluția unui program să depindă de o anumită condiție. Ea poate lua însă diverse forme, rolul programatorului fiind să conducă execuția programului pe calea corectă, ținând cont de acea condiție logică. Apare astfel structura decizionala if, care ramifică evoluția programului în funcție de valoarea de adevăr  a condiției testate.   
    
    
=== Schema logică ===  
=== Schema logică ===  
Prima etapă din parcurgerea unei structuri decizionale de tipul if-else o reprezintă testarea condiției logice. în cazul în care aceasta este evaluată ca adevărată se execută instructiunea1, cea asociată ramurii if. în cazul în care condiția logică este evaluată ca falsă se execută instructiunea2, cea asociată ramurii else. După executarea instrucțiunii asociate, structura if-else se încheie și programul se continuă cu linia următoare corpului decizional.
Prima etapă din parcurgerea unei structuri decizionale de tipul if-else o reprezintă testarea condiției logice. în cazul în care aceasta este evaluată ca adevărată se execută instructiunea1, cea asociată ramurii if. în cazul în care condiția logică este evaluată ca falsă se execută instructiunea2, cea asociată ramurii else. După executarea instrucțiunii asociate, structura if-else se încheie și programul se continuă cu linia următoare blocului decizional.
   
   
[[Fișier:structura_decizionala.png]]
[[Fișier:structura_decizionala.png]]
Linia 19: Linia 19:
</syntaxhighlight>
</syntaxhighlight>
b)<syntaxhighlight lang="C">
b)<syntaxhighlight lang="C">
if (conditie)  
if (conditie) {
instructiune1;
instructiune1;
else
}
else {
instructiune2;
instructiune2;
}
</syntaxhighlight>
</syntaxhighlight>
c) <syntaxhighlight lang="C">
c) <syntaxhighlight lang="C">
if (conditie1)
if (conditie1) {
instructiune 1;
instructiune 1;
else if (conditie2)
}
else if (conditie2) {
instructiune 2;
instructiune 2;
else if (conditie 3)
}
else if (conditie 3) {
instructiune3;
instructiune3;
}
................................
................................
else
else {
instructiune;
instructiune;
}
</syntaxhighlight>
</syntaxhighlight>


Linia 41: Linia 47:
Această observație ne conduce la următoarele două cazuri:  
Această observație ne conduce la următoarele două cazuri:  
    
    
* dacă nu există corpuri de instrucțiuni, un else este legat de if-ul imediat anterior;  
* dacă nu există blocuri de instrucțiuni, un else este legat de if-ul imediat anterior;  
<syntaxhighlight lang="C">
<syntaxhighlight lang="C">
if (a > 5)  
if (a > 5)  
if (b > a)
    if (b > a)  
printf ("b este mai mare ca 5");
printf ("b este mai mare ca a");
else
    else  
printf ("b este intre 5 si a");
printf ("b este mai mic sau egal cu a");
   
</syntaxhighlight>
</syntaxhighlight>
* dacă există corpuri de instrucțiuni, un else este legat de ultimul if fără pereche.
* dacă există blocuri de instrucțiuni, un else este legat de ultimul if fără pereche.
<syntaxhighlight lang="C">
<syntaxhighlight lang="C">
if (a > 5) {
if (a > 5) {
if (b > a)
    if (b > a)
      printf ("b este mai mare ca 5");
        printf ("b este mai mare ca a");
}
}
else  
else  
printf ("a nu este mai mare ca 5");
    printf ("a nu este mai mare ca 5");
</syntaxhighlight>
</syntaxhighlight>


Linia 66: Linia 73:
double alpha = -1.0;  
double alpha = -1.0;  
if (number > 0)  
if (number > 0)  
if (alpha > 0)  
if (alpha > 0)
printf( "Here I am!\n");
printf( "Here I am!\n");
else  
else  
Linia 73: Linia 80:
</syntaxhighlight>
</syntaxhighlight>


== Condiția logică ==  
== Evaluarea expresiilor logice ==  
    
    
Am stabilit deja că o condiție logică, prin valoarea ei de adevăr, ramifică evoluția programului.  
Am stabilit deja că o condiție logică, prin valoarea ei de adevăr, ramifică evoluția programului.  
Linia 81: Linia 88:
    
    
În C, condiția  poate avea mai multe reprezentări, după cum urmează  
În C, condiția  poate avea mai multe reprezentări, după cum urmează  
 
=== Operandul ===
 
'''Exemplu:'''
Verificați că un număr citit de la tastatură poate fi numitorul unei fracții.


=== Operația cu operatori relaționali (==, !=, <=, <, >, >=) ===
=== Operatori relaţionali şi logici ===
 
'''Exemplu:'''
Asociați o valoare variabilei cost în funcție de valoarea variabilei distance după cum urmează:
{| class="wikitable"
! colspan="2" |
|-
| style="text-align: center;" |distance
| style="text-align: center;" |cost


|-
* > - mai mare
| style="text-align: center;" | Intre 0 si 100
* >= -mai mare egal
| style="text-align: center;" | 5.50
* <  -mai mic
|-
* <= -mai mic egal
| style="text-align: center"  | Peste 100, dar mai putin de 500
* == -egal
| style="text-align: center;" | 8.00
* != -diferit
|-
* && -si
| style="text-align: center;" | Peste 500, dar nu mai mult de 1000
* || -sau
| style="text-align: center;" | 10.50
* !  -negare
|-
| style="text-align: center;" | 1000 sau mai mult
| style="text-align: center;" | 13.00


|}


=== Operația cu operatori logici (&&, ||, !, ^) ===
'''Exemplu operatori relaționari și logici'''
 
 
'''Exemplu:'''  
Folosind operatori logici, aduceți următoarea structură decizională la forma cea mai simplă:
<syntaxhighlight lang="C">
if (doesSignificantWork) {
if (makesBreakthrough)
nobelPrizeCandidate = true;
else
nobelPrizeCandidate = false;
}
else if (!doesSignificantWork)
nobelPrizeCandidate = false;
</syntaxhighlight>


<div class="regula"> '''Observație:'''Pentru a putea lucra cu operatorii logici, este necesar să ne reamintim modul în care aceștia operează.
{| class="wikitable"
! colspan="5" | Tabelul operatorilor logici
|-
| style="text-align: center;" | a
| style="text-align: center;" | b
| style="text-align: center;" | !a
| style="text-align: center"  | a && b
| style="text-align: center"  | a ll b
|-
| style="text-align: center"  | 1
| style="text-align: center;" | 1
| style="text-align: center;" | 0
| style="text-align: center"  | 1
| style="text-align: center"  | 1
|-
| style="text-align: center"  | 0
| style="text-align: center"  | 0
| style="text-align: center;" | 1
| style="text-align: center"  | 0
| style="text-align: center"  | 0
|-
| style="text-align: center"  | 0
| style="text-align: center;" | 1
| style="text-align: center;" | 1
| style="text-align: center"  | 0
| style="text-align: center"  | 1
|}
</div>
== Alternative la if-else ==
=== Operatorul condițional (  ?  :  ) ===
Singurul operator ternar din C, operatorul condițional funcționează asemenea unui if cu o singură ramură de tip else if. Sintaxa operatorului condițional este următoarea:
<syntaxhighlight lang="C">
<syntaxhighlight lang="C">
(conditie) ? (instructiune1) : (instructiune2)
</syntaxhighlight>


Aşadar, blocul decizional
#include <stdio.h>
<syntaxhighlight lang="C">
if (a>b)
int main(){
printf ("a este mai mare decat b");
    int a = 2, b = 6, c = 0, result;
else
printf ("a este mai mic sau egal cu b");
    result = !(a < c) && (a < b) || (b <=c);
</syntaxhighlight>
poate fi înlocuit astfel:
<syntaxhighlight lang="C">
(a>b) ? ( printf ("a este mai mare decat b")) : ( printf ("a este mai mic sau egal cu b"));
</syntaxhighlight>
 
== Obiective ==
 
în urma acestui laborator, studentul va fi capabil să:
* înțeleagă cum funcționează o structură decizională;  
* scrie programe în C folosind construcții decizionale.
 
== Structura decizională ==
 
Se întâmplă adesea ca evoluția unui program să depindă de un moment prezent. Acel moment prezent poate lua însă diverse forme, rolul programatorului fiind să conducă execuția programului pe calea corectă, pe baza unor condiții. Apare astfel structura decizionala if, care ramifică evoluția programului în funcție de valoarea de adevăr  a condiției testate. 
 
=== Schema logică ===
Prima etapă din parcurgerea unei structuri decizionale de tipul if-else o reprezintă testarea condiției logice. în cazul în care aceasta este evaluată ca adevărată se execută instructiunea1, cea asociată ramurii if. în cazul în care condiția logică este evaluată ca falsă se execută instructiunea2, cea asociată ramurii else. După executarea instrucțiunii asociate, structura if-else se încheie și programul se continuă cu linia următoare corpului decizional.
   
   
[[Fișier:structura_decizionala.png]]
    printf("result is %d\n", result);
    return 0;
}


=== Sintaxă generală ===
a) <syntaxhighlight lang="C">
if (conditie) instructiune;
</syntaxhighlight>
b)<syntaxhighlight lang="C">
if (conditie)
instructiune1;
else
instructiune2;
</syntaxhighlight>
</syntaxhighlight>
c) <syntaxhighlight lang="C">
In exemplul de mai sus tineti cont de [https://en.cppreference.com/w/cpp/language/operator_precedence precedenta operatorilor].
if (conditie1)
instructiune 1;
else if (conditie2)
instructiune 2;
else if (conditie 3)
instructiune3;
................................
else
instructiune;
</syntaxhighlight>
 
=== Asocierea ramurilor if-else===


<div class="regula"> ''' Observație: ''' în cazul în care un if are mai multe ramuri, un else se asociază celui mai apropiat if.</div>
Această observație ne conduce la următoarele două cazuri:
 
* dacă nu există corpuri de instrucțiuni, un else este legat de if-ul imediat anterior;
<syntaxhighlight lang="C">
if (a > 5)
if (b > a)
printf ("b este mai mare ca 5");
else
printf ("b este intre 5 si a");
</syntaxhighlight>
* dacă există corpuri de instrucțiuni, un else este legat de ultimul if fără pereche.
<syntaxhighlight lang="C">
if (a > 5) {
if (b > a)
      printf ("b este mai mare ca 5");
}
else
printf ("a nu este mai mare ca 5");
</syntaxhighlight>
'''Exemplu:'''
Ce va afișa acest program prost indentat?
<syntaxhighlight lang="C">
int number = 4;
double alpha = -1.0;
if (number > 0)
if (alpha > 0)
printf( "Here I am!\n");
else
printf( "No, I’m here!\n");
printf("No, actually, I’m here!\n");
</syntaxhighlight>
== Condiția logică ==
 
Am stabilit deja că o condiție logică, prin valoarea ei de adevăr, ramifică evoluția programului.
 
<div class="regula">'''<font color="red"> Atenție:</font>''' Adevărat în C înseamnă orice rezultat diferit de 0 (nul) al unei evaluări, în timp ce despre fals vorbim când o expresie este evaluată la 0 (nul).
</div>
 
În C, condiția  poate avea mai multe reprezentări, după cum urmează
 
=== Operandul ===  
=== Operandul ===  
    
    
Linia 290: Linia 148:
|}
|}


=== Operația cu operatori logici (&&, ||, !, ^) ===  
=== Operația cu operatori logici (&&, ||, !) ===  
    
    
    
    
Linia 300: Linia 158:
nobelPrizeCandidate = true;  
nobelPrizeCandidate = true;  
else
else
nobelPrizeCandidate = false;  
nobelPrizeCandidate = false;  
}  
}  
else if (!doesSignificantWork)  
else if (!doesSignificantWork) {
nobelPrizeCandidate = false;
nobelPrizeCandidate = false;
}
</syntaxhighlight>
</syntaxhighlight>


<div class="regula"> '''Observație:'''Pentru a putea lucra cu operatorii logici, este necesar să ne reamintim modul în care aceștia operează.  
 
<div class="regula"> '''Observație:''' Cuvântul cheie '''bool''', ca și valorile '''true''' și '''false''', au fost introduse în standardul C99, deci dacă doriți să-l folosiți codul trebuie compilat cu <code style="color: green">--std=c99</code> ca argument al compilatorului (gcc).</div>
 
Pentru a putea lucra cu operatorii logici, este necesar să ne reamintim modul în care aceștia operează.  
{| class="wikitable"
{| class="wikitable"
! colspan="5" | Tabelul operatorilor logici
! colspan="5" | Tabelul operatorilor logici
Linia 316: Linia 178:
| style="text-align: center"  | a ll b
| style="text-align: center"  | a ll b
|-
|-
| style="text-align: center"  | 1
| style="text-align: center"  | 0
| style="text-align: center;" | 1
| style="text-align: center;" | 0
| style="text-align: center;" | 0
| style="text-align: center"  | 1
| style="text-align: center"  | 1
|-
| style="text-align: center"  | 0
| style="text-align: center"  | 0
| style="text-align: center;" | 1
| style="text-align: center;" | 1
| style="text-align: center"  | 0
| style="text-align: center"  | 0
Linia 329: Linia 185:
|-
|-
| style="text-align: center"  | 0
| style="text-align: center"  | 0
| style="text-align: center"  | 1
| style="text-align: center;" | 1
| style="text-align: center;" | 1
| style="text-align: center;" | 1
| style="text-align: center"  | 0
| style="text-align: center"  | 0
| style="text-align: center"  | 1
|-
| style="text-align: center"  | 1
| style="text-align: center;" | 0
| style="text-align: center;" | 0
| style="text-align: center"  | 0
| style="text-align: center"  | 1
|-
| style="text-align: center"  | 1
| style="text-align: center;" | 1
| style="text-align: center;" | 0
| style="text-align: center"  | 1
| style="text-align: center"  | 1
| style="text-align: center"  | 1


|}
|}
 
<div class="regula"> '''Observație:''' În tabel remarcăm că operatorul logic '''SI ( && )''' întoarce 1 dacă și numai dacă ambele expresii, ''a'' și ''b'' în cazul nostru, întorc o valoare nenulă. în orice alt caz, operatorul '''SI''' întoarce 0. Așadar, pentru a optimiza timpul de execuție a programului, expresia a doua, ''b'' în cazul nostru, va fi evaluată dacă și numai dacă prima expresie, ''a'', a întors o valoare nenulă.
În mod asemănător lucrează și operatorul '''SAU ( || )'''.
</div>
</div>
'''Exemplu''': Ce va afișa următorul program?
<syntaxhighlight lang="C">
#include <stdio.h>
int main() {
    int a = 5, b = 10;
    if (++a || ++b) {
        printf("%d  %d", a, b);
    }
    else {
        printf("Wayne Rooney");
    }
    return 0;
}
</syntaxhighlight>


== Alternative la if-else ==
== Alternative la if-else ==
Linia 343: Linia 226:
Singurul operator ternar din C, operatorul condițional funcționează asemenea unui if cu o singură ramură de tip else if. Sintaxa operatorului condițional este următoarea:  
Singurul operator ternar din C, operatorul condițional funcționează asemenea unui if cu o singură ramură de tip else if. Sintaxa operatorului condițional este următoarea:  
<syntaxhighlight lang="C">
<syntaxhighlight lang="C">
(conditie) ? (instructiune1) : (instructiune2)
(conditie) ? (expresie1) : (expresie2)
</syntaxhighlight>
</syntaxhighlight>


Aşadar, blocul decizional
Aşadar, blocul decizional
<syntaxhighlight lang="C">
<syntaxhighlight lang="C">
if (a>b)
if (a > b)
printf ("a este mai mare decat b");
printf ("a este mai mare decat b");
else
else
Linia 355: Linia 238:
poate fi înlocuit astfel:
poate fi înlocuit astfel:
<syntaxhighlight lang="C">
<syntaxhighlight lang="C">
(a>b) ? ( printf ("a este mai mare decat b")) : ( printf ("a este mai mic sau egal cu b"));
printf(a > b ? "a este mai mare decat b" : "a este mai mic sau egal cu b");
printf(a > b ? "a este mai mare decat b" : "a este mai mic sau egal cu b");
//sau
(a > b) ? ( printf ("a este mai mare decat b")) : ( printf ("a este mai mic sau egal cu b"));
</syntaxhighlight>
</syntaxhighlight>
<div class="regula">'''Observație:''' Deși prima variantă este cea recunoscută ca fiind corectă, remarcăm că și a două variantă se comportă la fel ca prima. Asta se datorează modului în care funcționează operatorul condițional: el cere ca ambele expresii, ''expresie1'' și ''expresie2'', să întoarcă "valori". A doua variantă funcționează deoarece funcția ''printf()'' întoarce întotdeauna o [http://www.tutorialspoint.com/c_standard_library/c_function_printf.htm valoare].
</div>


=== Structura decizională switch-case ===  
=== Structura decizională switch-case ===  
Linia 363: Linia 249:
<syntaxhighlight lang="C">
<syntaxhighlight lang="C">
switch (variabilaTestata) {
switch (variabilaTestata) {
case valoare1: { instructiune1;
case valoare1: instructiune1;
[break;]
[break;]
}
case valoare2: { instructiune2;
case valoare2: instructiune2;
[break;]
[break;]
}
case valoare3: { instructiune3;
case valoare3: instructiune3;
[break;]
[break;]
}
.........................................................................
.........................................................................
default: {instructiune;
default: instructiune;
}
}
}
</syntaxhighlight>
</syntaxhighlight>
Valorile ''valoare1'', ''valoare2'' etc. sunt proprii tipului de dată întreg, la fel ca ''variabilaTestata''. Ne reamintim însă că întreg nu înseamnă doar variabile de tip '''int''', astfel că ''variabilaTestata'' poate fi de tip '''char'''.  
Valorile ''valoare1'', ''valoare2'' etc. sunt proprii tipului de dată întreg, la fel ca ''variabilaTestata''. Ne reamintim însă că întreg nu înseamnă doar variabile de tip '''int''', astfel că ''variabilaTestata'' poate fi de tip '''char'''.  
<div class="regula">'''Observație:''' instrucțiunea ''break'' este opțională. Modul  care  switch-case funcționează este următorul:  
<div class="regula">'''Observație:''' instrucțiunea ''break'' este opțională. Modul  care  switch-case funcționează este următorul:  
 
<ol type="a">
a) se compară valoarea variabilei ''variabilaTestata'' cu ''valoarea1'';
<li>se compară valoarea variabilei ''variabilaTestata'' cu ''valoarea1'';</li>
 
<li>dacă cele două sunt egale, se execută ''instructiune1''. Apoi există două cazuri:
b) dacă cele două sunt egale, se execută ''instructiune1''. Apoi există două cazuri:
<ol type="i">
 
<li>dacă există ''break;'' structura switch-case se încheie și se sare pe linia urmatoare întregului bloc decizional;</li>
i. dacă există ''break;'' structura switch-case se încheie și se sare pe linia urmatoare întregului corp decizional;
<li>dacă nu există ''break;'' execuția se continuă până se întalnește un ''break;'' sau până când se încheie structura switch-case. Până la acel moment se vor executa toate instrucțiunile întâlnite pe parcurs (''instructiune2, instructiune3'' etc.);</li>
 
</ol>
ii. dacă nu există ''break;'' execuția se continuă până se întalnește un ''break;'' sau până când se încheie structura switch-case. Până la acel moment se vor executa toate instrucțiunile întâlnite pe parcurs (''instructiune2, instructiune3'' etc.);
</li>
 
<li>dacă valoarea variabilei ''variabilaTestata'' nu este egală cu niciuna dintre valorile ''valoare1, valoare2'' etc atunci se execută ''instructiune'', asociată etichetei default.</li>
c) dacă valoarea variabilei ''variabilaTestata'' nu este egală cu niciuna dintre valorile ''valoare1, valoare2'' etc atunci se execută ''instructiune'', asociată etichetei default.
</ol>
</div>
</div>


Linia 402: Linia 288:
5. Insulele Feroe
5. Insulele Feroe
6. Grecia
6. Grecia


== Exerciții ==
== Exerciții ==


1. Ce va afișa următorul program?  
<ol>
<li>Ce va afișa următorul program?  
<syntaxhighlight lang="C">
<syntaxhighlight lang="C">
void main(){
int main() {
     int a=100;
     int a = 100;
     if(a>10)
     if (a > 10) {
         printf("Tiberiu Soare ");
         printf("Tiberiu Soare ");
     else if(a>20)
    }
     else if (a > 20) {
         printf("Horia Andreescu ");
         printf("Horia Andreescu ");
     else if(a>30)
    }
          printf("Iosif Ion Prunner ");
     else if (a > 30) {
}
        printf("Iosif Ion Prunner ");
</syntaxhighlight>
    }
a) Tiberiu Soare
    return 0;
b) Horia Andreescu
}</syntaxhighlight></li>
c) Tiberiu Soare
<li> Ştiind că un student primește 350 lei/lună dacă are media cel puțin 8.50, 450 lei/lună pentru o medie mai mare sau egală cu 9.50 și 600 lei/lună dacă are media cel puțin 9.70, scrieți un program prin care studentul să afle ce bursă urmează să primească (media va fi citită de la tastatură). </li>
Horia Andreescu
<li> Ce va afișa următorul program?  
Iosif Ion Prunner
d) Compilation error: More than one conditions are true
e) Niciuna dintre cele de mai sus.
 
2. Ştiind că un student primește 350 lei/lună dacă are media cel puțin 8.50, 450 lei/lună pentru o medie mai mare sau egală cu 9.50 și 600 lei/lună dacă are media cel puțin 9.70, scrieți un program prin care studentul să afle ce bursă urmează să primească (media va fi citită de la tastatură).  
 
3. Ce va afișa următorul program?  
<syntaxhighlight lang="C">
<syntaxhighlight lang="C">
#include<stdio.h>
#include <stdio.h>
void main(){
int main() {
     int m=5,n=10,q=20;
     int m = 5, n = 10, q = 20;
     if(q/n*m)
     if (q / n * m)
         printf("Bill Gates ");
         printf("Bill Gates ");
     else
     else
         printf("Amancio Ortega ");
         printf("Amancio Ortega ");
         printf("Carlos Slim Helu ");
         printf("Carlos Slim Helu ");
}
    return 0;
</syntaxhighlight>
}</syntaxhighlight></li>
a) Bill Gates
<li>Scrieți un program care citește de la tastatură notele unui elev la limba română, matematică și informatică și afișează dacă elevul a promovat sau nu bacalaureatul. </li>
b) Amancio Ortega
<li>Fie a și b două numere întregi citite de la tastatură. Scrieți un algoritm care să verifice dacă a si b sunt numere consecutive.</li>
Carlos Slim Helu
<li>Se citesc de la tastatură 3 numere reprezentând lungimea cele 3 laturi ale unui triunghi. Să se afișeze dacă triunghiul este dreptunghic.</li>
c) Run time error
<li>Se citește de la tastatură un număr întreg fără semn de 8 biți. Să se afișeze dacă numărul este sau nu un palindrom (dacă are aceeași valoare citit și de la stânga la dreapta si de la dreapta la stanga; de exemplu 101, sau 242).</li>
d) Compilation error
</ol>
e) Niciuna din cele de mai sus
 
4. Ce va afișa următorul program?
<syntaxhighlight lang="C">
#include<stdio.h>
void main(){
    int a=5,b=10;
    if(++a||++b)
        printf("%d  %d",a,b);
    else
        printf("Wayne Rooney");
}
</syntaxhighlight>
a) 5 10
b) 6 11
c) 6 10
d) 5 11
e) Wayne Rooney
 
5. Scrieți un program care citește de la tastatură notele unui elev la limba română, matematică și informatică și afișează dacă elevul a promovat sau nu bacalaureatul.  
 
6. Scrieți un program care afișează toate numerele pare de la 1 la un număr citit de la tastatură.
 
== Exerciții ==
 
1. Ce va afișa următorul program?
<syntaxhighlight lang="C">
void main(){
    int a=100;
    if(a>10)
        printf("Tiberiu Soare ");
    else if(a>20)
        printf("Horia Andreescu ");
    else if(a>30)
          printf("Iosif Ion Prunner ");
}
</syntaxhighlight>
a) Tiberiu Soare
b) Horia Andreescu
c) Tiberiu Soare
Horia Andreescu
Iosif Ion Prunner
d) Compilation error: More than one conditions are true
e) Niciuna dintre cele de mai sus.
 
2. Ştiind că un student primește 350 lei/lună dacă are media cel puțin 8.50, 450 lei/lună pentru o medie mai mare sau egală cu 9.50 și 600 lei/lună dacă are media cel puțin 9.70, scrieți un program prin care studentul să afle ce bursă urmează să primească (media va fi citită de la tastatură).
 
3. Ce va afișa următorul program?
<syntaxhighlight lang="C">
#include<stdio.h>
void main(){
    int m=5,n=10,q=20;
    if(q/n*m)
        printf("Bill Gates ");
    else
        printf("Amancio Ortega ");
        printf("Carlos Slim Helu ");
}
</syntaxhighlight>
a) Bill Gates
b) Amancio Ortega
Carlos Slim Helu
c) Run time error
d) Compilation error
e) Niciuna din cele de mai sus
 
4. Ce va afișa următorul program?
<syntaxhighlight lang="C">
#include<stdio.h>
void main(){
    int a=5,b=10;
    if(++a||++b)
        printf("%d  %d",a,b);
    else
        printf("Wayne Rooney");
}
</syntaxhighlight>
a) 5 10
b) 6 11
c) 6 10
d) 5 11
e) Wayne Rooney
 
5. Scrieți un program care citește de la tastatură notele unui elev la limba română, matematică și informatică și afișează dacă elevul a promovat sau nu bacalaureatul.
 
6. Scrieți un program care afișează toate numerele pare de la 1 la un număr citit de la tastatură.

Versiunea curentă din 6 noiembrie 2020 13:11

Obiective

în urma acestui laborator, studentul va fi capabil să:

  • înțeleagă cum funcționează o structură decizională;
  • scrie programe în C folosind construcții decizionale.

Structura decizională

Se întâmplă adesea ca evoluția unui program să depindă de o anumită condiție. Ea poate lua însă diverse forme, rolul programatorului fiind să conducă execuția programului pe calea corectă, ținând cont de acea condiție logică. Apare astfel structura decizionala if, care ramifică evoluția programului în funcție de valoarea de adevăr a condiției testate.

Schema logică

Prima etapă din parcurgerea unei structuri decizionale de tipul if-else o reprezintă testarea condiției logice. în cazul în care aceasta este evaluată ca adevărată se execută instructiunea1, cea asociată ramurii if. în cazul în care condiția logică este evaluată ca falsă se execută instructiunea2, cea asociată ramurii else. După executarea instrucțiunii asociate, structura if-else se încheie și programul se continuă cu linia următoare blocului decizional.

Sintaxă generală

a)

if (conditie) instructiune;

b)

if (conditie) {
	 instructiune1;
}
else {
	 instructiune2;
}

c)

if (conditie1) {
	instructiune 1;
}
else if (conditie2) {
	instructiune 2;
}
else if (conditie 3) {
	instructiune3;
}
................................
else {
	instructiune;
}

Asocierea ramurilor if-else

Observație: în cazul în care un if are mai multe ramuri, un else se asociază celui mai apropiat if.

Această observație ne conduce la următoarele două cazuri:

  • dacă nu există blocuri de instrucțiuni, un else este legat de if-ul imediat anterior;
if (a > 5) 
    if (b > a) 
	printf ("b este mai mare ca a");
    else 
	printf ("b este mai mic sau egal cu a");
  • dacă există blocuri de instrucțiuni, un else este legat de ultimul if fără pereche.
if (a > 5) {
    if (b > a)
        printf ("b este mai mare ca a");
}
else 
    printf ("a nu este mai mare ca 5");

Exemplu:

Ce va afișa acest program prost indentat?

int number = 4; 
double alpha = -1.0; 
if (number > 0) 
	if (alpha > 0)
		printf( "Here I am!\n");
else 
	printf( "No, I’m here!\n"); 
printf("No, actually, I’m here!\n");

Evaluarea expresiilor logice

Am stabilit deja că o condiție logică, prin valoarea ei de adevăr, ramifică evoluția programului.

Atenție: Adevărat în C înseamnă orice rezultat diferit de 0 (nul) al unei evaluări, în timp ce despre fals vorbim când o expresie este evaluată la 0 (nul).

În C, condiția poate avea mai multe reprezentări, după cum urmează


Operatori relaţionali şi logici

  • > - mai mare
  • >= -mai mare egal
  • < -mai mic
  • <= -mai mic egal
  • == -egal
  • != -diferit
  • && -si
  • || -sau
  • ! -negare


Exemplu operatori relaționari și logici

#include <stdio.h>
 
int main(){
    int a = 2, b = 6, c = 0, result;
 
    result = !(a < c) && (a < b) || (b <=c);
 
    printf("result is %d\n", result);
    return 0;
}

In exemplul de mai sus tineti cont de precedenta operatorilor.

Operandul

Exemplu: Verificați că un număr citit de la tastatură poate fi numitorul unei fracții.

Operația cu operatori relaționali (==, !=, <=, <, >, >=)

Exemplu: Asociați o valoare variabilei cost în funcție de valoarea variabilei distance după cum urmează:

distance cost
Intre 0 si 100 5.50
Peste 100, dar mai putin de 500 8.00
Peste 500, dar nu mai mult de 1000 10.50
1000 sau mai mult 13.00

Operația cu operatori logici (&&, ||, !)

Exemplu: Folosind operatori logici, aduceți următoarea structură decizională la forma cea mai simplă:

if (doesSignificantWork) { 
	if (makesBreakthrough) 
		nobelPrizeCandidate = true; 
	else
		nobelPrizeCandidate = false; 
} 
else if (!doesSignificantWork) {
	nobelPrizeCandidate = false;
}


Observație: Cuvântul cheie bool, ca și valorile true și false, au fost introduse în standardul C99, deci dacă doriți să-l folosiți codul trebuie compilat cu --std=c99 ca argument al compilatorului (gcc).

Pentru a putea lucra cu operatorii logici, este necesar să ne reamintim modul în care aceștia operează.

Tabelul operatorilor logici
a b !a a && b a ll b
0 0 1 0 0
0 1 1 0 1
1 0 0 0 1
1 1 0 1 1
Observație: În tabel remarcăm că operatorul logic SI ( && ) întoarce 1 dacă și numai dacă ambele expresii, a și b în cazul nostru, întorc o valoare nenulă. în orice alt caz, operatorul SI întoarce 0. Așadar, pentru a optimiza timpul de execuție a programului, expresia a doua, b în cazul nostru, va fi evaluată dacă și numai dacă prima expresie, a, a întors o valoare nenulă.

În mod asemănător lucrează și operatorul SAU ( || ).

Exemplu: Ce va afișa următorul program?

#include <stdio.h>
int main() {
    int a = 5, b = 10;
    if (++a || ++b) {
         printf("%d  %d", a, b);
    }
    else {
         printf("Wayne Rooney");
    }
    return 0;
}

Alternative la if-else

Operatorul condițional (  ?  : )

Singurul operator ternar din C, operatorul condițional funcționează asemenea unui if cu o singură ramură de tip else if. Sintaxa operatorului condițional este următoarea:

(conditie) ? (expresie1) : (expresie2)

Aşadar, blocul decizional

if (a > b)
	printf ("a este mai mare decat b");
else
	printf ("a este mai mic sau egal cu b");

poate fi înlocuit astfel:

printf(a > b ? "a este mai mare decat b" : "a este mai mic sau egal cu b");
//sau
(a > b) ? ( printf ("a este mai mare decat b")) : ( printf ("a este mai mic sau egal cu b"));
Observație: Deși prima variantă este cea recunoscută ca fiind corectă, remarcăm că și a două variantă se comportă la fel ca prima. Asta se datorează modului în care funcționează operatorul condițional: el cere ca ambele expresii, expresie1 și expresie2, să întoarcă "valori". A doua variantă funcționează deoarece funcția printf() întoarce întotdeauna o valoare.

Structura decizională switch-case

Această instrucțiune de decizie este similară unui if cu mai multe ramuri de tip else-if. Sintaxa este următoarea:

switch (variabilaTestata)	{
	case valoare1:	 instructiune1;
				 [break;]
				
	case valoare2:	 instructiune2;
				 [break;]
				
	case valoare3:	 instructiune3;
				 [break;]
				
.........................................................................
	default:		instructiune;
				
}

Valorile valoare1, valoare2 etc. sunt proprii tipului de dată întreg, la fel ca variabilaTestata. Ne reamintim însă că întreg nu înseamnă doar variabile de tip int, astfel că variabilaTestata poate fi de tip char.

Observație: instrucțiunea break este opțională. Modul care switch-case funcționează este următorul:
  1. se compară valoarea variabilei variabilaTestata cu valoarea1;
  2. dacă cele două sunt egale, se execută instructiune1. Apoi există două cazuri:
    1. dacă există break; structura switch-case se încheie și se sare pe linia urmatoare întregului bloc decizional;
    2. dacă nu există break; execuția se continuă până se întalnește un break; sau până când se încheie structura switch-case. Până la acel moment se vor executa toate instrucțiunile întâlnite pe parcurs (instructiune2, instructiune3 etc.);
  3. dacă valoarea variabilei variabilaTestata nu este egală cu niciuna dintre valorile valoare1, valoare2 etc atunci se execută instructiune, asociată etichetei default.

Pentru a verifica echivalența dintre if-else și switch-case, rezolvați folosind ambele structuri decizionale următoarea problemă:

Exemplu: Un microbist vrea să afle situația Grupei F de calificare la EURO2016. Astfel, el va introduce o cifră pentru a vedea ce "națională" ocupă acel loc. Folosind următoarea listă, informați-l corect pe suporter.

1. Irlanda de Nord 2. România 3. Ungaria 4. Finlanda 5. Insulele Feroe 6. Grecia

Exerciții

  1. Ce va afișa următorul program?
    int main() {
        int a = 100;
        if (a > 10) {
             printf("Tiberiu Soare ");
        }
        else if (a > 20) {
             printf("Horia Andreescu ");
        }
        else if (a > 30) {
             printf("Iosif Ion Prunner ");
        }
        return 0;
    }
    
  2. Ştiind că un student primește 350 lei/lună dacă are media cel puțin 8.50, 450 lei/lună pentru o medie mai mare sau egală cu 9.50 și 600 lei/lună dacă are media cel puțin 9.70, scrieți un program prin care studentul să afle ce bursă urmează să primească (media va fi citită de la tastatură).
  3. Ce va afișa următorul program?
    #include <stdio.h>
    int main() {
        int m = 5, n = 10, q = 20;
        if (q / n * m)
             printf("Bill Gates ");
        else
             printf("Amancio Ortega ");
             printf("Carlos Slim Helu ");
        return 0;
    }
    
  4. Scrieți un program care citește de la tastatură notele unui elev la limba română, matematică și informatică și afișează dacă elevul a promovat sau nu bacalaureatul.
  5. Fie a și b două numere întregi citite de la tastatură. Scrieți un algoritm care să verifice dacă a si b sunt numere consecutive.
  6. Se citesc de la tastatură 3 numere reprezentând lungimea cele 3 laturi ale unui triunghi. Să se afișeze dacă triunghiul este dreptunghic.
  7. Se citește de la tastatură un număr întreg fără semn de 8 biți. Să se afișeze dacă numărul este sau nu un palindrom (dacă are aceeași valoare citit și de la stânga la dreapta si de la dreapta la stanga; de exemplu 101, sau 242).