Limbajul_C_in_2h
-
Upload
mihaela-irofte -
Category
Documents
-
view
216 -
download
0
Transcript of Limbajul_C_in_2h
-
8/7/2019 Limbajul_C_in_2h
1/11
Limbajul C n dou ore
Vom face aici o prezentare general a limbajului C (cu cteva elemente de C++) plecnd
de la rezolvarea urmtoareiprobleme de programare:
Scriei un program care afieaz pe monitor mesajul Voi scrie C de n ori, dup
care apare mesajul n= i ateapt ca utilizatorul s tasteze valoarea lui n, numr ntreg.
Dac n e strict pozitiv programul scrie Ok i afieaz de n ori litera C, altfel apare
mesajul Nu pot afisa ceva de ### ori unde, pe monitor, n locul marcat cu
### trebuie s apar valoarea lui n.
Iat cum ar trebui s arate monitorul la finalul execuiei n fiecare caz n parte:
cazul n>0
i cazul n
-
8/7/2019 Limbajul_C_in_2h
2/11
Incepem editarea fiierului surs al programului, s l numim primul.cpp, cu urmtoarea
linie:
/* Primul program ilustrativ */
care conine un comentariu n stilulC. Compilarea textului surs se execut linie cu linie, de sus
n jos, fiecare linie fiind citit de la stnga la dreapta. Compilatorul ignor toate caracterele dintre
perechile /* i */ (inclusiv pe acestea), aa c avem la dispoziie un spaiu n care putem scrie ce
vrem. Un astfel de comentariu se poate ntinde pe mai multe linii. Comentariile nu fac parte din
program, ele au rolul de a da unele lmuriri celui ce citete textul surs i, n cazul programelor
complexe, sunt foarte utile pentru nelegerea diverselor secvene de cod. Exist istilulC++ de
comentariu, acestea ncep cu dou slash-uri, //, i se termin la captul liniei, ele sunt utilizate
pentru a da scurte indicaii asupra coninutului liniei de cod curente. Prezena comentariilor este
facultativ, dar recomandabil.
Urmtoarea linie este obligatorie:# include
Aceast linie conine o directiv de preprocesare i nu face nici ea parte din program. Dup ce
lansm comanda Compile compilatorul, nainte de a ncepe compilarea propriu-zis a
fiierului, lanseaz n execuie preprocesorul un program specializat n prelucrarea automat a
textelor (prin substituii) - care citete toate directivele de preprocesare i le execut. In cazul
directivei include linia directivei este nlocuit cu ntreg coninutul fiierului iostream, fiier
care conine tot ce este necesar programului pentru executarea operaiilor de citire/scriere
(sinonime: intrare/ieire, input/output). Printre altele, prin acest mecanism ajung n fiierul
nostru surs definiiile obiectelor cout i cin (ca instane ale unor clase de fluxuri de date,
stream-uri).Identificatorulcout desemneaz consola de ieire (output console), adic monitorul,iarcin desemneaz consola de intrare (input console), adic tastatura. Fr aceast directiv de
includere a bibliotecii iostream compilatorul ar da, la prima apariie a cuvntului cout, mesajul
de eroare 'cout' : undeclared identifier. Alte biblioteci des utilizate:
pentru funcii matematice (exponeniale, logaritmi, funcii trigonometrice, etc) i
pentru operaii cu iruri de caractere (string-uri).
Subliniem de la bun nceput c textul surs trebuie editat(scris) numai cu un set restrns
de caractere: literele a,b,c, ... , z, A,B,C, ... , Z, cifrele 0,1, ..., 9, i simbolurile direct imprimabile
de la tastatur:
obinem la compilare eroarea: invalid preprocessor command 'INCLUDE'.
De remacat i faptul c, pentru o scriere mai lizibil, se pot insera oricte blancuri (cu
tastele space sau tab) ntre atomii lexicali (tokens) ai directivei. E corect i aa
2
-
8/7/2019 Limbajul_C_in_2h
3/11
# include < iostream >
dar s nu exagerm. Aceast facilitate trebuie folosit pentru aezarea n pagin, ntr-un mod ct
mai clar, a textului surs. In faza de preprocesare compilatorul terge toate spaiile care nu sunt
neaparat necesare pentru pstrarea sensului directivelor i al instruciunilor.
Directivele de preprocesare nu fac parte din limbajul C (nici din C++), ele sunt specifice
fiecrui compilator n parte. Ca regul general, ele ncep cu simbolul # i se termin n
aer, fr un simbol terminator (cum este ; pentru instruciunile C). Ca exemplificare, dintre
directivele de preprocesare ale mediului de dezvoltare MS Visual C++ 9.0 mai menionm pe
#define i #using (vezi http://msdn.microsoft.com/en-us/library/3sxhs2ty.aspx).
Urmeaz acum nc o linie de cod care va fi prezent n toate programele noastre:
using namespace std;
i care deseori este numit directiva using dei ea este o instruciune C++. Denumirea poate
crea confunzii, mai ales c exit chiar o directiv de preprocesare #using, dar este folosit
pentru a sugera asemnarea dintre efectul acestei instruciuni i o substituie de texte efectuat lapreprocesare: ca i cum, de exemplu, identificatorul cout ar fi nlocuit cu std::cout peste tot
unde apare n textul surs.
Ca urmare a creterii complexitii programelor i a utilizrii unor biblioteci de funcii i
de clase tot mai bogate, pentru a evita coliziunile tot mai frecvente dintre nume (utilizarea
aceluiai identificator pentru obiecte diferite) n C++ a fost introdus mecanismul spaiilor de
nume: programatorul poate prefixa identificatorii utilizai, cu sintaxa
prefix::identificator
prefixul desemnnd un anumit spaiu de nume, namespace. Instruciunea noastr using declar
c vom utiliza spaiul de nume std (standard) i este necesar pentru a simplifica referirea
fluxurilor standard cin i cout. Fr aceasta ar trebui s scriem std::cin n loc de cin, deexemplu.
Instruciunea using namespace std;este compus din patru atomi lexicali: cuvintele
cheie using i namespace (aparinnd limbajului C++), identificatorul std (care denumete
spaiul de nume standard cel mai des folosit) i terminatorul de instruciuni ;. Identificatorul
std este definit undeva n codul inclus n programul nostru prin directiva #include,
ca dovad, dac schimbm ordinea acestor dou linii obinem la compilare eroarea: 'std' : a
namespace with this name does not exist.
Instruciunile limbajului C se termin, cele mai multe, cu simbolul ;, dac sfritul unei
instruciuni coincide cu sfritul unui bloc { } terminatorul ; nu mai este necesar (cu excepia
cazului cnd este cerut expres de sintaxa instruciunii. Simbolul ; nu este separator ci
terminator de instruciuni: el face parte integrant din instruciunea pe care o finalizeaz. De
exemplu, pe linia
a=1; b=2; c=a+b;
am scris, cu ajutorul a 14 caractere, trei instruciuni, prima instruciune este scris cu 4 caractere,
a doua tot cu 4, a treia cu 6 caractere, iar ntre instruciuni nu se afl nimic. Regula este
3
http://msdn.microsoft.com/en-us/library/3sxhs2ty.aspxhttp://msdn.microsoft.com/en-us/library/3sxhs2ty.aspx -
8/7/2019 Limbajul_C_in_2h
4/11
urmtoarea: n textul surs, o instruciune ncepe imediat dup ce se termin cea dinaintea ei.
Reamintim c blancurile sunt eliminate la preprocesare, aa c pentru a face programul ct mai
lizibil, instruciunile se scriu cte una pe linie i ct mai aerisit.
Iat acum i codul sursal programului nostru:
char litera='C';
int citeste(void){
int n;
coutn;
return n;
}
void afiseaza(int nr){
int i;
for(i=0; i
-
8/7/2019 Limbajul_C_in_2h
5/11
declarat n mod explicit de programator astfel nct compilatorul s tie, n principal, cum s
organizeze memoria alocat acelei date.
Cu instruciunea declaraie:
char litera='C';
declarm variabila litera ca fiind o dat de tip char i o iniializm cu valoarea 'C'. Cuvntul
litera este identificatorulcare d numele variabilei, i a fost ales de noi, spre deosebire de
char care este un cuvnt cheie al limbajului (un identificator rezervat) i care poate fi folosit
numai pentru a desemna tipul de dat caracter pe un octet. Identificatorii pot fi formai numai
din litere, cifre i caracterul _ (underscore), cu restricia c primul caracter nu poate fi o cifr.
Lungimea maxim a unui identificator depinde de compilator (pentru MS Visual C++ 9.0 vezi
http://msdn.microsoft.com/en-us/library/565w213d.aspx).
Variabila litera fiind declarat de tip char, la ntlnirea instruciunii de mai sus
compilatorul rezerv un octet de memorie pentru variabila litera i scrie n acest octet codul
ASCII al literei C (i anume 43 hexa).
Tipurile uzuale pentru variabile simple sunt: char pentru caractere, int pentru numerentregi i double pentru numere reale n dubl precizie (fa de float simpl precizie).
Variabila litera este global deoarece a fost declarat n exteriorul oricrei funcii.
Valorile ei pot fi utilizate direct de ctre toate funciile care sunt definite dup declararea ei,
altfel spus, numele ei este vizibildin orice punct al fiierului surs de dup linia n care a fost
declarat. Spre deosebire de ea, variabilele declarate n interiorul unei funcii sunt variabile
locale, ele pot fi referite numai n interiorul corpului funciei n care sunt declarate.
Declaraiile pot fi fcute i fr iniializarea variabilei declarate, n felul urmtor:
char litera;
dar n acest caz trebuie s avem grij ca, nainte de a o folosi, s i atribuim variabilei litera o
valoare iniial, printr-o instruciune expresie, de exemplu,litera='C';
Atenie, spre deosebire de instruciunile declaraii, care pot apare oriunde n textul surs,
instruciunile expresie pot s apar numai n interiorul corpului unei funcii.
S analizm acum definiia funciei citeste
int citeste(void){
int n;
coutn;
return n;
}
O funcie este format dintr-osecven de instruciuni care prelucreaz datele de intrare
n funcie (valorile actuale ale argumentelor funciei), mpreun cu alte date proprii, i care
returneaz ctre funcia apelant, o dat de ieire, rezultatulfunciei. Exist i funcii fr date de
intrare, precum i funcii care nu returneaz nimic.
5
http://msdn.microsoft.com/en-us/library/565w213d.aspxhttp://msdn.microsoft.com/en-us/library/565w213d.aspx -
8/7/2019 Limbajul_C_in_2h
6/11
Din prima linie a definiiei funciei citeste deducem c aceasta nu are date de intrare
(acolo unde ar trebui s fie lista parametrilor este scris cuvntul cheie void - vacant) iar
rezultatul ei este de tip int (adic va returna un numr ntreg).
In general, definiia unei funcii are forma:
tip_returnat nume_funcie (lista_parametrilor_funciei) {
corpul_funciei
}
Dac este nevoie, putem numai s declarm funcia (fr s o i definim), scriind numai
prototipul funciei (adic antetul funciei urmat de terminatorul de instruciune ;) astfel
tip_returnat nume_funcie (lista_parametrilor_funciei);
dar tot va trebui s definim, undeva mai jos, nainte de sfritul fiierului surs, funcia.
Corpul funciei se scrie ntotdeauna ntre dou acolade pereche, {}, i este format dintr-o
secven de instruciuni. Nu este permis imbricarea funciilor, adic definirea unei funcii n
interiorul corpului alteia.
In corpul funciei citeste declarm variabila n, scriem pe monitor mesajul "n=", citim dela tastatur valoarea variabilei n i returnm, ca rezultat al funciei, valoarea citit.
Pentru afiarea valorii unei variabile oarecare, x de exemplu, utilizm operatorul de
scriere ,
-
8/7/2019 Limbajul_C_in_2h
7/11
cnd vrem s citim mai multe valori, este mai sigur s scriem pentru fiecare citire cte o
instruciune n parte sau chiar cte o pereche de instruciuni (prima pentru afiarea unui mesaj
explicativ i a doua pentru citirea propriu-zis), aa cum am ntlnit deja
coutn;
Execuia unei funcii se ncheie cnd fluxul de control ajunge la execuia unei instructiuni
return, sau, dac funcia nu trebue s ntoarc nici un rezultat, la atingerea acoladei care incheie
corpul funciei. Funcia citeste se ncheie cu instruciunea
return n;
care depune n registrul EAX al microprocesorului valoarea variabilei n, de unde estepreluat de
funcia apelant. In exemplul nostru, citeste este apelat o singur dat, n funcia main, de
instruciunea
k=citeste();
care atribuie variabilei kvaloarea citit de funcie de la tastatur. Observai c la apelarea unei
funcii fr argumente nu se folosete cuvntul cheie void.Funcia afiseaza
void afiseaza(int nr){
int i;
for(i=0; i
-
8/7/2019 Limbajul_C_in_2h
8/11
Dac trebuie s executm mai multe aciuni n corpul for-ului, vom folosi o instruciune
compus, grupnd n interiorul unei perechi de acolade, {}, mai multe instruciuni simple (aa
cum avem de exemplu ramura else a instruciunii ifdin funcia main).
S analizm acum funcia principal:
int main(void){
int k;
cout
-
8/7/2019 Limbajul_C_in_2h
9/11
if (expresie_test)instructiune_corp
i care, dac testul este ndeplinit, insereaz n fluxul de control al execuiei instruciunea corp,
altfel nu face nimic.
In mod obinuit, expresiile test sunt comparaii de forma ab. De reinut c expresia a==b testeaz dac a este egal cu b, n timp ce expresia a=b
atribuie lui a valoarea lui b (operatorul == este operatorul de comparaie, iar operatorul =
este operatorul de atribuire). Deoarece n limbajul natural semnul egal este folosit n ambele
sensuri (i comparaie i atribuire), n limbajul C se produc adesea erori prin utilizarea unui
singur semn de egalitate acolo unde ar trebui dou semne. O astfel de eroare este greu de
depistat, ea nu iese la compilare (compilatorul accept i atribuirea a=b ca expresie test n if
sau for - vom vedea mai trziu de ce), iar la rulare programul d rezultate haotice. Pentru
evitarea acestei situaii unele compilatoare de C, cnd ntlnesc atribuiri n expresii condiionale,
avertizeaz utilizatorul asupra posibilei confuzii. Mai mult, unele limbaje de programare
provenite din C, cum ar fi Java sau C#, au introdus tipuri logice de date astfel nct s fac
imposibil aceast eroare de editare. MS Visual C++ 9.0 nu d nici un avertisment, aa c trebuies fim ateni la comparaii.
S urmrim acum evoluia mijloacelor de calcul prin prisma creterii complexitii:
primile maini mecanice de calcul efectuau doar calcule cu cte o singur operaie (cum fac
acum cele mai simple calculatoarele de buzunar). Au aprut apoi calculatoare electronice
capabile s efectueze mai multe operaii la o singur comand, s evalueze o ntreag expresie
aritmetic (exist i astzi calculatoare de buzunar care pot evalua formule). Urmtoarea etap:
calculatoare capabile s evalueze mai multe expresii la o singur comand, prin rularea unui
program format dintr-o secven de instruciuni executate ntr-o ordine dictat de rezultatele
expresiilor evaluate. Iniial calculatoarele programabile dispuneau de puin memorie intern, deordinul kiloocteilor, aa c programele trebuiau s fie scurte, cu cteva instruciuni; pentru
prelucrri complexe ele au fost organizate ca sub-programe (funcii, proceduri, subrutine, etc.) i
ncrcate n memorie doar atunci cnd erau apelate. Dup cum am vzut deja, un program C este
o colecie de astfel de sub-programe.
Evoluia a continuat: pentru utilizarea mai multor programe C n acelai timp, acestora
li s-au scos funciile principale i au fost transformate n clase, variabilele globale devenind
variabile membru iar funciile rmase devenind funcii membru ale claselor. Incrcarea lor n
memorie a fost transformat n instanierea claselor, iar lansrile n execuie au fost nlocuite cu
apeluri ctre funciile membru, apeluri fcute prin intermediul instanelor (obiectelor) clasei. Pe
scurt, n C++ a fost introdus tipul class, programatorul avnd posibilitatea s-i defineasc
propriile clase sau s foloseasc unele deja existente, prin definirea unei clase se definete un nou
tip de dat, de complexitatea unui vechi program C, pentru utilizarea unei clase trebuie s
declarm i s iniializm o variabil de tipul dat de acea clas, adic s instaniem un obiectal
clasei.
De exemplu, n fiierul iostream din directorul \include al compilatorului MS Visual C+
+ 9.0 gsim urmtoarea declaraie:
9
-
8/7/2019 Limbajul_C_in_2h
10/11
extern ostream &cout;
Aceast instruciune declar cout ca fiind o referin (iniializat ntr-un fiier extern) ctre un
obiect din clasa ostream, care este o clas specializat n operaii de ieire (output stream). Tot
n fiierul iostream gsim directiva #include, iar n fiierul istream gsim
#include. Noi am inclus n fisierul nostru surs fiierul iostream i astfel, prin
includeri succesive, definiia clasei ostream i declaraia lui cout ajung n fiierul surs al
programului nostru, transformndu-l ntr-un program C++, dei n liniile de cod scrise de noi este
definit nici o clas.
In final, deoarece programele noastre C sunt de fapt programe C++, trebuie s precizm
urmtoarele: limbajul C++ este o extensie a limbajului C realizat prin adugarea tipului de dat
class, un program C++ este format din declaraii de variabile globale i din definiii de clase i
de funcii care manipuleaz obiecte din aceste clase, dintre funcii una se numete main i cu ea
ncepe execuia programului. Aceast extindere a limbajului a fost iniiat n 1979 de ctre
Bjarne Stroustrup, cercettor la AT&T Bell Laboratories (tot acolo unde a fost creat i limbajul
C), care iniial a numit noul limbaj "C with Classes" i apoi, n 1983, i-a dat denumireadefinitiv de C++. Manualul fundamental a fost scris de Bjarne Stroustrup n 1985, The C++
Programming Language. Pentru mai multe amnunte, vezi pagina personal a autorului,
http://www.research.att.com/~bs/.
Pentru a ilustra cele spuse mai sus despre noiunea de clas, prezentm n final varianta
C++ a programului nostru, obinut prin schimbri minimale, n care programul nostru C devine
o clas C++:
#include
usingnamespace std;
class scriitor{
public: char litera;
int citeste(void){
int n;
coutn;
return n;
}
void afiseaza(int nr){
int i;
for(i=0; i
-
8/7/2019 Limbajul_C_in_2h
11/11
cout