C-ul este un limbaj orientat pentru aplicatii de uz general . Datorita caracteristicilor sale este un limbaj foarte utilizat de toate categoriile de programatori.
Dintre caracteristicile sale amintim :
este un limbaj structurat;
permite o exprimare compacta si concisa a programelor;
este simplu de utilizat
Pe scurt, C-ul este un limbaj restrāns , puternic si flexibil care poate fi folosit pentru mai multe tipuri de aplicatii :
n programe de sistem :
n sisteme de operare ;
n driver-e de dispozitive ;
n interfete utilizator ;
n programe de aplicatie
n editoare de texte ;
n gestiuni baze de date ;
n programe utilizator ;
C-ul executa secvential instructiunile, dar poseda instructiuni de decizie care pot altera secventa .
De asemenea , are instructiuni de ciclare , posibilitatea de a defini functii recursive si multe altele.
Referitor la declaratiile de date , la fel ca si Pascal-ul , C-ul admite tipuri de date de baza si tipuri de date derivate .
Tipurile de date de baza ale C-ului sunt intreg , real si caracter.Aceste tipuri de date de baza sunt in stransa legatura cu masina pe care a fost implementat limbajul .
Fiecare tip de data de baza are o lungime in octeti care depinde de tipul de masina . Exista si tipuri de date mai complexe cum ar fi :
n structurile ;
n uniunile ;
n masivele ;
Un tip de date care nu a fost amintit pana acum este tipul pointer . Pointerii dau C-ului flexibilitate.
Exista :
n pointeri la date ;
n pointeri la functii ;
n pointeri la pointeri .
Pe baza tipurilor de date enumerate anterior se pot crea tipuri de date noi foarte complexe.
C-ul permite constructii fundamentale care se folosesc in toate limbajele de programare structurate.
Acestea sunt:
declaratii grupate
si instructiuni (blocul)
decizie si selectie
if ... else
switch
ciclare
for
while
do
salt neconditionat
break
continue
goto
Setul bogat de operatori pe care-i contine C-ul contribuie la reputatia lui de a fi un limbaj concis . El contine aproximativ 40 de operatori.
Referitor la operatiunile de intrare-iesire trebuie sa amintim ca acestea sunt efectuate de functii care nu fac parte din limbaj.
Toate functiile sunt catalogate intr-o biblioteca standard care va sta la dispozitie.
Biblioteca standard contine functii pentru manipulare fisiere , intrari/iesiri pentru consola , functii pentru rezervare zone memorie , eliberare zone de memorie , transfer intre anumite zone de memorie, functii pentru siruri de caractere, functii matematice , functii grafice.
In general functiile sunt catalogate intr-o biblioteca care trebuie legata cu programul utilizatorului.
Avantajul folosirii unei biblioteci standard este ca programele C pot fi portabile.
Codul sursa depinde foarte putin de masina , dar biblioteca standard depinde de masina .
Daca dorim sa executam programul pe alta masina singurele operatiuni care se executa sunt compilarea si link-editarea , sursa ramānānd neschimbata
1.2. Etapele realizarii unui program
Secventele operatiunilor care se executa pentru realizarea programului sunt:
- crearea fisierului sursa cu editorul ;
- compilarea fisierului, obtinindu-se programul obiect;
- link-editarea programului, obtinindu-se programul executabil;
- lansarea programului in executie pentru testare si depanare.
1.3.Structura unui program
Vom incepe cu un exemplu.
Exempulul 1.3.1.
exemplu de program C */
main ()
Acest program dupa executie va scrie pe terminal :
Orice program C este compus din una sau mai multe functii care realizeaza operatiile de calcul sau de intrare /iesire.
In programul nostru intalnim doua functii:
main()
puts()
main este o functie cu un rol deosebit de al celorlalte functii.
Orice program C are o singura functie main cu semnificatia de program principal. Parantezele sunt necesare pentru a arata ca main este o functie.
Tot ce este intre acolada ( ) constituie programul principal.
Sa analizam functia puts.
Observam ca dupa numele functiei urmeaza o paranteza deschisa dupa care un text in ghilimele si apoi o paranteza inchisa. Parantezele care urmeaza dupa numele functiei inchid lista de argumente a functiei.
Deci apelul de functie puts("La Multi Ani") ; va avea ca rezultat scrierea pe ecran a textului dintre ghilimele.
In acest program apar comentariile .Comentariile incep cu /* si se termina cu */ .Ele se folosesc pentru a descrie un program . Compilatorul le ignora dar comentariile sunt utile pentru intelegerea programului .
In concluzie structura unui program C este:
main()
1.4.Functii de intare/iesire
Dintre functiile de intrare/iesire cel mai des utilizate sunt printf si scanf.
printf este o functie de scriere pe terminal.
Putem scrie programul din exemplul 1.3.1. folosind functia printf in locul lui puts.
Programul va arata astfel:
Exemplul 1.4.1.
main ()
Efectul este acelasi cu exceptia faptului ca se face saltul la randul urmator. Acest salt este dat de caracterul \n - caracterul NEW LINE.
Acelasi text poate fi scris folosind 3 instructiuni printf:
Exemplul 1.4.2.
main()
Pana acum am folosit functia printf pentru scrierea textelor. Putem folosi aceeasi functie pentru a scrie valori numerice. Sa presupunem ca vrem sa tiparim un numar intreg de 4 cifre.
Exemplul 1.4.3.
Fie urmatorul program:
main()
Acum functia printf va scrie la terminal valoarea variabilei x . Pe ecran va apare
%6 - semnifica faptul ca x este tiparit cu 6 cifre;
d - spune ca x este un numar intreg;
x - este variabila a carei valoare va fi scrisa.
In momentul compilarii ne asteptam ca instructiunea x=5555 sa genereze rezervarea unei zone de memorie pentru variabila x si sa scrie in memorie numarul 5555.
Lucrurile nu se petrec asa . Pentru a sti cat spatiu se rezerva unei variabile trebuie sa-i declaram tipul.
Daca x este un intreg atunci vom scrie : int x ;
Daca x va lua valori reale ( numere cu parte zecimala ) se va scrie : float x;
Daca x este o variabila caracter (x va contine un cod ASCII al unui caracter de exemplu 65 este codul lui A) atunci x se va declara: char x;
Exemplul 1.4.4.
Programul corect este:
main()
Daca x este un numar real ( cu parte zecimala ) pentru scriere se va folosi formatul %6.2f unde :
6 - reprezinta numarul de cifre
2 - numarul de zecimale
Exemplul 1.4.5.
Programul va fi :
main()
Daca x este o variabila caracter formatul folosit pentru tiparire va fi %c.
Exemplul 1.4.6.
main()
Pe ecran va apare
x are valoarea x.
Cand scriem la terminal folosind functia printf textul dintre ghilimele apare identic la terminal cu exceptia caracterelor de format (%d,%f,s.a.m.d.). In locul formatelor vor apare valorile variabilelor din lista de argumente.
Fie functia:
printf("x [%d] = %3.1f", i,alfa);
Corespondenta intre format si lista de variabile este biunivoca.Fiecarei variabile ii corespunde un format.
Pentru functia de mai sus daca i este 10 si alfa este 6.1 , atunci la terminal va apare :
x [10] = 6.1
In concluzie scrierea variabilei se va face la pozitia pe care o are formatul de scriere.
Sa studiem acum functia scanf . Functia scanf citeste date de la tastatura si le scrie in memorie.
Fie urmatorul program:
Exemplul 1.4.6.
main()
%c - este formatul de citire
&x - reprezinta adresa variabilei x deci locul unde va fi depus caracterul introdus de la tastatura.
Pentru scanf sunt valabile aceleasi formate ca pentru printf.
Exemplul 1.4.7.
main()
Programul de mai sus va citi date de la terminal , de exemplu 10 , 1.1,1 si le va afisa : x=10 y=1.1 z=1
1.5 Instructiuni de ciclare
Asa cum am amintit in paragraful 1 limbajul C are ca instructiuni de ciclare, instructiunile for , while , do ... while.
Vom studia doua din ele.
Dam un exemplu de program in care vom folosi instructiunea for:
Exemplul 1.5.1.
/* program pentru calcularea sumei primelor 100 numere naturale */
main()
Instructiunea for este o instructiune de ciclare compusa din 3 parti.
n prima parte este partea de initializare (i=1) si se executa o singura data.
n a doua parte este testul care controleaza bucla (i<=n)
n a treia parte reprezinta partea de reinitializare (i=i+1)
Succesiunea operatiiilor poate fi urmarita mai jos.
i=1
s=s+i
i=i+1
DA
i <= n
NU
In continuare modificam programul din exemplul 1.5.1. si folosim instructiunea while (cat timp).
Exemplul 1.5.2.
main()
printf("suma primelor 100 numere este %d",s);
}
Executia unei instructiuni whilw are urmatoarele etape:
a) - se testeaza expresia dintre paranteze;
b) - daca conditia este indeplinita i<=n se executa corpul ciclului ( instructiunile dintre acolade)
c) - daca conditia nu este indeplinita se sare la sfarsitul ciclului dupa acolada
Succesiunea operatiilor se poate urmari mai jos:
DA
i <= n
NU
s=s+i
i=i+1
printf (...)
Constante simbolice
Un program trebuie sa rezolve o clasa de probleme asemanatoare , de aceea este recomandabil sa sde foloseasca variabile si constante simbolice.
Constantele simbolice sunt nume carora li se asociaza o valoare.Ele se declara cu # define.
Pentru a exemplifica folosirea constantelor simbolice modificam programul 1.5.2. introducand o declaratie de constanta simbolica.
Exemplul 1.6.1.
# define n 100
main()
printf("suma primelor 100 numere este %d",s);
Un program care foloseste constantele simbolice este mai clar, mai usor de inteles . Pentru cel care urmareste un program numarul 50 de exemplu nu are o semnificatie deosebita dar daca avem o definitie de constanta #define nrpers 50 atunci 50 va reprezenta numarul de persoane.
In general numele constantelor trebuie sa reflecte si rolul acelei constante in program .
Dupa definirea constantei in program se va folosi doar numele ei , intelegandu-se prin aceasta ca lucram cu valoarea ei.
Alt avantaj ar fi la modificarea programului .Modificand valoarea constantei orice aparitie a constantei in program va avea noua valoare.
Masive
In limbajul C declaratia masivelor se face in modul urmator :
tip nume [dim1] [dim2] ... [dimn]
unde tip - reprezinta tipul componentelor matricii
nume - reprezinta numele masivului
dim - dimensiunile masivului
Un masiv de numere intregi unidimensional de 10 componente se declara astfel: int mat [10]; ,sau alta declaratie : char s [20] - masiv unidimensional de 20 de componente de tip caracter.
Un masiv bidimensional se deaclara in felul urmator:
int mat [10] [10]
In continuare vom prezenta un program de adunare a unor siruri de numere . Datele vor fi introduse prin instructiuni de atribuire.
Exemplul 1.7.1.
/* program de adunare 1 */
main()
In C prima componenta a unei matrici este cea de indice 0 . Indicele
are o valoare >=0 si intreaga .Sa presupunem acum ca adunarea se face pentru numere pozitive.
Pentru aceasta avem nevoie de o instructiune care sa testeze daca numarul este pozitiv sau nu.
Exemplul 1.7.2.
/* program adunare 2 */
main()
Dupa cum vedeti am folosit o instructiune de decizie si anume instructiunea if.
Forma ei este :
if (conditie)
instructiune_1
else
instructiune_2
Instructiunea if se executa astfel:
n se evalueaza conditia. Daca conditia este adevarata atunci se executa instructiunea_1 ;
n daca conditia este falsa se executa instructiunea_2;
Instructiunea_1 si instructiunea_2 se pot inlocui cu un grup de instructiuni incadrate de acolade.
Functii
Functia in limbajul C este echivalentul unei functii sau subrutine din alte limbaje , de exemplu FORTRAN.
Ea este o secventa de instructiuni care poate fi folosita in mod repetat.
Folosind functiile , programele se pot simplifica foarte mult.Astfel , daca vom folosi functii bine proiectate putem realiza programe oricat de complexe intr-un timp relativ scurt.
Se da un exemplu de functie :
n fie o functie fact(n) care calculeaza factorialul unui numar;
n fact(n) va avea un singur parametru de intrare n.
In continuare vom prezenta programul care testeaza functia si apoi functia fact(n).
Exemplu 1.8.1.
main() /* test pentru fact */
int fact (n) /*calculul factorialului*/
int n;
Structura unei functii este urmatoarea:
tip nume (lista argumente )
declaratie argumente
Pentru functia factorial definita inainte , ca lista de argumente avem variabila n. Ea se va declara dupa numele functiei.
Dupa acolada urmeaza declaratii si instructiuni.De asemenea observam o instructiune return in corpul functiei.
Aceasta instructiune are ca rol intoarcearea in programul principal a valorii calculate de functie.
Deci apelul fact(n) va avea ca rezultat valoarea argumentului instructiunii return.
Tipul functiei trebuie sa coincida cu tipul argumentului instructiunii return.
Variabile globale
Variabilele din main sau din functii sunt locale functiilor respective.Nu poate avea acces la variabila respectiva decat functia in care a fost declarata.
De exemplu , variabila n din functia fact nu are nici o legatura cu variabila n din functia main.
Aceste variabile locale functiei se numesc variabile automate.Aceste variabile automate nu-si pastreaza valorile de la un apel la altul .De aceea la un nou apel este necesara reinitializarea acestor variable.
Pentru a pastra valorile variabilei de la un apel la altul s-au prevazut variabilele globale care pot fi modificate de orice functie din program.
Ele se declara in afara oricarei functii inclusiv main.
Aceste variabile globale isi pastreaza valoarea chiar daca functiile care le-au stabilit isi termina executia.
EXERCITII REZOLVATE
1.Program care afiseaza tabela Fahrenheit-Celsius pentru
F=0,20,....,300
main()
Semnificatia unor simboluri folosite:
= atribuire;
<= mai mic sau egal.
2. Modificarea programului 1 folosind constante simbolice :
#define lower 0 /* limita de jos a tabelei de temperatura */
#define upper 300 /* limita superioara */
#define step 20 /* marimea pasului */
main() /* tabela fahrenheit-celsius*/
Biblioteca standard C pune la dispozitie functii pentru citit si scris cate un caracter.
getchar() - citeste urmatorul caracter de intrare la fiecare apel si intoarce acest caracter ca valoare a sa.
Dupa apelul a=getchar() variabila a va contine urmatorul caracter de intrare. Caracterele provin de la terminal sau de la un dispozitiv oarecare de intrare.
Functia putchar(c) este opusul lui getchar().Ea va tipari continutul variabilei c la un dispozitiv de iesire.
Cu ajutorul acestor functii se pot scrie multe programe utile. De exemplu un program care copiaza la iesire pana la aparitia caracterului #.
pseudocod
start
citeste (var) un caracter scris intre
cat timp var<> # apostroafe are semnificatia
scrie (var) de cod ASCII al caracterului
citeste (var) respectiv.
stop
In limbajul C se va obtine:
main() /* copiaza intarea la iesire*/
Programul poate fi simplificat astfel:
main() /* copiaza intrarea la iesire*/
Programul va citi un caracter , il atribuie lui c apoi testeaza daca caracterul este '#'.Daca da se termina ciclul si programul , daca nu se continua bucla while (se va citi un nou caracter).
Program care numara caracterele de la intrare pana apare caracterul '#'.
nc - variabila care contine numarul de caractere.
Var - variabila caracter.
start
citeste (var)
nc=0
cat timp (var<> '#')
nc=nc+1
citeste (var)
stop
Programul in C:
main() /* numara caractere de la intrare*/
Sprcificatia de format ld semnaleaza lui printf ca intregul de tiparit este pe 4 octeti.
long - are semnificatia de intreg dublu.
Se poate declara nc, numar real precizie dubla pentru a putea manipula un numar mai mare de caractere.
Int nc - ne limiteaza la 32768
long nc - un intreg long are valoarea maxima 2147483647
Ca double vom putea reprezenta numere pe 8 octeti in virgula mobila.
main() /* numara caracterele de la intrare */
%f - se foloseste pentru float si pentru double
%.0f - inseamna ca nu se mai tipareste partea fractionara
Corpul buclei for este vid. Totul se executa in partea de test si reinitializare.
Mai observam ca daca primul caracter este # partea de test esueaza si rezultatul este 0.
Program care numara liniile de la intrare .
pseudocod
start
citeste (var )
nl=0
cat timp (var<>'#')
daca (c=Newline)
n1=n1+1
stop
Programul in limbajul C :
main() /* numara liniile de la intrare */
Programul citeste caractere.Daca caracterul este newline atunci se incrementeaza variabila nl (numarul de linii) astfel se citesc caractere. Programul se termina la aparitia caracterului '#'.
7.Program care numara cuvinte , linii , caractere .
cuvant - orice secventa de caractere care nu contine blank , tab , newline.
Tab - caracterul '\t' care este echivalentul a 6 spatii. Deci la apasarea tastei tab cursorul se misca 6 pozitii la dreapta.
Pseudocod
start
cuvant = nu;
nl=ncuvant=ncaracter=0
citeste (var)
cat timp (var <> '#")
nrcaracter=nrcaracter +1
daca (c=newline)
nl=nl+1
daca (c=' ' sau c=newline sau c=tab)
atunci
cuvant=nu;
altfel
daca cuvant=nu
cuvant=da
ncuvant=ncuvant+1
Cateva cuvinte despre program :
cuvant - variabila care ne spune daca ne aflam inter-un cuvant sau nu
nl - variabila care numara liniile
ncuvant - variabila care numara cuvintele
ncaracter - variabila care numara caracterele
Daca variabila var este diferita de caracterul # atunci numarul de caractere creste cu o unitate.
Daca var este newline atunci se incrementeaza numarul de linii.
Daca var este spatiu sau tab sau newline atunci ne aflam la inceputul unui cuvant sau in afara lui.
Daca var este spatiu sau tab sau newline atunci ne aflam la inceputul unui cuvant sau in afara lui.
Daca var este diferit de spatiu , tab sau newline si inainte nu a fost cuvant , atunci variabila cuvant va lua valoarea da (incepe un cuvant) si numarul de cuvinte se incrementeaza.
Programul in limbajul C:
#define da 1
#define nu 0
main() /* numara linii , cuvinte , caractere din intrare */
}
printf ("%d %d %d \n" , nl , ncuvant , ncaracter);
}
In programul de mai sus se observa ca am introdus noi simboluri:
= = - operator de egalitate
!= - operator de diferit
|| - operatorul sau
' ' - caracterul blank
'\n' - caracterul newline
'\t' - caracterul tab
Deci linia - if (c== ' ' || c=='\n' || c=='\t') se citeste astfel:
n daca c este blank sau c este newline sau c este tab.
8.Program care numara aparitiile fiecarei cifre, ale caracterelor spatiu (blank , tab , newline) si ale tuturor celorlalte caractere.
nspatiu - vector care contine numarul de caractere blank, tab, newline;
ncifra [10] - vector care contine numarul de aparitii ale fiecarei cifre;
ncifra [1] - numar de aparitii ale cifrei 1;
ncifra [9] - numar de aparitii ale cifrei 9;
nalte - numar de aparitii ale altor caractere;
pseudocod
start
nalte=0
nspatiu=0
pentru ( i=0 ; i < 10 ; i=i+1)
ncifra i=0
citeste (var)
cat timp (var <> '#')
daca (var >= '0' si var <= '9')
ncifra[var-'0']=ncifra[var-'0'] +1
altfel daca (var = ' ' sau var = '\n' sau var = '\t')
nspatiu=nspatiu+1
altfel
nalte=nalte+1
scrie ("cifre")
pentru (i=0 ; i 10 ; i=i+1)
scrie(ncifra i )
scrie("spatii")
scrie(nspatii)
scrie("caractere")
scrie("nalte")
stop
Prima parte a pseudocodului contine initializarea variabilelor ncifra , nalte , nspatii.
Daca variabila este cifra adica are codul ASCII cuprins intre codul ASCII al lui 0 si codul ASCII a lui 9 atunci se incrementeaza componenta respectiva a lui ncifra.
Mentionam ca cifrele au urmatoarele coduri ASCII:
cifra 0 30 hexazecimal
1 31
2 32
.. ..
9 39
Deci comparatia var >= 0 si var <= 9 se reduce la a compara codul ASCII a lui var cu coduri ale cifrelor 0 si 9 . Adica se compara codul lui var cu codurile 30 si 39. Daca este intre ele atunci var este cifra.
Ce inseamna ncifra - 0 = ncifra - var - 0 +1 ?
Presupunem ca var este cifra 2 deci are codul 32 , atunci 2 - 0 este o diferenta intre codurile 32 si 30 si da rezultatul 2 , rezultand : ncifra[2]=ncifra[2]+1 adica se incrementeaza numarul de aparitii ale
cifrei 2 .
Programul scris in limbajul C:
main() /* numara cifre , spatii , alte caractere */
9.Sa se scrie o functie power care realizeaza ridicarea la putere intreaga a unui numar.
main() /* program de test pentru power */
power (int x, int n)
/* int x,n;*/
Scrieti un program care sa-si converteasca intrarea la litere mici , folosind o functie lower(c) care intoarce pe c daca c nu e litera si valoarea literei mici daca c e litera.
Scrieti un program care sa tipareasca o histograma a lungimii cuvintelor de la intrarea sa . Histograma se va trasa orizontal.
Scrieti un program care afiseaza cuvintele de la intarare cate unul pe o linie.
Scrieti programul de tab care sa inlocuiasca tab-urile din intrare cu numarul potrivit de blank-uri pentru a se ajunge la urmatoarea coloana de tabulare.Se presupune un set fixat de coloane de tabulare de exemplu n.
Scrieti un program entab care inlocuieste sirurile de blank-uri prin numrul minim de tab-uri si blank-uri care realizeaza aceeasi spatiere.
Scrieti un program care elimina toate comentariile dintr-un program C.
Scrieti un program care sa gaseasca erorile elementare de sintaxa dintr-un program C , de genul paranteze rotunde , patrate , acolade neinchise , ghilimele , apostroafe, comentarii.
Scrieti o functie reverse(s) care sa inverseze sirul de caractere s.
Scrieti o functie reverse(s) care sa inverseze sirul de cractere s.
|