Upload
ioana-onutu
View
101
Download
4
Embed Size (px)
DESCRIPTION
sdf
Citation preview
Programarea în limbajul C - Îndrumar de laborator ______________________________________________________________________________________________________________________________________________________
1
LABORATORUL 1
OPERAREA CU CONSTANTE CARACTER ŞI CU ȘIRURI DE CARACTERE FUNCŢIILE DE BIBLIOTECA AFERENTE
Constante caracter O constantă caracter reprezintă un caracter şi are ca valoare codul ASCII al caracterului respectiv. O constantă caracter grafic (codul cuprins în intervalul [32,126]) se poate scrie incluzând caracterul respectiv intre caractere apostrof. Cod ASCII Exemple : 'A' 65 'b' 98 '*' 77 ' ' (spaţiu) 32 Anumite caractere negrafice (codul cuprins intre [0,31] sau de valoare 127) au notaţii speciale la scrierea cărora se utilizează caracterul backslash (\). O astfel de constantă caracter se scrie incluzând notaţia respectiva intre caractere apostrof. Se spune ca backslash introduce o secvenţă escape. Cod ASCII Exemple : activare sunet '\a' 7 revenire cu un spaţiu '\b' 8 tabulator orizontal '\t' 9 rând nou '\n' 10 retur de car (poziţionează '\r' 13 cursorul în coloana 1 din rândul curent) Secvenţa escape poate fi folosita pentru a reprezenta constantele caracter ghilimele, apostrof şi backslash. Cod ASCII Exemple : ghilimele '\"' 34 apostrof '\'' 39 backslash '\\' 92 Secvenţa escape poate fi folosita pentru a defini constante caracter pentru orice caracter al codului ASCII. Astfel construcţia '\ooo', unde o este o cifra octala, reprezintă constantă caracter corespunzătoare codului ASCII egal cu valoarea întregului octal ooo (numerele octale nu trebuie precedate de zerouri nesemnificative). Exemple : '\a' = '\7' activare sunet '\"' = '\42' ghilimele Calculatoarele compatibile IBM PC utilizează codul ASCII extins, care conţine 256 de coduri, reprezentând valori în intervalul [0,255]. Codurile din intervalul [0,127] corespund
Programarea în limbajul C - Îndrumar de laborator ______________________________________________________________________________________________________________________________________________________
2
caracterelor codului ASCII obişnuit, iar cele din intervalul [128,255] corespund unor caractere ce au o utilizare specială. Constantele caracter corespunzătoare caracterelor aparţinând codului ASCII extins din intervalul [128,255] se definesc prin secvenţe escape în care se indica codul acestora. Exemple : '\377' caracterul cu codul 255 '\344' caracterul cu codul 228 (litera greceasca sigma) '\0' constantă caracter NUL, marca a sfârşitului de sir de caractere
CODUL ASCII
Programarea în limbajul C - Îndrumar de laborator ______________________________________________________________________________________________________________________________________________________
3
CODUL ASCII EXTINS
Programarea în limbajul C - Îndrumar de laborator ______________________________________________________________________________________________________________________________________________________
4
SEMNIFICAŢIA CARACTERELOR DE CONTROL ÎN COD ASCII
Şiruri de caractere O succesiune de zero sau mai multe caractere formează o constantă sir sau un sir de caractere. Un sir de caractere se reprezintă prin încadrarea acestuia intre ghilimele. Exemplu : "Acesta e un sir de caractere" reprezintă şirul de caractere Acesta e un sir de caractere Dacă se doreşte folosirea caracterelor negrafice în compunerea unui sir de caractere sau a caracterelor backslash sau ghilimele se utilizează secvenţele escape aferente. Exemple : "1\"2" reprezintă succesiunea 1"2 "a\\b" reprezintă succesiunea a\b "O'Neil" reprezintă succesiunea O'Neil Un şir poate fi continuat pe rândul următor folosind caracterul backslash. Caracterul ce precede pe backslash se va concatena cu primul caracter de pe rândul următor. ATENTIE : Un sir de caractere se păstrează în memorie într-o succesiune de octeţi al cărui număr este egal cu numărul caracterelor şirului respectiv + 1, deoarece se memorează şi caracterul NUL (care marchează sfârşitul şirului). Funcţiile getch şi getche Aceste funcţii sunt dependente de implementare. Ambele funcţii permit citirea direct de la tastatură a unui caracter. Funcţiile getch şi getche au prototipurile în fişierul conio.h, deci utilizarea lor implică includerea acestor fişiere. Funcţia getch - citeşte de la tastatură FARĂ ECOU, deci caracterul tastat la tastatură nu se afişează (automat) şi pe ecranul consolei;
Programarea în limbajul C - Îndrumar de laborator ______________________________________________________________________________________________________________________________________________________
5
- permite citirea de la tastatură atât a caracterelor corespunzătoare codului ASCII, cat şi a celor corespunzătoare unor funcţii speciale (tastele funcţionale F1, F2 etc sau combinaţii de taste speciale); - la citirea unui caracter al codului ASCII, funcţia returnează codul ASCII al caracterului respectiv; - în cazul în care se acţionează o tasta care nu corespunde codului ASCII, funcţia getch se apelează de doua ori : la primul apel funcţia returnează valoarea zero, iar la cel de al doilea apel se returnează o valoare specifica tastei acţionate. Funcţia getche - este analogă cu funcţia getch, cu singura diferenţă ca ea realizează citirea CU ECOU a caracterului tastat. Aceasta înseamnă ca se afişează automat pe ecranul terminalului caracterul tastat. Ambele funcţii nu au parametri şi se pot apela ca operanzi în expresii. La apelarea lor se vizualizează fereastră utilizator şi se aşteaptă tastarea unui caracter. Programul continua după tastarea caracterului. Un apel de forma : getch(); se utilizează în cazul în care dorim să vizualizam fereastră utilizator şi să suspendam programul pentru a analiza conţinutul curent al ecranului. Pentru a continua execuţia programului se acţionează o tasta corespunzătoare unui caracter al codului ASCII. Funcţia putch Aceasta funcţie afişează un caracter pe ecranul terminalului standard. Ea are un parametru ce determina imaginea (caracterul) afişat la terminal. Prototipul funcţiei putch se afla în fişierul conio.h Funcţia putch poate fi apelata astfel : putch(expresie) Valoarea expresiei se interpretează ca fiind codul ASCII al caracterului care se afişează. Dacă valoarea expresiei se afla în intervalul [32,126], atunci se afişează un caracter grafic al codului ASCII. Dacă valoarea respectiva este în afară acestui interval, atunci se afişează corespunzător anumite imagini. Funcţia putch returnează codul imaginii afişate (valoarea parametrului de apel). Macrourile getchar şi putchar
Aceste macrouri sunt definite în fişierul stdio.h. Ele se apelează la fel ca funcţiile. Macroul getchar - permite citirea cu ecou a caracterelor de la terminalul standard. Se pot citi numai caractere ale codului ASCII, nu şi caractere corespunzătoare tastelor speciale. - prin intermediul acestui macro, caracterele nu se citesc direct de la tastatura. Caracterele tastate se introduc într-o zona tampon până la acţionarea tastei <Enter>. în acest moment, în zona tampon se introduce caracterul de rând nou şi se continua execuţia lui getchar. Se revine din funcţie returnându-se codul ASCII al caracterului curent din zona tampon. La un nou apel se revine
Programarea în limbajul C - Îndrumar de laborator ______________________________________________________________________________________________________________________________________________________
6
cu codul ASCII al caracterului următor din zona tampon. La epuizarea tuturor caracterelor din zona tampon, apelul lui getchar implică tastarea la terminal a unui nou set de caractere care se reîncarcă în zona tampon. - se apelează fără parametri : getchar(); si de obicei este un operand al unei expresii. OBSERVAŢIE : citirea caracterelor prin intermediul zonelor tampon are avantajul de a permite corectarea erorilor la tastare (înainte de acţionarea tastei <Enter>). Macroul putchar - afişează un caracter al codului ASCII. El returnează codul caracterului afişat sau -1 la eroare. Se poate apela prin formatul : putchar(expresie); unde valoarea expresiei reprezintă codul ASCII al caracterului care se afişează. OBSERVAŢII : apelul putch('\n') are ca efect trecerea cursorului în linia următoare; : apelul putchar('\n') are ca efect trecerea cursorului în coloana 1 a liniei următoare (practic se expandează '\n' la '\n' şi '\r'). Funcţia puts - afişează la terminalul standard un sir de caractere ale codului ASCII. După afişarea şirului respectiv cursorul trece automat în coloana întâi de pe linia următoare (deci caracterul NUL se înlocuieşte cu newline). - funcţia are ca parametru adresa de început a zonei de memorie care conţine caracterele de afişat - funcţia are prototipul în fişierul stdio.h Exemplu : Un apel de forma : puts("\nPentru a termina programul actionati o tasta"); are ca efect afişarea pe un rând nou a textului Pentru a termina programul actionati o tasta, după care cursorul se plasează la începutul liniei următoare.
Programarea în limbajul C - Îndrumar de laborator ______________________________________________________________________________________________________________________________________________________
7
TEMA 1
Problema 1.
a. Examinaţi corectitudinea construcţiei următoarelor constante caracter :
- 'ab'
- 'a
- '\'
- 3'
b. Examinaţi corectitudinea construcţiei următoarelor constante şiruri de caractere :
- 'ab'
- """
- "a
- "ab\"
c. Precizaţi semnificaţia următoarelor construcţii :
- '\t'
- '\0'
- '\42'
- "a\1b"
- "a\13"
Problema 2.
1. Copiaţi în caiete textul programului de mai jos .
2. Copiaţi-l într-o fereastră noua, compilaţi-l, link-editaţi-l şi lansaţi-l în execuţie.
3. Explicaţi semnificaţia enunţului #define.
4. Explicaţi utilitatea apelului getch().
5. Modificaţi şirul de caractere astfel încât execuţia programului să afişeze un mesaj de salut
care să vi se adreseze explicit (incluzând numele dumneavoastră).
#include <stdio.h>
#include <conio.h>
#define TEXT "Acesta este un sir de caractere ce va fi substituit lui TEXT"
int main(void)
{
puts(TEXT);
getch();
return 0;
}
Programarea în limbajul C - Îndrumar de laborator ______________________________________________________________________________________________________________________________________________________
8
Problema 3.
1. Copiaţi într-o fereastră noua, compilaţi, link-editaţi şi lansaţi în execuţie programul de
mai jos (concentraţi-va asupra execuţiei; în program exista şi instrucţiuni pe care le veţi învăța
în săptămânile următoare).
2. Deduceţi pentru fiecare caracter introdus şi reprezentarea binara.
#include <stdio.h>
#include <conio.h>
int main(void)
{
unsigned char c;
while((c=getch())!=0)
{
putch(c);
printf(" -> cod ASCII = %d (zecimal) sau %x (hexa) sau %o (octal)\n",c,c,c);
}
return 0;
}
Problema 4.
Scrieţi un program care să afişeze următoarele caractere:
A,\,",1,',c
şi apoi să emită semnalul sonor.
Problema 5.
1. Copiaţi în caiete şi apoi într-o fereastră nouă textul programului de mai jos.
2. Compilaţi, link-editaţi şi lansaţi în execuţie programul.
3. Introduceţi ca date de intrare, pe rând, diverse caractere corespunzătoare codului ASCII.
Notaţi în caiete rezultatele obţinute.
4. Acţionaţi pentru introducerea datei de intrare o tasta ce nu corespunde codului ASCII.
5. Modificaţi programul astfel încât, după afişarea caracterului, cursorul să avanseze la o
linie noua.
6. Modificaţi programul astfel încât înainte de a se termina execuţia lui să se afişeze fereastră
utilizator şi să se aştepte acţionarea unei taste.
7. Explicaţi semnificaţia construcţiei #include.
8. Substituiţi apelul putch(getch()) cu putch(getch() - 'a' + 'A'). Ce se întâmpla dacă tastaţi o
litera mica? Explicaţi comportamentul programului.
Programarea în limbajul C - Îndrumar de laborator ______________________________________________________________________________________________________________________________________________________
9
#include <conio.h>
int main(void)
{
putch(getch());
return 0;
}
Problema 6.
1. să se scrie un program care citeşte un caracter folosind macro-ul getchar, îl afişează
folosind macro-ul putchar, trece cursorul în coloana 1 a liniei următoare şi afişează fereastră
utilizator până la acţionarea unei taste. ATENTIE la modul de introducere a datelor.
2. Modificaţi programul astfel încât să se afişeze pe o linie nouă mesajul :
Pentru a termina programul actionati o tasta
Programarea în limbajul C - Îndrumar de laborator ______________________________________________________________________________________________________________________________________________________
10
LABORATORUL 2
SCRIEREA şi CITIREA CU FORMAT LA TERMINALUL STANDARD FUNCŢIILE PRINTF şi SCANF
Funcţia printf afişează date pe ecranul terminalului standard sub controlul unor formate. Sintaxa apelului este : printf(parametru_control, par1,par2,...,parn); unde par1,par2,...,parn - sunt expresii ale căror valori se scriu conform specificatorilor de format prezenţi în parametrul de control Parametrul control este un sir de caractere ce conţine : - succesiuni de caractere care se afişează ca atare; - specificatori de format care definesc conversiile valorilor parametrilor par1...parn din format extern în format intern. Un specificator de format începe cu caracterul % după care urmează : - opţional : un caracter minus - implicit datele se cadrează la dreapta câmpului în care se scriu. în prezenta minusului, datele se cadrează la stânga; - opţional : un sir de cifre zecimale - acesta defineşte numărul minim de poziţii ale câmpului în care se afişează caracterele ce intra în compunerea formatului extern al datei. în cazul în care afişarea datei necesita un câmp de lungime mai mare decât cel precizat, se face automat extensia câmpului la numărul necesar de poziţii. în cazul în care data necesita un câmp mai mic, ea se va scrie în câmpul respectiv în stânga sau în dreapta, după cum este prezent sau nu semnul minus în specificatorul de format corespunzător ei. De asemenea, în acest caz, câmpul se completează cu caractere nesemnificative; implicit, caracterele nesemnificative sunt spaţii. Caracterele nesemnificative vor fi zerouri dacă numărul ce indica dimensiunea minima a câmpului începe cu un zero nesemnificativ. - opţional : un punct urmat de un sir de cifre zecimale - şirul de cifre zecimale specifica precizia datei care se scrie sub controlul specificatorului respectiv. în cazul în care data care se scrie este un număr real, precizia defineşte numărul de zecimale care se scriu. în cazul în care data este un sir de caractere, precizia indica numărul de caractere care se scriu. - una sau doua litere - acestea definesc tipul de conversie aplicat datei care se scrie. Semnificaţia ultimei litere a specificatorului de format la scriere : Litera Conversia realizată d - data se converteşte din tipul int în zecimal şi se scriu la ieşire caracterele zecimale
ale ei, eventual precedate de semnul -, dacă data este negativa ; o - data se converteşte din tipul int în octal şi se scriu la ieşire caracterele ei octale; x - data se converteşte din tipul int în hexazecimal şi se scriu la ieşire caracterele ei
hexazecimale; X - ca şi în cazul literei x, dar în scrierea hexazecimala se folosesc literele mari (A - F);
Programarea în limbajul C - Îndrumar de laborator ______________________________________________________________________________________________________________________________________________________
11
u - data se converteşte din tipul unsigned în zecimal întreg fără semn c - valoarea parametrului care ii corespunde se considera ca reprezintă codul ASCII al
unui caracter şi se scrie caracterul respectiv; s - parametrul care-i corespunde se scrie ca un sir de caractere; se considera ca şirul se
termina la întâlnirea caracterului NUL ('\0'); f - valoarea parametrului care-i corespunde se converteşte din tipul float sau double în formatul: ddddd.....d.dddd...d
(d reprezintă o cifra zecimala), unde numărul de cifre după punctul zecimal este fie cel indicat de precizia specificatorului de format, fie este egal cu 6. Partea întreagă este precedata de semnul minus dacă numărul este negativ;
e - conversia se realizează din tipul float sau double în formatul : d.ddd.....de+/-ddd
unde numărul cifrelor de după punctul zecimal este dat de precizia specificatorului de format sau este egal cu 6, dacă aceasta este absenta. Partea întreagă este precedata de semnul minus dacă numărul este negativ. La exponent se va scrie una, doua sau trei cifre, în funcţie de valoarea numărului;
E - ca şi în cazul literei e, cu deosebirea ca litera e se schimba cu E : d.ddd.....dE+/-ddd La exponent se va scrie una, doua sau trei cifre, în funcţie de valoarea numărului; g - se aplica una din conversiile definite de literele f sau e, alegându-se cea care se
reprezintă pe un număr minim de caractere; G - ca şi g cu singura deosebire ca se utilizează E în loc de e. Literele d,o,x şi u pot fi precedate de litera l şi în acest caz conversia se realizează din long în loc de int. Literele f,e,E,g şi G pot fi precedate de litera L şi în acest caz conversia se realizează din long double în loc de float sau double. Funcţia scanf preia date tastate de la terminalul standard sub controlul unor formate. Sintaxa apelului este : scanf(control,par1,par2,...,parn); - par1,par2,...,parn - sunt adresele zonelor în care se păstrează datele citite după ce au fost convertite din formatele lor externe în formate interne corespunzătoare. Adresa unei zone de memorie se exprima adesea folosind operatorul unar &; - parametrul de control este un sir de caractere care defineşte formatul datelor şi al eventualelor texte aflate la intrarea de la tastatura; Caracterele albe din compunerea parametrului de control sunt neglijate. Restul caracterelor, care nu fac parte dintr-un specificator de format, trebuie să existe la intrare în poziţii corespunzătoare (acestea se folosesc în vederea efectuării de controale asupra datelor citite). Specificatorii de format încep cu caracterul % şi se termina cu 1-2 litere. Literele definesc tipul de conversie aplicat datei care se scrie.
Programarea în limbajul C - Îndrumar de laborator ______________________________________________________________________________________________________________________________________________________
12
Intre procent şi litere intr-un specificator de format se mai pot utiliza: - opţional : un caracter asterisc - caz în care data din câmpul respectiv va fi prezenta la intrare, dar ea nu se atribuie nici unei variabile şi deci nu-i va corespunde un parametru; - opţional : un sir de cifre care defineşte lungimea maxima a câmpului din care se citeşte data sub controlul formatului respectiv; Câmpul controlat de un specificator de format începe cu primul caracter care nu este alb şi se termina : - fie la caracterul după care urmează un caracter alb; - fie la caracterul după care urmează un caracter care nu corespunde specificatorul de format care controlează acel câmp;
- fie la caracterul prin care se ajunge la lungimea maxima a câmpului indicata în specificatorul de format (doar dacă în specificatorul de format este indicata lungimea maxima). Funcţia scanf citeşte toate câmpurile care corespund specificatorilor de format, inclusiv eventualele texte prezentate în parametrul control. În cazul unei erori, citirea se întrerupe în locul în care s-a întâlnit eroarea. Eroarea poate proveni : - din necorespondenţa textului curent în parametrul de control cu cel din fişierul de intrare; - din neconcordanta dintre data din câmp şi specificatorul de format sub controlul căruia se face citirea. Apariţia unei erori poate fi pusa uşor în evidenta deoarece funcţia scanf returnează, la revenirea din ea, numărul câmpurilor citite corect. Funcţia scanf citeşte date din zona tampon ataşata tastaturii, la fel ca şi getchar. De aceea, datele se citesc efectiv după ce s-a acţionat tasta Enter. Semnificaţia ultimei litere a specificatorului de format la citire : Litera Conversia realizată d - data din câmpul de intrare este un sir de cifre zecimale, precedat eventual de un semn
şi se converteşte din zecimal în binar de tip int; o - ca şi în cazul literei d, cu deosebirea ca şirul de cifre este considerat ca formează un
număr octal; x - ca şi în cazul literei d, cu deosebirea ca şirul de cifre este considerat ca formează un
număr hexazecimal; se utilizează literele mici a-f sau mari A-F pentru a scrie cifrele peste 9;
X - ca şi în cazul literei x; u - data de intrare este un sir de cifre zecimale care formează un număr întreg fără semn
şi se converteşte în binar tipul unsigned; c - data de intrare se considera formata din caracterul curent de la intrare şi parametrului
corespunzător i se atribuie codul ASCII al acestui caracter; în acest caz nu se face avans peste caracterele albe, ca în cazul celorlalţi specificatori;
Programarea în limbajul C - Îndrumar de laborator ______________________________________________________________________________________________________________________________________________________
13
s - data se considera ca este un sir de caractere; şirul începe, conform regulilor generale, cu primul caracter care nu este alb şi se termina la caracterul după care urmează un caracter alb sau când s-au citit atâtea caractere câte indica dimensiunea maxima din specificatorul de format;
f - data de intrare reprezintă un număr flotant, eventual precedat de un semn; se converteşte în virgula flotanta simpla precizie; data care se citeşte poate fi scrisa atât în formatul cu exponent, cat şi în formatul fără exponent.
Literele d,o,x şi X pot fi precedate de litera l şi în acest caz conversia se realizează spre long în loc de int sau de litera h şi în acest caz conversia se realizează spre short . Specificatorul terminat cu lu realizează conversia spre unsigned long. Litera f va fi precedata de litera l pentru a face conversia spre formatul virgula flotanta dubla precizie, deci spre tipul double. Specificatorul terminat cu Lf permite conversia numerelor zecimale, atât din format cu exponent cat şi fora, spre formatul virgula flotanta long double.
Programarea în limbajul C - Îndrumar de laborator ______________________________________________________________________________________________________________________________________________________
14
TEMA 2
Problema 1. 1. Copiaţi în caiete textul programului de mai jos. 2. Copiaţi textul programului de mai jos într-o fereastră noua. 3. Compilaţi-l, link-editaţi-l şi lansaţi-l în execuţie. 4. Urmăriţi rezultatele execuţiei pe ecranul utilizator şi explicaţi forma de afişare. 5. Modificaţi "inteligent" specificatorii de format, urmăriţi şi explicaţi rezultatele astfel obţinute. #include <stdio.h> #include <conio.h> #define A "Bine ati venit în lumea programelor C" int main(void) /* programul ilustreaza afişarea caracterelor si a sirurilor de caractere cu diferiti specificatori de format */ { printf("%c\n",'A'); printf("|%5c|\n",'A'); printf("|%-5c|\n",'A'); puts(A); printf("A=*%s*\n", A); printf("A=*%38s*\n", A); printf("A=*%40.23s*\n", A); getch(); return 0;
} Problema 2. 1. Copiaţi în caiete textul programului de mai jos. 2. Copiaţi textul programului de mai jos într-o fereastră noua. 3. Compilaţi-l, link-editaţi-l şi lansaţi-l în execuţie. 4. Urmăriţi rezultatele execuţiei pe ecranul utilizator şi explicaţi forma de afişare. 5. Modificaţi "inteligent" specificatorii de format, urmăriţi şi explicaţi rezultatele astfel obţinute. 6. Modificaţi definiţia constantei simbolice A astfel încât ea aibă valoarea 32768. Explicaţi comportamentul "ciudat" al programului. Faceţi modificările necesare astfel încât programul să afişeze corect şi aceasta valoare. #include <stdio.h> #define A 12345 int main(void)
Programarea în limbajul C - Îndrumar de laborator ______________________________________________________________________________________________________________________________________________________
15
/* programul ilustreaza afişarea numerelor întregi cu diferiti specificatori de format */ { printf("A=%d\n", A); printf("A=*%7d*\n", A); printf("A=*%-7d*\n", A); printf("A=%o\n", A); printf("A=%x\n", A); printf("A=%X\n", A); return 0;
} Problema 3. 1. Copiaţi în caiete textul programului de mai jos. 2. Copiaţi textul programului de mai jos într-o fereastră noua. 3. Compilaţi-l, link-editaţi-l şi lansaţi-l în execuţie. 4. Urmăriţi rezultatele execuţiei pe ecranul utilizator şi explicaţi forma de afişare. 5. Modificaţi "inteligent" specificatorii de format, urmăriţi şi explicaţi rezultatele astfel obţinute. 6. Modificaţi definiţia constantei simbolice X astfel încât ea să aiba valoarea 1.8e308. Explicaţi comportamentul "ciudat" al programului. Faceţi modificările necesare astfel încât programul să afişeze corect şi aceasta valoare. #include <stdio.h> #define A 47.389 #define X -123.5e20 int main(void) /* programul ilustrează afişarea numerelor neîntregi cu diferiti specificatori de format */ { printf("A=%f\n", A); printf("A=%.3f\n", A); printf("A=%.2f\n", A); printf("A=%.1f\n", A); printf("A=%.0f\n", A); printf("X=%e\n", X); printf("X=%.4e\n", X); printf("X=%.3e\n", X); printf("X=%.2e\n", X); printf("X=%.1e\n", X); printf("%20f\n%20e\n%20g\n", 1.25,1.25,1.25); printf("%20f\n%20e\n%20g\n", .25,.25,.25); printf("%20f\n%20e\n%20g\n",123e-1,123e-1,123e-1); printf("%20f\n%20e\n%20g\n", 12.3e4,12.3e4,12.3e4); return 0;
}
Programarea în limbajul C - Îndrumar de laborator ______________________________________________________________________________________________________________________________________________________
16
Problema 4 Pe baza exemplelor de mai sus (dar mai ales a cunoştinţelor dobândite prin citirea şi învățarea cursului) scrieţi în caiete şi apoi să rulaţi un program C care : - să definească constantele simbolice: S - "Salut !" A - 1996 X - 123456.789012345 - să afişeze şirul S în centrul ecranului (sunt 80 de poziţii pe linie) - să afişeze A ca întreg pe 9 poziţii, cadrat la stânga zonei - să afişeze X în forma cu exponent cu 7 cifre la partea zecimala a acestui format. Problema 5. 1. Copiaţi textul programului de mai jos într-o fereastră nouă şi lansaţi-l în execuţie (programul ilustrează citirea datelor de tip caracter). 2. Introduceţi diverse valori pentru caracterul ce se citeşte. 3. Modificaţi programul astfel încât ecranul consolei să rămână blocat pe ecranul utilizator până la apăsarea unei taste. 4. Modificaţi programul astfel încât să se citească doua date de tip caracter. #include <stdio.h> int main(void) { char ch; printf("Introduceţi un caracter:"); scanf("%c",&ch); printf("\nAti introdus caracterul %c\n", ch); return 0;
} Problema 6. 1. Copiaţi textul programului de mai jos într-o fereastră nouă şi lansaţi-l în execuţie (programul ilustrează citirea datelor de tip întreg). 2. Explicaţi semnificaţia specificatorilor de format utilizaţi. 3. Introduceţi valori corecte pentru cele 5 numere întregi care se citesc (separate prin <Enter>). 4. Introduceţi 5 valori corecte de numere întregi separate prin blank-uri. Explicaţi modul de execuţie al programului. 5. Introduceţi de exemplu secvenţa de caractere 5.<Enter>. Explicaţi rezultatele obţinute. #include <stdio.h> #include <conio.h> int main(void) { int n0,n1,n2,n3,n4,nr; printf("Introduceţi un numar întreg = "); scanf("%d",&n0);
Programarea în limbajul C - Îndrumar de laborator ______________________________________________________________________________________________________________________________________________________
17
printf("%d",n0); printf("Introduceţi 4 numere întregi ="); nr=scanf("%d%d%d%d", &n1, &n2, &n3, &n4); printf("n1 = %d n2 = %d n3 = %d n4 = %d\nnr=%d\n",n1,n2,n3,n4,nr); getch(); return 0;
} Problema 7. 1. Copiaţi textul programului de mai jos într-o fereastră nouă şi lansaţi-l în execuţie (programul ilustrează citirea datelor de tip real). 2. Explicaţi semnificaţia specificatorilor de format utilizaţi. 3. Introduceţi diverse valori pentru cele 3 numere reale (de exemplu : 1 3e5 0.1234567890) şi explicaţi rezultatele execuţiei programului. 4. Modificaţi adecvat programul astfel încât introducerea datelor să fie însoţita de câte un mesaj adecvat pentru fiecare data introdusă (deci înaintea introducerii valorii xi, i=1,2,3, să apară pe ecran textul xi=). Atenţie la modul de introducere a datelor, astfel încât programul să fie exploatat adecvat. #include <stdio.h> #include <conio.h> int main(void) { float x1,x2,x3; int nr; printf("Introduceti 3 nr. reale ="); nr=scanf("%f%f%f",&x1,&x2,&x3); printf("x1 = %e\nx2 = %e\nx3 = %e\nnr=%d\n",x1,x2,x3,nr); getch(); return 0;
} Problema 8. Pe baza exemplelor de mai sus (dar mai ales a cunoştinţelor dobândite prin citirea şi învățarea cursului) scrieţi în caiete şi apoi rulaţi un program C care citeşte de la tastatură 3 valori reale dublă precizie şi apoi le afişează. Citirea şi afişarea datelor vor fi însoţite de mesaje adecvate. Se va afişa totodată informaţia asociată corectitudinii citirii datelor introduse.
Programarea în limbajul C - Îndrumar de laborator ______________________________________________________________________________________________________________________________________________________
18
LABORATORUL 3
OPERATORI ÎN LIMBAJUL C
Vom prezenta, pentru început, principalii operatori ai limbajului C, urmând ca, pe
parcursul laboratoarelor următoare, să introducem şi ceilalţi operatori
Operatorii ce apar într-o expresie pot fi operatori unari, ce se aplică unui singur
operand, operatori binari, ce leagă doi operanzi, sau operatori ternari, ce leagă trei operanzi.
Operatorii se pot clasifica în funcţie de clasa de operaţii pe care o implementează, sau
în funcţie de prioritatea atribuită. La scrierea unei expresii se pot folosi operatori din aceeaşi
clasă sau din clase diferite. La evaluarea unei expresii se ţine seama de priorităţile operatorilor
ce aparţin unor clase diferite, de asociativitatea operatorilor de aceeaşi prioritate şi de regula
conversiilor implicite.
Operatori paranteză
Aceşti operatori au prioritate maximă şi sunt reprezentaţi prin simbolurile :
( ) - paranteze rotunde
[ ] - paranteze pătrate
Parantezele rotunde se folosesc pentru a modifica ordinea operaţiilor efectuate în
vederea calculului unei expresii, forţând evaluarea cu prioritate a sub expresiei incluse în
paranteze. Ele se utilizează de asemenea şi pentru a marca apelul unei funcţii.
Parantezele pătrate includ expresii ce reprezintă indici, fiind numite şi operatori de
indexare.
Operatori aritmetici
Operatorii aritmetici, prezentaţi în ordine descrescătoare a priorităţilor, sunt :
- operatori unari : + (pozitivare)
- (negativare)
- operatori binari multiplicativi : * (înmulţire)
/ (împărţire)
% (rest) - numai pentru operanzi întregi !
- operatori binari aditivi : + (adunare)
- (scădere)
Toţi operatorii unari au aceeaşi prioritate şi se asociază de la dreapta la stânga. Toţi
operatorii multiplicativi au aceeaşi prioritate şi se asociază de la stânga la dreapta. În mod
similar, operatorii aditivi au aceeaşi prioritate şi se asociază de la stânga la dreapta.
În general, rezultatul calculelor este incorect dacă se depăşeşte intervalul valorilor
reprezentabile pentru fiecare tip de dată în parte.
Programarea în limbajul C - Îndrumar de laborator ______________________________________________________________________________________________________________________________________________________
19
În evaluarea expresiilor se aplică regula conversiilor implicite. Aceasta se enunţă
astfel :
Dacă operatorul curent se aplică unor operanzi de acelaşi tip, se execută operaţia
respectivă, iar tipul rezultatului este tipul comun al operanzilor; dacă operatorul curent se
aplică unor operanzi de tipuri diferite, operandul de tip aşa-numit “inferior” se converteşte
spre tipul aşa-numit “superior” al celuilalt operand, se execută operaţia şi tipul rezultatului
este tipul “superior”.
Concret, în primul rând se convertesc operanzii de tip char la tipul int.
Apoi, dacă unul din operanzi este de tip long double atunci celălalt operand se
converteşte la tipul long double şi rezultatul operaţiei este de tip long double. Dacă unul din
operanzi este de tip double atunci celălalt operand se converteşte la tipul double şi rezultatul
operaţiei este de tip double. Dacă unul din operanzi este de tip float atunci celălalt operand se
converteşte la tipul float şi rezultatul operaţiei este de tip float. Dacă unul din operanzi este de
tip unsigned long atunci celălalt operand se converteşte la tipul unsigned long şi rezultatul
operaţiei este de tip unsigned long. Dacă unul din operanzi este de tip long int atunci celălalt
operand se converteşte la tipul long int şi rezultatul operaţiei este de tip long int. Dacă unul
din operanzi este de tip unsigned int atunci celălalt operand se converteşte la tipul unsigned
int şi rezultatul operaţiei este de tip unsigned int.
Aplicând regula de mai sus în procesul de evaluare a unei expresii pe rând fiecărui
operator, se determină în final tipul şi valoarea expresiei respective.
Exemplul 1.
a) Valoarea expresiei 9/2 este 4 deoarece, ambii operanzi fiind de tip întreg, tipul
expresiei este de asemenea întreg (operatorul / furnizează la aplicarea să asupra unor operanzi
de tip întreg, câtul împărţirii primului operand la cel de al doilea).
b) Dacă a şi b sunt variabile, expresia aritmetică b
a
2 se scrie corect în limbajul C ca :
a/2/b sau a/(2*b). Formularea a/2*b descrie expresia ba
2. Aceasta deoarece în cazul
operatorilor binari ce au aceeaşi prioritate, asocierea acestora se face de la stânga la dreapta.
Operatori de relaţie
Operatorii de relaţie sunt operatori binari, au cu toţii aceeaşi prioritate şi ei sunt :
< (mai mic)
<= (mai mic sau egal)
> (mai mare)
>= (mai mare sau egal).
Programarea în limbajul C - Îndrumar de laborator ______________________________________________________________________________________________________________________________________________________
20
O expresie de forma :
expresie_1 operator_relaţie expresie_2 ,
unde expresie_1 şi expresie_2 sunt expresii valide în C, iar operator_relaţie este unul din
operatorii de relaţie, se numeşte expresie de relaţie şi este de tip int. Valoarea unei astfel de
expresii este 1 dacă valorile celor două expresii expresie_1 şi expresie_2 satisfac relaţia
specificată de operatorul în cauză şi 0 în caz contrar.
Operatori de egalitate
Operatorii de egalitate, operatori binari, ce au cu toţii aceeaşi prioritate, sunt :
== (egal)
!= (diferit)
O expresie de forma :
expresie_1 operator_egalitate expresie_2 ,
unde expresie_1 şi expresie_2 sunt expresii valide în C, iar operator_egalitate este unul din
operatorii de egalitate, se numeşte expresie de egalitate şi este de tip int. Valoarea unei astfel
de expresii este 1 dacă valorile celor două expresii expresie_1 şi expresie_2 satisfac relaţia
specificată de operatorul în cauză şi 0 în caz contrar.
Exemplul 2. Expresia care descrie corect testul asupra parităţii unui număr întreg x ( care
apare deci într-o declaraţie de forma int x) se scrie în limbajul C ca :
x % 2 == 0
şi ea are de exemplu valoarea 0 pentru x = 11 şi 1 pentru x = 10.
Operatori logici
Facem pentru început observaţia că în limbajul C nu există definit tipul de date logic.
Se consideră că valoarea de adevăr “fals” este reprezentată de valoarea zero, iar orice valoare
diferită de zero este interpretată ca valoare de adevăr “adevărat”.
Operatorii logici prezentaţi în ordine descrescătoare a priorităţilor sunt :
! (negaţia logică) - operator unar
&& (ŞI logic) - operator binar
|| (SAU logic) - operator binar
Operatorul unar se asociază de la dreapta la stânga, iar operatorii binari se asociază de la
stânga la dreapta.
O expresie de forma :
expresie_1 operator_logic expresie_2 ,
unde expresie_1 şi expresie_2 sunt expresii valide C, iar operator_logic este unul din
operatorii logici binari, se numeşte expresie logică şi este de tip int. Valoarea unei astfel de
Programarea în limbajul C - Îndrumar de laborator ______________________________________________________________________________________________________________________________________________________
21
expresii este 1 dacă valorile celor două expresii E1 şi E2 satisfac relaţia specificată de
operatorul în cauză şi 0 în caz contrar.
Exemplul 3. Dacă an este o variabilă de tip întreg despre care se presupune că reprezintă un an
calendaristic, expresia care exprimă condiţia ca an să fie bisect are forma (un an este bisect
dacă el aparţine intervalului [1600, 4900], este multiplu de 4 şi nu este multiplu de 100, cu
excepţia anilor multiplii de 400) :
an >= 1600 && an <= 4900 && (an % 4 == 0 && an % 100 != 0 || an % 400 ==0)
şi ea are valoarea 1 pentru anii bisecţi ce aparţin intervalului şi 0 pentru anii nebisecţi sau care
nu aparţin intervalului menţionat.
Operatori de atribuire
Operatorul de atribuire în limbajul C are simbolul :
= (atribuire)
O expresie de forma:
v = (expresie)
unde v este o variabilă simplă, elementul unui tablou sau al unei structuri, iar expresie este o
expresie validă C, se numeşte expresie de atribuire. Cum operatorul de atribuire este unul
dintre cei mai puţin prioritari, parantezele pot lipsi în cele mai multe cazuri. Expresia de
atribuire se evaluează astfel : se evaluează întâi expresie, iar rezultatul obţinut se converteşte
dacă este cazul la tipul lui v, după care i se atribuie lui v. Ea are ca tip, tipul membrului stâng
şi ca valoare, valoarea expresiei rezultată în urma conversiei.
O construcţie de forma :
v = (v1 = (expresie))
este corectă şi reprezintă tot o expresie de atribuire, lui v atribuindu-i-se valoarea lui v1,
eventual după o conversie de tip dacă este cazul. Deoarece operatorul de atribuire se asociază
de la dreapta la stânga, expresia se poate scrie în general :
v = v1 = v2= ......= vn = (expresie)
În limbajul C, pentru a prescurta scrierea unei expresii de forma:
v = v operand (expresie)
unde operand este unul din operanzii : / % * - +, este permisă scrierea echivalentă :
v operand = expresie
Operatori de incrementare şi de decrementare
Programarea în limbajul C - Îndrumar de laborator ______________________________________________________________________________________________________________________________________________________
22
Operatorii de incrementare şi de decrementare sunt operatori unari şi au simbolurile :
++ (incrementare)
-- (decrementare)
Aceşti operatori pot fi folosiţi prefixând operandul, caz în care se foloseşte valoarea
operandului la care s-a aplicat în prealabil operatorul respectiv, sau postfixând operandul, caz
în care se foloseşte valoarea operandului dinaintea aplicării operatorului respectiv.
Exemplul 4. Dacă x este o variabilă ce are la un moment dat valoarea 5 atunci :
a) După evaluarea expresiei de atribuire y = ++x, y = 6 şi x = 6
b) După evaluarea expresiei de atribuire y = x++, y = 5 şi x = 6
Operatorul de forţare a tipului sau de conversie explicită
Acest operator este unar şi se scrie sub forma :
(tip) operand
unde tip este numele unui tip predefinit sau definit de utilizator , iar efectul aplicării unui
astfel de operator este conversia valorii operandului spre tipul tip.
Exemplul 5. Dacă n este o variabilă de tip întreg, atunci expresia n/(n + 1), evaluată în C, are,
indiferent de valoarea lui n, valoarea 0. Pentru calculul numărului fracţionar corespunzător, ea
se scrie fie ca n/(n+1.0), fie, folosind o conversie explicită de tip care să forţeze tipul unuia
din cei doi operanzi ai împărţirii la un tip real (de exemplu double) : (double)n/(n + 1).
Operatorul dimensiune
Acest operator este unar şi are simbolul
sizeof (dimensiune)
El se poate folosi în una din formele de mai jos :
a) sizeof data
unde data este numele unei variabile simple, al unei variabile tablou sau al unei structuri;
b) sizeof (tip)
unde tip este numele unui tip de data, predefinit sau definit de utilizator.
Operatorul adresă
Operatorul adresă este un operator unar şi are simbolul :
& (adresă)
El se aplică pentru a determina adresa de început a zonei de memorie alocate unei date.
Programarea în limbajul C - Îndrumar de laborator ______________________________________________________________________________________________________________________________________________________
23
Operatorul condiţional
Acest operator ternar permite construirea unei expresii a cărei valoare depinde de
valoarea unei condiţii şi el este simbolizat prin caracterele :
? :
asociindu-se de la dreapta la stânga.
O expresie care foloseşte acest operator se numeşte expresie condiţională şi ea se
construieşte astfel :
expresie_1? expresie_2 : expresie_3
unde expresie_1, expresie_2, expresie_3 sunt expresii valide în limbajul C.
O expresie condiţională se evaluează astfel :se calculează valoarea expresiei
expresie_1. Dacă rezultatul obţinut este diferit de zero, atunci tipul şi valoarea expresiei
coincid cu tipul şi valoarea expresiei expresie_2. În caz contrar, tipul şi valoarea expresiei
coincid cu tipul şi valoarea expresiei expresie_3.
Exemplul 6. Dacă a şi b sunt două variabile, expresia a > b ? a : b furnizează maximul dintre
cele două valori.
Operatorul virgulă
Operatorul virgulă este un operator binar cu simbolul :
, (virgulă)
şi se foloseşte pentru a lega două expresii într-una singură, printr-o construcţie de forma :
expresie_1 , expresie_2
care reprezintă din punct de vedere sintactic o singură expresie, ce are acelaşi tip şi aceeaşi
valoare ca şi expresia expresie_2.
Operatorul virgulă se foloseşte în cazurile în care sintaxa limbajului impune folosirea unei singure expresii, iar complexitatea calculelor necesită evaluarea mai multor expresii.
Programarea în limbajul C - Îndrumar de laborator ______________________________________________________________________________________________________________________________________________________
24
TEMA 3 Copiaţi în caiete tabelul de mai jos : Tabel cu priorităţile operatorilor (operatorii de pe aceeaşi linie au aceeaşi prioritate) ( ) [ ] . -> -(unar) +(unar) *(unar) &(unar) ! ~ ++ -- (tip) sizeof * / % + - << >> < <= >= > == != &(binar) ^ | && || ? : = =op (op poate fi *(binar) / % +(binar) -(binar) << >> & ^ |) ,
ATENTIE : Toţi operatorii se asociază de la stânga la dreapta, exceptând cei unari, condiţionali şi de atribuire care se asociază de la dreapta la stânga .
Notaţi în caiete tabelele de adevăr pentru operatorii logici | ADEVARAT FALS ! |-------------------------------------- negaţie logica | FALS ADEVARAT && | ADEVARAT FALS -------------------------|---------------------------- SI logic ADEVARAT | ADEVARAT FALS FALS | FALS FALS || | ADEVARAT FALS -------------------------|---------------------------- SAU logic ADEVARAT | ADEVARAT ADEVARAT FALS | ADEVARAT FALS Reamintim ca în C nu exista predefinit tipul de date logice (ce are drept componente
valorile logice ADEVARAT şi FALS). O variabila se considera ca având valoarea logica ADEVARAT dacă ea este nenulă, având valoarea FALS atunci când ea este nula.
Programarea în limbajul C - Îndrumar de laborator ______________________________________________________________________________________________________________________________________________________
25
Problema 1. Analizaţi exemplele de mai jos răspunzând la întrebările puse. În cazul în care consideraţi ca expresiile sunt scrise incorect, corectaţi-le.
Exemplul 1. Pentru x variabila de tip real, este corecta expresia ? 99(x + 1,5) Exemplul 2. Pentru l1,l2,l3 variabile de tip logic, sunt corecte expresiile de mai jos ? && l1 l2 ! l1 || l2 l2 && ! l1 Ce valoare au expresiile scrise corect pentru l1 != 0 şi l2 = 0 ? Dar pentru l1 = 0 şi l2 != 0 Este expresia a doua echivalenta cu ! (l1 || l2) ? Dar cea de a treia cu l2 && (! l1) ? Exemplul 3. Pentru x variabila de tip real este corecta expresia de mai jos care exprima condiţia
ca x să fie mai mic decât 5 sau mai mare ca 10 ? x < 5 && x > 10 Dar expresia de mai jos care exprima condiţia ca x să fie egal cu zero : x=0 Ce valoare au expresiile scrise corect pentru x=0, pentru x=5 şi pentru x=7 ? Exemplul 4. Pentru a,b variabile de tip real, sunt corecte expresiile de mai jos ? a\b a%b Dar pentru a, b variabile de tip întreg? Ce valori au expresiile pentru a=8 şi b=3 în cele
doua cazuri ?
Problema 2 ilustreaza "beneficiile" utilizării depanatorului (debugger-ului)!
Problema 2. Să se copie programul de mai jos într-o fereastră nouă şi să se execute.
Daţi valorile : ore=1, min=6, sec=8.
: ore=9, min=6, sec=8.
Explicaţi comportamentul sau "CIUDAT" şi găsiţi remediul.
Executaţi programul pas cu pas, introducând în fereastră Watch expresiile 3600*ore, 60*min,
sec.
Programarea în limbajul C - Îndrumar de laborator ______________________________________________________________________________________________________________________________________________________
26
#include <stdio.h>
int main(void)
{
short ore,min,sec,t;
printf("Introduceti timpul in ore, minute si secunde ");
if (scanf("%hd%hd%hd",&ore,&min,&sec)!=3)
printf("Date incorecte");
else
{
t=ore*3600+min*60+sec;
printf("%d ore %d minute %d secunde = %d secunde", ore,min,sec,t);
}
return 0;
}
Problemele 3 şi 4 ilustrează modul de utilizare a principalilor operatori din C şi C++.
Copiaţi în caiete textele programelor aferente şi apoi executaţi-le pe rând. Identificaţi semnificaţia fiecărui operator în parte, priorităţile acestora, tipul operanzilor şi explicaţi rezultatele obţinute.
Problema 3.
#include <stdio.h> #include <conio.h> int main(void) { int an,bis; int a,b,c,d; double x,y,z,t; char car; clrscr(); a=10; b=3; x=10.; c=a/b; y=a/b; t=x/b; d=a%b; z=a%b; printf("a=%d\tb=%d\nc=%d\ty=%f\tt=%f\nd=%d\tz=%f\n",a,b,c,y,t,d,z); printf("an = "); scanf("%d",&an);
Programarea în limbajul C - Îndrumar de laborator ______________________________________________________________________________________________________________________________________________________
27
bis=an >= 1600 && an <= 4900 && (an%4 == 0 && an %100 != 0 || an %400 ==0); printf("Anul %d este %s", \ an, bis? "bisect" : "nebisect"); printf("\na<b %d",a<b); printf("\na>b %d\n",a>b); printf("Tastati o litera minuscula ..."); printf("\nMajuscula corespunzatoare este %c\n",getche() - 'a' + 'A'); getch(); return 0;
}
Problema 4 #include <stdio.h> #include <conio.h> #include <stdlib.h> int main(void) { int a,b,c,d; long long l; double x,y,z; char car; a=8; b=a++; c=--a; printf("a = %d\tb = %d\tc = %d\n", a,b, c); x=8; printf("a= "); scanf("%d",&a); c=(a>x)+1; printf("a = %d\tx = %g\tc (a>x)+1 = %d\n", a,x, c); x+=1; printf("x = %f\n", x); printf("sizeof (char)\t\t =%2d\n",sizeof(char)); printf("sizeof (short)\t\t =%2d\n",sizeof(short)); printf("sizeof (int)\t\t =%2d\n",sizeof(int)); printf("sizeof (long)\t\t =%2d\n",sizeof (long )); printf("sizeof (long long)\t =%2d\n",sizeof(long long)); printf("sizeof (float)\t\t =%2d\n",sizeof(float)); printf("sizeof (double)\t\t =%2d\n",sizeof(double)); printf("sizeof (long double)\t =%2d\n",sizeof(long double)); printf("b/(b+1) =%.14g\n", (double)b/(b+1)); //explicati rolul conversiei spre double l=2147483648; printf("Valoarea expresiei l==2147483647+1 = %d\n",l==2147483647+1);
//explicati rezultatul si faceti modificari pentru a obtine valoarea corecta
Programarea în limbajul C - Îndrumar de laborator ______________________________________________________________________________________________________________________________________________________
28
printf("x,y= "); scanf("%lf%lf",&x,&y); z=x<y?x:y; printf("x = %g\ty = %g\tmin(x,y) = %g\n" ,x,y,z); getch(); return 0; }
Problema 5. Să se scrie un program C care preia de la consola şi afişează doua numere reale (float) x,y şi 2 numere întregi m şi n.
a. să se calculeze memoreze şi afişeze separat expresiile t=x*y, z=x/y. să se comenteze : - rezultatul produsului x*y pentru x=1e20 y=1e20 - rezultatul împărțirii x/y pentru x=1e+37 y=1e-2 x=1e-38 y=1e-8 b. să se calculeze memoreze şi afişeze: - maximul dintre x şi m - restul împărțirii lui m la 2n c. să se afişeze un mesaj din care să rezulte dacă n este impar .
Programarea în limbajul C - Îndrumar de laborator ______________________________________________________________________________________________________________________________________________________
29
LABORATORUL 4 INSTRUCŢIUNEA if ŞI INSTRUCŢIUNI EXPRESIE
Instrucţiunea if implementează structura de decizie din programarea structurată. Ea
permite selectarea pentru execuţie a uneia dintre două alternative, în urma testării valorii unei
expresii ce implementează relaţia de condiţionare a deciziei.
Sintaxa instrucţiunii este:
if (expresie)
instrucţiune_1
else
instrucţiune_2
unde expresie este o expresie C validă, iar instrucţiune_1 şi instrucţiune_2 reprezintă
respectiv câte o instrucţiune a limbajului C. În cazul în care alternativele deciziei trebuie
descrise prin mai multe instrucţiuni, acestea se grupează într-o instrucţiune compusă. Pentru
claritatea redactării (lizibilitate) se recomandă scrierea indentată care pune mai bine în
evidenţă cele două alternative.
Modul de execuţie al instrucţiunii este următorul : se evaluează expresia expresie .
Dacă aceasta are o valoare diferită de zero, se execută instrucţiunea instrucţiune_1 şi nu se
execută instrucţiunea instrucţiune_2. Altfel, deci dacă expresie are o valoare egală cu zero,
se execută instrucţiunea instrucţiune_2 şi nu se execută instrucţiunea instrucţiune_1.
Sintaxa permite ca instrucţiunea instrucţiune_2 să fie vidă, caz în care se omite şi
cuvântul rezervat else.
Exemplul 1. Instrucţiunea if cu alternative exprimate prin câte o singură instrucţiune.
.............
int nota ;
.............
if (nota >= 5)
printf(“Felicitari ! Ati promovat!\n”) ;
else
printf(“Nu ati promovat !\n”) ;
Exemplul 2. Instrucţiunea if cu alternative exprimate prin instrucţiuni compuse.
.............
double s,y ;
int n ;
.............
if (n < 10)
Programarea în limbajul C - Îndrumar de laborator ______________________________________________________________________________________________________________________________________________________
30
{
n++;
s += y ;
}
else
{
n-- ;
s -= y ;
}
Exemplul 3. Semnalăm printr-un exemplu necesitatea folosirii atente a separatorului
punct şi virgulă (;) :
.............
double s,x,y ;
..................
if (x != y) ; /* ATENŢIE !!!!! */
{
x++ ;
s = x + y ;
}
Scrierea neglijentă a separatorului ; marchează sfârşitul instrucţiunii if (interpretat de
compilator ca fiind cu o singură alternativă, descrisă prin instrucţiunea vidă). Compilatorul nu
va semnala eroare, instrucţiunea compusă se va Execută necondiţionat, incorect deci.
Exemplul 4. O formă de scriere abuzivă a deciziei este :
int a, b, gasit ;
..................
if (a == b)
gasit = 1 ;
else
gasit = 0 ;
Soluţia mai compactă este dată de simpla atribuire:
gasit = a == b ;
Dacă instrucţiune_1 este la rândul ei o decizie, o construcţie de forma :
if (expresie_1) if (expresie_2) instrucţiune_1 else instrucţiune_2
Programarea în limbajul C - Îndrumar de laborator ______________________________________________________________________________________________________________________________________________________
31
ar putea fi interpretată ambiguu, în două moduri, şi anume :
Varianta 1 :
if (expresie_1)
if (expresie_2)
instrucţiune_1
else
instrucţiune_2
caz în care instrucţiune_2 este alternativa celui de al doilea if.
Varianta 2 :
if (expresie_1)
if (expresie_2)
instrucţiune_1
else
instrucţiune_2
caz în care instrucţiune_2 este alternativa primului if.
Evident, datorită faptului că formatul de redactare a unui program în limbajul C este
liber, scrierea indentată nu face decât să sugereze cele două posibile modalităţi de interpretare,
ele fiind de fapt echivalente.
Compilatorul rezolvă această ambiguitate, asociind construcţia else ultimului if care o
precede în textul sursă căruia nu i s-a asociat deja un else şi nu se găseşte în interiorul unei
instrucţiuni compuse. Ca urmare compilatorul va interpreta construcţia prezentată în varianta
1, caz în care alternativa else se asociază celui de al doilea if.
Pentru a implementa în C varianta a doua, scrierea corectă este :
if (expresie_1)
{
if (expresie_2)
instrucţiune_1
}
else
instrucţiune_2
}
Programarea în limbajul C - Îndrumar de laborator ______________________________________________________________________________________________________________________________________________________
32
TEMA 4
Copiaţi în caiete şi RETINETI denumirile şi prototipurile funcţiilor din tabelul de mai jos
Tabel cu cele mai uzuale funcţii ce au prototipul în fişierul math.h
abs calculează şi returnează valoarea absoluta a unui argument întreg - int abs(int x);
labs calculează şi returnează valoarea absoluta a unui argument de tip long long labs(long x);
fabs calculează şi returnează valoarea absoluta a unui numar real double fabs(double x);
acos implementează funcţia arccos - rezultatul exprimat în radiani double acos(double x);
asin implementează funcţia arcsin - rezultatul exprimat în radiani double asin(double x);
atan implementează funcţia arctg - rezultatul exprimat în radiani double atan(double x);
atan2 calculează şi returnează valoarea funcţiei arctg evaluata pentru raportul dintre primul argument şi cel de al doilea; double atan2(double y, double x); // arctg(y/x)
sin implementează funcţia sinus - argumentul exprimat în radiani double sin(double x);
cos implementează funcţia cosinus - argumentul exprimat în radiani double cos(double x);
tan implementează funcţia tangent - argumentul exprimat în radiani double tan(double x);
sinh implementează funcţia sinus hiperbolic double sinh(double x);
cosh implementează funcţia cosinus hiperbolic double cosh(double x);
tanh implementează funcţia tangent hiperbolic double tanh(double x);
exp implementează funcţia exponenţială double exp(double x);
log calculează şi returnează logaritmul natural al argumentului double log(double x);
log10 calculează şi returnează logaritmul zecimal al argumentului double log10(double x);
pow calculează şi returnează primul argument ridicat la o putere egala cu cel de al doilea argument double pow(double x, double y);
pow10 calculează şi returnează 10 la puterea cel de al doilea argument double pow10(double x);
sqrt calculează şi returnează rădăcina pătrată a argumentului double sqrt(double x);
ceil rotunjeşte valoarea argumentului (numar real)- aproximare prin exces double ceil(double x);
floor trunchiază valoarea argumentului (numar real)- aproximare prin lipsa double floor(double x);
fmod returnează restul împărțirii primului argument la cel de al doilea double fmod(double x, double y);
Programarea în limbajul C - Îndrumar de laborator ______________________________________________________________________________________________________________________________________________________
33
Problema 1. Să se scrie un program C care să calculeze, să memoreze şi să afişeze, pentru
valori preluate de la consola, valorile funcţiei f definita astfel:
0x,5,12x
0x,1
0x,x3
1
)x(f
Problema 2. Să se scrie un program C pentru rezolvarea ecuaţiei de gradul 1(discuţie
completa).
Problema 3. Să se scrie un program C care :
- defineşte constantă simbolica PI = 3.141;
- calculează şi afişează sinPI, cosPI, tgPI;
- se poate calcula tg(PI/2) ?
- calculează şi afişează sin de 45 de grade ;
- calculează şi afişează arcsin(sin(3*PI/2)).
Problema 4. Să se scrie un program C care citeşte un întreg din intervalul [1600,4900] ce
reprezintă un an calendaristic şi afişează numărul de zile din anul respectiv.
Problema 5. Să se scrie un program C care:
- preia de la consola şi afişează doua numere reale x,y, 2 caractere k1,k2 şi 3 valori
întregi m,n,p. Preluarea şi afişarea datelor vor fi însoţite de mesaje adecvate;
- calculează, memorează şi afişează media aritmetica dintre m şi n;
- calculează şi afişează cea mai mare valoare dintre m, n şi p;
- calculează memorează şi afişează valorile incrementate cu o unitate ale lui m şi x;
- calculează, memorează şi afişează expresiile :
e1=e la puterea x + |x| la puterea y;
e2=n/n+1;
e3=10 la puterea m;
e4=ln x;
- calculează şi afişează valoarea polinomului :
p= 3x^3 + 5x^2 -1
unde simbolul ^ reprezintă ridicarea la putere;
- afişează un mesaj din care să rezulte dacă reprezentarea în cod ASCII a lui k1
precede în tabelul de coduri ASCII pe cea a lui k2.
Problema 6. să se scrie un program C pentru rezolvarea ecuaţiei de gradul 2 (discuţie
completa).
Programarea în limbajul C - Îndrumar de laborator ______________________________________________________________________________________________________________________________________________________
34
LABORATORUL 5 INSTRUCŢIUNILE CICLICE while ŞI do - while
Raţionamentul uman de tip iterativ îşi găseşte corespondentul în limbajul C în
instrucţiunile ciclice (repetitive). Acestea permit execuţia repetată a unei instrucţiuni, sau a
unei secvenţe de instrucţiuni înglobate într-o instrucţiune compusă. Instrucţiunea sau secvenţa
de instrucţiuni ce se execută în mod repetat formează corpul ciclului.
În principiu, orice acţiune repetitivă trebuie să se încheie după un număr finit de paşi
(reluări/repetări), ca urmare a îndeplinirii unei condiţii ce constituie aşa-numita relaţie de
condiţionare a ciclului.
Întreaga construcţie este considerată din punct de vedere sintactic ca o singură
instrucţiune şi se poate utiliza în orice context în care este permisă prezenţa unei instrucţiuni
în C.
În limbajul C există trei tipuri de instrucţiuni ciclice :
- instrucţiunea while - ce implementează ciclul cu test iniţial;
- instrucţiunea do - while - ce implementează ciclul cu test final;
- instrucţiunea for ce implementează ciclul cu contor.
7.5.1. Instrucţiunea while
Instrucţiunea implementează structura de ciclu cu test inţial (condiţionat anterior) din
programarea structurată şi are sintaxa :
while (expresie)
instrucţiune;
unde expresie este orice expresie validă în limbajul C şi implementează relaţia de
condiţionare a ciclului şi instrucţiune este o singură instrucţiune C . Această cerinţă nu
reprezintă o restricţie majoră deoarece, în cazul în care corpul ciclului ar trebui descris prin
mai multe instrucţiuni, acestea se pot grupa într-o singură instrucţiune, construind o
instrucţiune compusă.
Efectul execuţiei acestei instrucţiuni este următorul : se evaluează expresia expresie.
Atâta timp cât valoarea acestei expresii este nenulă se execută în mod repetat instrucţiunea
instrucţiune. Execuţia ciclului se încheie în momentul în care expresia are valoarea zero,
situaţie în care se continuă cu execuţia instrucţiunii imediat următoare instrucţiunii while.
Observaţii :
- corpul ciclului poate să nu se execute niciodată dacă expresia are valoarea zero chiar
la intrarea în ciclu;
Programarea în limbajul C - Îndrumar de laborator ______________________________________________________________________________________________________________________________________________________
35
- evident contextul în care se execută instrucţiunea ce constituie corpul ciclului trebuie
să acţioneze asupra expresiei, modificând-o astfel încât, la un moment dat, aceasta să devină
nulă, asigurând astfel finitudine numărului de execuţii ale corpului ciclului;
- instrucţiunea care constituie corpul ciclului poate să definească un alt mod de
execuţie a instrucţiunii while decât cel indicat mai sus. Astfel ea poate realiza încheierea
instrucţiunii while fără a se evalua expresia ce constituie relaţia de condiţionare, prin
intermediul unei aşa numite ieşiri forţate din ciclu (de exemplu corpul ciclului poate conţine
un apel al funcţiei exit).
Instrucţiunea do - while
Instrucţiunea implementează structura de ciclu cu test final (condiţionat posterior) din
programarea structurată şi are sintaxa :
do
instrucţiune;
while (expresie);
unde expresie este orice expresie validă în limbajul C şi implementează relaţia de
condiţionare a ciclului, iar instrucţiune este o singură instrucţiune C (în cazul în care corpul
ciclului ar trebui descris prin mai multe instrucţiuni, acestea se grupează într-o instrucţiune
compusă).
Efectul execuţiei acestei instrucţiuni este următorul :
- 1- se execută instrucţiune (corpul ciclului).;
- 2- se evaluează expresia expresie. În cazul în care expresia este nenulă se
revine la pasul 1, în caz contrar execuţia se încheie, situaţie în care se continuă cu execuţia
instrucţiunii imediat următoare instrucţiunii do - while.
Observaţii :
- corpul ciclului se execută cel puţin o dată, spre deosebire de cazul ciclului while;
- evident contextul în care se execută instrucţiunea ce constituie corpul ciclului trebuie
să acţioneze asupra expresiei, modificând-o astfel încât, la un moment dat, aceasta să devină
nulă, asigurând astfel finitudine numărului de execuţii ale corpului ciclului;
- instrucţiunea care constituie corpul ciclului poate să definească un alt mod de
execuţie a instrucţiunii do - while decât cel indicat mai sus. Astfel ea poate realiza încheierea
instrucţiunii do - while fără a se evalua expresia ce constituie relaţia de condiţionare, prin
intermediul unei aşa numite ieşiri forţate din ciclu (de exemplu corpul ciclului poate conţine
un apel al funcţiei exit).
Având în vedere diferenţele menţionate în privinţa momentului evaluării condiţiei,
înainte pentru while şi respectiv după execuţia corpului ciclului, pentru do-while, pentru
Programarea în limbajul C - Îndrumar de laborator ______________________________________________________________________________________________________________________________________________________
36
aplicaţiile în care corpul ciclului se execută cel puţin odată, ciclul do-while se poate folosi cu
acelaşi corp în locul ciclului while şi reciproc. Astfel se poate scrie generic :
do while (expresie)
instrucţiune; instrucţiune;
while (expresie);
Programarea în limbajul C - Îndrumar de laborator ______________________________________________________________________________________________________________________________________________________
37
TEMA 5 Problema 1. Să se calculeze, pentru o valoare n preluata de la consola, suma şi produsul
primelor n numere naturale :
a. folosind instrucţiunea WHILE ;
b. folosind instrucţiunea DO WHILE.
Se va urmări pas cu pas evoluţia variabilelor de interes (folosind fereastră Watch şi comanda
de execuţie pas cu pas a unui program).
Problema 2. Pentru un numar întreg n preluat de la consola să se calculeze suma cifrelor sale.
Programul interoghează repetat operatorul asupra continuării execuţiei, aceasta încheindu-se
atunci când la întrebarea "Doriti să continuati ?" operatorul răspunde tastând n sau N.
Problema 3. Ştiind ca dezvoltarea în serie pentru cos(x) este
cos(x)=1 - x*x/2! + x*x*x*x/4! - x*x*x*x*x*x/6! + ..... ,
sa se calculeze valoarea aproximativa pentru cos(x), pentru un x preluat de la consola, eroarea
de calcul fiind inferioara unui epsilon preluat de la consola .
INDICAŢIE: eroarea este inferioara lui epsilon când modulul termenului ce urmează a fi
adăugat în suma este inferior lui epsilon. Se va afişa pentru control şi valoarea calculata cu
funcţia de biblioteca cos.
Problema 4.
Ştiind ca dezvoltarea în serie ce poate aproxima numărul PI este:
PI=4*(1-1/3+1/5-1/7+..........),
sa se calculeze valoarea aproximativa a lui PI, cu o eroare mai mica decât un epsilon preluat
de la consola.
INDICAŢIE: eroarea este inferioara lui epsilon când modulul termenului ce urmează a fi
adăugat în suma este inferior lui epsilon. Se vor folosi pentru epsilon valori de ordinul 1e-2,
1e-3, 1e-4.
Se va compara rezultatul obţinut cu valoarea exactă a lui PI=3.14159265358979 (constanta
simbolică M_PI din fișierul math.h).
Problema 5. Să se scrie un program care, preluând un număr întreg (<=10) de la consola,
afişează transcrierea să în notaţie romana (gândiţi o soluţie care să poată fi uşor generalizabila
pentru orice n).
Programarea în limbajul C - Îndrumar de laborator ______________________________________________________________________________________________________________________________________________________
38
LABORATORUL 6 INSTRUCŢIUNEA for
Instrucţiunea implementează o structura de ciclu cu test inţial mai complex,
asemănătoare structurii de ciclu cu contor din programarea structurată şi are sintaxa :
for (expresie_1;expresie_2;expresie_3)
instrucţiune
unde expresie_1, expresie_2, expresie_3 reprezintă expresii valide în limbajul C şi
instrucţiune reprezintă o singură instrucţiune C (în cazul în care corpul ciclului ar trebui
descris prin mai multe instrucţiuni, acestea se grupează într-o instrucţiune compusă).
expresie_1 se numeşte expresie de iniţializare a ciclului;
expresie_2 implementează relaţia de condiţionare a ciclului;
expresie_3 implementează partea de reiniţializare a ciclului, sau de actualizare a
indexului.
Efectul execuţiei acestei instrucţiuni este următorul :
- 1- se evaluează expresie_1;
- 2- se evaluează expresie_2. În cazul în care expresia expresie_2 este nenulă
se continuă execuţia ciclului cu pasul 3, în caz contrar execuţia se încheie, situaţie în care se
continuă cu execuţia instrucţiunii imediat următoare instrucţiunii for;
- 3- se execută instrucţiune (corpul ciclului);
- 4- se evaluează expresie_3 şi se continuă execuţia ciclului cu pasul 2.
Observaţii :
- corpul ciclului poate să nu se execute niciodată dacă expresia expresie_2 are valoarea
zero chiar la intrarea în ciclu;
- evident contextul în care se execută instrucţiunea ce constituie corpul ciclului trebuie
să acţioneze asupra expresiei expresie_2, modificând-o astfel încât, la un moment dat, aceasta
să devină nulă, asigurând astfel finitudine numărului de execuţii ale corpului ciclului;
- instrucţiunea care constituie corpul ciclului poate să definească un alt mod de
execuţie a instrucţiunii for decât cel indicat mai sus. Astfel ea poate realiza încheierea
instrucţiunii for fără a se evalua expresia ce constituie relaţia de condiţionare, prin intermediul
unei aşa numite ieşiri forţate din ciclu (de exemplu corpul ciclului poate conţine un apel al
funcţiei exit).
Ciclurile while şi for sunt echivalente, cu excepţia situaţiilor în care corpul ciclurilor
conţine instrucţiunea continue.
Programarea în limbajul C - Îndrumar de laborator ______________________________________________________________________________________________________________________________________________________
39
Astfel instrucţiunea for poate fi scrisă folosind secvenţa :
for (expresie_1;expresie_2;expresie_3) expresie_1 ;
instrucţiune while (expresie_2)
{
instrucţiune
expresie_3 ;
}
şi reciproc, orice instrucţiune while poate fi scrisă folosind instrucţiunea for :
while (expresie) for (; expresie ; )
instrucţiune instrucţiune
respectiv :
while (1) for (; ;)
instrucţiune instrucţiune
Evident în acest ultim caz, instrucţiune trebuie să prevadă o modalitate de ieşire forţată
din ciclu.
În general se recomandă utilizarea instrucţiunii for în ciclurile în care sunt prezente şi
părţile de iniţializare şi reiniţializare ale ciclului, numite cicluri cu contor.
Programarea în limbajul C - Îndrumar de laborator ______________________________________________________________________________________________________________________________________________________
40
TEMA 6
Problema 1. Să se calculeze, pentru o valoare n preluata de la consola, suma şi produsul primelor n
numere naturale folosind instrucţiunea FOR.
Se va urmări pas cu pas evoluţia variabilelor de interes (folosind fereastră Watch şi comanda de
execuţie pas cu pas a unui program).
Problema 2. Pentru un a real şi un p întreg preluate de la consola să se calculeze a la puterea p prin
înmulţiri repetate.
Urmăriţi pas cu pas evoluţia contorului şi a variabilelor de interes.
Pentru a=10 se vor pune în evidenta limitele domeniilor float, double şi long double.
Problema 3. Se preia de la consola numărul termenilor ce urmează a fi prelucraţi. Se cere să se
scrie un program care să calculeze suma termenilor şi media aritmetica a termenilor pozitivi
(termenii NU se păstrează în memorie, ci doar se prelucrează).
Problema 4. Să se scrie un program C care să afişeze toate cele 256 caractere ale codului ASCII
extins: pe câte o linie nr. de ordine în tabelul ASCII şi caracterul aferent. Afişarea trebuie să se
oprească astfel încât să permită citirea tabelului ecran cu ecran, invitând operatorul să acţioneze
o tasta pentru a continua. Se va tine cont ca pe ecran se pot afişa 25 de linii.
Problema 5. Să se calculeze suma primelor k numere impare, unde k este un întreg pozitiv ce se
preia de la consola.
Problema 6. Pentru toate perechile distincte de numere întregi, inferioare unui n preluat de la
consola, să se afişeze cmmdc al acestora.
Problema 7. Să se scrie un program care să determine dacă un întreg pozitiv preluat de la consola
este prim sau nu.