Documente Academic
Documente Profesional
Documente Cultură
2016
Declaraţii
• Toate variabilele trebuie declarate înainte de
utilizare,
deși anumite declarații pot fi făcute implicit din
context.
PCLP CURS 5 1
09.11.2016
Întrebare
• Calificatorul const declară variabile sau
constante?
• Calificatorul const poate fi aplicat la declararea
oricărei variabile pentru a specifica că valoarea ei nu
se va schimba.
PCLP CURS 5 2
09.11.2016
• Împărțirea întreagă trunchiază orice parte • Codul care afișează că un an este sau nu bisect:
fracționară. if ((an % 4 == 0 && an % 100 != 0) || an % 400 == 0)
• Expresia x % y printf("%d e bisect\n", an);
else
furnizează restul împărțirii lui x lui la y și deci,
este zero când y îl împarte exact pe x. printf("%d nu e bisect\n", an);
17:52 PCLP CURS 5 13 17:52 PCLP CURS 5 14
PCLP CURS 5 3
09.11.2016
PCLP CURS 5 4
09.11.2016
Exemplificare cu funcţia atoi, care converteşte un Alt exemplu de conversie de la char la int este
şir de cifre la echivalentul său numeric: funcţia lower, care converteşte un caracter din codul
ASCII la minusculă. Dacă caracterul nu este o literă
mare lower îl returnează nemodificat.
/* atoi: convert s to integer */
/* lower: convert c to lower case; ASCII only */
int atoi(char s[])
Expresia: s[i] - '0' furnizează int lower(int c)
{
valoarea numerică a caracterului {
int i, n;
stocat în s[i].
n = 0; if (c >= 'A' && c <= 'Z') Această funcție nu
for (i = 0; s[i] >= '0' && s[i] <= '9'; ++i) return c + 'a' - 'A'; lucrează corect pentru
else un alt set de caractere
n = 10 * n + (s[i] - '0');
în afara codului ASCII,
return n; return c; cum ar fi codul EBCDIC.
} }
17:52 PCLP CURS 5 25 17:52 PCLP CURS 5 26
• De acum înainte vom folosi funcțiile din headerul • Răspunsul variază de la maşină la maşină, reflectând
<ctype.h>. diferenţele în arhitectură.
17:52 PCLP CURS 5 27 17:52 PCLP CURS 5 28
• Pe altele, un char este promovat la un int • Dar modele de biți arbitrare stocate în variabile
caracter pot fi
prin adăugarea de zerouri la stânga şi
astfel el este totdeauna un număr pozitiv. negative pe anumite mașini și
pozitive pe altele.
17:52 PCLP CURS 5 29 17:52 PCLP CURS 5 30
PCLP CURS 5 5
09.11.2016
• Altfel, dacă unul dintre operanzi este de tip • Apoi, dacă unul dintre operanzi este de tip long
double, converteşte-l pe celălalt la tipul long.
converteşte-l pe celălalt la tipul double.
17:52 PCLP CURS 5 35 17:52 PCLP CURS 5 36
PCLP CURS 5 6
09.11.2016
PCLP CURS 5 7
09.11.2016
PCLP CURS 5 8
09.11.2016
PCLP CURS 5 9
09.11.2016
s[i] = '\0';
• Un exemplu de construcție similară am întâlnit
return i;
anterior la funcția getline (vezi în continuare). }
17:52 PCLP CURS 5 59 17:52 PCLP CURS 5 60
PCLP CURS 5 10
09.11.2016
PCLP CURS 5 11
09.11.2016
Întrebare Operatorul ^
• x = 0313(8) = 11001011(2). Se cere să se • Operatorul ^ este operatorul XOR logic pe biţi.
seteze bitul 2 din x la valoarea 1 folosind
operatorul | și o variabilă SET_ON, astfel: • El este asociativ şi expresiile care-l conţin pot fi
x = x | SET_ON; rearanjate.
• Care este valoarea variabilei SET_ON intern (în • Rezultatul este funcţia logică XOR pe biţi aplicată
baza 2) și în baza 8? operanzilor săi.
^ 0 1
SET_ON are toți biții 0, mai puțin bitul 2, care e 1 • Tabelul de adevăr asociat este:
SET_ON = 00000100(2) = 04(8)
x: 11001011 | 0 0 1
SET_ON: 00000100
x:
--------------
11001111
1 1 0
17:52 PCLP CURS 5 71 17:52 PCLP CURS 5 72
PCLP CURS 5 12
09.11.2016
Confuzie
Exemplu cu operatorul XOR pe biți ^
• Nu trebuie să confundăm
01010101 ^ operatorii pe biți & și |
01100110 cu operatorii logici && și ||.
• Operatorul XOR pe biţi ^
---------------- pune 1 în fiecare poziţie de bit • De exemplu, dacă x este 1 și y este 2,
00110011 unde operanzii au biţi de valori atunci 1(10) = 0000 0001(2)
diferite şi x & y este zero
pune 0 în fiecare poziţie unde în timp ce 2(10) = 0000 0010(2)
operanzii au biţi de aceiaşi
x && y este unu.
valoare. 1 = Adevărat
2 = Adevărat
17:52 PCLP CURS 5 73 17:52 PCLP CURS 5 74
PCLP CURS 5 13
09.11.2016
PCLP CURS 5 14
09.11.2016
• Dacă expr1 şi expr2 sunt expresii, atunci • Să observăm parantezele din jurul expresiei expr2
atribuirea:
• În atribuirea de mai jos:
expr1 op = expr2 x *= y + 1
este echivalentă cu:
este echivalentă cu atribuirea:
expr1 = (expr1) op (expr2) x = x * (y + 1)
exceptând faptul că expr1 este calculată o singură
şi nicidecum cu atribuirea:
dată.
x = x * y + 1
17:52 PCLP CURS 5 87 17:52 PCLP CURS 5 88
PCLP CURS 5 15
09.11.2016
operatorul de atribuire face codul mai uşor de • Ceilalți operatori de atribuire (+=, -= etc.) pot apărea
înţeles, și ei în expresii
deoarece cititorul nu o să stea să verifice dacă cele deși acest lucru este mai puțin frecvent.
două expresii lungi sunt la fel,
• În toate expresiile de acest gen:
sau să se întrebe de ce nu sunt.
tipul de dată al expresiei de atribuire este
• Un operator de atribuire ajută compilatorul să tipul operandului din stânga
producă un cod eficient. valoarea este valoarea de după atribuire.
17:52 PCLP CURS 5 91 17:52 PCLP CURS 5 92
Expresii condiţionale • Dacă f este float, iar n este int, atunci expresia:
• Astfel pentru a atribui lui z cea mai mare valoare (n > 0) ? f : n
dintre a și b, vom scrie: este de tip float indiferent că n e pozitiv sau nu
z = (a > b) ? a : b; /* z = max(a, b) */ • Parantezele nu sunt necesare în jurul primei expresii
(expr1) a unei expresii condiționale,
• Expresia condițională este într-adevăr o expresie și deoarece prioritatea operatorului ?: este foarte
poate fi utilizată în orice loc unde poate să apară scăzută, exact deasupra atribuirii.
orice altă expresie.
• Cu toate acestea ele sunt recomandate
• Dacă expr2 și expr3 sunt de tipuri diferite, fac partea de condiție a expresiei condiționale mai lizibilă
tipul rezultatului este determinat de regulile de
• Expresia condițională adesea conduce la un cod succint.
conversie discutate anterior.
17:52 PCLP CURS 5 95 17:52 PCLP CURS 5 96
PCLP CURS 5 16
09.11.2016
• Ciclul de mai jos afișează primele n elemente ale unui Exemplu ilustrativ
tablou, Chiar dacă pare complicat este mai
10 pe linie, compact decât echivalentul cu if-else
fiecare coloană separată de un blank,
iar fiecare linie (inclusiv ultima) terminată cu newline.
for ( i = 0; i < n; ++i)
printf("%6d%c", a[i],
(i%10 == 9 || i == n-1) ? '\n' : ' ');
• O linie nouă este afişată
după fiecare al 10-lea element şi totodată
după al n-lea.
• Toate celelalte elemente sunt urmate de un blank.
17:52 PCLP CURS 5 97 17:52 PCLP CURS 5 98
PCLP CURS 5 17
09.11.2016
• C – ca multe limbaje – nu specifică ordinea în care • Similar, ordinea în care argumentele funcţiei sunt
operanzii unui operator sunt evaluați (excepție fac &&, evaluate nu este specificată,
||, ?: și ‘,‘). astfel că instrucţiunea
• De exemplu, într-o instrucțiune ca: printf("%d %d\n", ++n, power(2, n)); /* Wrong */
Concluzia
• Concluzia este:
să nu scriem cod care depinde de ordinea
evaluării. III. CONTROLUL EXECUŢIEI
PROGRAMELOR
PCLP CURS 5 18
09.11.2016
1. Instrucţiuni şi blocuri
Control flow • O expresie precum
x = 0 sau i++ sau printf(...)
devine o instrucţiune atunci când este
• Într-un limbaj de programare, controlul execuţiei urmată de caracterul punct şi virgulă “;”, ca în:
programului (control flow) x = 0;
i++;
specifică ordinea în care sunt efectuate calculele. printf(...);
PCLP CURS 5 19
09.11.2016
• Expresiile sunt evaluate în ordine. • Dacă nu există nici o acțiune explicită de făcut,
• Dacă o expresie este adevărată, atunci partea
else
instrucţiunea asociată cu ea este executată şi aceasta instrucţiune
încheie întreaga construcţie.
poate să lipsească,
• Codul fiecărei instrucţiuni este reprezentat sau poate fi utilizată pentru verificarea erorilor
fie de o singură instrucţiune, pentru a captura o condiţie „imposibilă”.
fie de un grup de instrucţiuni grupate între acolade.
• Pentru a ilustra o decizie triplă, prezentăm în
• Ultimul else se referă la cazul în care nu s-a intrat pe continuare o funcţie de căutare binară
niciuna din ramurile anterioare care decide dacă o valoare particulară x apare în
adică nici o expresie nu a fost adevărată. tabloul sortat crescător v.
17:52 PCLP CURS 5 119 17:52 PCLP CURS 5 120
PCLP CURS 5 20
09.11.2016
Căutarea binară
• Funcţia returnează poziţia
Exemplu: n = 5, x = 3,
un număr între 0 şi n-1 v = (-1, 2, 3, 9, 11)
dacă x apare în v şi => 2
-1 0 1 2 3 4
dacă nu apare. -1 2 3 9 11
switch (expresie) {
4. Instrucţiunea switch
case expresie-constantă: instrucţiuni
• Instrucţiunea switch este o decizie multiplă specială
case expresie-constantă: instrucţiuni
ea determină transferul controlului unei instrucţiuni
sau unui bloc de instrucţiuni dintr-un şir de instrucţiuni default: instrucţiuni
în funcţie de valoarea unei expresii. }
PCLP CURS 5 21
09.11.2016
• Poate exista, de asemenea, cel mult o instrucţiune • Dacă nici o expresie-constantă din nici un case nu
etichetată cu: este egală cu valoarea expresiei şi dacă există un
default: prefix default,
• Când o instrucţiune switch se execută, se atunci se execută instrucţiunea de după default,
evaluează expresia din paranteze şi altfel nici o instrucţiune din switch nu se execută.
valoarea ei se compară cu fiecare expresie-
constantă din fiecare case. • Toate expresie-constantă din fiecare case trebuie să
fie diferite între ele.
• Dacă se găseşte o expresie-constantă din case
egală cu valoarea expresiei, • Ramura etichetată cu default, se execută
atunci execuţia începe cu instrucţiunea care dacă niciuna din case-urile existente nu este
urmează după case-ul respectiv. satisfăcută.
17:52 PCLP CURS 5 127 17:52 PCLP CURS 5 128
potriveşte {
int c, i, nwhite, nother, ndigit[10];
atunci instrucţiunea switch nu face nimic.
nwhite = nother = 0;
• Ramurile case şi default pot apărea în orice for (i = 0; i < 10; i++)
ordine. ndigit[i] = 0;
while ((c = getchar()) != EOF) {
• Reluăm un program scris anterior prin care switch (c) {
număram apariţiile fiecărei cifre, a spaţiilor albe şi a case '0': case '1': case '2': case '3':
tuturor celorlalte caractere case '4': case '5': case '6': case '7':
case '8': case '9':
înlocuind secvenţa if ... else if ... else cu ndigit[c-'0']++;
instrucţiunea switch break;
17:52 PCLP CURS 5 129 17:52 PCLP CURS 5 130
case ' ': case '\n': case '\t': • Instrucţiunea break determină o ieşire imediată din
nwhite++; switch.
break;
default: • Deoarece case-urile servesc doar ca etichete
nother++; după ce codul unui case este efectuat, execuţia
break; continuă cu următorul case
} /* end switch */
dacă nu se precizează explicit ieşirea din switch.
} /* end while */
printf("digits ="); • Pentru ieşirea din switch se folosesc
for (i = 0; i < 10; i++)
printf(" %d", ndigit[i]);
instrucţiunile break sau return.
printf(", white space = %d, other = %d\n",
• O instrucţiune break poate fi utilizată de asemenea
nwhite, nother);
return 0;
pentru a forţa o ieşire imediată
} din ciclurile while, for şi do aşa cum vom vedea.
17:52 PCLP CURS 5 131 17:52 PCLP CURS 5 132
PCLP CURS 5 22
09.11.2016
PCLP CURS 5 23