Laborator PCLP1 Ciclul II

40
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

description

sdf

Transcript of Laborator PCLP1 Ciclul II

Page 1: Laborator PCLP1 Ciclul II

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

Page 2: Laborator PCLP1 Ciclul II

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

Page 3: Laborator PCLP1 Ciclul II

Programarea în limbajul C - Îndrumar de laborator ______________________________________________________________________________________________________________________________________________________

3

CODUL ASCII EXTINS

Page 4: Laborator PCLP1 Ciclul II

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;

Page 5: Laborator PCLP1 Ciclul II

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

Page 6: Laborator PCLP1 Ciclul II

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.

Page 7: Laborator PCLP1 Ciclul II

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;

}

Page 8: Laborator PCLP1 Ciclul II

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.

Page 9: Laborator PCLP1 Ciclul II

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

Page 10: Laborator PCLP1 Ciclul II

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);

Page 11: Laborator PCLP1 Ciclul II

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.

Page 12: Laborator PCLP1 Ciclul II

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;

Page 13: Laborator PCLP1 Ciclul II

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.

Page 14: Laborator PCLP1 Ciclul II

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)

Page 15: Laborator PCLP1 Ciclul II

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;

}

Page 16: Laborator PCLP1 Ciclul II

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);

Page 17: Laborator PCLP1 Ciclul II

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.

Page 18: Laborator PCLP1 Ciclul II

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.

Page 19: Laborator PCLP1 Ciclul II

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).

Page 20: Laborator PCLP1 Ciclul II

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

Page 21: Laborator PCLP1 Ciclul II

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

Page 22: Laborator PCLP1 Ciclul II

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.

Page 23: Laborator PCLP1 Ciclul II

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.

Page 24: Laborator PCLP1 Ciclul II

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.

Page 25: Laborator PCLP1 Ciclul II

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.

Page 26: Laborator PCLP1 Ciclul II

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);

Page 27: Laborator PCLP1 Ciclul II

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

Page 28: Laborator PCLP1 Ciclul II

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 .

Page 29: Laborator PCLP1 Ciclul II

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)

Page 30: Laborator PCLP1 Ciclul II

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

Page 31: Laborator PCLP1 Ciclul II

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

}

Page 32: Laborator PCLP1 Ciclul II

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);

Page 33: Laborator PCLP1 Ciclul II

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).

Page 34: Laborator PCLP1 Ciclul II

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;

Page 35: Laborator PCLP1 Ciclul II

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

Page 36: Laborator PCLP1 Ciclul II

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);

Page 37: Laborator PCLP1 Ciclul II

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).

Page 38: Laborator PCLP1 Ciclul II

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.

Page 39: Laborator PCLP1 Ciclul II

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.

Page 40: Laborator PCLP1 Ciclul II

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.