Sunteți pe pagina 1din 78

UNIVERSITATEA DE STAT DIN MOLDOVA

Eleonora Seiciuc

Lucia Bitcovschi

Programarea n limbajul C

Instruciunu metodice, probleme rezolvate, lucrri de laborator

Chiinu 2010
1

Cuprins
Introducere ......................................................................................................................................3
Lucrare de laborator N1..................................................................................................................4
Lucrare de laborator N2..................................................................................................................9
Lucrare de laborator N3................................................................................................................15
Lucrare de laborator N4................................................................................................................21
Lucrare de laborator N5................................................................................................................26
Lucrare de laborator N6................................................................................................................34
Lucrare de laborator N7................................................................................................................43
Lucrare de laborator N8................................................................................................................50
Lucrare de laborator N9................................................................................................................58
Lucrare de laborator N10..............................................................................................................67
Bibliografie...............................................................................................................................................................78

Introducere
Disciplina Fundamentele programrii se studiaz de studenii facultii Matematic i
Informatic n semestrele 1 i 2 i prevede studierea limbajului de programare C.
Broura dat se dorete a fi un supliment la manualele de C/C++ existente pe piaa
lucrrilor de informatic. Ea este o culegere de lucrri de laborator, dar nu se limiteaz doar la
asta. Fiecare lucrare de laborator este precedat de un set de sugestii i indicaii teoretice de lucru
care au ca scop oferirea n mod succint a funciilor i instruciunilor limbajului referitor la tema
lucrrii. La fel fiecare lucrare de laborator conine mai multe probleme rezolvate, fiind prezentate
programele respective (cu explicaiile necesare), i un set de probleme propuse spre rezolvare. La
fiecare lucrare sunt propuse i un ir de de ntrebri de control pentru testarea cunotinelor.
Sunt propuse 10 lucrri de laborator:
lucr.
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.

Denumirea lucrrii
Funcii de intrare/ieire, tipuri de baz.
Operatori, operanzi, expresii i funcii matematice n limbajul C.
Instruciuni ciclice.
Pointeri i tablouri.
Prelucrarea irurilor de caractere.
Lucrul cu tablourile unidimensionale.
Lucrul cu tablourile bidimensionale.
Subprograme.
Tipuri de date definite de utilizator, redenumirea tipurilor.
Prelucrarea fiierelor.

ore
6-8
4-6
6-8
6-8
4-6
4-6
4-6
6-8
6-8
4-6

Toate lucrrile de laborator i exemplele respective pot fi rulate pe un calculator PC, cu


compilatorul Borland C++ 3.1. Astfel, majoritatea exemplelor din lucrare, chiar dac sunt scrise
n limbajul C standard (deci neobiectual), folosesc un minim de faciliti aduse de limbajul C++,
cum ar fi comentariile cu simbolurile // i declararea variabilelor simultan cu iniializarea lor,
n cadrul unor instruciuni repetitive.
Studenii efectueaz fiecare lucrare de laborator, o salveaz pe calculator i susin lucrarea.
Susinerea lucrri se face, de regul, n mod practic la calculator prin prezentarea lucrrii i
testarea asistat de calculator pe ntrebrile de control venite din partea profesorului.

Lucrare de laborator N1
Tema: Funcii de intrare/ieire, tipuri de baz.
Scopul lucrrii: nsuirea funciilor de intrare/ieire, utilizarea lor la introducerea i
extragerea datelor sub controlul unor formate i fr aceasta.
Indicaii i sugestii de lucru:
Funcia clrscr() terge ecranul. Are prototipul void clrscr(void) i se afl n fiierul
<conio.h>.
Funcia getch() citete fr ecou un caracter de la intrarea standard direct n memorie, fr
acionarea tastei Enter. La citirea unui caracter ASCII funcia returneaz codul caracterului citit.
La citirea unui caracter ne ASCII funcia se apeleaz de dou ori: la primul apel ea returneaz
valoarea 0, iar la cel de al doilea apel ea returneaz o valoare specific tastei acionate. Are
prototipul int getch(void), n fiierul <conio.h>.
Funcia getche() citete cu ecou un caracter de la intrarea standard direct n memorie, fr
acionarea tastei Enter. La citirea unui caracter ASCII funcia se apeleaz de dou ori: la primul
apel ea returneaz valoarea 0, iar la cel de al doilea apel ea returneaz o valoare specific tastei
acionate. Are prototipul int getche(void), n fiierul <conio.h>.
Funcia putch(e) scrie un caracter la ieirea standard. Ea are un singur parametru. Funcia
returneaz codul imaginei extrase, adic valoarea lui e. De exemplu, putch(\n), trece cursorul
pe linia urmtoare n aceeai coloan.
Funcia getchar() citete cu ecou caractere ASCII de la intrarea standard ntr-un tampon
special pn la acionarea tastei Enter. La acionarea tastei Enter, ea returneaz codul caracterului
curent din tampon. La urmtorul apel funcia returneaz codul caracterului urmtor din tampon.
Dac n tampon nu mai sunt caractere, atunci apelul funciei impune citirea unui nou set de
caractere de la intrarea standard n tampon. Prototipul este: int putchar(int c), n fiierul
<stdio.h>.
Funcia getc() citete din flux un caracter.
Funcia gets() citete cu ecou un ir de caractere ASCII de la intrarea standard care se
termin cu <Enter>. Ea are un parametru valoarea cruia este adresa de nceput a zonei de
memorie unde se pstreaz irul de caractere citit. De obicei acest parametru este numele unui
tablou unidimensional de tip char. La apsarea tastei Enter funcia nu scrie caracterul newline
(\n) n memorie, ci caracterul NUL (\0), care semnific sfritul irului. Deci, \n se
substitute prin \0. Fiecare caracter ocup un octet n memorie. Rezult c un ir de n caractere
ocup n+1 octei.
Funcia puts(s) scrie la ieirea standard un ir de caractere ASCII, care n memorie se
termin cu caracterul NUL (\0), Ea are un parametru, valoarea cruia este adresa de nceput a
irului de extras. De obicei, acest parametru este numele unui tablou unidimensional de tip char.
La ntlnirea caracterului NUL, funcia nu scrie acest caracter, ci trece cursorul la nceputul liniei
urmtoare, adic se substituie caracterul \0 prin \n.
Funcia returneaz adresa de nceput a zonei de memorie unde se pstreaz irul citit, adic
adresa primului caracter. Dac ntlnete caracterul EOF, funcia returneaz valoarea 0. Are
prototipul n fiierul <stdio.h>.
Funcia putchar(e) scrie un caracter ASCII la ieirea standard. Ea returneaz codul
caracterului extras sau -1 n caz de eroare. Aici putchar(\n), ca i putchar(10), trece cursorul
la nceputul liniei urmtoare.
Funcia are prototipul int putchar(int e), n fiierul <stdio.h>.
Funcia printf(c, p1, p2, p3, ...) scrie la ieirea standard date sub controlul unor formate.
Are unul sau mai muli parametri. De obicei, parametrul c este un ir de caractere scris n
4

ghilimele, care conine textele eventuale de extras i specificatorii de format eventuali pentru
datele de extras. Textele din parametrul c sunt extrase fr schimbare. Secvenele escape, cum ar
fi \n, \t, \0 .a., nu sunt extrase ci sunt executate. Parametrii p1, p2, p3, ... sunt expresii,
valorile crora vor fi extrase. La fiecare din aceti parametri, n irul de caractere c, i corespunde
un specificator de format, care indic cum se va extrage valoarea respectiv. Un specificator de
format ncepe cu % i se termin cu una sau dou litere anumite. El determin conversia valorii
de extras din formatul intern n formatul extern. Parametrii p1, p2, p3, pot lipsi. Atunci vor fi
extrase numai textele din parametrul c.
Funcia returneaz numrul de octei (caracter) extrai la ieirea standard sau -1 n caz de
eroare. Ea are prototipul n fiierul <stdio.h>.
Funcia scanf(c, p1, p2, p3, ...) citete de la intrarea standard date sub controlul unor
formate. Are mai muli parametri. De obicei, parametrul c este un ir de caractere scris n
ghilimele, care conine specificatori de format pentru datele de la intrare. El poate conine i
caractere albe care sunt neglijate. Parametrii p1, p2, p3, ... sunt adresele zonelor de memorie
unde se vor pstra datele citite. De obicei, adresa unei zone de memorie se exprim prin
operatorul & n faa numelui unei variabile simple sau cu indice. La fiecare dintre aceti
parametri, n irul de caractere c, i corespunde un specificator de format, care indic cum se va
citi data respectiv de la intrare. Un specificator de format ncepe cu % i se termin cu una sau
dou litere anumite. El determin conversia datei de citit din formatul extern n formatul intern.
Se cunosc urmtorii specificatori: %d, %i - ntreg, %f - real, %lf - real lung, %ld - ntreg
lung, %u-ntreg fr semn, %c - citete caracterul curent, %s - citete irul, %e - real n format
exponenial, %p - pointer.
Funcia citete toate datele ce corespund specificatorilor de format din parametrul c. Dac o
dat de la intrare nu corespunde specificatorului de format, atunci citirea se ntrerupe. Funcia
returneaz numrul datelor citite corect. Ea are prototipul n fiierul <stdio.h>.
Funcia fflush(stdin) golete stream-ul intrrii standard (terge coninutul buferului
tastaturii). Ea are prototipul n fiierul <process.h>.
Funcia exit(c) ntrerupe execuia programului. Parametrul c definete starea programului
n momentul apelului funciei. De obicei, valoarea 0 a parametrului c definete o stare normal
de terminare a execuiei programului, iar o valoare diferit de 0 semnific prezena unei erori. Se
folosete pentru a termina execuia unui program. Funcia are prototipul n fiierul <stdlib.h> .
sizeof este un operator care determin dimensiunea n octei a unei date sau a unui tip de
date. De exemplu, sizeof(int) returneaz numrul de octei necesari pentru a pstra o valoare de
tipul int, iar sizeof d returneaz numrul de octei alocai datei cu numele d.

Tipuri de date
ntregi
reale
s imple

caracter
enum erativ
logic

s tatice

m asiv
ir
s tructurate

m ulim e
articol

dinamice

fi ier

Tipuri simple de date


Grupa
Grupa
de
de dat
dat

ntreg

[signed] char

Lungime
Lungime
((octe
octeii))
1

un signed char

0..255 (0..28-1)

un signed [int]
[short] [in t]

2
2

0..65535
-32768..32767

un signed long

0..232-1

long [int]
float

4
4

-231..231-1
3.4*10-38..3.4*1038

double

1.7*10-308.. 1.7*10308

long double

10

3.4*10-4932.. 3.4*104932

Tipul
Tipul

Real

Domeniu
Domeniu de
de valori
valori
-128..127 (-27..27-1)

Exemple de programe:
Exemplul 1.1. Programul citete o liter minuscul i extrage caracterul precedent acestei
litere din setul de caractere al calculatorului.
#include<conio.h>
#include<stdio.h>
void main(void)
{
char c;
clrscr();
c=getchar();
putchar(c-1);
getch();
}

Exemplul 1.2. Programul citete un ir de caractere i extrage lungimea irului citit.


#include<conio.h>
#include<stdio.h>
#include<string.h>
void main(void)
{
char s[256];
clrscr();
gets(s);
printf(irul are %d caractere,strlen(s));
getch();
}

Exemplul 1.3. Programul definete i citete 4 numere de la tastatur de tip int, float, long
double, char i le afieaz la ecran.
#include<conio.h>
#include<stdio.h>
void main(void)
{
char c=a;
int k=3;
float f=5.9;
double d=9.999;
clrscr();
printf(%c\t%d\t%f\t%lf,c,k,f,d);
getch();

Exemplul 1.4. Programul afieaz ntre dou caractere * constanta 123.456f (definit prin
directiva #define) cu diferii specificatori de format pentru date de tip float.
#include<conio.h>
#include<stdio.h>
#define a 123.456f
void main(void)
{
clrscr();
printf(*%f*\n,a);
printf(*%2f*\n,a);
printf(*%20f*\n,a);
printf(*%-20f*\n,a);
printf(*%020f*\n,a);
printf(*%.2f*\n,a);
printf(*%.10f*\n,a);
printf(*%2.2f*\n,a);
printf(*%2.10f*\n,a);
printf(*%20.10f*\n,a);
printf(*%-20.10f*\n,a);
printf(*%020.10f*\n,a);
getch();
}

Exemplul 1.5. Programul citete cu getch() caractere ne ASCII i apoi extrage codul
fiecruia cu printf().
#include<conio.h>
#include<stdio.h>
void main(void)
{
char a;
clrscr();
getch();
// primul apel
printf("al doilea apel:%d\n",getch());
getch();
// primul apel
a=getch();
// al doilea apel
printf("al doilea apel:%d\n",a);
getch();
// primul apel
printf("al doilea apel:%d\n",a=getch());
getch();
}

Exemplul 1.6. Este dat numrul ntreg a. Folosind numai operaia de nmulire s se
calculeze a8 prin trei operaii.
#include<conio.h>
#include<stdio.h>
void main(void)
{
int a,k,l,f;
clrscr();
printf("introducei valoarea lui a);
scanf(%d,&a);
k=a*a;
//a2
l=k*k;
//a4
f=l*l;
//a8
printf("rezultat=%d",f);
getch();
}

Probleme propuse spre rezolvare:


1. Programul citete dou numere ntregi i afieaz media lor aritmetic.

2. Programul afieaz ntre dou caractere * constanta 123.456 (definit prin directiva #define)
cu urmtorii specificatori de format: %f, %2f, %10f, %-10f, %010f, %.2f, %.10f, %2.2f.
3. Programul afieaz n zecimal, octal i hexazecimal constanta 123456789 definit prin
directiva #define.
4. Programul citete un caracter ne ASCII (cu getchar()) i apoi afieaz (cu printf()) codul
caracterului citit i caracterul.
5. Programul citete (cu scanf()) un numr ntreg zecimal format din cel mult nou cifre i apoi
afieaz (cu printf()) numrul citit n zecimal, octal i hexazecimal.
6. Sunt date trei numere de tipul: int, float, double. Calculai suma lor, produsul i diferena lor
i afiai rezultatele la ecran.
7. Programul citete (cu scanf()) o dat calendaristic sub forma ddmmyy (o succesiune de 6
cifre) i apoi o afieaz (cu printf()) sub forma 20yy/mm/dd. Aici dd, mm i yy sunt numere
din dou cifre care reprezint respectiv ziua, luna i anul.
8. Programul citete (cu scanf()) numele i prenumele unei persoane separate prin spaii albe,
apoi afieaz (cu printf()) numele pe un rnd i prenumele pe alt rnd.
9. Sunt date numere ntregi x i y. S se obin: x y .
1 + xy

10. Dat a ntreg. Folosind doar operaia de nmulire s se calculeze a2, a5, a17 prin ase operaii.
11. Dat a ntreg. Folosind doar operaia de nmulire s se calculeze a4, a12, a28 prin ase operaii.
12. S - au amestecat v1 litri de ap de temperatura t1 cu v2 litri de ap de temperatura t2. S se
calculeze volumul i temperatura compoziiei obinute.
13. Sunt date x i y numere ntregi. S se gseasc media aritmetic i media geometric a
modulului lor.
14. Este dat x ntreg. Folosind numai operaia de nmulire, adunare i scdere, s se calculeze
expresia: 2x4-3x3+4x2-5x+6.
Se permit nu mai mult de 4 operaii de nmulire, 4 operaii de adunare i scdere.
15. Sunt date lungimile catetelor triunghiului drept. S se gseasc ipotenuza i aria lui.
16. Sunt date numerele ntregi x i y. Folosind numai operaiile de nmulire, adunare i scdere,
s se calculeze: 3x2y2-2xy2-7x2y-4y2+15xy+2x2-3x+10y+6.
Se permite folosirea nu mai mult de opt operaii de nmulire, de adunare i scdere.
17. Programul citete (cu scanf()) o majuscul i apoi afieaz (cu printf()) minusculele
corespunztoare.
18. Folosind operatorul sizeof afiai ct memorie se rezerv pentru fiecare tip de date (char,
signed char, unsigned char, short, signed short, unsigned short, int, signed int, unsigned int, long
int, long signed int, long unsiged int, float, double, long double).
ntrebri de control:
1.
2.
3.
4.
5.
6.
7.
8.
9.

Cum se lanseaz un program la execuie n Turbo C++ ?


n care fiiere se afl prototipurile funciilor standard ?
Cum se afieaz Help-ul pentru o funcie standard, de exemplu clrscr() ?
Care sunt deosebirile dintre funciile getche() i getchar() ?
Ce valori returneaz funciile de intrare ?
Ce valori returneaz funciile de ieire ?
Cum i pentru ce se utilizeaz funcia exit() ?
Care sunt funciile de citire cu ecou ?
Care funcii de intrare cer acionarea tastei Enter ?

10. char a;
unsigned char b;
a=200; b=200;
printf(ntreg %d\t caracter %c,a, a);
printf(\n ntreg %d\t caracter %c,b, b);

Ce se va extrage la ecran? Explicai.


8

Lucrare de laborator N2
Tema: Operatori, operanzi, expresii i funcii matematice n limbajul C.
Scopul lucrrii: .Utilizarea corect a operatorilor, alctuirea corect a expresiilor cu
respectarea regulilor de conversie implicit i conversia forat a datelor.
Suport teoretic:
O expresie este o secven de caractere care specific o regul pentru calculul unei valori.
Aceast valoare poate fi: numeric, alfanumeric, boolean sau de tip structurat. Trebuie s v
mrturisim c acum a sosit momentul s definim acest termen mult mai precis.
O expresie poate fi foarte simpl. Cifra 7 singura (o constant) i litera M (o variabila) sunt
expresii valide. Dar, o expresie poate fi de asemenea foarte complicat.
Observai membrul drept al enunului de mai jos:
m:=7*a+b*(j+sqrt(x))
unde:
7, a, j si x sunt toate expresii;
7*a este o expresie;
Funcia sqrt(x) este o expresie;
j+sqrt(x), cu sau fr paranteze exterioare, este o expresie;
Tot membrul drept este o expresie.
O expresie are sens, n timpul compilrii, dac toate elementele componente au fost n
prealabil declarate i au fost respectate regulile de sintax a limbajului. O expresie se calculeaz
n timpul execuiei dac, dup momentul cnd s-a ajuns la codul obiect, tuturor identificatorilor li
s-au atribuit valori (specifice) care permit s fie evaluai.
Fiecare din cei trei operatori (+,-, | |) care pot fi folosii pentru conectarea termenilor unor
expresii simple se numesc operatori de adugare (adding operators).
Fiecare din cei patru operatori (*, /, % i &&) care pot fi folosii pentru conectarea
factorilor se numesc operatori de multiplicare (multiplying operator).
Pentru micarea biilor spre stnga i spre dreapta, se folosesc operaiile << i >>.
Deoarece biii sunt mutai ctre un capt, la cellalt capt se adaug zerouri. (n cazul unui ntreg
negativ cu semn o deplasare la dreapta va determina introducerea unui 1, astfel nct bitul de
semn se va pstra.) Biii deplasai dincolo de capt nu se ntorc la captul cellalt, ci sunt
pierdui.
Operaiile de deplasare a biilor pot fi foarte utile atunci cnd decodificai intrarea de la un
dispozitiv extern. O deplasare la dreapta mparte efectiv un numr cu 2, iar o deplasare la stnga
l nmulete cu 2.
Funciile matematice: pow(x,y), poly(x, n, c[]), sin(x), sqrt(x), cos(x), exp(x), log(x),
log10(x), asin(x), acos(x), atan(x) au prototipul n fiierul <math.h>. Toate funciile
trigonometrice presupun argumentul exprimat n radiani. Pentru a transforma gradele n radiani
se nmulesc gradele cu / 180 , unde constanta = 3.14 .
Tabela 2.1: Funcii matematice din fiierul math.h
Prototipul funciei

Efect

double acos(double x);

arccosinus de x

double asin(double x);

arcsinus de x

double atan(double x);

arctangenta de x

double atan2(double y, double x);

arctangenta de y/x

double ceil(double x);

cel mai mic intreg mai mare sau egal cu x

double cos(double x);

cosinus de x

double exp(double x);

exponeniala

double fabs(double x);

valoarea absoluta a lui x

double floor(double x);

cel mai mare intreg mai mic sau egal cu x

double log(double x);

ln de x

double log10(double x);

lg de x

double pow(double x, double y);

x la puterea y

double sin(double x);

calculeaz valoarea funciei sinus de unghiul x


exprimat n radiani.

double sqrt(double x);

radicalul lui x

double tan(double x);

tangenta lui x

double poly(x, n, c[])

calculeaz valoarea polinomului


p=cnxn+cn-1xn-1+...+c2x2+c1x+c0

Media geometric a numerelor a1, a2,...,an este (a1*a2*...*an)(1/n).


Tabela 2.2: Operatori i descrierea lor.
Operatorul

Descrierea

<

mai mic

<=

mai mic i egal

>

mai mare

>=

mai mare i egal

!=

diferit

==

egal

&&

a&&b are valoarea 1, atunci i numai atunci, cnd i a i b au valori diferite de 0.

negarea logic, !a are valoarea 0 (false), dac a are valoarea diferit de 0 i 1 (true), dac a are
valoarea 0.

||

sau

complement fa de 1

<<

deplasare la stnga

>>

deplasare la dreapta

sau logic pe bii

+=

suma cu atribuire

++

increment

--

decrementul

mprire

%=

restul mpririi egal

?:

condiie

10

Tabela 2.3: Codurile ASCII.


0

Ctrl |

25

Ctrl Y

50

75

105

Ctrl A

26

Ctrl Z

51

76

106

Ctrl B

27

ESCAPE

52

77

107

Ctrl C

28

Ctrl <

53

78

108

Ctrl D

29

Ctrl /

54

79

109

Ctrl E

30

Ctrl =

55

80

110

Ctrl F

31

Ctrl -

56

81

111

Ctrl G

32

BLANK

57

82

112

Ctrl H

33

58

83

113

Ctrl I

34

"

59

84

114

10

\n

35

60

<

85

115

11

Ctrl K

36

61

86

116

12

Ctrl L

37

62

>

87

117

13

Return

38

&

63

88

118

14

Ctrl N

39

'

64

89

119

15

Ctrl O

40

65

90

120

16

Ctrl P

41

66

92

121

17

Ctrl Q

42

67

97

122

18

Ctrl R

43

68

98

123

19

Ctrl S

44

69

99

124

20

Ctrl T

45

70

100

125

21

Ctrl U

46

71

101

126

22

Ctrl V

47

72

102

23

Ctrl W

48

73

103

24

Ctrl X

49

74

104

Exemple de programe:
Exemplul 2.1. Sunt date 2 variabile de tip real. S se efectueze operaiile suma, produs i
mprire.
#include<stdio.h>
#include<conio.h>
void main()
{
float k,l;
clrscr();
printf("dati k si l:");
scanf("%f%f",&k,&l);
printf("suma=%.2f",k+l);
printf("\nimpartirea=%.2f",k/l);
printf("\nprodus=%.2f",k*l);
getch();}

11

Exemplul 2.2. Este dat un numr ntreg. Programul verific dac numrul introdus este
pozitiv, negativ sau zero.
#include <stdio.h>
void main()
{
int nr;
printf("Numar=");
scanf("%d",&nr);
(nr<0)?printf("negativ\n"):((nr>0)?printf("pozitiv\n") : printf("zero\n"));
}

Exemplul 2.3. Programul citete dou numere ntregi i testeaz operatorii >> i <<.
Tastai programul pentru: x=1, u=4; x=2, u=8; x=3, u=5; x=-1, u=-1; x=-5, u=-5.
#include<stdio.h>
#include<conio.h>
void main()
{
long x,y;
int u,v;
clrscr();
printf("dati x,u:");
scanf("%ld%d",&x,&u);
//deplasare la stnga a lui u, nseamn nmulirea lui cu 2
v=u<<2;
printf("\nu=%d\t%d<<2=%d\n",u,u,v);
//deplasare la dreapta a lui x, nseamn mprirea lui cu 2
y=x>>2;
printf("\nx=%ld\t%ld>>2=%ld\n",x,x,y);
getch();
}

Exemplul 2.4. Programul determine maximul i minimul dintre dou numere ntregi date.
#define max(x,y) x>y?x:y
#define min(x,y) x<y?x:y
#include <stdio.h>
void main()
{
int x,y;
printf(dai x i y);
scanf(%d%d,&x,&y);
printf(maximul=%d,max(x,y));
printf(\nminimul=%d,min(x,y));
getch();
}

Exemplul 2.5. S se determine aria unui triunghi n funcie de lungimile laturilor sale.
#include<stdio.h>
#include<conio.h>
#include<math.h>
void main()
{
float a,b,c,p,aria;
printf(Dai lungimile laturilor:\n);
scanf(%f%f%f,&a,&b,&c);
p=(a+b+c)/2;
aria=sqrt(p*(p-a)*(p-b)*(p-c));
printf(Aria este: %7.3f,aria);
getch();
}

Exemplul 2.5. Este dat n ntreg. S se afle ultima cifr a lui n.


#include<stdio.h>
#include<conio.h>
void main()
{
int n,c;

12

clrscr();
printf("n=");
scanf("%d",&n);
n=n%10;
printf("c=%d",c);
getch();
}

Probleme propuse spre rezolvare:


1. S se calculeze puterea a n-a a lui 2, unde n este un ntreg dat de la tastatur, folosind
operatorul de deplasare la stnga.
2. S se gseasc lungimea dintre dou puncte cu coordonatele x1, y1 i x2, y2.
3. Fie a, b, c trei numere reale. S se verifice dac a, b pot reprezenta lungimile laturilor unui
dreptunghi, respectiv c s fie diagonala n acel dreptunghi.
4. Sunt date a, b, c numere ntregi. S se verifice, dac se execut expresia: a < b < c.
5. Sunt date x, y, z. S se calculeze:
a. max(x, y, z);
b. max(x+y+z, xyz);
c. min2(x+y+z/2, xyz)+1.
sin 2 cx13 + dx22 cd

6. Sunt date c,d. S se calculeze:

3
1

2
2

(cx + dx x1 ) + 3.14

+ tg (cx13 + dx22 x1 ) , unde x1- rdcina

mare, iar x2 - rdcina mic a ecuaiei x 2 3x cd = 0.


7. Sunt date a, b. S se calculeze s:
a. s =

2a(a + 2b + a 2 + 4ab)
2

a + (a + 4ab )(a + 4b + a + 4ab)

b
b 2 + 1/ b

1
+ 1)
b. s = (ab
1
1

c.

a3b3 1
a3b3 + 1 ;
/ 1
1
ab a b a b + ab + 1 ab + a 1b 1
a + a 3 / 4b1 / 2 + a1 / 4b3 / 2 + b 2 4
3 b (a1 / 2 b) 1 / 3 4
s=(
(
a
)
+
b
)
+
) /( a + b ) 1;
a1 / 2 + 2a1 / 4b1 / 2 + b
a 1 / 4 (a1 / 4 b )
2 2

3
4
3
23
2
d. s = (3 b2 + a3 b + a 2 ) b a + a b ba + 2b + 2 b 9 ;
1
4 1
2

ba + a a b a

2b 2 b2 9

2b
5/3 5/ 4
ab 2 a 8ab 3 / 4 ) 2 / 3 .
e. s = (a b 6a b +12
3/ 4
2/3
3

ab a 4ab

+ 4a

8. Sunt date x, y. S se calculeze a, b, dac:


a. a = x 1 3 y , b = x(arctgz + e ( x + 3) ) ;
2
2
1+

b. a =

x
y
+
2
4

( y x) 2 y x ;
3 + e y 1 ,
b
=
1
+
y

x
+
+
2
3
1 + x 2 y tgz

c. a = y +

x
y2 +

x2
y + x3 / 3

z
, b = (1 + tg 2 ) ;
2

2
5
y
, b= x x + x ;
2
z + x /4
3! 5!
2
e. a = (1 + y) xx +2 y /( x +2 4) , b = 1 +4 cos( y 22) ;
x / 2 + sin z
e
+ 1/( x + 4)
2
f. a = 2 cos( x 2 / 6) , b = 1 + z 2 ;
3+ z /5
1/ 2 + sin y

d. a = ln ( y x )( x

13

g. a =

1
1 + sin 2 ( x + y )
2
+ x , b = cos (arctg ) ;
2 2
z
2 + x 2 x /(1 + x y )

2
2
1
3
3
h. a = ( ( y + 2 xy )(2 y + 4 x y ) (2 x)1 / 3 ) 6 , b =
3
y 3 2x

x+ y
x y

x y
x + y y xy + x ;
x y
x+ y
2 xy
+
x+ y
x y

ntrebri de control:
1. Ce este o expresie, un operand, un operator. Ce operatori cunoatei?
2. Explicai cum se utilizeaz operatorul adres & ?
3. Explicai cum se utilizeaz operatorul condiionat ? :.
4. Ce specificatori de format se folosesc pentru a citi i a scrie date numerice flotante de
tipul long double?
5. Fie int x=2, y; y=--x; x=y--; Care este valoarea lui x?
6. Fie int x=2, y; y=x++; x=++y; Care este valoarea lui x?
7. Fie char c; c=R+m-M; Care este tipul valorii lui c i ce va afia printf(%d,c)?
8. Explicai cum lucreaz funciile abs(), log10(), pow(x, z) i dai exemple?
9. Care sunt specificatorii pentru tipurile: int, float, char, double i care este diapazonul
acestor tipuri?
10.Fie int x=1, y=2, n=3, m=4; n=x/y; m=x%y; Care sunt valorile lui n i m?

14

Lucrare de laborator N3
Tema: Instruciuni ciclice.
Scopul lucrrii: nsuirea instruciunilor limbajului.
Suport teoretic:
Instruciunea compus este un bloc de instruciuni cu formatul:{declaraii;
instruciuni;}. La nceputul blocului prin declaraii se pot defini i iniializa date de diferite
tipuri. Prin instruciuni se realizeaz prelucrarea datelor.
Instruciunea if este o instruciune de ramificare. Ea are dou formate: incomplet i
complet. Formatul incomplete este: if (expresie) instruciune1.
La ntlnirea acestei instruciuni se evalueaz expresia din paranteze. Dac expresia are
valoarea adevr, adic o valoare diferit de 0, atunci se execut instruciune1 i apoi se trece la
instruciunea imediat urmtoare dup instruciunea if. n caz contrar, se trece imediat la
instruciunea urmtoare.
Deci forma general a instruciunii if este: if (expresie) instruciune1; else
instruciune2; Se evalueaz expresia din parantez i n caz de adevr se execut instruciune1,
altfel se execut instruciune2. Dup aceasta se trece la instruciunea urmtoare dup if.
Instruciunile instruciune1 i instruciune2 pot fi simple i compuse.
Instruciunile if pot fi incluse una n alta.
Instruciunea for este o instruciune de ciclu condiionat i are formatul: for(i1; i2; i3)
instruciune; Aici i1, i2, i3 sunt expresii: i1 este expresia de iniializare a ciclului, i2 este
expresia care determin condiia de repetare a ciclului, i3 este expresia de reiniializare a ciclului;
instruciune este corpul ciclului i poate fi o instruciune simpl sau compus. Corpul ciclului
sunt acele instruciuni de prelucrare a datelor care trebuie repetate. i corpul ciclului poate lipsi.
n acest caz ciclul const numai din antet i instruciunea vid: for(i1; i2; i3);
Instruciunea for se execut n felul urmtor: se efectueaz operaiile de iniializare ale
ciclului i1, apoi se evalueaz expresia i2. Dac i2 are o valoare diferit de 0, adic valoarea
adevr, atunci se execut instruciune corpul ciclului. n caz contrar, cnd i2 are valoarea 0,
adic valoarea fals, se termin execuia ciclului for i se trece la instruciunea urmtoare dup
ciclu. Dup execuia corpului, ciclul se reiniializeaz se execut operaiile definite de i3 i se
revine iari la verificarea condiiei de repetare a ciclului i2.
Instruciunea while este o instruciune de ciclul condiionat i are formatul: while(i1)
instruciune; antetul ciclului este while(i1) i conine n paranteze expresia i1 care este condiia
de repetare a ciclului. Corpul ciclului este instruciune i poate fi o instruciune simpl sau
compus. Ea conine acele operaii care trebuie repetate n ciclu. Corpul ciclului poate lipsi. Se
evalueaz i1 i corpul ciclului se execut de attea ori de cte ori i1 are valoarea adevr.
Instruciunea do-while se execut astfel: mai nti se execut instruciune, adic corpul
ciclului, apoi se evalueaz i1, care este condiia de repetare a ciclului. Dac i1 este adevr, atunci
se repet execuia corpului ciclului. n caz contrar, adic dac i1 este 0, atunci se termin
execuia ciclului i se trece la instruciunea urmtoare dup ciclu.
Instruciunea continue se folosete n corpul unui ciclu i are formatul: continue;
Instruciunea dat abandoneaz iteraia curent a ciclului i trece la iteraia urmtoare a lui.
Instruciunea break se folosete numai n corpul unui ciclu sau n instruciunea switch.
La ntlnirea instruciunii break n corpul unui ciclu se termin execuia ciclului i se trece la
instruciunea urmtoare dup ciclu. La folosirea instruciunii break n instruciunea switch se
iese din instruciunea switch i se trece la instruciunea urmtoare dup switch.
Instruciunea switch este o instruciune care realizeaz o alternativ din mai multe
alternative posibile i are formatul:
15

switch (expresie) {
case valoare1: instructiune1; break;
case valoare2: instructiune2; break;

case valoaren: instructiunen; break;


default: instructiune; }
In limba engleza, switch nseamn comutator. Conform acestei forme generale, dup
cuvntul cheie switch, exist o expresie de tip int sau compatibil cu aceasta (deci poate fi
i de tip char, byte sau short, dar nu de tip long), a crei valoare servete drept

comutator. Se deschide apoi acolada corpului instruciunii, n care exist mai multe cazuri.
Fiecare caz ncepe prin cuvntul cheie case, urmat de o valoare de tip ntreg, dup care apar
una sau mai multe instruciuni (simple sau compuse) i opional intruciunea break. Dup ce sau epuizat toate cazurile, opional se poate scrie cuvntul cheie default urmat de una sau mai
multe instruciuni i se nchide acolada corpului instruciunii switch.
Executarea instruciunii switch decurge astfel: se evalueaz mai nti expresie i se
obine o valoare, care servete drept comutator. Aceast valoare se compar, de sus n jos, cu
fiecare din valorile indicate dup cuvintele cheie case, pn cnd se gsete prima valoare
care coincide cu cea a comutatorului. Dac s-a gsit o astfel de valoare, se execut toate
instruciunile care ncep cu cazul respectiv i se ncheie la prima instruciune break ntlnit
sau, n lipsa acesteia, pn la acolad de nchidere a corpului instruciunii switch. dac ns
nici unul din cazuri nu conine valoarea potrivit a comutatorului, atunci se execut instruciunile
care urmeaz dup cuvntul cheie default sau, n lipsa acestuia, nu se execut nimic.
Instruciunele case i default se folosesc numai n instruciunea switch.
Instruciunea goto este o instruciune de salt necondiionat. Ea are formatul goto nume,
unde nume este numele unei etichete. Eticheta este un identificator (un nume) care se scrie n
faa unei instruciuni cu simbolul : dup el. De exemplu lab1: i++; Aici numele lab1 este o
etichet. La ntlnirea instruciunii goto lab1; se trece imediat la execuia instruciunii cu eticheta
lab1 n fa, adic la instruciunea i++.
Instruciunea return se folosete pentru a reveni dintr-o funcie. Ea are formatul return;
sau return expresie; n primul caz, funcia din care se revine nu returneaz nici o valoare. Al
doilea caz se folosete cnd funcia returneaz o valoare i anume valoarea expresie definete
valoarea de returnat. Tipul valorii pentru expresie trebuie s coincid cu tipul indicat n antetul
funciei respective pentru valoarea returnat. Instruciunea return poate fi scris n orice punct al
corpului unei funcii, ns nu este obligatorie. n corpul aceleai funcii pot fi scrise mai multe
instruciuni return.
Exemple de programe:
Exemplul 3.1. Este dat n ntreg. S se afle prima cifra a lui n (n=123, prima cifr este 1).
#include<stdio.h>
#include<conio.h>
void main()
{
int n,c;
clrscr();
printf("n=");
scanf("%d",&n);
//ct n este mai mare ca 9 se face mprirea lui n la 10, pn se
ajunge la prima cifr
while(n>9) n=n/10;
printf("prima cifra este=%d",n);
getch();
}

Exemplul 3.2.Este dat n ntreg. S se numere din cte cifre este compus n (n=345, c=3).
#include<stdio.h>
#include<conio.h>

16

void main()
{
int n,c;
//c este un contor, iniial are valoarea zero
c=0;
clrscr();
printf("n=");
scanf("%d",&n);
//att ct n este mai mare ca zero, n se mparte la zece i c crete
while(n>0){
n=n/10;
c=c+1;
}
printf("c=%d",c);
getch();
}

Exemplul 3.3. Date a, b dou numere ntregi. S se afle cel mai mic multiplu comun al lor.
#include<stdio.h>
#include<conio.h>
void main()
{
int i,min,a,b,div;
float mult;
clrscr();
printf("a, b");
scanf("%d%d",&a,&b);
if(a<b) min=a; else min=b;
//mai nti gsim minimul dintre a i b
//parcurgem ciclul pn la minim
for(i=1;i<=min;i++)
//gsim cel mai mare divizor comun a lui a i b
if((a%i==0)&&(b%i==0)) div=i;
//calculm multiplu comun
mult=(a*b)/(float)div; //float n faa lui div-pentru conversie de tip
printf("multiplu comun a 2 numere=%.2f", mult);
getch();
}

Exemplul 3.4. S se calculeze expresia: produs = (1 + 12 )(1 + 12 )(1 + 12 )...(1 + 12 ) .


#include<stdio.h>
#include<conio.h>
void main()
{
int i,n;
float produs;
clrscr();
printf("n=");
scanf("%d",&n);
//notm iniial produsul cu valoarea 1
produs=1;
for(i=1;i<n;i++)
produs=produs*(1+(1/(float)(i*i)));
printf("produs=%.2f",s);
getch();
}

Exemplul 3.5. Este dat numrul n . S se verifice dac n este numr prim sau nu(numr
prim se mparte la 1 i la el nsi (1, 2, 3, 5, 7, 11 etc.)).
#include<stdio.h>
#include<conio.h>
void main()
{
int i,n,prime;
prime=1;
clrscr();
printf("n=");
scanf("%d",&n);
//parcurgem ciclul de la 2 pn la jumtatea lui n

17

for(i=2; i<n/2; i++)


if(n%i==0) prime=0;
//dac n are divizori atunci
if(prime==1) printf(n este numr prim);
else printf(n nu este numr prim);
getch();
}

Exemplul 3.6. Folosind instruciunea case i do while calculm:


a. Este dat numrul n s se verifice dac este numr perfect(suma divizorilor este
egal cu el nsi 6=1+2+3);
n

b. S se calculeze expresia: 1i (i + 1) / i!;


i =1

c. S se calculeze expresia: s = 1 + x +

x 2 x3
xn
+ + + , e = 0.0001 , x / n! > e .
2! 3!
n!

#include<stdio.h>
#include<conio.h>
#include<math.h>
void main()
{
int i,n,f,s1,s2,x,y,n1;
float s=0,s3,e;
char c;
clrscr();
s1=s2=0; s=0; x=y=1; f=1;
printf("n=");
scanf("%d",&n);
do{
printf("\n1:se verifica daca este perfect");
printf("\n2:sa se calculeze expresia din punctual b");
printf("\n3:sa se calculeze suma din punctual c");
printf("\n4:esirea\n");
c=getch();
//ateapta alegerea unei operaii
switch(c){
//c primete una din valorile (1- 4)
case '1':
for(i=1; i<n; i++){
// aflm divizorii lui n i calculm suma lor
if(n%i==0) s1=s1+i;}
if(s1==n) printf("numar perfect");
else printf("nu este numar perfect");break;
case '2':
for(i=1; i<n; i++) {
f=f*i;
//calculm factorialul
s=s+(pow(-1,i)*(i+1))/f; }
printf("factorial=%d\tsuma=%f\n",f,s); break;
case '3':
printf("dati x"); scanf("%d",&x);
e=0,0001; s3=1; n1=1; y=x;
while(abs(y)>e)
{
n1=n1+1;
s3=s3+y;
y=y*(float)(x/n1);
}
printf("\ns=%f\tn=%d\n",s3,n1);
printf("\ny=%d\n",y);
break; }}
while(c!='4'); //ciclul lucreaz att timp pn[ c va primi valoarea 4
getch();
}

Exemplul 3.7. S se afieze toate numerele prime din intervalul [2;50].


#include<stdio.h>
#include<conio.h>
void main(){

18

int i,j;
int prim=0; //
for(i=2; i<50; i++) {
for(j=2; j<i; j++)
{// dac restul mpririi nu e zero, atunci are loc instruciunea
//de continue, n caz contrar se trece la else
if(i%j) continue;
else {
prim=1; break; //dac s-a gsit un numr prim se iese din ciclu
}
}
if(!prim) printf("%3d",i); prim=0;
}
getch();
}

Probleme propuse spre rezolvare:


1.

Este dat x numr ntreg. S se calculeze f(x):


a.
b.

c.
2.
3.
4.
5.

x 2 , daca 2 x < 2,
f ( x) =
4, in caz contrar;

x 2 + 4 x + 5, x 2,

f ( x) =
1
x 2 + 4 x + 5 , in ca z contrar;
0, x 0,

2
f ( x) =
x x, 0 < x 1,
x 2 sin x 2 , in caz contrar.

Programul citete valorile a, b, c de tip long, rezolv ecuaia ax2+bx+c=0 i afieaz


rezultatul.
Programul citete un numr ntreg din segmentul [1;7] i afieaz denumirea zilei din
sptmn ce corespunde acestei cifre (1 luni, 2 mari,, 7 - duminic).
Un numr natural n se numete perfect daca este egal cu suma divizorilor si naturali mai
mici ca n. Sa se determine toate numerele perfecte pn la un numr dat.
Pentru n i x numere ntregi date s se calculeze:
a.

xi

i! ;

d.

i =1

b.

7.

1
( +

i =1 i!

x );

e.

(1 +
i =1

sin( ix) ;
)
i!

g.
h.

(1)i (i 1) / 2 ;
i!
i =1
n

1 x

i =1 i!( x + i )! 2
[lg1]

2i + x

[lg 2 ]

[lg n]

(1)
(1)
(1)
(1 x)i +1 + 1 ;
i.
.
+
+ ... +

2
1
2
n
((
i

1
)!
+
1
)
i =1
n
Pentru n dat s se calculeze: xi , x1 = y1 = 1, xi = 0,3xi 1 , yi = xi 1 + yi 1 , i = 2,3,...
i =1 1 + yi
c.

6.

(1)i (i + 1) ;
i!
i =1
n

x + cos(ix)

2i
i =1

f.

Pentru a1 = b1 = 1; ak = 3bk 1 + 2ak 1; bk = 2ak 1 + bk 1; k = 2,3,... ; n dat, s se calculeze:


2k
.

2
2
k =1 (1 + ak + bk ) k!
n

8.

Pentru a1 = u; b1 = v; ak = 2bk 1 + ak 1; bk = 2ak21 + bk 1 , k = 2,3,... Sunt date u, v, s se


calculeze:

9.

ak bk
.

k =1 ( k + 1)!
n

Sa se afle toate numerele ntregi pozitive formate din 3 cifre, egale cu media aritmetica a
numerelor
obinute din fiecare din aceste numere n urma efecturii tuturor
permutrilor (inclusiv cea identica) din
cifrele sale.
19

10.
11.
12.
13.

14.
15.
16.
17.
18.
19.

20.

Sa se scrie un program care s calculeze cel de-al n-lea numr al irului lui Fibonacci
(Astfel, fiecare numr Fibonacci este suma celor dou numere Fibonacci anterioare,
rezultnd secvena 0, 1, 1, 2, 3, 5, 8, 13,...).
Sunt date a, b numere ntregi. S se determine toate numerele prime din intervalul [a, b].
Pentru un numr n dat s se determine dac n este numr polindrom (numr polindrom
6789876).
Programul citete un numr pozitiv s cu cel mult dou cifre dup virgul care exprim o
sum de bani n lei, determin i afieaz numrul minim de bancnote de 500, 200, 100, 50,
20, 10, 5,1 lei i monede de 50, 25, 10, 5, 1 bani necesare pentru a exprima suma s.
Folosii instruciunea do-while.
Sunt date a, b numere ntregi. S se afieze toate numerele perfecte din intervalul [a,b].
Pentru n ntreg dat s se gseasc toate perechile gemene mai mici ca n. Pereche gemene
sunt numerele prime cu diferena 2(5 i 7, 11 i 13, 29 i 31 etc.).
Pentru n ntreg dat. S se gseasc perechea maxim de numere gemene mai mici ca n.
Scriei un program care determin numrul de zerouri n n! (n<=100). n!=1*2*3**(n1)*n. Numrul n este introdus de la tastatur. Exemplu: 12. Rezultat: 4.
Din cifrele a dou numere naturale de alctuit cel mai mare numr, pstrnd ordinea iniial
a cifrelor din numerele date. De la tastatur se introduc dou numere. Exemplu: 23 91662.
Rezultat: 9231662.
Numerele de la 1 la N sunt aezate n ordine cresctoare pe circumferina unui cerc astfel
c N ajunge situate lng 1. ncepnd cu numrul S se marcheaz numerele din K n K, n
ordine cresctoare a lor, pn cnd un numr este marcat de 2 ori. Cte numere au rmas ne
marcate? Numerele N, S i K se citesc de la tastatur. S se afieze la ecran numerele n
ordinea de marcare i numrul de valori, ce au rmas ne marcate. Exemplu: N=8, S=2,
K=5. Rezultat: 2 7 4 1 6 3 8 5 2; 0.
Se citesc cele N cifre ale unui numr natural, N dat, n ordine descresctoare a rangurilor.
Pentru K dat, s se gseasc cel mai mare numr care rmne dup tergere a K cifre,
pstrnd ordinea dat a cifrelor (N, K <255). Exemplu: N=12; K=7; 682395892161.
Rezultat: 99261.

ntrebri de control:
1. Ce este o instruciune compus?
2. Care este formatul instruciunii if ? Explicai cum lucreaz, dai exemplu.
3. Care este formatul ciclului for, care este antetul i corpul ciclului? Explicai cum lucreaz, dai
exemplu.
4. Care este deosebirea dintre ciclurile for, while i do-while?
5. Care este formatul instruciunii switch? Explicai cum lucreaz aceast instruciune.
6. Unde i cum se folosesc instruciunile continue i break?
7. De cte ori se vor executa ciclurile: for(;;); for(;;) continue; for (;;) break? Explicai.
8. De cte ori se vor executa ciclurile: do {;} while (3.14); do {continue;} while(-1); do
{break;} while(0); do {continue;} while(0); do {break;} while(1); Explicai.
9. Fie char h; h=getch(); puts(ati introdus);
switch(h) {
default: puts(greit);
case 1: printf(%d\n,1);
case 2: printf(%d\n,2);
case 3: printf(%d\n,3);
case 4: printf(%d\n,4);
}

Ce se extrage la ecran? Explicai.


10. Fie long double w; printf(\nw=); while(scanf(%lf,&w)!=1) { clrscr();
printf(Greit! Repetai introducerea\n); printf(\nw=);}

De cte ori se va executa ciclul? Explicai.


20

Lucrare de laborator N4
Tema: Pointeri i tablouri.
Scopul lucrrii: obinerea deprinderilor practice la utilizarea pointerilor, nsuiri
aritmeticii pointerilor n limbajul C i a legturii dintre pointeri i tablouri.
Suport teoretic:
Un pointer este o variabil valorile creia sunt adrese de memorie. Pe adresele-valori ale
unui pointer se pot pstra date de un anumit tip. Acest tip se indic n declaraia variabilei de tip
pointer i se numete tipul de baz al pointerului sau tipul spre care pointeaz pointerul.
Declaraia de pointer are formatul: tip *id1, *id2,_, *idn, unde tip este un tip de date care
arat ce tip de date se vor pstra pe adresele-valori ale variabilelor id1, id2,_,idn. De exemplu:
int *pi, i; Aici i este o variabil simpl de tip int, iar pi este un pointer ce indic spre tipul int,
adic n pi se vor pstra adrese ale datelor de tip int. La fel char *c; c este pointer la un obiect de
tipul char. Se pot declara i tablouri de pointeri: char *s[80].
Alocarea memoriei pentru pointeri. Unui pointer i se aloc, de obicei, un cuvnt al
calculatorului, adic 2 octei. ns modificatorii near, far, huge pentru tipul pointer modific
modul de alocare a pointerilor n memorie. Modificatorii far i huge aloc 2 cuvinte, adic 4
octei de memorie pentru pointeri, iar near sau lipsa oricrui modificator semnific alocarea
pointerului pe un cuvnt, adic pe 2 octei de memorie.
Operatori specifici pentru pointeri: * - se utilizeaz pentru accesul la coninutul
variabilei adresate; & - se utilizeaz pentru aflarea adresei variabilei. Pentru tiprirea adreselor
se folosete specificatorul de format %p. Pentru a atribui pointerului pi adresa variabilei i scriem
pi=&i. Dac pi este un pointer, atunci *pi este data stocat pe adresa-valoare a lui pi. De
exemplu, fie i=10 i pi=&i. Atunci pi are ca valoare adresa lui i, iar *pi este chiar valoarea 10 a
lui i. La declaraie pointerii se pot iniializa: float w, *y=&w; sau char *pc=Informatica;
Aici pc este un pointer de tipul char * i lui i se atribuie ca valoare adresa de nceput a irului de
caractere Informatica, adic adresa primului caracter din ir.
Se pot declara pointeri de tipul void *, adic pointeri la care nu se indic tipul de baz. n
acest caz nu se tie n prealabil tipul datelor ce se vor pstra pe adresele-valori ale pointerului.
De exemplu: int x=10, *pi; void *pv; Atribuirea pi=&x i pv=pi sunt corecte. Atribuirea pi=pv
nu este corect. La atribuirea sau citirea datelor de pe adresele-valori ale unui pointer de tip void
* trebuie explicit indicat tipul datelor respective, adic pi=(int*)pv.
Operaii aritmetice cu pointeri: valorile a doi pointeri pot fi comparate folosind
operatori relaionali. Operaia este folosit, de obicei, pentru pointerii care pointeaz spre
elementele aceluiai tablou. Comparaia unui pointer cu NULL constant special definit n
<stdio.h>, are rolul de a verifica dac s-a fcut alocarea unei zone pointerului respectiv. Este
definit adunarea (scderea) unui scalar la un (dintr-un) pointer rezultatul fiind tot un
pointer i diferena dintre doi pointeri, operaiile avnd sens doar dac pointerul pstreaz
adresa unui element dintr-un tablou. Fie p i q doi pointeri la elemente ale aceluiai tablou.
Expresia p+i indic elementul situat n vector cu i poziii la dreapta fa de p, iar expresia p-q are
ca valoare numrul de elemente cuprinse ntre cele dou adrese. Operaia de incrementare (++)
i decrementare (--) pentru pointeri mrete (micoreaz) adresa-valoare a pointerului cu
numrul de octei necesari pentru a pstra o valoare de tipul spre care pointeaz pointerul. De
exemplu, dac avem declarat int *p; atunci ++p, ca i p++, mrete valoarea lui p cu 2 octei,
21

deoarece o valoare de tipul int este alocat pe 2 octei. Analogic, dac avem declarat double *w;
atunci w++, ca i ++w, mrete valoarea lui w cu 8, deoarece tipul double cere 8 octei.
Legtura dintre pointeri i tablouri. Fie tab[n] un tablou unidimensional cu n elemente.
Atunci numele tab este un pointer care are ca valoare adresa primului element al tabloului, adic
are valoarea &tab[0]. Deci tab+1 este adresa elementului cu indicele 1, adic &tab[1], tab+2
este adresa elementului cu indicele 2, adic &tab[2] .a.m.d. Respectiv *(tab+0), adic *tab este
elementul tab[0], *(tab+1) este elementul tab[1], *(tab+2) este elementul tab[2] .a.m.d.
Fie acum tab[m][n] un tablou bidimensional cu m linii i n coloane. Atunci tab[0] este un
pointer care are ca valoare adresa de nceput a liniei 0 a tabloului tab[m][n], adic &tab[0][0],
tab[1] este un pointer care are ca valoare adresa de nceput a liniei 1 a tabloului tab[m][n], adic
&tab[1][0] .a.m.d. Deci tab[0], tab[1],..., tab[m] este un tablou de pointeri. La rndul su,
numele tab al tabloului tab[m][n] este un pointer ce pointeaz spre irul de pointeri tab[0],
tab[1], tab[2],..., adic pointerul tab are ca valoare adresa pointerului tab[0]. Din toate acestea
rezult c expresiile &tab[i][j], tab[i]+j, *tab+i*n+j sunt echivalente. La fel expresiile tab[i][j],
*(tab[i]+j), *(*tab+i*n+j) sunt echivalente. Deci **tab este nu altceva dect elementul
tab[0][0].
Exemple de programe:
Exemplul 4.1. Programul determin elementul maxim dintr-un ir numeric; sunt
demonstrate diferite moduri de adresare la elementele unui tablou unidimensional.
#include<conio.h>
#include<stdio.h>
void main()
{
int x[]={10,20,30,40,50}, *px,i,r,t;
clrscr();
px=x;
r=*px;
for (i=0;i<5;i++)
{
t=*(px+i);
if (r<t) r=x[i];
}
printf(Elementul maxim al irului x este %i,r);
}

Exemplul 4.2. Programul inverseaz un ir de caractere


#include<conio.h>
#include<string.h>
#include<stdio.h>
void main()
{
char *s=programare,i,j,aux;
clrscr();
puts(irul iniial:);
puts(s);
for (i=0, j=strlen(s)-1; i<j;i++,j--)
{ aux=*(s+i); *(s+i)=*(s+j); *(s+j)=aux;
puts(irul inversat:);
puts(s);
getch();
}

Exemplul 4.3. Programul afieaz doar numerele prime dintr-un tablou de numere ntregi
pozitive.
#include<conio.h>
#include<stdio.h>
void main()

22

{
unsigned a[]={10,7,9,40,5,7}, i=0,s=0,d,h;
clrscr();
puts(irul iniial este:);
while ( i<6)
printf(%u\t, *(a+i++));
while (s<6)
{
d=0;
for (h=1; h<=a[s];h++)
if ( *(a+s)%h1==0) d++;
if (d==2) printf(%u\t, *(a+s++)) ;
}
getch();
}

Exemplul 4.4. Programul determin caracterul de cod maxim ntr-un ir de caractere.


#include<conio.h>
#include<string.h>
#include<stdio.h>
void main()
{
char *s=programare C++,i=-1,x;
clrscr();
x=*s;
for (;++i<strlen(s);)
if (x<*(s+i)) x=*(s+i);
puts(Caracterul de cod maxim n irul);
printf(%s\neste %c,s,x) ;
getch();
}

Exemplul 4.5. Programul ordoneaz cresctor un ir de caractere.


#include<conio.h>
#include<stdio.h>
void main()
{
char x[]=UNIVERSITATEA DE STAT A MOLDOVEI;
int n=strlen(x),i,j,aux;
clrscr();
puts(irul iniial:);
puts(x);
for (i=0; i<n-1; i++)
for (j=i+1; j<n; j++)
if (x[i]>x[j] )
{ aux=x[i]; x[i]=x[j]; x[j]=aux;
puts(\nirul ordonat cresctor:);
puts(s);
getch();
}

Exemplul 4.6. Programul formeaz din vectorul x de numere ntregi un vector y de numere
ntregi, n care y[i] s fie restul mpririi lui x[i] la suma cifrelor lui.
#include<conio.h>
#include<stdio.h>
void main()
{
unsigned x[]={123,17,439,5146,5667}, i=0,y[5],s;
clrscr();
puts(irul numeric iniial este:);
while ( i<5)
printf(%u\t, *(x+i++));
for (i=0; i<5; i++)
{
s=0;
while (x[i]>0)

23

{ s+=x[i]%10; x[i]=x[i]/10; }
*(y+i)=s;
}
puts(irul numeric format:);
i=0;
while (i<5) printf(%u\t, *(y+i++)) ;
}
getch();
}

Exemplul 4.7. Programul afieaz doar simbolurile cuprinse ntre simbolurile ( i ). Se


presupune c nu exist mai multe paranteze.
#include<conio.h>
#include<stdio.h>
void main()
{
char *s=abcd(1,2,3,4,5)xzy;
int k, *p, *q;
clrscr();
puts(irul iniial:);
puts(s);
p=strchr(s,();
q=strchr(s,));
k=p-s;
j=q-s;
for (i=k+1; i<j; i++)
printf(%c,*(s+i));
getch();
}

Exemplul 4.8. Programul afieaz doar simbolurile cuprinse ntre simbolurile ( i ). Se


presupune c nu exist mai multe paranteze. (Alt variant)
#include<conio.h>
#include<stdio.h>
void main()
{
char *s=abcd(1,2,3,4,5)xzy;
int k, *p, *q;
clrscr();
puts(irul iniial:);
puts(s);
for (i=0; *(s+i++);)
{
if ( *(s+i)!=( ) continue;
while ( *(s+ ++i)!=) )
printf(%c,*(s+i));
}
getch();
}

Exemplul 4.9. Programul determin i afieaz elementul maxim pe liniile unui tablou
bidimensional. Sunt demonstrate diferite moduri de adresare la elementele tabloului.
#include<conio.h>
#include<stdio.h>
void main()
{
unsigned v[5][5],i,j,max,n,m;
puts(Introdu numrul de linii i de coloane:);
scanf(%i%i,&n,&m);
for (i=0;i<n;i++)
for (j=0;j<m;j++)
//accesul ctre elementele tabloului prin numele lui
scanf(%i, *v+i*m+j);
for (i=0;i<n;i++)
{ //accesul ctre elementele tabloului prin indicatorii v[0], v[1],
max=*(v[i]+j); for (j=0;j<m;j++)
if ( max<v[i][j] ) max=v[i][j]; //acces la elemente tabloului prin indici

24

printf(Elementul maxim pe linia %i este %i\n,i+1,max);


}
for (i=0; i<n*m;i++)
printf(%i\t,*(*v+i));
// accesul ctre elementele tabloului prin v indicator la indicatorul v[0]

}
Probleme propuse spre rezolvare:
1. Programul determin cel mai mic numr dintre elementele de indice par ale unui ir numeric.
2. Programul transcrie toate elementele nule ale unui ir numeric la nceputul tabelului, la sfrit
transcrie toate elementele ne nule, pstrnd ordinea lor.
3. Programul deplaseaz elementele unui ir numeric a[10] astfel nct a[i] s se deplaseze n a[i1], iar a[0] n a[9].
4. Programul deplaseaz spre stnga un tablou a[10] cu k poziii. Ultimele k poziii se
completeaz cu 0.
5. Programul arunc din textul dat toate cuvintele de lungime mai mare ca 6 simboluri. Se va
afia textul iniial i cel redactat.
6. Programul afieaz din irul S l simboluri ncepnd cu poziia k .
7. Programul realizeaz n tabloul a[10] cu numere sortate introducerea unui numr k astfel nct
tabloul s rmn sortat.
8. Programul realizeaz inversarea elementelor matricei ptrate de ordin n n raport cu diagonala
secundar.
11. S se bordeze o matrice A (avnd m linii i n coloane) cu linia m+1 i coloana n+1, unde
A[m+1][j] s fie suma elementelor de pe coloana j (cu j de la 1 la n), iar A[i][n+1] s fie suma
elementelor de pe linia i (cu i de la 1 la m).
12. Programul nmulete un vector din n elemente cu o matrice numeric de dimensiunea m n.
ntrebri de control:
1. Ce este un pointer ?
2. Ct memorie se aloc unei variabile de tip pointer ?
3. Cum se extrage valoarea unui pointer la ecran ? dar valoarea de pe adresa pstrat n variabila
de tip pointer ?
4. Fie int *p, *q, a=1, b=0; p=&a ; q=&b; if (*p<*q) *q=*p; else q=p; Ce va afia
printf( %i

%i

%i

%i, a,b,*p,*q); ?

5. Care dintre expresiile urmtoare este eronat, tiind c variabilele p, q i a sunt declarate:
int a, *p, **q;
a) a=*q=*p

b) p=&(**q)

c) *q=&a

d) *p*=*(*q)+a ?

6. Care este numrul de bii necesari pentru memorarea tabloului declarat int a[20]; ?
7. Dac vectorul a este declarat char a[20]; atunci elementul al treilea este:
a) a[3]

b) *a[3]

c) *(a+2)

d) *(a+3) ?

8. Dac vectorul a este declarat char a[20]; atunci elementul al treilea este:
a) a[3]

b) *a[3]

c) *(a+2)

d) *(a+3) ?

9. Ce este un pointer nul, ce reprezint constanta NULL i unde este definit ?


10. Fie char a=a, *pa; int x=10, *px; float y=2.8, *py; double z=12345.54321,

13.
14.

*pz; long double w=123456789.987654321, *pw ; pa=&a ; px=&x ; py=&y ;


pz=&z ; pw=&w ; Ce va afia printf(%c\t%d\t%f\t%lf\t%Lf\n, *pa, *px,
*py, *pz, *pw) ; ?
Fie int x=2000, *p=&x, **q=&p, ***w=&q ; Ce va afia printf(%d %d %d
%d, x, *p, **q, ***w) ; ?
Fie int s[20]= {0,1,2,3,4,5}, *pi=s ; Ce va afia printf(%d %d %d %d %d
%d, *pi, *++pi, *++pi, *++pi, *++pi, *++pi) ; ?

25

Lucrare de laborator N5
Tema: Prelucrarea irurilor de caractere.
Scopul lucrrii: Utilizarea funciilor standarde de prelucrare a irurilor de caractere i
operaii cu iruri.
Suport teoretic:
Cele mai des ntlnite utilizri ale tablourilor unidimensionale n limbajul C sunt irurile de
caractere, deoarece n C nu este prevzut tipul de date ir de caractere. Pentru memorarea
irurilor se utilizeaz tablouri cu tipul de baz char, care au pe ultima poziie caracterul \0.
Pe lng necesitatea de a defini un ir de caractere ca i tablou de caractere, n prelucrarea
irurilor se utilizeaz deseori tipul pointer la caracter.
De exemplu:
char sir[20]; // tablou de 20 de caractere
char *psir;
// pointer la caractere.
Astfel, sir este o variabila de tipul tablou de caractere pentru care se rezerv un spaiu de
memorie de 20 de octei, n timp ce psir este un pointer la caracter care poate primi ca valoare
adresa unui caracter (n particular, adresa primului element dintr-un ir de caractere). Trebuie
reinut c ori de cte ori se lucreaz cu variabile iruri de caractere ntr-un program, trebuie s
existe fie o definiie de forma celei prezentate pentru variabila sir, prin care se rezerv static (n
timpul compilrii), spaiul de memorie necesar variabilei, fie s se aloce dinamic memoria
necesar.
Funciile pentru prelucrarea irurilor sunt declarate n fiierul antet string.h. Ele primesc
adresele irurilor prelucrate, prin intermediul parametrilor de tipul pointer la caracter.
Denumirea funciilor de prelucrare a irurilor declarate n fiierul stdio.h
funcia
char * gets(char* s)

explicaie
Citete caracterele din intrarea standard pn la ntlnirea
caracterului Enter, care nu se adaug la irul s; plaseaz '\0' la
sfritul lui s; returneaz adresa primului caracter din ir.
int puts(char* s)
Tiprete irul s, trece apoi la rnd nou.
printf("%s",s1)
Tiprete irul s1.
Denumirea funciilor de prelucrare a irurilor declarate n fiierul string.h
funcia
explicaie
int strncmp(char* s1, char* s2, int n) Compar irurile s1 i s2 spre care pointeaz pointerii s1,
s2. Funcia returneaz 1 dac s1>s2, valoarea -1 dac
s1<s2, i valoarea 0 dac s1=s2. Dar se compar irurile
pentru cel mult n caractere.
char *strcpy(char* s1, char* s2)
Copie irul surs s2 n irul destinaie s1 i returneaz
adresa irului destinaie.
char* strcat(char* s1, char* s2)
Concatenarea irurilor i afiarea irului rezultat.
char* strchr(char s, char c)
Poziia primei apariii a caracterului c n irul s, respectiv
NULL dac c nu este n s.
strcspn(char* s1, char* s2)
Afieaz prima apariie a caracterului care coincide n
ambele iruri.
char *strncpy(char* s1, char* s2, int Copie maxim n caractere de la irul surs s2 n irul
n)
destinaie s1 i returneaz adresa irului destinaie.
26

char *strtok(char *s1, const char *s2); Desparte irul s1 de irul s2.
int strlen(char* s1)
Returneaz lungimea irului fr a numra caracterul de
sfrit \0.
strlwr(char* s1)
Convertete irul din litere mari (A la Z) n litere mici (a
la z).
strset(char* s1, char* s2)
Caut prima intrare a irului s2 n irul s1.
strrev(char* s)
Inverseaz irul.
strrchr(char* s, int c)
Verific ultima intrare a simbolului c n irul s.
Returneaz pointerul spre ultimul simbol ce coincide cu c
a irului s. Dac nu-l gsete returneaz NULL.
char*strpbrk(const char*s, const Cut n irul s orice simbol din irul s1 i afieaz pe
char*s1)
acel care mai naite se ntlnete n irul s.
strrupr(s)
Convertete irul din litere mici n litere mari .
isalpha(s)
Verific dac s este liter.
isdigit(c)
Verific dac c cifr.
islower(s)
Verific dac s este liter de la a la z.
isspace(c)
Verific dac c este spaiu.z
int atoi(const char* s)
Convertete irul s ntr-o valoare ntreag.
int atol(const char* s)
Convertete irul s ntr-o valoare ntreag lung.
itoa(int n, char* s, int )
Convertete un ntreg n char.
Double atof(char* s)
Convertete sirul s ntr-o valoare real
char*gcvt(double v,int n, char*buf)
Convertete datele de tip double ntr-un ir de simboluri,
inclusiv simbol cu virgul mobil. Mai des se folosete la
convertirea numerelor introduse ca ir de simboluri, i
efectuarea anumitor operaii asupra lor.
Exemple de programe:
Exemplul 5.1. Este dat irul s. S se tipreasc cte litere de a se ntlnesc in ultimul
cuvnt din ir (de ex. Ana frate ada; rezulat: 2).
#include<stdio.h>
#include<conio.h>
#include<string.h>
void main()
{
char s[256];
int i,j=0;
clrscr();
gets(s);
for(i=strlen(s)-1; s[i]!=' '; i--)
//parcurgem irul de la sfrit
if(s[i]=='a') j++;
//dac gsim litera a, contorul j va crete
printf(" Litere de a n ultimul cuvnt sunt: %d",j);
getch();
}

Exemplul 5.2. Fiecare caracter se nlocuiete cu urmtorul caracter(de ex. abc se tiprete
bcd) pn la apsarea tastei cifrei 9.
#include<stdio.h>
#include<conio.h>
#include<string.h>
void main()
{
char g,c;
int i,j,x,k;
g=0;
clrscr();
while(!g)

27

{
c=getchar();
// ct g=0, se citesc cu ecou caractere, pn c!=9
if ( c == '9' )
{g = 1; continue;} // dac c=9, atunci g=1 i se trece la urmtorul pas
putchar (c+1);
// tiprete urmtorul caracter
}
getch();
}

Exemplul 5.3. Este dat irul d. Se concateneaz irurile i se copie un ir n alt ir.
#include <string.h>
#include <stdio.h>
#include <conio.h>
void main(void)
{
char d[25];
char *blank = " ", *c = "C++", *t = "Turbo";
clrscr();
gets(d);
strcat(d, blank); // la concatenare se pstreaz textul din ambele iruri
strcpy(d, t);
// irul t se copie n d, i textul din irul d se terge
strcat(d, c);
//se concateneaz
printf("%s\n", d); // se va afia: TurboC++
getch();
}

Exemplul 5.4. Este dat irul s. S se numere cte cuvinte are irul.
#include<stdio.h>
#include<conio.h>
#include<string.h>
void main()
{
char s[20];
int i,k;
k=1;
clrscr();
printf("sir:\n");
gets(s);
for(i=1;i<strlen(s);i++) //irul e parcurs din poziia 1 pn la sf.irului
{
if((s[i-1]==' ')&&s[i]!=' ') // verificm dac este cuvnt
k++;
//contor ce numr cuvintele
}
printf(" %d",k);
getch();
}

Exemplul 5.5. Este dat irul s. De desprit fiecare propoziie din rnd nou. Propoziia se
termin cu punct.
#include<stdio.h>
#include<conio.h>
#include<string.h>
void main()
{
char s[256],*t;
clrscr();
printf("sir:\n");
gets(s);
t=strtok(s,".");
while(t!=NULL)
{
printf("%s\n",t);
t=strtok(NULL,".");
}
getch();
}

// atribuim lui t irul s pn la punct


//att timp ct n t sunt propoziii
//tiprim din rand nou

28

Exemplul 5.6. Este dat un cuvnt s de maxim 20 caractere. S se verifice dac cuvntul
introdus este polidrom (care se citete i de la stnga i de la dreapta la fel; de exemplu cojoc).
#include<stdio.h>
#include<conio.h>
#include<string.h>
#include<stdlib.h>
void main()
{
char s[20];
int i,k,l,h=1;
clrscr();
printf("sir\n");
gets(s);
k=strlen(s);
l=k/2;
for(i=0;i<l;i++)
{ if(h)
if(s[i]==s[k-i-1]) h=1; else {printf("nu\n"); getch(); exit(0);}
}
printf("polidrom=%s",s);
getch();
}

Exemplul 5.7. Este dat irul s. S se tipreasc cuvintele ce au lungimea mai mare dect 6
caractere.
#include<stdio.h>
#include<conio.h>
#include<string.h>
void main()
{
char s[256];
int i,j,x;
j=0;x=0;
clrscr();
printf("sir\n");
gets(s);
for(i=0;i<strlen(s);i++) {
j++;
if(s[i]==' ')
{
if(j>6)
for(k=x;k<i;k++) s[k]=' ';
j=0;x=1;
}}
printf("=%s",s);
getch();
}

Exemplul 5.8. Este dat irul s. De tiprit irul astfel nct, unde sunt mai mult de un spaiu
de considerat numai unul (De exemplu: azi plou, rezultat: azi plou).
#include<stdio.h>
#include<conio.h>
#include<string.h>
void main()
{
char s[256];
int i,j;
clrscr();
printf("sir\n");
gets(s);
for(i=0,j=0;i<strlen(s);i++)

if((s[i]!=' ')||(s[i]==' ')&&(s[i+1]!=' '))

//se verific dac s[i] nu-i spaiu sau s[i] este spaiu i urmtoarea poziie nu-i
//spaiu, atunci n irul s[j], unde j crete la fiecare simbol, se nscrie s[i]

s[j++]=s[i];
s[j]='\0';

//ultimul caracter zero

29

puts(s);
getch();

//tiprim irul

Exemplul 5.9. S se tipreasc poziia caracterului ce se afl n ambele iruri.


#include<conio.h>
#include<stdio.h>
#include<string.h>
void main()
{
char s[256];
int i,l;
clrscr();
printf(irul:);
gets(s);
for(l=0;l<strlen(s);l++)
i=strcspn(s,"nmn");
printf("%d\t",i);
getch();
}

// de exemplu: abcdmh
// atribuie poziia primului caracter din irul s
//i=4 deoarece m se afl pe poziia 4

Exemplul 5.10. Este dat irul s i subirul cutat. S se caute un subir n irul s.
#include<conio.h>
#include<stdio.h>
#include<string.h>
void main()
{
char s[256],s1[256],*p;
int i;
clrscr();
printf("dati irul s:");
gets(s);
printf("dati subirul cutat:");
gets(s1);
for(int l=0; l<strlen(s); l++)
p=strstr(s,s1);
printf("Subirul cutat: %s\t",p);
getch();
}

//de exemplu: ada ion mihai


//ion

//ion

Exemplul 5.11. Este dat irul s. S se tipreasc la ecran:


irul pn la dou puncte;
irul dup dou puncte.
#include<conio.h>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
void main()
{
char s[256],*p;
int i,j; i=j=0;
clrscr();
printf("dati irul:");
gets(s);
// de exemplu: asfsd:fdfh:hjkl;
p=s;
printf("\nirul pna la dou puncte:");
while(p[i]!=':'){
putchar(p[i]); i++; }
// afiarea irului (asfsd)
i++; j++;
printf("\nsirul dupa doua puncte:\n");
for(i; i<=strlen(p); i++)
putchar(p[i]);
// fdfh:hjkl;
getch();
}

30

Exemplul 5.12. Este dat irul s. S se gseasc cuvintele ce conin litera s.


#include <string.h>
#include <stdio.h>
#include <conio.h>
void main(void)
{
char s[256];
char *ptr, c='s';
clrscr();
printf("dai irul:\n");
gets(s);
ptr = strchr(s,c);
if (ptr) printf("caracterul %c se afl pe poziia: %s\n", c, ptr);
else printf("nu este aa caracter\n");
getch();
}

Exemplul 5.13. Este dat irul s. S se afieze lungimea celui mai scurt cuvnt i numrul
de cuvinte.
#include<stdio.h>
#include<string.h>
#include<conio.h>
void main()
{
char s[256],*t,*p;
int k,min;
k=0;
clrscr();
printf("dati sirul:");
gets(s);
t=s;
t=strtok(s," ");
// lui t se atribuie cuvintele (desprite prin spaiu)
min=strlen(t);
// notm prin min lungimea irului t
while(t!=NULL)
// verificm att timp ct avem cuvinte
{
printf("%s\n",t); //tiprim fiecare cuvnt din rand nou
if(min>strlen(t)) //dac se gsete un cuvnt cu lungimea mai mic ca min
min=strlen(t); //atunci min primete lungimea acelui cuvnt
t=strtok(NULL," ");
k++;
//contorizeaz numrul de cuvinte
}
printf("\nnr de cuvinte:%d\nlungimea celui mai scurt cuvant:%d",k,min);
getch();
}

Exemplul 5.14. Folosind funcia gcvt(), s se efectueze unele operaii pentru convertirea
irului.
#include<stdio.h>
#include<string.h>
#include<conio.h>
#include<stdlib.h>
void main()
{
char s[256];
double n;
int k=4; n=2.897;
gcvt(n, k. s);
printf(%s ,s);
// 2.897
// numr negativ
n=-982.897;
gcvt(n, k. s);
printf(%s ,s);
// -982.8
// numr n format tiinific
n=0.897e3;
gcvt(n, k. s);

31

printf(%s ,s);

// 8970

Probleme propuse spre rezolvare:


1. Se citete un ir. S se numere cuvintele care ncep cu litera b.
2. S se afieze toate poziiile unui caracter intr-un ir dat. Caracterul se introduce de la
tastatur(de exemplu: adelina; a are poziia 0 i 6).
3. Se citete un ir de caractere care nu conine caractere albe. S se decid dac irul este
alctuit exclusiv din caractere numerice.
4. S se determine numrul de litere mari i mici dintr-un text dat.
5. Se citete un ir ce conine i dou puncte. S se afieze textul cuprins ntre dou puncte ( Ex:
ada:hjk:vbnv, irul rezultat: hjk).
6. Se citete un ir. S se tipreasc la ecran cuvntul cu lungimea mai mic.
7. Se citete un ir. S se tipreasc la ecran caracterul de cod maxim i simbolurile cu codurile
cuprinse ntre [100, 235].
8. Se citete un ir. S se tipreasc la ecran irul dintre paranteze (Ex: asdf (ghdfhg ) fdhj,6g ghdfhg).
9. Se d o list de cuvinte separate prin spaiu, lista se ncheie prin dou rnduri goale succesive
(dou enter-uri). S se tipreasc n ordine alfabetic toate polindroamele care apar n list. Un
polindrom este un cuvnt care este identic citit att de la nceput spre sfrit ct i de la sfrit
spre nceput (Ex: cazac, elevele, cojoc).
10. Se citete un text. Textul conine cuvinte separate printr-un spaiu. Dac textul conine *,
atunci fiecare simbol / ce precede * s fie nlocuit cu ,.
11. Se citete un text. Textul conine cuvinte separate printr-un spaiu. S se scrie, pe linii
separate, fiecare cuvnt care apare n text urmat de un numr care va reprezenta de cte ori apare
cuvntul n text. S se determine cuvntul care apare de cele mai multe ori.
12. Se citete un text. Textul conine cuvinte separate printr-un spaiu. Se va genera un nou text
care va conine cuvintele ordonate alfabetic.
13. Se citete un text. Textul conine cuvinte separate printr-un spaiu. S se determine numrul
de apariii al fiecrui caracter. Informaia referitoare la un caracter se va afia o singur dat.
14. Se citete un text. Textul conine cuvinte separate printr-un spaiu. Se va genera un nou text
care va conine cuvintele n ordine invers (asdf - fdsa).
15. S se sorteze alfabetic un ir de cuvinte (eventual, s se disting literele mici de cele mari).
16. Se d un text de maxim 30 de caractere. S se listeze toate cuvintele de dou caractere din
acest text.
17. Se dau dou texte. S se stabileasc o vocal comun celor dou texte, care apare de cele mai
puine ori.
18. Fie un ir de forma: cifr-liter, cifr liter etc.(Ex : 2a4b5c). S se genereze un astfel de
ir: aabbbbccccc.
19. Se citete un ir de caractere alfanumerice. Considerm c literele sunt separatorii numerelor.
Afiai datele de tip numeric preluate n ordine din irul citit. Numerele vor fi scrise cte unul pe
o linie.
Ex.
in.txt
out.txt
a23sc345ss5e
23
345
5
20. Se citete un text de la tastatur astfel nct cuvintele s fie separate printr-un singur spaiu i
imediat dup ultimul cuvnt se scrie punct. Textul va fi scris pe un singur rnd:
a. S se determine dac textul are cuvinte distincte (se ignora diferena de cheie).
b. S se tipreasc cuvintele cu lungimea mai mare ca 6.
c. S se determine dac textul conine cifre
32

21. Este dat un ir de caractere (lungimea irului este <=100). De codificat acest ir n urmtorul
mod: caracterele se plaseaz ntr-un ptrat de dimensiune minim pe spiral, ncepnd cu colul
din dreapta jos n direcia acelor de ceasornic. Spaiul se codific prin *.
Intrare: de la tastatur se va introduce irul de caractere.
Ieire: se va afia la ecran dimensiunea aleas a ptratului i textului codificat.
Exemplu: Bun dimineaa, Chiinu!
Ieire: 5 ineatminaai!u,dihC**anuB
i n e a t
m i n a a
i ! u ,
d i h C *
* a n u B
22. Se consider dou iruri: a=a1an i b=b1bm formate din n i respectiv m litere. Asupra
irului a se pot face urtoarele operaii.
tergere: S(i) terge litera de pe poziia i. Inserare: I(j,c) insereaz litera c pe poziia j.
Modificare:M(i,c) nlocuiete litera de pe poziia i cu c. S se transforme irul a n irul b
cu numr minim de astfel de operaii. Exemplu: a= DANIELA, b=IOANA. Numrul minim
de operaii este 5 i anume: M(1,1); I(2,O); S(5); S(6); S(5). Intrare: a i b se citesc de la
tastatur. Restricii: m>0, n<80.
ntrebri de control:
1. Ce returneaz funciile: strlen(ASEM), strlen(asem0), strlen(ASEM\N), strlen
(0), strlen()?
2. Care va fi rezultatul returnat de funciile: strcat(Limbajul C, ++),
strncat(Cibernetica, ,Informatica Aplicat, Management, Matematica, 21)?
3. Ce afieaz puts(strstr(Informatica Aplicat,scop));? Explicai.
4. Ce returneaz funciile: strcmp(asem,ASEM), stricmp(ASEM, asem),
strncmp(Limbajul C, Limbajul C++, 10), strnicmp(INFORMATICA,
informatica,1)?
5. Fie char *s=Costel, Vicu i Andrei merg la teatru, *q=Vicu; puts(strstr(s,q));
Cine merge la teatru? Explicai.
6. #define L 15
char sir[L];
strcpy(sir,"123\0456");
printf("irul copiat este:/%s/ i are lungimea:%d\n",sir, strlen(sir));

Ce se tiprete pe ecran?.
7.

char s[]=70000;
int i=atoi(s);
long l=ato1(s);
printf(%d\t%ld,i,l); Explicai. Ce se tiprete la ecran?.
8. char s[]=asdfghjert;
int i;
i=strcspn(s,fnm); Ce se tiprete la ecran, ce valoare primete
9. char s1[]=asdfghjert;
char s2[]=esa; char *p;
p=strpbrk(s1,s2);
printf((%s, p); Explicai. Ce se tiprete la ecran?.
10. char s1[]=asdfghjert;
char *p;
p=strrchr(s1,j);
printf((%s, p); Explicai. Ce se tiprete la ecran?.

variabila i?.

33

Lucrare de laborator N6
Tema: Lucrul cu tablourile unidimensionale.
Scopul lucrrii: obinerea deprinderilor practice la utilizarea tablourilor unidimensionale
i operaiile de prelucrare a lor.
Suport teoretic:
Definiie: Masivele sunt structuri de date omogene cu un numr finit i cunoscut de
elemente, ce ocup un spaiu contiguu de memorie.
Un masiv este caracterizat de urmtoarele elemente:
numele;
tipul de date asociat;
numrul de dimensiuni;
numrul de elemente pentru fiecare dimensiune.
Definiie: Vectorii sunt masive unidimensionale. In C++ vectorii se declar folosind
sintaxa: tip nume[n] unde:
tip tipul de date folosit; poate fi unul din tipurile de baz (int, float, char, ) sau un tip
definit de utilizator (articole, obiecte)
nume numele prin care va fi referit vectorul
n numrul de elemente ale vectorului
Exemple de declaratii:
// vector de 100 valori ntregi
int vanzari[100];
// vector de 15 valori reale
float temperaturi[15];

Memorarea vectorilor se face ntr-un spaiu contiguu de memorie. Numele vectorului este
de fapt un pointer ctre adresa primului element. Pentru o declaraie de forma int v[5];
reprezentarea n memoria intern este:
v

v[0]

v[1]

v[2]

v[3]

v[4]

Dimensiunea total a vectorului este calculat ca produs ntre numrul de elemente i


dimensiunea unui element.
Iniializarea vectorului se poate face la declarare printr-o construcie de forma:
tip nume[]={lista_valori}.
Se observ c n acest caz nu este necesar precizarea numrului de elemente. Acesta va fi
dedus automat de compilator din dimensiunea listei cu care se face initializarea. In cazul in care
numrul de elemente precizat este mai mare dect numrul de elemente din list se va realiza o
initializare partiala a vectorului.
Exemple de initializri la declarare:
// iniializare fr precizarea explicit a numrului maxim de elemente
int v1[] = {1, 2, 3, 4, 5};
// iniializare complet cu precizarea numrului maxim de elemente
int v2[3] = {17, 19, 23};

34

// iniializare parial
int v3[5] = {7, 6, 5};

Accesul la elementele vectorului se face direct; compilatorul calculeaz adresa elementului


pe baza indexului i a dimensiunii unui element. Numerotarea elementelor se face incepnd cu
zero. Pentru un vector v cu n elemente referirea elementelor se face folosind v[0], v[1], v[2], ,
v[n-1].
Operaii de baz:
Citirea de la tastatur ;

printf("dai nr de elemente:");
scanf("%d",&nrelem);
for (i = 0; i < nrelem; i++)
{
printf("vector[%d]=",i);
scanf("%d",&vector[i]);
}

Afiarea pe monitor;

for (i = 0; i < nrelem; i++)


printf("%3d",vector[i]);

Cutarea elementului dup valoare ;

// parcurgem vectorul
for (i = 0; i < nrelem; i++)
if (vector[i] == valoare)
{ f=1;// notm c am gsit valoarea cutat
printf("elementul cautat %d e pe pozitia: d:",vector[i],i);
}
// element negsit
if (f==0) printf("elementul cautat nu este in vector: ");

Inserarea elementului;

// se presupune c dimensiunea maxim a vectorului


// este cel putin egala cu nrElemente + 1
int pozitia;
printf("dati pozita pe care vreti sa inserati:");
scanf("%d",&pozitia);
printf("dati valoarea pentru inserare:");
scanf("%d",&valoare);
for (i = 0; i < nrelem; i++)
if (pozitia == nrelem)
// inserare la sfarsitul vectorului
vector[nrelem] = valoare;
else
// inserare n interiorul vectorului
{
// se deplaseaz la dreapta a elementele aflate dup poziia de inserare
for (int i = nrelem; i > pozitia; i--)
vector[i] = vector[i-1];
// i se insereaz elementul
vector[pozitia] = valoare;
}
printf("Dupa inserare:\n");
for (i = 0; i < nrelem+1; i++)
printf("%3d",vector[i]);

tergerea elementului;

// deplasm la stanga elementele aflate dup poziia de stergere


printf("dati pozita pe care vreti s o stergei:");
scanf("%d",&pozitia);
for (i = pozitia; i < nrelem; i++)
vector[i] = vector[i+1];
printf("Dupa stergere:\n");
for (i = 0; i < nrelem; i++)
printf("%3d",vector[i]);

35

Exemple de programe:
Exemplul 6.1. Dat un tablou de 10 elemente. Programul determin suma elementelor de pe
poziiile pare.
#include<stdio.h>
#include<conio.h>
void main()
{
int a[10], i, s;
s=0;
printf(Introducem elementele vectorului:\n);
for(i=0; i<10; i++){
printf(a[%d]=, i);
scanf(%d, &a[i]);
}
for(i=0; i<10; i++)
if(i%2==0) s=s+a[i]; // se verific dac poziia elementului este par
printf(\nSuma elementelor de pe poziiile pare este=%d, s);
}

Exemplul 6.2. Se d un tablou de n elemente, toate elementele sunt diferite. S se afieze


pe primele locuri elementele egale cu zero, apoi restul elementelor pstrnd ordinea lor( Ex.: 1 2
0 4 0 0 0 1 2 4 ).
#include<stdio.h>
#include<conio.h>
void main()
{
int a[100], n, i, j, x[100];
clrscr();
printf("\ndimensiunea vectorului:");
scanf("%d",&n);
for(i=0; i<n; i++)
{
printf("a[%d]=", i);
scanf("%d", &a[i]);
}
j=0;
for(i=0; i<n; i++)
if(a[i]==0) { j++; x[j-1]=a[i]; }
// se verific dac elementul este zero, atunci j crete i nscriem n x
for(i=0; i<n; i++)
if(a[i]!=0) { j++; x[j-1]=a[i]; }
printf("vectorul final\n");
for(i=0; i<n; i++)
printf("%d%c", x[i],';');
getch();
}

Exemplul 6.3. Se d un tablou de n elemente. S se deplasare la stnga cu x poziii i


pozitiile eliberate se nlocuiesc cu zero ( Ex.: 1 2 3 4 5 6; x=2; 3 4 5 6 0 0 ).
#include<stdio.h>
#include<conio.h>
void main()
{
int a[100], n, i, j, x;
clrscr();
printf("\ndimensiunea vectorului:");
scanf("%d", &n);
printf("\nnumrul de poziii de deplasare:");
scanf("%d", &x);
printf("\nIntrodu elementele:\n");
for(i=0; i<n; i++)
{

36

printf("a[%d]=", i);
scanf("%d", &a[i]);
}
for(i=0; i<x; i++)
{
for(j=0; j<n; j++) a[j]=a[j+1];
// se face deplasarea la stnga
a[j-1]=0;
// i nscrierea lui zero pe poziiile eliberate
}
printf("vectorul final\n");
for(i=0; i<n; i++)
printf("%3d", a[i]);
getch();
}

Exemplul 6.4. Se d un tablou de n elemente. S se gseasc elementul maxim din acest


tablou.
#include<stdio.h>
#include<conio.h>
void main()
{
int a[100], n, i, j, max;
clrscr();
printf("\ndimensiunea vectorului:");
scanf("%d", &n);
printf("\nIntrodu elementele:\n");
for(i=0; i<n; i++)
{
printf("a[%d]=", i);
scanf("%d", &a[i]);
}
max=a[0];
//iniial elementul maxim este elementul de pe poziia zero
for(i=0; i<n; i++)
if (a[i]>max) max=a[i];
// gsim elementul maxim
printf("%3d", max);
getch();
}

Exemplul 6.5. Sunt dai doi vectori de aceeai dimensiune a i b. S se gseasc:


poziiile pentru care elementele din vectorul a sunt mai mari ca elementele din vectorul
b;
poziiile pentru care elementele din vectorul a sunt egale cu elementele din vectorul b

#include<stdio.h>
#include<conio.h>
#include<alloc.h>
void main()
{
int k,*a, n, i, j,*b, l;
clrscr();
printf("\ndimensiunea vectorului:");
scanf("%d", &n);
/* se aloc memorie pentru vectorul a: dimensiunea vectorului se nmulete
cu dimensiunea tipului int(2 octei) */
a=(int*)malloc(n*sizeof(int));
b=(int*)malloc(n*sizeof(int)); // se aloc memorie pentru vectorul b
printf("elementele vectorului a:\n");
for(i=0; i<n; i++)
{
printf("a[%d]=", i);
scanf("%d", a+i);
}
printf("elementele vectorului b:\n");
for(i=0; i<n; i++)
{
printf("\nb[%d]=", i);

37

scanf("%d", b+i);
}
printf("a:");
for(i=0; i<n; i++)
printf("%3d", a[i]);
printf("\nb:");
for(i=0; i<n; i++)
printf("%3d", b[i]);
k=0;
printf("\npoziiile pentru care elementele din vectorul a sunt mai mari ca
din b\n");
for(i=0; i<n; i++)
/* dac mcar un element din a este mai mare ca un element din b, atunci k
pstreaz poziia elementului mai mare */
if(*(a+i)>*(b+i)) { k=i;
printf("%3d", k);
}
l=0;
printf("\npoziiile elementele corespunztoare primului vector egale cu
elementele din al doilea vector\n");
for(i=0; i<n; i++)
if(*(a+i) ==*(b+i)) { l=i;
// dac elemental sunt egale, atunci l pstreaz poziia elementelor egale
printf("%3d", l);
}
free(a); // se elibereaz memoria alocat vectorului a
free(b); // se elibereaz memoria alocat vectorului b
getch();
}

Exemplul 6.6. Se d un tablou de n elemente. S se gseasc cel mai mic element pozitiv
#include<stdio.h>
#include<conio.h>
#include<alloc.h>
void main()
{
int k,*a, n, i, min;
clrscr();
printf("\ndimen vec:");
scanf("%d", &n);
a=(int*)malloc(n*sizeof(int));
printf("elementele vectorului a:\n");
for(i=0; i<n; i++)
{
printf("a[%d]=", i);
scanf("%d", a+i);
}
printf("a:");
for(i=0; i<n; i++)
printf("%3d", a[i]);
min=a[0]; k=0;
printf("\n");
for(i=0; i<n; i++)
if((*(a+i)<0)&&*(a+i)<min)
{ min=*(a+i); k=i;}
printf("pozitia elementului negativ %d are minimul %d", k, min);
free(a);
getch();
}

Exemplul 6.7. Se d un tablou de n elemente. S se sorteze descresctor folosind metoda bulelor


(adic se compar primul cu al doilea, 2 cu 3,etc. Ex: 6 2 4 3 1 5;
prima parcugere: 2 4 3 1 5 6;
a doua parcurgere: 2 3 1 4 5 6;
38

a treia parcurgere: 2 1 3 4 5 6;
a patra parcurgere: 1 2 3 4 5 6;

#include<stdio.h>
#include<conio.h>
#include<alloc.h> //biblioteca pentru funcia malocc
void main()
{
int k,*a, n, i, aux, j;
clrscr();
printf("\ndimen vec:");
scanf("%d", &n);
a=(int*)malloc(n*sizeof(int));
printf("elementele vectorului a:\n");
for(i=0; i<n; i++)
{
printf("a[%d]=", i);
scanf("%d", a+i);
}
printf("a:");
for(i=0; i<n; i++)
printf("%3d", *(a+i));
printf("\n");
for(i=0; i<n-1; i++) //se parcurge de la 0 pn la n-1
for(j=i+1; j<n; j++) // se parcurge de la i+1 pn la n
{
if(*(a+i) <*(a+j)) //comparm elementele
{
aux=*(a+i); // pstrm elemntul (a[0])
*(a+i)=*(a+j); // se inverseaz (a[0]=a[1])
*(a+j)=aux; // (a[1]= a[0]) i etc.
}
}
printf("vectorul sortate\n");
for(i=0; i<n; i++)
printf("%3d", *(a+i));
free(a);
getch();
}

Exemplul 6.8. Este dat vectorul a de lungimea n. S se mite ciclic la drapta cu x poziii.
#include<stdio.h>
#include<conio.h>
void main()
{
int a[100], n, i, j, x, k;
clrscr();
printf("\ndimen vec:");
scanf("%d", &n);
printf("\nnumarul de pozitii de deplasare:");
scanf("%d", &x);
printf("\nIntrodu numarul de elemente:\n");
for(i=0; i<n; i++)
{
printf("a[%d]=", i);
scanf("%d", &a[i]);
}
for(i=0; i<x; i++)
{
k=a[n-1];
for(j=n-1;j>=0;j--)
a[j]=a[j-1];
a[0]=k;
}
printf("irul final\n");

39

for(i=0; i<n; i++)


printf("%3d", a[i]);
getch();
}

Exemplul 6.9. Este dat vectorul a de lungimea n. S se schimbe cu locurile elementul maximal
cu cel minimal.
#include<stdio.h>
#include<conio.h>
void main()
{
int a[10], n, i, j, max, min, k;
clrscr();
printf("\ndimen vec:");
scanf("%d", &n);
for(i=0; i<n; i++)
{
printf("a[%d]=", i);
scanf("%d", &a[i]);
}
printf("\nsirul initial\n\n");
for(i=0; i<n; i++)
printf("%d ", a[i]);
max=min=a[0];
for(i=0;i<n;i++)
if(a[i]<min) {min=a[i]; k=i;}
for(i=0; i<n; i++)
if(a[i]>max){max=a[i]; j=i;}
a[k]=a[j];
a[j]=min;
printf("\nirul final\n\n");
for(i=0;i<n;i++)
printf("%d ",a[i]);
getch();
}

Probleme propuse spre rezolvare:


1. Se d un tablou de 10 elemente. S se determine suma elementelor pare.
2. Se d un tablou de 10 elemente. S se determine cte elementelor pare i cte impare sunt.
3. Se d un tablou de n elemente. S se determine produsul elementelor divizibile la 3.
4. Se d un tablou de n elemente. S se tipreasc elementele care se repet cel mai des. Dac
sunt mai multe de acelai fel, atunci s se indice unul din ele.
5. Se d un vector din n elemente. S gseasc poziia ultimului element pozitiv.
6. Se d un tablou de 10 elemente nici un element nu este nul. S se determine de cte ori se
schimb semnul
numerelor scrise n tablou (trebuie verificate cte dou, ca s le vedem
semnul mai bine le nmulim).
7. Se d un tablou de 10 elemente ntregi pozitive formate din 2 cifre(10 - 99). S se
determine cte elemente sunt distincte (elementul se numr numai odat).
8. Se d un tablou de 10 elemente. S se determine de cte ori se ntlnete elementul maxim n
tablou.
9. Se d un vector de n elemente. S construiasc un nou vector ce conine acelea elemente
ca tabloul iniial cu condiia c toate elementele negative preced pe cele pozitive.
10. Se d un tablou de n elemente, toate elementele sunt diferite. S se afieze pe primele
locuri elementele diferite de zero, apoi elementele egale cu zero pstrnd ordinea lor (Ex:
1 2 0 4 0 1 2 4 0 0).
11. Se d un tablou de n elemente. S se deplaseze ciclic la stnga cu x poziii (Ex: 1 2 3 4 5 ;
x=3 4 5 1 2 3).
40

12. Se d tablou a de n elemente. S se alctuiasc algoritmul de numrare a elementelor


maxime i minime din tablouul a de n.
13. Se d tablou a de n elemente. S se construiasc un nou vector de lungimea n, pentru care
elementul i este media aritmetic ale primelor i elemente din vectorul iniial.
14. Sunt dai doi vectori de lungimea n cu elementele n ordine descresctoare. S se
construiasc un alt vector de lungimea n+n elemente, n ordine cresctoare i conine
elementele vectorilor iniiali.
15. Se d tabloul a de n elemente. Au fost introduse meciurile cu participarea echipei ZIMBRU.
Elementele tabloului sunt egale cu zero (ZIMBRU a suferit nfrngere), 1 (meciul s-a
terminat la egalitate) cu 2 (nvingtoare). S se stabileasc n cte meciuri echipa a suferit
nfrngere, n cte a ctigat i n cte a fost la egalitate.
16. n tabloul t[31] a fost nscris temperatura zilnic a lunii ianuarie. S se numere n cte zile a
fost nregistrat temperatura sub zero grade i n cte mai sus de zero grade. S se stabileasc
numrul de zile z, n care a fost nregistrat o temperatur mai mic dect temperatura medie
a lunii i numrul de zile z1 n care temperatura a depit mrimea medie.
17. Se d un vector din n elemente. S se determine numrul elementelor pentru care elementele
precedente sunt mai mari.
18. Statu-Palm-Barb-Cot a ngropat patru comori n vrfurile unui dreptunghi, scriindu-i
coordonatele comorilor pe un pergament. n timpul unei lupte cu Ft-Frumos pergamentul s-a
pierdut. Din fericire, Statu-Palm-Barb-Cot a memorat coordonatele a trei puncte n care se
afl comorile. Scriei un program, care va determina coordonatele celei de a patra comori.
Punctele n care au fost ngropate comorile au coordonate ntregi (x1,y1), |x1|<100, |y1|<100.
Coordonatele a trei vrfuri ale dreptunghiului se introduc de la tastatur n ordinea (x1,y1), (
x2,y2), ( x3,y3). Coordonatele celui de a patra vrf se afieaz la ecran n ordinea (x4,y4).
Exemplu: 1 1 5 1 1 7. Rezultat: 5 7.
19. Se dau N(N+1)/2 numere ntregi strict pozitive, mai mici sau egale ca 10000. S se aeze
aceste numere, dac este posibil, ntr-o piramid cu urmtoarele proprieti:
piramida are N nivele, pe fiecare nivel 1 sunt 1 numere;
fiecare numr din piramid, n afar de cele de pe ultimul nivel, este egal cu suma celor dou
numere pe care se sprijin.
Exemplu: 1 1 2 3 3 4 5 8 9 17
Rezultat: 17
8 9
3 5 4
1 2 3 1.
20. Se d tabloul a de n elemente, unde este introdus informaia despre ndeplinirea planului
de producere a strungurilor de ctre 10 uzine de profil ce aparin ministerului respectiv.
Valorile .a[i] (i=0,..,n) au urmtoarea semnificaie:
a[i]>0 numrul de strunguri produs supraplan de ctre uzin cu numrul de ordine
i;
a[i]=0 arat c uzina a produs att ct prevede planul;
a[i]<0 indic cte strunguri nu ajung pentru a ndeplini planul.
S se compun algoritmul de numrare a uzinelor ce au ndeplinit planul sau au depit. S se
stabileasc dac ministerul respectiv a ndeplinit planul, rspunsul da sau nu. S se calculeze
cu ct n-au realizat planul unele uzine (a[i]<0).
ntrebri de control:
1. Ce nseamn tablou. Cum se definete?
2. Poate tabloul(vectorul) include diferite tipuri. Dac da sau nu explicai. Dai exemplu.
3. int i, a[100], k=0;
for(i=0; i<6; i++)
if(a[i]<0) k=k*i; printf(k=%d,k);

Ce se tiprete la ecran? Explicai.


41

4. Ce se tiprete? Explicai.
int i, a[100], k=0;
for(i=0; i<6; i++)
if(a[i]%2==1) k++; printf(k=%d,k);

5. Ct memorie se aloc pentru un vector de lungimea n i de tipul: int, double, char, float. ?
6. Cnd se folosesc funcile free() i malloc(), i ce fac ele? n care fiier se includ ele?
7. Ce se tiprete? Explicai.
int i, a[100], k=1;
for(i=0; i<6; i++)
if(a[i]!=0) k=k*a[i];
else k=0; printf(k=%d,k);

8. Sunt dai doi vectori. Cum se face nscrierea ambilor vectori n al treilea vector? i ce
dimensiune va avea al treilea vector?

42

Lucrare de laborator N7
Tema: Lucrul cu tablourile bidimensionale.
Scopul lucrrii: obinerea deprinderilor practice la utilizarea tablourilor bidimensionale i
operaiile de prelucrare a lor.
Suport teoretic:
Matricele sunt masive unidimensionale. Sintaxa de declarare este: tip nume[m][n] unde:
tip tipul de data folosit; poate fi unul din tipurile de baza (int, float, char, ) sau un tip
definit de utilizator (articole, obiecte);
nume numele prin care va fi referita matricea;
n numarul de linii din matrice;
m numarul de coloane din matrice.
Exemple de declaratii:
// matrice de intregi cu 10 linii si 10 coloane
int vanzari[10][10];
// vector de valori reale
float temperature[3][15];

Memorarea matricelor se face, ca i n cazul vectorilor, ntr-un spaiu continuu de memorie.


Numele matricei un pointer ctre adresa primului element. Elementele matricei sunt stocate n
memorie linie dup linie.
Pentru o declaraie de forma float m[2][3] reprezentarea n memoria interna este:
m

m[0][0] m[0][1] m[0][2] m[1][0] m[1][1] m[1][2]

Dimensiunea total a matricei este calculat ca produs ntre numrul de linii, numrul de
coloane i dimensiunea unui element.
Iniializarea matricei se poate face la declarare printr-o construcie de forma:
tip nume[][n]={{lista_valori1}, {lista_valori2}, , {lista_valorim}}.
Se observ c n acest caz nu este necesar precizarea numrului de elemente asociat
primei dimensiuni. Acesta va fi dedus automat de compilator din dimensiunea listei cu care se
face initializarea. n cazul n care numrul de linii precizat este mai mare dect numrul de
elemente din list se va realiza o iniializare parial a matricei.
Exemple de iniializri la declarare:
// iniializare fr precizarea explicit a numrului de linii
int m1[][2] = {{1, 2}, {3, 4}, {5, 6}};
// iniializare complet cu precizarea numrului de linii i coloane
int m2[2][3] = {{17, 19, 23}, {29, 31, 37}};
// iniializare parial
int m3[2][5] = {{7, 6}, {5}};

Accesul la elementele matricei se face direct; compilatorul calculeaz adresa elementului


pe baza liniei, a coloanei, a numrului de elemente pe linie i a dimensiunii unui element.
Formula folosit este:
43

adr(m[i][j]) = adr(m[0][0]) + (i * nr_max_elemente_linie + j) * dim_element.


Numerotarea liniilor i a coloanelor se face ncepnd cu zero.
Exemple de accesare elemente:
// citeste al doilea element de
int a = m2[1][1];
// modifica primul element
m2[0][0] = 7;

pe a doua linie din matrice

Transmiterea ca parametri se face ca i in cazul vectorilor prin numele masivului. Problema


care apare n cazul matricelor este aceea c numrul de coloane trebuie fixat pentru a permite
calcularea de ctre compilator a adresei elementelor. n cazul n care se dorete lucrul cu matrice
oarecare, transmiterea se va face prin pointeri iar adresa elementelor se va calcula dupa formula
prezentat anterior. n acest caz va trebui trimis ca parametru att dimensiunea maxim a
matricei ct i dimensiunea minim a acesteia.
In practic apar cazuri n care matricele au anumite caracteristici care permit o stocare mai
eficienta dect cea standard. Exemple de asemenea matrice sunt: matricele diagonale, matricele
simetrice.
Matricele diagonale sunt matrice ptratice de dimensiune n care conin elemente nenule
numai pe diagonala principal:
7 0 0
0 2 0
0 0 11
In acest caz memorarea se va face folosind un vector de dimensiune n care va memora
elementele de pe diagonala principala.
Exemplu de utilizare:
// declarare si initializare
int matDiag[3] = {7, 2, 11};
// citire valoare
int val1 = CitireValoare(matDiag, 3, 1, 2);
// scriere valoare (1, 1);
ScriereValoare(matDiag, 3, 1, 1, 5);

Matricele simetrice sunt matrice patratice in care corespondente de sub i de peste


diagonala principala sunt egale (adica m[i][j] = m[j][i] pentru oricare i si j). n acest caz se va
folosi un vector care va conine numai elementele de peste i de pe diagonala principal.
Matricea
1 2 3 4
2 5 6 7
3 4 8 9
7 8 9 10
va fi liniarizata sub forma:
1 2 3 4 5 6 7 8 9 10
Calculul pozitiei elementului i,j dintr-o matrice de dimensiune n se face dupa formula:
p = (n 1) + (n 2) + ... + (n i) + j = i n (1 + 2 + ... + i ) + j = i n

i (i 1)
+j
2
pentru j <= i. Daca j > i,

atunci se interschimb i cu j.
Funcia de acces la elemente este:
int& Valoare(int* matrice, int n, int i, int j)

44

{
// interschimbm elementele daca este cazul
if (j > i)
{
int t = j;
j = i;
i = t;
}
// calculam pozitia
int pozitia = i*n + (i*(i-1))/2 + j;
return matrice[pozitia];
}

Exemplu de utilizare:
// declarare si initializare
int matSim[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
// citire valoare
int val1 = Valoare(matSim, 4, 1, 2);
// scriere valoare (1, 1);

Valoare(matSim, 4, 1, 1) = 7;
Aceeai tehnica se poate aplica i n cazul matricelor triunghiulare.
Matricele rare sunt matrice care au majoritatea elementelor nule (mai mult doua treimi). n
acest caz este mai eficient s memorm matricea sub forma a trei vactori care s conin linia,
coloana i valoarea pentru elementele nenule.
Pentru matricea:
0 0 0 0
0 0 0 23
0 7 0 0
0 0 0 0
vom avea vectorii:
Linii:
1 2
Coloane: 3 1
Valori:
23 7
Alternativ, putem stoca elementele intr-un singur vector de articole care s conin linia,
coloana i valoarea pentru fiecare element nenul.
Exemple de programe:
Exemplu 7.1. Este dat matricea de dimensiunea n*m. S se afieze cte elementele sunt
pare pe fiecare linie.
#include<stdio.h>
#include<conio.h>
#include<malloc.h>
void main()
{
int i,j,n,m,a[5][5],pare;
clrscr();
printf("\nintroduceti numrul de linii");
scanf("%d",&n);
printf("\nintroducei numrul de coloane");
scanf("%d",&m);
printf("\nintroducei elementele matricei:\n");
for(i=0;i<n;i++)
for(j=0;j<m;j++)
{
printf("a[%d][%d]=",i,j);
scanf("%d",&a[i][j]);
}

45

printf("\nAfim elementele matricei:\n");


for(i=0;i<n;i++)
{
for(j=0;j<n;j++)
printf("%3d",a[i][j]);
printf("\n");
}
printf("\nAfisam cate elementele sunt pare si impare pe fiecare nie:\n");
for(i=0;i<n;i++)
{
pare=0;
// notam prin k numrul de elemente pare
for(j=0;j<n;j++)
if(a[i][j]%2==0)
//daca se mparte la 2 si restul este zero
pare++;
printf("%3d",pare);
}
getch();
}

Exemplul 7.2. Este dat matricea de dimensiunea n*n. S se calculeze produsul unui
vector de dimensiunea n cu matricea de dimensiunea n*n, Rezultatul va fi un vector de
dimensiunea n.
#include<stdio.h>
#include<conio.h>
#include<malloc.h>
void main()
{
int i,j,n,m,a[10][10],k=0,s,c[10],b[10];
clrscr();
printf("\nintroduceti numarul de linii");
scanf("%d",&n);
printf("\nintroducei elementele matricei:\n");
for(i=0;i<n;i++)
for(j=0;j<n;j++)
{
printf("a[%d][%d]=",i,j);
scanf("%d",&a[i][j]);
}
printf("\nintroducei elementele vectorului:\n");
for(i=0;i<n;i++)
{
printf("b[%d]=",i);
scanf("%d",&b[i]);
}
printf("\nprodusul unui vector cu o matrice:\n");
for(j=0;j<n;j++)
{
s=0;
for(i=0;i<n;i++)
s=s+b[i]*a[i][j];
c[k]=s; k++;
}
for(i=0;i<n;i++)
printf("%3d",c[i]);
getch();
}

Exemplul 7.3. Este dat matricea de dimensiunea n*m. S se afieze maximul pe fiecare
coloan dintre elementele pozitive.
#include<stdio.h>
#include<conio.h>
#include<malloc.h>
void main()
{
int i,j,n,m,*a,max;

46

clrscr();
printf("\nintroducei numarul de linii");
scanf("%d",&n);
printf("\nintroducei numarul de coloane");
scanf("%d",&m);
a=(int*)malloc(n*m*sizeof(int)); // alocm memorie
printf("\nintroducei elementele matricei:\n");
for(i=0;i<n;i++)
for(j=0;j<m;j++)
{
printf("a[%d][%d]=",i,j);
scanf("%d",a+i*m+j);
}
printf("\nAfim elementele matricei:\n");
for(i=0;i<n;i++)
{
for(j=0;j<n;j++)
printf("%3d",*(a+i*m+j));
printf("\n");
}
printf("\nAfim maximul pe fiecare coloan:\n");
for(j=0;j<m;j++)
{
// notm prin max primul element din fiecare coloan
max=*(a+0*m+j);
for(i=0;i<n;i++)
// verificm dac elementul este mai mare ca zero if dac este mai mare
dect max
if(*(a+i*m+j)>0 && *(a+i*m+j)>max)
max=*(a+i*m+j);
printf("%3d",max);
}
free(a); // eliberm memoria ocupat
getch();
}

Exemplul 7.4. Este dat matricea de dimensiunea n*m. S se calculeze suma elementelor
mai sus de diagonala principal i suma elementelor mai jos de diagonala principal.
#include<stdio.h>
#include<conio.h>
#include<malloc.h>
void main()
{
int i,j,n,m,*a,sum=0,suma=0;
clrscr();
printf("\n introducei numrul de linii");
scanf("%d",&n);
a=(int*)malloc(n*n*sizeof(int));
printf("\n introducei elementele matricei:\n");
for(i=0;i<n;i++)
for(j=0;j<n;j++)
{
printf("a[%d][%d]=",i,j);
scanf("%d",a+i*n+j);
}
printf("\nAfim elementele matricei:\n");
for(i=0;i<n;i++)
{
for(j=0;j<n;j++)
printf("%3d",*(a+i*n+j));
printf("\n");
}
printf("\nAfisam suma elementelor mai sus de diagonala principal:\n");
for(i=0;i<n;i++)
for(j=0;j<n;j++)

47

if(i<j)
suma=suma+*(a+i*n+j);
printf("%3d",suma);
printf("\nAfisam suma elementelor mai jos de diagonala principala:\n");
for(i=0;i<n;i++)
for(j=0;j<n;j++)
if(i>j)
sum=sum+*(a+i*n+j);
printf("%3d",sum);
free(a);
getch();
}

Probleme propuse spre rezolvare:


1. Se d un vector numeric de n elemente i o matrice numeric de dimensiunea m*n. S se
nmuleasc matricea cu vectorul.
2. S se determine poziia i elementul maxim dintre elementele maxime de pe fiecare linie a
unei matrice de dimensiunea m*n.
3. S se afieze toate elementele pare din matricea dat m*n.
4. Este dat matricea n*n. S se afieze numrul elementelor negative de pe diagonala
secundar. i numrul elementelor pozitive de pe diagonala principal.
5. Este dat matricea m*n. S se afieze numrul elementelor negative de pe fiecare linie. i
numrul elementelor pozitive de pe fiecare coloan.
6. Determinai de cte ori se ntlnete elementul minimal n matricea de dimensiunea m*n i
afiai poziiile unde se gsete.
7. Dintr-o matrice dat M, s se listeze valorile tuturor punctelor a i poziia lor. M[i, j] este
considerat punct a dac este minim pe linia i i maxim pe coloana j.
8. S se elimene dintr-o matrice A (cu m linii i n coloane) linia 1 i coloana k i s se listeze
matricea rmas. (Nu se va folosi o alt matrice).
9. S se afieze matricea A (cu m linii i n coloane) cu linia m+1 i coloana n+1, unde A[m+1,
j] s fie suma elementelor de pe coloana j, cu j de la 1 la m, iar A[i, n+1] s fie suma
elementelor de pe linia i, cu i de la 1 la n.
10. Se d o fotografie specificat printr-o matrice ptratic, care conine 0 i 1 (0 pentru punctele
albe, 1 pentru punctele negre). Se consider fonul alb, obiectele negre. Iar dac dou puncte
negre sunt vecine pe linie, coloan sau diagonal, atunci aparin aceluiai obiect. S se
numere cte obiecte distincte apar n fotografie. Exemplu: 1 0 1 0
1010
0010
0 1 0 1. Rezultat: 2.
11. Se numete ptrat magic ptratul N*N, n care sunt nscrise numerele 1,2, .., N2 astfel nct
suma numerelor fiecrei linii este egal cu suma elementelor fiecrei coloane i, n plus, cu
suma elementelor situate pe cele dou diagonale ale ptratului. Scriei un program, care
construiete ptratul magic pentru N dat (2<N<=25).
Exemplu: 3
Rezultat: 4 3 8
951
2 7 6.
12. Se consider o matrice ptratic de dimensiune N*N (N<=50), ale crei elemente sunt cifre
de la 0 la 9. S se afieze toate elementele situate de asupra diagonalei principale (inclusiv pe
diagonal) sub forma unui triunghi, ca n exemplul de mai jos. Datele se citesc de la tastatur.
13. Se d matricea A[N, N] de numere ntregi (N<=10). De parcurs matricea n urtoarea ordine:
primul se va afia A[N, 1] A[1, N].
14. S se verifice dac o matrice A(3,3) de tip ntreg, este sau nu o matrice simetric.

48

15. Se consider un grup format din N2 (N<50) copii de nlimi diferite. Se cere s se aeze n
spiral copiii n ordinea cresctoare a nlimilor. Copilul cu nlimea cea mai mic va fi plasat
n centrul spiralei.
Exemplu: 3
1.80 1.90 1.75 1.65 1.70 1.55 1.68 1.78 1.95.
Rezultat:
1.95 1.90 1.80
1.65 1.55 1.78
1.68 1.70 1.75.
ntrebri de control:
1.
2.
3.
4.

Cum se definete o matrice ?


Cte feluri de matrice cunoatei ?
Poate matricea include diferite tipuri. Dac da sau nu explicai. Dai exemplu.
int i, j, b[3][3];
for(i=0; i++<3;)
for(j=0;j<3;j++) { b[i][j]=8>>(i+j)%3; printf((%4d,*(*(b+i)+j));}
printf(\n); Ce se tiprete la ecran? Explicai.

5. Ce nseamn matrice simetric? Explicai.


6. Care este funcia de alocare a memoriei ntr-o matrice. Explicai cum vom aloca memorie
pentru matricea *a de dimensiunea n*m.
7. Ce se tiprete la ecran? Explicai.
for(i=0;i<n;i++)
for(j=0;j<n;j++)
{
printf("a[%d][%d]=",i,j);
scanf("%d",a+i*n+j);
}

49

Lucrare de laborator N8
Tema: Subprograme.
Scopul lucrrii: Definirea subprogramelor-utilizator, apelarea i aplicarea lor.
Suport teoretic:
Subprogramele snt uniti de program care:
au un algoritm propriu,
pot fi proiectate independent,
pot fi scrise independent,
pot fi compilate independent,
nu se pot executa independent ci numai n cadrul unui program (apel).
Avantajele utilizrii lor:
evitarea scrierii repetate a aceluiai set de instruciuni,
creterea eficienei, prin reutilizarea subprogramelor (biblioteci de subprograme).
Programele se pot descompune n subprobleme (module), adic n grupe de aciuni care se
pot repeta de un numr de ori i care se execut numai n funcie de anumite condiii. Acest lucru
determin existena unui modul principal pentru prelucrrile principale i pentru activarea
subordonailor. Cnd se apeleaz un subprogram, executarea continu cu prima instruciune
din respectivul subprogram. Cnd se termin executarea instruciunilor din subprogram, se
continu cu instruciunea urmtoare apelului, din blocul apelant.
Subprogramele in limbajul C++ se numesc funcii.
Subprogramele pot fi:
standard (predefinite) sau
nestandard (utilizator)
Exemple de funcii sdandard utilizate frecvent:
Funcii de i/o: gets (), fgets (), puts (), scanf (), printf (), getch (), getchar (), fscanf (),
Funcii de lucru cu iruri de caractere: strlen (), strcat (), strchr (), strcmp (), atoi (),
Funcii matematice: exp(), log(), sin(), cos(), ceil(), floor(), pow(), sqrt(), abs(),
Ce trebuie s tim despre funcii?
cum le putem defini,
cum s le apelm,
cum s stabilim legtura dintre funcie i programul apelant.
Definiia conine antetul funciei i corpul acesteia. Nu este admis definirea unei funcii
n corpul altei funcii.
Sintaxa antetului:
tip_rezultat nume (lista parametrilor formali);
Aici tip_rezultat poate fi : un tip standard, o adres a unui tip definit anterior, o structur de
tip articol. Dac este omis se consider ca fiind tipul int.
sau
void nume (lista parametrilor formali)
Dac are tipul void , apelul la funcie se face dintr-o linie de program aparte. n celelalte cazuri
poate fi parte component a unor expresii.
Lista parametrilor formali este o list separat prin virgule de nume de variabile i
tipurile asociate lor, care primesc valorile argumentelor atunci cnd este apelat funcia. O
funcie poate s nu aib parametri. Totui, parantezele sunt necesare, chiar dac nu exist
parametri. Toi parametrii funciei trebuie declarai individual, fiecare coninnd att tipul ct i
50

numele. Ei snt creai la intrarea n funcie i distrui la ieirea din ea. Parametrilor formali li se
pot aplica atribuiri sau folosii n expresii. Aceste variabile ndeplinesc sarcina de primire a
valorilor argumentelor transmise funciei.
Corpul funciei este un bloc, care implementeaz algoritmul de calcul folosit de ctre
funcie. n corpul funciei apar (n orice ordine) declaraii pentru variabilele locale i instruciuni.
Dac funcia ntoarce o valoare, se folosete instruciunea return valoare. La execuie, la
ntlnirea acestei instruciuni, se revine n funcia apelant.
Sfera de influen a funciilor. Fiecare funcie este un bloc de cod discret. Nici o
instruciune din alt funcie nu poate avea acces la el dect printr-un apel al funciei. De exemplu
nu putem folosi goto pentru a sri n mijlocul altei funcii. Codul i datele definite ntr-o funcie
nu pot s interacioneze cu codul sau cu datele definite n alta, deoarece cele dou funcii au
diferite sfere de influen. Variabilele definite ntr-o funcie se numesc variabile locale. Clasa de
memorare este segmentul de stiv. Ele snt vizibile doar la nivelul blocului n care au fost
declarate. Durata de via este egal cu durata execuiei blocului respectiv. Adic variabilele
locale nu-i pstreaz valoarea ntre apelrile funciei. Excepie este atunci cnd variabila se
declar cu specificatorul de clas de memorie static.
Variabilele globale se declar n afara oricrei funcii i pot fi utilizate de toate funciile
care urmeaz declaraiei respective. La declarare acestea snt iniializate automat cu 0. Ele au
alocat spaiu n tot timpul execuiei programului. Sunt utile atunci cnd mai multe funcii ale
aceluiai program folosesc aceleai date.
Observaie: n C++ toate funciile au acelai nivel de influen. Asta nseamn c nu pot fi
definite ntr-o funcie alte funcii.
Funcia se utilizeaz prin apelare la ea. Apelul funciei este o construcie urmat de
punct i virgul, numit instruciune de apel, de forma:
nume_funcie (lista_parametrilor_efectivi);
Parametrii efectivi trebuie s corespund cu cei formali ca ordine i tip. La apel, se atribuie
parametrilor formali valorile parametrilor efectivi, dup care se execut instruciunile din corpul
funciei. La revenirea din funcie, controlul este redat funciei apelante, i execuia continu cu
instruciunea urmtoare instruciunii de apel, din funcia apelant. O alt posibilitate de a apela o
funcie este aceea n care apelul funciei constituie operandul unei expresii (apelul funciei
intervine intr-o expresie). Acest lucru este posibil doar n cazul n care funcia returneaz o
valoare, folosit n calculul expresiei(doar pentru funciile cu tip). La ntlnirea instruciunii
return, dup atribuirea valorii, execuia funciei se ncheie i se revine la funcia care a apelat-o.
n absena instruciunii return, execuia funciei se ncheie dup execuia ultimei instruciuni. n
acest caz nu se ntoarce nici o valoare.
Parametrii declarai n antetul unei funcii sunt numii formali, pentru a sublinia faptul c
ei nu reprezint valori concrete, ci numai in locul acestora pentru a putea exprima procesul de
calcul realizat prin funcie. Ei se concretizeaz la execuie prin apelurile funciei.
Parametrii folosii la apelul unei funcii sunt parametri reali, efectivi, concrei, actuali iar
valorile lor vor fi atribuite parametrilor formali, la execuie. Utilizarea parametrilor formali la
implementarea funciilor i atribuirea de valori concrete pentru ei, la execuie, reprezint un prim
nivel de abstractizare n programare. Acest mod de programare se numete programare
procedural i realizeaz un proces de abstractizare prin parametri.
Funciile comunic prin argumente: ele primesc ca parametri (argumente) datele de
intrare, efectueaz prelucrrile descrise n corpul funciei asupra acestora i pot returna o valoare
(rezultatul, datele de ieire). Transmiterea parametrilor se poate realiza:
prin valoare. Aceast metod copiaz valoarea unui argument ntr-un parametru formal al
subprogramului. n acest caz modificrile efectuate asupra parametrului nu au efect
asupra argumentului;
51

prin referin (adres). Prin aceast metod n parametru se copiaz adresa unui
argument. Aceasta nseamn c modificrile efectuate asupra parametrului afecteaz
argumentul. Se utilizeaz dac e necesar a transmite n programul apelant mai mult dect
o valoare. Cu puine excepii, C++ folosete apelarea funciilor prin valoare. Cnd o
matrice este folosit ca un argument al unei funcii, acesteia i este pasat adresa matricei.
Astfel, codul funciei opereaz asupra coninutului efectiv al matricei i poate s-l
modifice.

Funciile pot fi descrise n cadrul aceluiai fiier, sau n fiiere diferite, care sunt testate i
compilate separat, asamblarea lor realizndu-se cu ajutorul linkeditorului de legturi.
Funcii recursive se folosesc la programarea proceselor de calcul recursive.
Recursivitatea este procesul de definire a unui lucru prin el nsui. Se spune despre o funcie c
este recursiv, dac o instruciune din corpul ei apeleaz chiar acea funcie. Funcia de calcul al
factorialului e un exemplu simplu de funcie recursiv. n limbajul C funcia recursiv fact(n)
poate fi realizat astfel:
double fact(int n)
{ if(n==0) return 1.0;
else return n*fact(n-1);

Exemple de programe:
Exemplul 8.1. Funcia afisare afieaz 65 de simboluri * consecutive.
#include<stdio.h>
#define NAME Vasilache Andrei
#define ADDRESS Cogalniceanu, 65
#define LIM 40
void afisare(void);
void main()
{
afisare();
printf(\t%s\t,NAME);
printf(%s\n,ADDRESS);
afisare();
}
void afisare()
{
int n; for(n=1; n<=LIM; n++)
putchar(*);
putchar(\n);
}

// prototipul funciei
//apelul funciei
// al doilea apel al funciei

n urma execuiei programului vom avea afiat p ecran:


****************************************
Vasilache Andrei
Cogalniceanu,65
****************************************
Exemplul 8.2. Programul efectueaz acelai lucru; dar funcia are doi parametri : un
caracter i un ntreg.
#include<stdio.h>
#define NAME Vasilache Andrei
#define ADDRESS Cogalniceanu, 65
#define LIM 65
#define SPACE
void show_n_char(char ch, int n);
// prototipul funciei
void main()
{
int spaces;
show_n_char(*,LIM);
// apelul funciei
putchar(\n);

52

show_n_char(SPACE,20);
printf(%s,NAME);
spaces=(60-strlen(ADDRESS))/2;
show_n_char(SPACE, spaces);
printf(%s\n,ADDRESS);
show_n_char(*,LIM); // al doilea apel al funciei
}
void show_n_char(char ch,int n)
{
int i; for(i=1; i<=n; i++)
putchar(ch);
}

Exemplul 8.3. Programul nmulete dou valori ntregi, utiliznd o funcie.


#include<stdio.h>
int prod(int a, int b) { return a*b; }
void main()
{
int x,y,z;
x=10; y=20;
z=prod(x,y);
// funcia e atribuit folosit ntr-o expresie
printf(%i, prod(x,y)); // funcia nu e atribuit, dar e folosit
prod(x,y);
// valoarea returnat se pierde
}

Exemplul 8.4. Programul calculeaz factorialul pentru numerele din intervalul 0 170,
utiliznd o funcie.
#include<stdio.h>
#include<stdlib.h>
double fact(int n); // prototipul funciei
void main()
{
for (int m=0;m<171;m++)
{printf(m=%d \t m!=%g \n,m, fact(m));
if((m+1)%23==0)
{ puts(actionati o tasta);
getch(); }
}
double fact(int n)
{ double f; int i;
if(n<0 || n>170) return -1.0;
for(i=2, f=1.0; i<=n; i++) f*=i;
return f;
}

// sau if(wherex()==23)

Exemplul 8.5. Funcia calculeaz cel mai mare divizor comun a dou numere ntregi fr
semn.
unsigned dc(unsigned a, unsigned b)
{
unsigned c, d=1;
if (a==0||b==0) return a>b?a:b;
else for(c=2;c<=(a<b?a:b);c++)
if(a%c==0 && b%c==0) d=c;
return d;
}

Exemplul 8.6. Programul citete dou numere ntregi fr semn i calculeaz cel mai mic
multiplu comun al lor. Este folosit funcia din exemplul precedent care a fost salvat n fiierul
d:\bc\director\ex8_5.cpp
#include<stdio.h>
#include<conio.h>
#include d:\\bc\\director\\ex8_5.cpp
void main()
{
unsigned a, b, c;
clrscr();

53

puts(introdu doua numere fara semn:);


scanf(%u%u,&a,&b);
c=dc(a,b);
printf(cmmmc(a,b)=%u,a*b/c);
getch();
}

Exemplul 8.7. S se determine o rdcin a ecuaiei 6cos(x)+8sin(x)=0 pe segmentul [2,4]


cu precizia eps=0.00017 prin metoda biseciei.
#include<stdio.h>
#include<conio.h>
#include<math.h>
#define eps 0.0001
float f( float x)
{ return 6*cos(x)+8*sin(x);}
void main()
{
clrscr();
float a=2.0, b=4.0;
float ya,yc; double c; int n=0;
lab1: c=(a+b)/2.0; ya=f(a); yc=f(c); n++;
if ((c-a)<=eps){
printf("%7.4f-radacina aproximativa,n=%d",c,n);
goto end;
}
if(n>=100) { printf ("convergenta slaba, n=%d",n);
goto end;
}
if((ya*yc)<0){ b=c; goto lab1; }
else { a=c;
goto lab1; }
end: getch();
}

Exemplul 8.8. Funcia schimb cu locurile simbolul cu cod maxim cu simbolul cu cod
minim ntr-un ir de caractere
#include<stdio.h>
#include<conio.h>
void fct(char *s);
void main()
{
int i;
char *sir; puts(Input string:); gets(sir);
fct(s);
puts(s);
}
void fct(char *s)
{
int i = 0, max = *s, min = *s, pmin = 0, pmax = 0; char ch;
for ( ; s[i]; i++)
{
if (s[i]>max) { max = s[i]; pmax = i; }
if (s[i]<min) { min = s[i]; pmin = i; }
}
ch=*(s+pmax); *(s+pmax)=*(s+pmin); *(s+pmin)=ch;
}

Exemplul 8.9. Programul prelucreaz un ir numeric. Se utilizeaz o funcie de citire a


elementelor i o funcie ce returneaz numrul de elemente pare negative din ir.
#include<stdio.h>
#include<conio.h>
// prototipul functiei de citire a elementelor in masiv
void citire(int s[], int n);
// prototipul functiei de numarare a elementelor pare negative
int numar(int s[], int n);
void main()
{

54

int i, m[10], dim;


puts(dimensiunea sirului numeric:); scanf(%i,&dim);
citire(m,dim);
printf(sint %i numere pare negative, numar(m,dim));
}
void citire(int s[], int n)
{
puts(Elementele masivului:);
for(int i=0; i<n; i++) scanf(%i,&s[i]);
}
int numar(int s[], int n)
{
int i, c=0;
for(i=0; i<n; i++)
if(s[i]<0 && s[i]%2==0) c++;
return c;
}

Exemplul 8.10. Programul afieaz elementul maxim de pe liniile unei matrice. Se


utilizeaz o funcie care primete drept argumeni un pointer la matrice i numrul liniei.
#include<stdio.h>
#include<stdlib.h>
int n, m;
// variabile globale, acestea fiind dimensiunea matricei
// prototipul functiei de determinare a elementului maxim pe linia k
int max(int *p, int k);
void main()
{
int *p, i, j, z;
puts(dimensiunea matricei:); scanf(%i%i,&n, &m);
//alocare dinamic de memorie pentru matrice
p = (int*)malloc(n*m*sizeof(int));
for(i=0; i<n; i++)
{
for(j = 0; j < m; j++)
{ *(p+i*m+j)= random(11); // generare aleatoare a elementelor matricei
printf( %i , *(p+i*m+j));
}
printf(\n);
}
for( i = 0; i < n; i++)
{ // funcia primete ca argumeni pointerul la matrice i numrul liniei
z = max(p,i);
printf(Maximum pe linia %i - %i\n, i+1, z);
}
}
int max(int *p, int k)
{ int M, x;
M=*(p+k*m+0);
for( x = 0; x < m; x++)
if ( M < *(p+k*m+x) ) M = *(p+k*m+x);
return M;
}

Exemplul 8.11. Programul sumeaz componentele unui ir numeric. Se utilizeaz o funcie


recursiv
#include<stdio.h>
#include<conio.h>
int suma(int v[], int n);
// prototipul functiei recursive
void main()
{
int i, a[10], dim;
puts(dimensiunea sirului numeric:); scanf(%i,&dim);
for(i = 0; i < dim; i++)
scanf(%i,&a[i]);
printf(suma elementelor - %i, suma(a,dim-1));

55

getch();
}
int suma(int v[], int n)
{
if(n == 1) return 0;
else return (v[n-1] + suma(v,n-1);
}

Exemplul 8.12. Funcia cu numr variabil de parametri sumeaz numere ntregi.


#include<stdio.h>
#include<conio.h>
int suma(int m,...); // prototipul funciei cu numr variabil de parametri
void main()
{
printf(suma elementelor - %i, suma(2,6,4));
printf(suma elementelor - %i, suma(6,1,2,3,4,5,6));
getch();
}
int suma(int m,...)
{
int *p=&m, t=0;
for(; m; m--) t += *(++p);
return t;
}

Probleme propuse spre rezolvare:


1. S se realizeze un program care conine o funcie ce citete elementele unui vector de
dimensiunea n cu valori ntregi i o funcie ce returneaz cte elemente impare pozitive sunt.
2. S se realizeze un program care conine o funcie ce citete elementele unui vector de
dimensiunea n cu valori ntregi i o funcie ce returneaz produsul elementelor pare pozitive.
3. S se realizeze un program care conine o funcie ce citete elementele unui vector de
dimensiunea n cu valori reale i o funcie ce returneaz indicele celui mai mare element.
4. S se realizeze o funcie care primete un simbol ca parametru i returneaz numrul lui de
ordine dac-i liter i -1 n caz contrar. (De ex.: i c i C sunt litere cu numrul de ordine 3).
5. S se realizeze o funcie care primete un ir de simboluri ca parametru i returneaz 1 dac
irul e palindromic (se citete la fel din ambele direcii) i 0 n caz contrar.
6. S se realizeze un program care conine o funcie ce citete elementele unui vector de
dimensiunea n cu valori ntregi i o funcie ce returneaz lungimea celui mai lung subir
nedescresctor din acest tablou.
7. Programul calculeaz suma ptratelor numerelor din segmentul [m,n]. Se folosete o funcie
recursiv pentru a calcula suma.
8. Programul determin cel mai mic numr dintr-un ir numeric. Se folosete o funcie recursiv.
9. Programul afieaz cuvintele cu lungimea mai mare dect 6 simboluri dintr-un ir de
caractere, care este pasat unei funcii.
10. Date numerele reale s, t. De obinut y = f( t, -2s, 1.47 ) + f( 2.2, t, s-t ), unde
2a b sin c
f (a, b, c) =
5+ | c |
max(a, a + b) + max(a, b + c)
11. Date numerele reale a, b, c. De calculat y =
.
1 + max(a + bc,1.15)
ntrebri de control:
1. O funcie este total caracterizat de : ...
2. Dac funcia f are urmtorul prototip: tip f(lista parametrilor), atunci tip poate fi:
i. vector
ii. structur
iii. ntreg, real sau caracter
56

iv. pointer spre un tip definit anterior


v. tablou bidimensional
3. Cum se numesc parametrii folosii la definiia unui subprogram?
4. O funcie ntoarce obligatoriu o valoare?
5. O funcie trebuie s conin obligatoriu parametri?
6. Ce tipuri de subprograme cunoatei?
7. Ce trebuie s tim despre funcii?
8. Ce prezint antetul funciei?
9. Ce metode de transmitere a argumenilor n funcii cunoatei?
10. Ce este o funcie recursiv?
11. Funciile trebuie definite i descrise obligator n acelai fiier cu programul apelant?
12. Ce va tipri funcia?
int a=1;
void f() { int b=1, c=1; printf(a=%i b=%i c=%i\n, a++, b++, c++);
void main() { while(a<4) f(); }

13. Ce va tipri funcia?


int fun(int n, int a, int b)
{ int z=1, i; for (i=1; i<n; i++) z=z+a*b; return z;
void main()
{ int x=5, y=6, j=1; while (j<6)
{ printf(%i %i \n, j, fun(j,x,y)); j++; }
}

14. Ce se va afia n urma rulrii programului?:


f(int a, int &b, int c)
{ a=++b; c=a+=2; return a+b+c/3; }
void main()
{ int a, b, c; a=b=c=1;
printf(a=%i b=%i c=%i f=%i, a, b, c, f(a,b,c));

15. Ce valori va returna funcia f() apelat n programul principal?


int f(const char *s)
{ int n=0;
for( ; *s++ != \0; n++ );
return n;
}
void main()
{ printf( %s, f(informatica);

57

Lucrare de laborator N9
Tema: Tipuri de date definite de utilizator, redenumirea tipurilor.
Scopul lucrrii: Definirea i utilizarea unui tip nou de date: structuri, reuniuni,
enumerri, cmpuri de bii; nsuirea modalitii de redenumire a tipurilor.
Suport teoretic:
Un mod de grupare al datelor este tabloul. Tabloul este un set ordonat de date de acelai
tip. Un alt mod de grupare al datelor este structura. Structura reunete date de diferite tipuri, dar
care se afl ntr-o legtur logic. Obiectele ce fac parte din structur se numesc cmpuri sau
membrii structurii. La definirea i utilizarea structurilor e necesar a cunoate trei lucruri: 1)
definirea structurii; 2) declararea variabilei, care corespunde acestui tip; 3) asigurarea accesului
la componentele variabilei-structur.
O declaraie de structur are forma:
struct nume { lista de declaraii } nume1, nume2,, numen;

Aici nume definete un tip nou de date, iar nume1, nume2,..., numen sunt structuri, adic
variabile de tipul nume; lista de declaraii declar componentele structurii de tip nume.
Exemplu de definire: struct { char title[20]; int year; float value; };. Structura dat are 3
cmpuri. In unul se pstreaz denumirea crii, n altul anul ediiei, n al treilea preul.
Tipului structur i se poate asocia un nume generic, care poate fi indicat n forma: typedef
struct { char title[20]; int year; float value; } book ;. Specificatorul typedef este executat de
ctre compilator, nu de ctre preprocesor ca #define. n continuare numele generic book poate fi
utilizat la definirea noilor structuri. Exist i alt modalitate de asociere a numelui generic tipului
structura: struct book { char title[20]; int year; float value; };. Aceast modalitate este
necesar la definirea structurilor recursive deoarece typedef nu este suficient: struct node{ int
date; node* next; };. Structura S nu poate conine membri de tipul S, dar poate conine
membri ce pointeaz ctre S. Observaie: cnd definii o structur, definii nu o variabil, ci un
tip compus de variabile. Nu va exista nici o variabil pn nu vei declara una de acest tip.
Declararea variabilelor de tip structur se poate face odat cu definirea ei: struct { char
title[20]; int year; float value; } date1, mas[10];. n C++ dac a fost deja declarat o
structur, putem declara variabile de acest tip folosind doar numele ei generic, fr a preceda cu
cuvntul cheie struct. De exemplu avnd declararea struct book { char title[20]; int year;
float value; }; putem declara book date2, date3[10]. Cnd este declarat o variabil de tip
structur compilatorul de C/C++ aloc automat suficient memorie pentru toate elementele ei.
Lungimea zonei de memorie rezervat pentru variabila de tip struct rezult din nsumarea
lungimilor cmpurilor. Aceasta nu poate depi 65520 octei (ca orice variabil de tip structurat).
Pentru o structur i dovedete utilitatea operatorul sizeof, care asigur determinarea lungimii
zonei de memorie asociate unei variabile sau unui tip de date.
Accesul la membrii stucturii se face n dou moduri: global sau pe componente. Referirea
global este permis numai n operaia de atribuire, cu condiia ca ambele variabile (surs i
destinaie) s aib acelai tip. Referirea pe componente (prin numele lor) este o reflectare a
faptului c articolul este o structur cu acces direct. Referirea cmpurilor unei structuri se face
prin calificare, folosind operatorul. (punct). De exemplu: dac declarm book libry,
identificatorul libry.value indic la membrul value al structurii libry. Identificatorul libry.value
58

este variabil de tipul float i se utilizeaz asemntor variabilelor de acest tip, ca de exemplu:
scanf( %f ,&libry.value). Dac sunt declarate dou variabile a i b de acelai tip structur
putem efectua atribuirea a=b. Nu se admite atribuirea ntre variabile de tip structur care aparin
abloanelor diferite, fie i foarte asemntoare.
Se pot declara pointeri ctre structuri. Exist dou ntrebuinri ale pointerilor pentru
structuri : generarea unei apelri de funcii prin referin i crearea listelor nlnuite. De
exemplu : struct bal { float bilan; char nume[80]; } pers, *pstr;. Atunci pstr=&pers; plaseaz
adresa structurii pers n pstr. Pentru a avea acces la membrii structurii folosind acest pstr se
utilizeaz operatorul ->: pstr->bilan , pstr->nume[0].
Un alt mod de grupare a datelor este reuniunea. Diferena este doar aceea c se substituie
cuvntul struct prin cuvntul union. Declararea tipului reuniune se realizeaz astfel: union
nume_tip { tip_cimp1 cimp1; tip_cimp2 cimp2; ...; tip_cimpn cimpn;};
Spre deosebire de o structur lungimea zonei de memorie rezervate pentru o variabil de tip
reuniune va fi egal cu maximul dintre lungimile cmpurilor componente. Gestiunea coninutului
respectivei zone de memorie va trebui realizat de ctre programator.
Referirea la elementele unei reuniuni se face ca i la structuri.
Exemplu de declarare de reuniune:
union a { int x; long y; double z; char z[5]; } p, r[6], *t;
Aici s-au declarat reuniunea p de tipul a, tabloul de reuniuni r ce const din 6 elemente i
fiecare element este o reuniune de tipul a, un pointer t ce pointeaz spre acelai tip a. Pentru
fiecare reuniune declarat se vor aloca cte 8 octei, deoarece tipul double necesit 8 octei
numrul maxim.
Un alt tip definit de utilizator este tipul enumerare. Acest tip permite folosirea numelor
sugestive pentru valori numerice.
O declaraie de tip enumerare are forma:
enum nume_generic { nume0, nume1, , numen} list_variabile;
Aici nume_generic este numele tipului enumerare nou declarat, nume0, nume1,..., numen
sunt numele sugestive care se vor folosi n continuare n locul valorilor numerice 0, 1, ..., n i
anume: nume0 substituie valoarea 0, nume1 substituie valoarea 1, ..., numen substituie valoarea
n. Iar list_variabile sunt declarate variabile de tipul nume_generic, adic variabile de acest tip
enumerare. Aceste variabile sunt similare cu variabilele de tip int. De exemplu definim enum
season { win,spr,sum,aut } s; Atunci printf(%d %d, spr,sum) va afia 1 2.
La declaraia tipului enumerare se pot impune i alte valori pentru numele sugestive. De
exemplu, dac vom folosi construcia numei=si n loc de numei n lista numelor sugestive,
atunci aceasta va impune pentru numele sugestiv numei valoarea si. Respectiv numei+1 va avea
valoarea si+1. Dac definim n felul urmtor enumerarea de mai sus enum seazon {
win=1,spr,sum,aut } s; Atunci printf(%d %d, spr,sum) va afia 2 3.
Limbajul de programare C permite accesul la unul sau mai muli bii din octet. Una din
metodele de prelucrare pe bii este organizarea unui tip nou tipul cmpuri de bii. Acetia sunt

59

structuri speciale n care se definesc numrul de bii ocupai de fiecare element. O declaraie
pentru un tip cmpuri de bii are forma:
struct nume { tip nume_cimp1 : lungime_cimp ;
tip nume_cimp2 : lungime_cimp ;

tip nume_cimpn : lungime_cimp ;


} n1, n2,..., nm;

Aici tip poate fi unsigned, int, signed, char, unsigned char, iar lungime_cimp este
lungimea cmpului n bii i nu poate depi doi octei. Numele cmpului poate lipsi, atunci el
definete o zon de bii ne utilizat din octetul respectiv. Lungimea cmpului poate fi 0, atunci
cmpul urmtor se aloc n octetul urmtor. Biii se aloc ncepnd de la biii de ordin inferior ai
octetului spre cei de ordin superior. Dac un cmp nu ncape n octetul curent, el se aloc n
octetul urmtor.
Referirea la cmpurile de bii se face ca i n cazul structurilor obinuite. Exemplu de
declarare a tipului cmpuri de bii:
struct

BITFIELDS { unsigned a : 2;
int b : 4;
unsigned c : 1;
unsigned : 3;
int d : 2 ;
} x;

Aici este declarat variabila x de tipul cmpuri de bii. Aceast declarare ne asigur
urmtoarea amplasare:
15

14 13 12
ne utilizai

11

10
d

8
7
ne utilizai

3
b

1
a

Dac cmpul d ar fi avut lungimea mai mare dect 6 ar fi fost amplasat automat n urmtorul
octet. Pentru a regla n mod forat acest lucru se folosete, dup cum s-a spus mai sus, lungimea
0 a unui cmp.
n structuri pot fi utilizai n comun att componente obinuite ct i cmpuri de bii. De
exemplu:
struct

angajat

char nume[20];
float plata;
unsigned active : 1;
unsigned impozit : 3;

// activ sau ntrerupt

;
definete o nregistrare despre salariat care folosete doar un octet pentru a pstra dou
informaii: statutul angajatului i impozitul. Variabilele de tip cmpuri de bii au i restricii:
1) nu putem obine adresa unui cmp de bii; 2) nu pot fi introduse n tablouri.
}

C admite o facilitate numit typedef pentru a crea nume pentru noi tipuri de date. O astfel
de declaraie de tip are forma:
typedef

nume_tip_vechi nume_tip_nou;

De exemplu declaraia: typedef int LENGTH; face numele LENGTH sinonim pentru "int".
Tipul LENGTH poate fi utilizat n declaraii exact la fel ca int:
LENGTH len, maxlen;
LENGTH *lengths[];

Similar, declararea:
typedef char* STRING;
face ca STRING sa fie sinonim cu char* sau pointerul unui caracter, care poate fi utilizat n
declaraii ca: STRING p, lineptr[LINES] ;
60

Exemple de programe:
Exemplul 9.1. Programul simplific o fracie raional. Simplificarea se face prin
mprirea numrtorului i numitorului la cel mai mare divizor comun al lor.
#include<conio.h>
#include<stdio.h>
void main()
{// cmpul n reprezint numrtorul, m - numitorul
typedef struct { long unsigned n;
long unsigned m; } Rational;
Rational s; long unsigned k, cmmdc=1, h;
clrscr();
puts(Introducei o fracie raional);
scanf (%lu%lu,&s.n,&s.m) ;
puts(Ai introdus fracia: );
printf(%lu/%lu\n,s.n,s.m);
h=s.n < s.m ? s.n : s.m; // h este minimul dintre numrtor i numitor
for(k=1;k<h/2;k++)
if(s.m%k==0 && s.n%k==0) cmmdc=k;
s.n=s.n/cmmdc; s.m=s.m/cmmdc;
puts(Fracia simplificat este:);
printf(%lu/%lu,s.n,s.m);
getch();
}

Exemplul 9.2. Programul declar o structur carte care conine 3 elemente. Primul
element conine numele autorului, al doilea denumirea crii, al treilea preul. Sunt prelucrate
informaiile despre cteva cri.
#include<conio.h>
#include<stdio.h>
#define maxc 100
struct carte { char nume[20];
char titlu[40];
float pret; }
void main()
{
carte bibl[maxc];
// tablou de cri
int i, c=0;
puts(Dati titlul crii. Pentru sfrit acionai [enter] la nceput de
linie);
while ( c<maxc && gets(bibl[c].titlu) !=NULL && bibl[c].titlu[0] != \0 )
{ puts(Autor:);
gets(bibl[c].nume);
puts(Preul:);
scanf(%f, &bibl[c++].pret);
fflush(stdin);
// golirea intrrii
puts(Introducei titlul urmtoarei cri:);
}
puts(Iat lista crilor);
for (i=0;i<c;i++)
printf(%s, %s : $%.2f\n,bibl[i].titlu, bibl[i].nume, bibl[i].pret);
}

Exemplul 9.3. Se d o list de persoane i punctajele obinute de acestea la un concurs.


Programul ordoneaz descresctor persoanele n funcie de punctaj i afieaz lista ordonat.
#include<conio.h>
#include<stdio.h>
#define max 20
struct persoana { char nume[max];
int punctaj ; } ;
int Citeste ( persoana p[])
{
int i,n;

61

printf(Dai numrul de persoane: ); scanf(%d,&n);


for (i=0; i<n; i++)
{fflush ( stdin );
printf ( Dai numele persoanei nr. %d: , i+1);
gets( p[i].nume ); p[i].nume[max]=\0 ;
printf ( Dai punctajul lui %s: , p[i].nume );
scanf ( %d, &p[i].punctaj ) ; fflush ( stdin ) ;
}
return n;
}
void Schimba ( persoana *a, persoana *b)
{ persoana aux;
aux=*a; *a=*b; *b=aux;
}
int Ordoneaza ( persoana p[], int n)
{ int i, j, ord=1 ;
for ( i=0 ;i<n-1 ;i++)
if ( p[i].punctaj<p[i+1].punctaj ) ord=0 ;
if ( !ord )
{ for ( i=0; i<n-1; i++ )
for ( j=i+1; j<n; j++)
if ( p[i].punctaj<p[j].punctaj ) Schimba ( &p[i], &p[j] );
}
return ( !ord );
}
void Afiseaza ( persoana *x, int n )
{ int i;
for ( i=0; i<n; i++ )
printf ( %d. %20s -> %4d. \n , i+1, x[i].nume, x[i].punctaj );
}
void main()
{
persoana x[max];
// irul persoanelor
int n; clrscr();
puts ( Ordonare personae dupa punctaj );
if (( n = Citeste(x))==0 ) puts ( Nu exista persoane. );
else
{ if ( Ordoneaza (x,n) puts ( Am ordonat persoanele );
else printf ( Persoanele erau deja ordonate\n );
Afiseaza(x,n);
}
getch();
}

Exemplul 9.4. Programul exemplific folosirea reuniunilor pentru citirea i afiarea datelor
despre mai multe persoane de ambele sexe.
#include<conio.h>
#include<stdio.h>
#include<stdlib.n>
union partener { char sotie[20];
char sot[20];
} ;
struct persoana { char nume[20];
char sex;
int virsta;
union partener p;
} ;
void Citeste ( int nr_p, persoana *x )
{
int vs; char sx;
printf ( Se citesc datele persoanei a %d-a:\n, nr_p );
fflush ( stdin );
puts ( Numele: );
gets ( x->nume );

62

puts ( Virsta: );
scanf ( %d, &vs ); x->virsta=vs; fflush ( stdin );
puts ( Sexul: ); scanf ( %c, &sx ); x->sex=sx; fflush ( stdin );
if ( x->sex==F || x->sex==f )
{ puts ( Dati numele sotului: ); gets ( x->p.sot ); }
else { puts ( Dati numele sotiei: ); gets ( x->p.sotie ); }
}
void Scrie ( int nr_p, persoana x )
{
if ( wherey ()==20 ) { puts ( Apasati o tasta ); getch(); }
printf ( Datele persoanei a %d-a:\n, nr_p );
printf ( Numele: %s Virsta: %d Sexul: %c , x.nume, x.virsta, x.sex );
if ( x.sex==F || x.sex==f ) printf ( Numele sotului: %s\n, x.p.sot );
else printf ( Numele sotiei: %s\n, x.p.sotie );
}
void main()
{ clrscr();
persoana om[20]; int i,n;
puts ( Dati numarul de personae: ); scanf ( %d, &n );
for ( i=0; i<n; i++) Citeste ( i+1, &om[i] );
for ( i=0; i<n; i++ ) Scrie ( i+1, om[i] );
getch();
}

Exemplul 9.5. Programul afieaz codul binar ASCII al simbolului introdus de la tastatur.
#include<stdio.h>
#include<conio.h>
struct byte { int b1:1;
int b2:1;
int b3:1;
int b4:1;
int b5:1;
int b6:1;
int b7:1;
int b8:1; } ;
union bits { char ch;
byte bit;} b;
void decode ( bits b );
void main()
{
do { b.ch=getche();
printf ( ":" );
decode ( b );
} while ( b.ch!='q' );
}
void decode ( bits u )
{
if ( u.bit.b8 ) printf ( "1" );
else printf ( "0" );
if (u.bit.b7 ) printf ( "1" );
else printf ( "0" );
if ( u.bit.b6 ) printf ( "1" );
else printf ( "0" );
if ( u.bit.b5 ) printf ( "1" );
else printf ( "0" );
if ( u.bit.b4 ) printf ( "1" );
else printf ( "0" );
if ( u.bit.b3 ) printf ( "1" );
else printf ( "0" );
if ( u.bit.b2 ) printf ( "1" );
else printf ( "0" );
if ( u.bit.b1 ) printf ( "1" );
else printf ( "0" );
printf ( "\n" );
}

63

Exemplul 9.6. Programul exemplific folosirea enumerrilor.


#include<stdio.h>
#include<conio.h>
enum spectrum { red, orange, yellow, green, blue, violet } ;
void main()
{
enum spectrum color;
puts ( Introduceti culoarea ( pentru ieire tastai q ) );
while ( ( scanf (%d, &color)) == 1 )
{
switch ( color ) {
case red
:
puts ( Trandafirii sunt rosii ); break;
case orange :
puts ( Macii sunt orange ); break;
case yellow :
puts ( Florile florii soarelui sunt galbene ); break;
case green :
puts ( Iarba este verde ); break;
case blue
:
puts ( Clopoeii sunt albatri ); break;
case violet : puts ( Toporasii sunt violeti ); break;
default
: printf ( Nu cunosc nimic de culoarea data.\n ); }
puts ( Urmatoarea culoare );
}
}

Exemplul 9.7. Programul declar un tablou de structuri student cu elementele: nume


numele studentului, tabloul note[5] pentru a pstra notele, med pentru pstrarea notei medii.
Se utilizeaz funciile de introducere a datelor despre fiecare student, de calculare a notei medii
fiecrui student i atribuirii ei variabilei med, de afiare a listei studenilor.
#include<stdio.h>
#include<conio.h>
#include<stdlib.h>
struct student { char nume[10];
int note[5];
float med; };
void initiere (student * s, int n);
void calcul (student * s, int n);
void afisare (student * s, int n);
void main()
{
int n; clrscr();
student *m;
puts (Dai numrul de studeni:); scanf (%d, &n);
m=(student*)malloc(n*sizeof(student));
initiere (m,n);
calcul (m,n);
afisare (m,n);
getch ();
}
void initiere (student * s, int n)
{
int i, j, q;
for ( i=0; i<n; i++ ){
fflush ( stdin );
printf ( "nume %i: ", i+1 );
gets ((s+i)->nume);
for ( j=0; j<5; j++ ) { printf ( "nota %i: ",j+1);
scanf ( "%i",&q ); (s+i)->note[j]=q;
}
}
}
void calcul ( student* s, int n)
{
int i,j; float f;
for (i=0; i<n; i++ )
{ f=0.0;

64

for ( j=0; j<5; j++ )


(s+i)->med=f/5.0;

f+=(s+i)->note[j];

}
}
void afisare ( student *s, int n)
{
puts ("
NUME
|
MEDIA
");
for ( int i=0; i<n; i++ )
printf ( "%-10s|%7.1f\n",(s+i)->nume, (s+i)->med );
}

Probleme propuse spre rezolvare:


1. Programul realizeaz operaii cu fracii raionale ( introducere, extragere, atribuire, inversare,
adunare, scdere, nmulire, mprire ).
2. Programul realizeaz admiterea la un liceu i permite:
iniializarea vectorului de nregistrri de tip elev;
adugarea unui elev n vector;
nlocuirea unui elev cu alt elev;
inserarea unui elev pe o anumit poziie n vector;
eliminarea din vector a unui elev avnd un anumit nume;
cutarea unui elev dup nume;
calcularea mediilor;
listarea alfabetic a elevilor;
listarea elevilor n ordinea descresctoare a mediilor.
3. Programul administreaz un parc de automobile. Informaiile relative la un automobil sunt:
numrul de locuri, marca, tipul de carburant, numrul de nmatriculare. Programul permite
intrarea unei maini, ieirea unei maini, nlocuirea unei maini cu alta de acelai model (avnd
alt numr de nmatriculare).
4. Programul invit utilizatorul s introduc ziua, luna (denumirea prescurtat), anul i
afieaz numrul zilelor ce s-au scurs de la nceputul anului pn la ziua introdus.
5. Fiind date dou fracii p i q programul afieaz forma ireductibil a fraciilor p+q, p-q, p/q,
p*q, punnd n eviden numrtorul i numitorul acestora.
6. Programul determin de cte ori o persoan nscut n anul A>1900, luna L, ziua z, avnd
vrsta v i-a aniversat ziua de natere n aceeai zi a sptmnii cu cea n care s-a nscut.
7. Programul calculeaz valoarea unei expresii raionale.
8. Programul determin denumirea zilei dup o dat calendaristic presupus corect. Folosii
tipul union.
ntrebri de control:
1. Ce este un tip definit de utilizator ? Care sunt aceste tipuri i necesitatea lor ?
2. Ce este o structur ? Care este deosebirea dintre o structur i un tablou ?
3. Cum se declar o structur ? Cum se face referirea la componentele unei structuri ?
4. Cum se aloc memorie unei structuri ?
5. Definii o structur care s conin denumirea prescurtat a lunii pn la trei simboluri,
numrul de zile a lunii i numrul de ordine al lunii.
6. Definii un tablou din 12 structuri ca n punctul 5 i efectuai iniializarea lui pentru un an
bisect.
7. Condiia ca dou puncte distincte A i B ( de tip structur) s aparin aceleiai axe de
coordonate este:
a) A.x==0 && B.x==0 && A.y==0 && B.y==0
b) ( A.x==0 || B.x==0 ) && ( A.y==0 || B.y==0)
65

c) A.x==0 && B.x==0 || A.y==0 && B.y==0


d) A.x==0 || B.x==0 && A.y==0 || B.y==0
8. Este dat un fragment de program:
struct name { char first[20]; char last[20]; } ;
struct bem { int limbs; name title; char type[30]; } ;
bem *pb; bem deb = { 6, { Bernazel, Gwolkapwolk }, Arcturan };

A) Ce va afia: printf(%d\n, deb.limbs); printf(%s\n, pb->type);


printf(%s\n, pb->type + 2) ?
B) Cum poate fi accesat Gwolkapwolk ( n dou moduri ).
9. Ce este o reuniune ? Care este deosebirea dintre o structur i o reuniune ?
10. Cum se aloc memoria pentru o reuniune ?
11. Ce reprezint tipul cmpuri de bii ?
12. Cum se face referirea la cmpuri de bii ?
13. Ce tip poate avea un cmp de bii ?
14. Care este lungimea maxim a unui cmp de bii ?
15. Ce semnific lipsa numelui unui cmp de bii n declaraia tipului cmp de bii ?
16. Fie urmtoarea declarare :
struct

cimp

unsigned a : 3;
int
b : 2;
unsigned c : 4;
unsigned d : 1;
int
e : 2 ;

} x;

Ce amplasare ne asigur aceast declarare ?


17. Ce reprezint tipul enumerare ? Cum se declar tipul enumerare ?
18. Cum se aloc memoria pentru datele de tip enumerare ?
19. Care valori implicite substituie numele sugestive din declaraia unui tip enumerare ?
20. Cum se pot impune alte valori dect cele implicite pentru numele sugestive din
declaraia unui tip enumerare ?
21. Ce tip au valorile numelor sugestive din declaraia unui tip enumerare ?
22. Ce operaii pot fi efectuate cu datele de tip enumerare ?
23. Ce reprezint specificatorul typedef ?
24. Care-i deosebirea dintre typedef i #define ?

66

Lucrare de laborator N10


Tema: Prelucrarea fiierelor.
Scopul lucrrii: Crearea, actualizarea, modificarea i utilizarea fiierelor n probleme de
prelucrare a datelor.
Suport teoretic:
Un fiier este o colecie de date omogene, stocate pe un suport extern i identificat printrun nume. Datele fiierului se mai numesc elemente, componente, nregistrri, articole.
Fiierele se pstreaz pe diferite dispozitive externe. Folosirea fiierelor permite pstrarea
informaiei de orice natur pentru un timp ndelungat, transferarea datelor de pe un purttor
informaional pe altul, citirea i afiarea datelor n caz de necesitate. n C, C++ tratarea fiierelor
se face la dou nivele:
1. inferior: se realizeaz cu sprijinul direct al sistemului de operare, asemntor celui
din UNIX, denumit i neformatat sau unbuffered;
2. superior: se realizeaz cu mijloacele sistemului de programare C, C++ cu
utilizarea tipului structurat de date FILE denumit i sistem de fiiere de tip buffer sau formatat
Vom deosebi un fiier de date de pe un dispozitiv extern i un fiier de date din program
(din memoria operativ a calculatorului). Un fiier de date de pe un dispozitiv extern l vom
numi fiier fizic, iar un fiier de date din program l vom numi flux (stream) de date sau fiier
logic. Exist dou tipuri de fluxuri: text i binar.
Un flux text este o succesiune de caractere i este format din linii. Fiecare linie se termin
cu un caracter newline. La scrierea unui flux text pe un dispozitiv extern, n flux pot interveni
unele schimbri impuse de dispozitivul concret. Deci, e posibil s nu existe o coresponden
biunivoc ntre caracterele fluxului citit sau scris i caracterele fiierului respectiv de pe
dispozitivul extern.
Un flux binar este o secven de octei din memorie cu o coresponden biunivoc fa de
octeii de pe dispozitivul extern respectiv. Aici la scriere i la citire nu intervin schimbri.
Fiierele nu sunt toate la fel. De exemplu, dintr-un fiier putem extrage nregistrarea a
cincea sau modifica nregistrarea a zecea. Acestea sunt fiiere cu acces direct (aleatoriu). Dar
ntr-un fiier legat cu imprimanta sau alt port informaia poate fi transmis doar consecutiv n
aceeai ordine ca n stream. Acestea sunt fiiere cu acces secvenial. Asta e deosebirea ntre
stream i fiier: toate stream-urile sunt la fel, dar fiierele nu.
n timpul intrrii datelor n program dintr-un fiier de pe disc, are loc copierea lor n
memoria operativ a calculatorului, iar informaia din fiier ce se afl pe discul rigid rmne
neschimbat pe parcursul executrii programului. La ieirea datelor din program pe disc, n fiier
sunt nscrise datele ce se pstrau pn n acel moment n memoria operativ.
nscrierea sau citirea informaiei din fiier este efectuat cu ajutorul indicatorului de
poziie, care st pe nceputul fiierului la deschiderea acestuia. Pe msur ce fiecare caracter este
citit sau scris n fiier indicatorul de poziie este incrementat, asigurnd parcurgerea fiierului.
Cnd programul ncepe execuia, se deschid automat cinci stream-uri: stdin (standard input),
stdout (standard output), stderr (standard error). n plus BC++ deschide stream-ul stdprn i
stdaux, asociate printerului i portului consecutiv. Aceste stream-uri la fel se nchid automat.
Prelucrarea fiierelor presupune un ir de operaii specifice: crearea, deschiderea, citirea,
nchiderea, actualizarea, tergerea unui fiier, adugarea de noi nregistrri, poziionarea ntr-un
fiier .a. Aceste operaii pot fi realizate prin funcii speciale de prelucrare a fiierelor. Aceste
funcii au prototipul lor n fiierul <stdio.h> i numele unei astfel de funcii ncepe cu litera f.
Fiierul antet <stdio.h> mai definete i urmtoarele tipuri: size_t, fpos_t i FILE. Tipul size_t ca
i fpos_t este o varietate de ntreg fr semn. <stdio.h> definete mai multe funcii macro:NULL,
EOF, FOPEN_MAX, SEEK_SET, SEEK_END, SEEK_CUR. Funcia macro NULL definete
un pointer nul. EOF este definit drept -1 i este valoarea returnat cnd o funcie de intrare
67

ncearc s citeasc peste sfritul fiierului. FOPEN_MAX definete o valoare ntreag ce


reprezint numrul maximal de fiiere ce pot fi deschise simultan. Celelalte sunt folosite cu
funcia fseek(), care face accesul aleator dintr-un fiier. Pentru a citi sau scrie fiiere, e necesar a
declara n program o variabil pointer de tip FILE. Sintaxa de declarare a unui indicator de fiier
este urmtoarea:
FILE *file_pointer;
Pointerul este pentru fiier legtura cu fluxul de input/output. Un pointer pentru fiier este
un pointer ctre informaiile care definesc diferite lucruri despre fiier, cum ar fi: numele, starea
i poziia curent a fiierului.
Deschiderea unui fiier se realizeaz cu ajutorul funciei fopen(), care are urmtoarea
sintax:
FILE *fopen(const char *calea, const char *mod);
unde calea este un pointer spre un ir de caractere ce conine calea spre fiierul respectiv, iar
mod este un pointer spre un ir de caractere ce indic modul de acces la fiier. Funcia
returneaz un pointer spre tipul FILE sau pointerul nul n caz de eroare. Sunt posibile
urmtoarele moduri de acces la un fiier:
1. r deschiderea unui fiier text pentru citire;
2. w - deschiderea unui fiier text pentru scriere;
3. a - deschiderea unui fiier text pentru a aduga nregistrri la sfritul fiierului;
4. r+ - deschiderea unui fiier text pentru citire i scriere;
5. w+ - crearea unui fiier text pentru citire i scriere;
6. a+ - deschiderea unui fiier text pentru adugarea nregistrrilor la sfritul fiierului sau
crearea unui fiier text pentru citire i scriere;
7. rb - deschiderea unui fiier binar pentru citire;
8. wb - deschiderea unui fiier binar pentru scriere;
9. ab - deschiderea unui fiier binar pentru a aduga nregistrri la sfritul fiierului;
10. r+b - deschiderea unui fiier binar pentru citire i scriere;
11. w+b - crearea unui fiier binar pentru citire i scriere;
12. a+b - deschiderea unui fiier binar pentru adugarea nregistrrilor la sfritul fiierului
sau crearea unui fiier binar pentru citire i scriere.
Deschiderea cu modul w sau a a unui fiier inexistent duce la crearea lui.
Deschiderea cu modul w a unui fiier existent duce la tergerea lui i crearea unui fiier
nou.
Deschiderea cu modul a a unui fiier existent permite adugarea nregistrrilor la
sfritul fiierului.
Deschiderea cu modul r a unui fiier inexistent duce la eroare.
Deschiderea cu modul de citire i scriere a unui fiier inexistent duce la crearea lui.
Deschiderea cu modul de citire i scriere a unui fiier existent nu terge fiierul.
De exemplu, pentru a crea un fiier nou cu nume info.txt se va folosi sintaxa:
FILE *fisier;
fisier=fopen(info.txt,w).
n unele cazuri apare situaia cnd sistemul operaional nu poate deschide fiierul indicat n
funcia fopen(). Aceasta poate fi condiionat de lipsa spaiului pe discul rigid, sau de faptul c
fiierul indicat pur i simplu nu exist. n cazul ncercrii folosirii fiierului ce nu poate fi
deschis, programul va fi stopat n urma unei greeli de execuie. Pentru a evita stoparea avariat
a programului poate fi controlat starea de deschidere a fiierului cu ajutorul instruciunii
condiionate if, care va opri programul n caz de eec. Condiia pentru evitarea ieirii avariate din
program are urmtoarea sintax:
if ( fisier=fopen(info.txt,w))==NULL)
{ puts(fiierul nu poate fi deschis);
68

exit(1); }
nchiderea unui fiier, care a fost deschis cu fopen(), se face cu funcia fclose() care are
prototipul int fclose(FILE *fp ); aici fp este un pointer spre tipul FILE, returnat de funcia
fopen(). Funcia returneaz 0, dac a reuit nchiderea fiierului, i -1, n caz de eroare. Funcia
nscrie datele rmase n fluxul de date n fiier i apoi nchide fiierul, adic rupe legtura dintre
fluxul de date i fiier. nchiderea corect a fiierului se va face:
if ( fclose(fisier)!=0) puts(eroare la nchiderea fiierului);
Mai mult ca att, nchiderea fiierului elibereaz indicatorul i dup aceasta el poate fi
utilizat pentru accesul la alt fiier sau pentru ndeplinirea altor operaii cu fiierul. De menionat
faptul, c dup nscrierea datelor, fiierul trebuie nchis i numai dup aceasta deschis pentru
citire, astfel avnd acces respectiv la datele din fiier.
Scrierea unui caracter ntr-un fiier se face cu funcia putc() (vezi i funcia fputc()),
care are prototipul int putc(int ch, FILE *fp); aici fp este pointerul spre tipul FILE, returnat de
funcia fopen() la deschiderea fiierului, iar ch este caracterul care se nscrie n fiier.
Funcia returneaz codul caracterului scris n fiier sau EOF (adic -1) n caz de eroare.
Citirea unui caracter dintr-un fiier se face cu funcia getc() (vezi i funcia fgetc()),
care are prototipul int getc(FILE *fp); aici fp este pointerul spre tipul FILE, returnat de funcia
fopen() la deschiderea fiierului.
Funcia returneaz codul caracterului citit din fiier sau EOF, adic valoarea -1, dac s-a
ajuns la sfritul fiierului.
Funcia feof() determin momentul cnd a fost atins sfritul fiierului. Ea are prototipul
int feof(FILE *fp);
Funcia returneaz o valoare diferit de zero, dac a fost atins sfritul fiierului si 0 n caz
contrar.
Funcia fgets() cu prototipul char *fgets( char *s, int n, FILE *fp); citete un ir de
caractere din fiierul specificat de pointerul fp, pn cnd se ajunge la un caracter newline sau au
fost citite n-1 caractere; pointerul s indic spre zona de memorie unde se pstreaz irul de
caractere citit din fiier; citirea din fiier se ntrerupe sau la citirea caracterului newline sau dup
citirea a n-1 caractere. n zona indicat de s se scrie \n, dac el a fost citit din fiier, apoi se
scrie caracterul NUL (\0).
Funcia returneaz valoarea pointerului s sau pointerul NUL, n caz de EOF.
Funcia fputs() cu prototipul int fputs (const char *s, FILE *fp); efectueaz nscrierea
irului specificat de pointerul s n fiierul specificat de pointerul fp sau imprimarea lor pe hrtie
fr nserarea caracterului sfrit de linie. Pentru ca fiecare ir nscris n aa mod n fiier s
nceap din rnd nou, este necesar nserarea manual a simbolului sfrit de linie.
Funcia returneaz codul ultimului caracter scris n fiier sau EOF, n caz de eroare.
Funcia rewind() cu prototipul void rewind(FILE *fp); poziioneaz indicatorul de poziie
al fiierului la nceputul fiierului. Funcia nu returneaz nici o valoare.
Funcia ferror() cu prototipul int ferror(FILE *fp); determin dac o anumit operaie cu
fiiere a generat o eroare. Funcia returneaz o valoare diferit de zero, dac a survenit vre-o
eroare, i 0, dac n-a fost nici o eroare.
Funciile pentru prelucrarea caracterelor i irurilor au destinaia de nscriere/citire din
fiier numai a informaiei textuale. n caz, cnd e necesar de nscris n fiier date ce conin valori
numerice este folosit funcia fprintf() cu urmtoarea sintax
int fprintf (FILE *fp, const char *format, data); unde fp este indicatorul la fiierul n
care se realizeaz nscrierea, format este irul de control al formatului datelor nscrise i data
69

este lista variabilelor sau valorilor ce trebuie nscrise n fiier. Ea se comport ca i funcia
printf(), cu deosebirea c scrie datele n fiierul fp.
Funcia returneaz numrul de caractere (octei) efectiv scrise n fiier. Dac survine o
eroare pn la prima scriere, funcia returneaz o valoare negativ.
Funcia fscanf() cu prototipul int fscanf (FILE *fp, const char *format, data); citete
din fiierul indicat de pointerul *fp date sub controlul unor formate. Ea se comport ca i funcia
scanf(), cu deosebirea c citete datele din fiierul fp.
Funcia returneaz numrul de argumente crora li s-au atribuit efectiv valori. Dac a
aprut o eroare pn la prima atribuire, atunci funcia returneaz EOF, adic valoarea -1.
Funcia fflush() cu prototipul int fflush(FILE *fp); terge coninutul unui flux de ieire.
Ea scrie datele din flux n fiier, apoi terge coninutul acestui flux. Dac fp este pointerul NUL,
atunci se sterg toate fluxurile asociate cu fiierele deschise pentru scriere.
Fucia returneaz valoarea zero n caz de succes, i -1, n caz de eroare.
Funcia fwrite() cu prototipul unsigned fwrite (void *bufer, unsigned dim, unsigned n,
FILE *fp); scrie n fiierul indicat de pointerul *fp n obiecte (blocuri) de dimensiunea dim
octei fiecare. Datele se iau din zona de memorie indicat de pointerul bufer. Indicatorul de
poziie al fiierului se mrete cu numrul de caractere (octei) scrise. Pentru determinarea
mrimii dim se folosete funcia sizeof(dim). Dac vom deschide fiierul cu ajutorul unui
redactor de texte obinuit vom observa n el un coninut neneles. n realitate informaia (sau
mai bine zis nregistrrile) ce se afl n acest fiier este neleas de compilator i poate fi citit
cu funcia fread().
Funcia returneaz numrul de obiecte (blocuri) efectiv scrise, care poate fi i mai mic
dect numrul solicitat n.
Funcia fread() cu prototipul unsigned fread (void *bufer, unsigned dim, unsigned n,
FILE *fp); citete n obiecte (blocuri), fiecare avnd dim octei, din fiierul indicat de pointerul
*fp. Datele se plaseaz n tabloul indicat de pointerul bufer. Indicatorul de poziie al fiierului se
mrete cu numrul de octei citii.
Funcia returneaz numrul de blocuri efectiv citite, care poate fi mai mic dect numrul
solicitat n.
Funcia fseek() cu prototipul int fseek(FILE *fp, long depl, int origine); deplaseaz
indicatorul de poziie al fiierului. Funcia lucreaz la nivel de octei. Parametrul depl arat
numrul de octei peste care se va deplasa indicatorul fiierului, iar parametrul origine arat de
unde ncepe numrarea acestor octei. Parametrul origine poate avea una din urmtoarele valori:
SEEK_SET, care are valoarea 0 i semnific numrarea de la nceputul fiierului; SEEK_CUR,
care are valoarea 1 i semnific numrarea de la poziia curent nainte; SEEK_END, care are
valoarea -1 i semnific numrarea de la sfritul fiierului napoi.
Funcia returneaz valoarea 0, dac operaia de poziionare a reuit, i o valoare diferit de
zero, n caz de eroare.
Funcia ftell() cu prototipul long ftell(FILE *fp); returneaz poziia curent a
indicatorului de fiier. Funcia determin poziia indicatorului de fiier i returneaz numrul de
octei parcuri de la nceputul fiierului. Primul octet este sub numrul 0. Valoarea returnat
reprezint octetul curent, nu nregistrarea curent i poate fi utilizat de funcia fseek().
Funcia returneaz valoarea indicatorului de poziie al fiierului, dac operaia de
poziionare a reuit, i valoarea -1, n caz de eroare.
Exemple de programe:
70

Exemplul 10.1. Programul copiaz intrarea standard la ieirea standard, adic citete cte
un caracter din fiierul stdin i l scrie n fiierul stdout. Citirea se ntrerupe la ntlnirea
caracterului EOF (adic la acionarea tastelor Ctrl + Z).
#include<conio.h>
#include<stdio.h>
void main()
{
char c; clrscr();
while ( ( c=getc(stdin))!=-1)
putc(c, stdout);
getch();
}

// EOF e definit n fiierul stdio.h ca -1

Exemplul 10.2. Programul citete caractere de la claviatur i le scrie n fiierul cu numele


file01 pe disc pn la citiea caracterului EOF.
#include<conio.h>
#include<stdio.h>
void main()
{
FILE *fp; char c;
clrscr();
fp = fopen(file01,w);
while ( ( c=getc(stdin))!=EOF)
putc(c, fp);
fclose(fp);
getch();
}

Exemplul 10.3. Programul demonstreaz utilizarea fluxului de citire/scriere pentru citirea


din fiier i contorizarea simbolurilor citite.
#include<conio.h>
#include<stdio.h>
void main()
{
FILE *fp;
char S[20]; long count=0; int ch;
clrscr();
gets(S); // se ateapt introducerea numelui fiierului
// deschiderea fiierului pentru citire i
if ( ( fp = fopen(S, r) ) == NULL)
{ // verificarea execuiei deschiderii lui
printf(Nu se deschide fiierul %s\n,S);
exit(1);
} // se citesc simboluri din fiier pn la EOF
while ( ( c = getc(fp)) != EOF)
{ putc(ch,stdout);
// sau putchar(ch); se tipresc la ecran simbolurile citite
count++;
}
fclose(fp); printf(Fiierul %s conine %ld simboluri\n, S, count);
getch();
}

Exemplul 10.4. Programul citete cte un caracter de la intrarea standard i l adaug la


sfritul fiierului creat n exemplul 10.2.
#include<conio.h>
#include<stdio.h>
void main()
{
FILE *fp; char c;
clrscr();
fp = fopen(file01,a);
while ( ( c=getc(fp)) != -1)
putc(c, fp);
fclose(fp);
getch(); }

71

Exemplul 10.5. Programul citete de la intrarea standard un ir de numere ntregi, scrie cu


fprintf() numerele pare ntr-un fiier binar i numerele impare n alt fiier binar, apoi citete cu
fscanf() fiierele i le afieaz la ecran.
#include<conio.h>
#include<stdio.h>
void main()
{
FILE *fp1, *fp2; int n; clrscr();
fp1 = fopen(fpar,wb); fp2 = fopen(fimpar,wb);
while ( 1 ) // se introduc numere da la tastatur
{
if ( scanf( %d, &n )!=1) break; // pn se ntroduce un simbol
(n%2==0) ? fprintf( fp1, %4d, n) : fpintf( fp2, %4d, n);
}
fclose( fp1 ); fclose( fp2 );
fp1 = fopen(fpar,rb); fp2 = fopen(fimpar,rb);
puts(Fiierul cu numere pare:\n\n);
while ( fscanf( fp1, %4d, &n)==1) printf( %d\t,n);
puts(\nFiierul cu numere impare:\n\n);
while ( fscanf( fp2, %4d, &n)==1) printf( %d\t,n);
fclose(fp1);
fclose(fp2);
getch();
}

Exemplul 10.6. Programul citete de la intrarea standard un ir de numere ntregi, scrie cu


fprintf() numerele pare ntr-un fiier text i numerele impare n alt fiier text, apoi citete cu
fscanf() fiierele i le afieaz la ecran.
#include<conio.h>
#include<stdio.h>
void main()
{
FILE *fp1, *fp2; int n; clrscr();
fp1 = fopen(gpar,w+); fp2 = fopen(gimpar,w+);
while ( 1 )
{
if ( scanf( %d, &n )!=1) break; // citire de la tastatur
(n%2==0) ? fprintf( fp1, %d, n) : fpintf( fp2, %d, n);
} // scriere n fiiere
fclose( fp1 ); fclose( fp2 );
// indicatorul de poziie al fiierelor este readus la nceputul lor
rewind( fp1 ); rewind( fp2 );
puts(Fiierul cu numere pare:\n\n);
while ( fscanf( fp1, %d, &n)==1)
printf( %d\t,n); // citire din fiier i afiare la ecran
puts(\nFiierul cu numere impare:\n\n);
while ( fscanf( fp2, %d, &n)==1)
printf( %d\t,n); // citire din fiier i afiare la ecran
fclose(fp1);
fclose(fp2);
getch();
}

Exemplul 10.7. Programul citete cte un cuvnt de la intrarea standard i l adaug ntr-un
fiier.
#include<conio.h>
#include<stdio.h>
#define max 40
void main()
{
FILE *fp;
char words[max]; clrscr();
// deschiderea fiierului pentru adugare i
if ( ( fp = fopen(wordy, a+) ) == NULL)
{ printf(Nu se deschide fiierul\n);
exit(1);
}

72

puts( Introdu cuvntul urmtor; acioneaz Enter la nceputul cuvntului


pentru ntrerupere);
// se citesc cuvinte de la tastatur
while ( ( gets(words)) != NULL) && words[0] != \0)
fprintf ( fp, %s, words ); // se nscriu cuvintele n fiier
puts(Coninutul fiierului);
rewind( fp );
while ( fscanf( fp, %s, words ) == 1 )
puts(words);
if (fclose( fp ) != 0 )
fprintf( stderr, Eroare la nchiderea fiierului);
}

Exemplul 10.8. Programul demonstreaz utilizarea funciilor de citire/scriere fgets() i


fputs().
#include<conio.h>
#include<stdio.h>
#define max 20
void main()
{
char line[max]; clrscr();
while ( fgets(line, max, stdin) != NULL) && line[0] != \n)
fputs ( line, stdout );
}

Funcia gets() citete irul pn la simbolul \n;


Funcia fgets() citete irul inclusiv i simbolul \n;
Funcia puts() adaug simbolul \n la ieire;
Funcia fputs() nu adaug simbolul \n la ieire.
n legtur cu aceasta fgets() se utilizeaz n pereche cu fputs(), dar nu cu puts(). n aa
caz un simbol de linie nou s-ar preface la ieire n dou simboluri de linie nou.
Exemplul 10.9. Programul creeaz fiierul binar Bursa i scrie n el articole ce conin:
grupa, numele i prenumele studentului, nota medie obinut la sesiune i mrimea bursei. Datele
se citesc de la intrarea standard. Dup introducerea ultimului articol se tasteaz EOF
(<Ctrl+Z>).
#include<conio.h>
#include<stdio.h>
void main()
{
struct
{ char grupa[8], nume[15], pren[15]; float media; int bursa; }
student;
clrscr();
FILE *fp;
float p;
fp = fopen(Bursa, wb);
while ( scanf(%s, student.grupa) != -1)
{
scanf(%s,student.nume);
scanf(%s,student.pren);
scanf(%f,&p); student.media=p;
scanf(%i,&student.bursa);
fprintf( fp, %-7s%-15s%-15s%.2f%4d\n,student.grupa,
student.nume,
student.pren, student.media, student.bursa);
}
fclose(fp);
getch();
}

Exemplul 10.10. Programul caut n fiierul binar Bursa, creat n exemplul 10.9 studenii
cu nota medie maxim i afieaz informaia despre aceti studeni la ecran.
#include<conio.h>
#include<stdio.h>
void main()
{

73

struct
{ char grupa[8], nume[15], pren[15]; float media; int bursa; }
student;
clrscr();
FILE *fp;
float nm=0;
fp = fopen(Bursa, rb);
while ( !feof(fp))
{
fscanf( fp, %-7s%-15s%-15s%.2f%4d\n,student.grupa, student.nume,
student.pren, student.media, student.bursa);
if ( nm < student.media ) nm=student.media;
}
rewinf(fp);
while ( !feof(fp))
{
fscanf( fp, %-7s%-15s%-15s%.2f%4d\n,student.grupa,
student.nume,
student.pren, student.media, student.bursa);
if ( nm == student.media )
{
printf(%-7s,student.grupa);
printf(%-15s,student.nume);
printf(%-15s,student.pren);
printf(%.2f, student.media);
printf(%4i\n,student.bursa);
}
}
fclose(fp);
getch();
}

Exemplul 10.11. Programul creeaz fiierul binar Bursa i scrie n el articole ce conin:
grupa, numele i prenumele studentului, nota medie obinut la sesiune i mrimea bursei. Datele
se citesc de la intrarea standard. Se utilizeaz fwrite(). Pentru citirea din fiier se utilizeaz
fread().
#include<conio.h>
#include<stdio.h>
void main()
{
struct
{ char grupa[8], nume[15], pren[15]; float media; int bursa; }
student;
clrscr();
FILE *fp;
float p;
fp = fopen(Bursa, w+b); // fiier deschis pentru scriere i citire
while ( scanf(%s, student.grupa) != -1)
{
scanf(%s,student.nume);
scanf(%s,student.pren);
scanf(%f,&p); student.media=p;
scanf(%i,&student.bursa);
fwrite( &student, sizeof student, 1, fp );
}
fclose(fp);
rewinf(fp);
while ( !feof(fp))
{
fread( &student, sizeof student, 1, fp );
printf(%-7s,student.grupa);
printf(%-15s,student.nume);
printf(%-15s,student.pren);
printf(%.2f, student.media);
printf(%4i\n,student.bursa);
}
fclose(fp);
getch(); }

74

Exemplul 10.12.
Programul nscrie ntr-un fiier elementele unui tablou. Apoi
demonstreaz accesul aleator la nregistrrile sale.
#include <stdio.h>
#include <conio.h>
#include<stdlib.h>
#define ARSIZE 100
void main()
{
clrscr();
float numbers[ARSIZE], value;
const char *file="numbers.dat";
int i;
long pos;
FILE *fp;
// creaza tabloul de numere tip float
for ( i=0; i < ARSIZE; i++)
{
numbers[i] = 100.0 * i + 1.0/( i + 1);
printf("%f
",numbers[i]);
}
if ( ( fp = fopen( file, "wb")) == NULL )
{
puts("Eroare la deschidere");
exit(1);
}
// inscrie in fisier tabloul de dimensiunea ARSIZE
fwrite( numbers, sizeof( float ), ARSIZE, fp);
fclose( fp);
if ( ( fp = fopen(file, "rb"))==NULL)
{
puts("Eroare la deschidere");
exit(1);
}
// citeste din fisier inregistrarile selectate de utilizator
printf( "\nintroduceti un numar din diapazonul 0 - %i.\n", ARSIZE - 1);
scanf("%i", &i);
while ( i >= 0 && i < ARSIZE)
{
pos = ( long ) i * sizeof( float ); //gaseste deplasamentul
fseek( fp, pos, SEEK_SET ); // efectueaz deplasarea n cadrul fiierului
// efectueaz citirea din fiier a unei nregistrri
fread(&value, sizeof( float), 1, fp);
printf("Valoarea = %f\n", value);
printf("Urmatorul indice");
puts("pentru iesire indicati un indice ce nu apartine diapazonului");
scanf("%i",&i);
}
fclose( fp);
getch();
}

Probleme propuse spre rezolvare:


1. Programul copie un fiier text iniial (numele cruia se citete de la tastatur) n altul final
(numele cruia la fel se citete de la tastatur) doar cu majuscule.
2. Creai un program ce deschide dou fiiere, numele crora se introduc de la tastatur. Apoi
afieaz o linie din primul fiier, o linie din al doilea fiier, o linie din primul fiier, o linie din
al doilea fiier s.a.m.d. pn la ultima linie din fiierul cu cele mai multe linii.
3. Creai un fiier text i scriei n el numele, prenumele i numrul de telefon ale colegilor de
grup. Apoi afiai pe monitor informaia nscris n fiier.
75

4. Creai un fiier text i scriei n el numele, prenumele, numrul de telefon i data naterii ale
colegilor de grup. Folosii informaia din fiierul creat cu programul pentru sarcina 3. Apoi
afiai pe monitor informaia nscris n fiier.
5. Programul citete de la intrarea standard un ir de numere ntregi, scrie numerele pare ntr-un
fiier binar i numerele impare n alt fiier binar, apoi le afieaz la ecran.
6. Se consider fiierul text IN1.TXT i IN2.TXT. Fiecare din aceste fiiere conine cte un ir
de numere reale, ordonate cresctor. Scriei un program care comaseaz aceste fiiere n
fiierul OUT.TXT. Numerele vor fi scrise n fiier n ordine cresctoare.
7. Se consider fiierul IN.TXT care conine n numere separate prin spaiu ce reprezint
elementele unui tablou. Scriei un program care calculeaz recursiv suma valorilor elementelor
tabloului.
8. Se consider fiierul IN.TXT care conine pe fiecare linie cte o pereche de cuvinte, separate
prin spaiu. Primul cuvnt din fiecare pereche este n limba englez, al doilea n limba
romn. Scriei un program care aranjeaz aceste perechi n ordinea lexicografic a cuvintelor
din limba englez.
9. Fiierul IN.TXT conine 3*n numere reale (n triplete). Scriei un program care modific
fiierul astfel: fiecare al doilea element din triplete consecutive se nlocuiete cu media
aritmetic a vecinilor si.
10. Fiierul text ELEVI.IN conine datele referitoare la examene a cel mult 200 concureni.
Datele despre fiecare concurent snt numele, prenumele i media obinut la examene. Scriei
un program care scrie n fiierul ELEVI.OUT lista elevilor admii ( care au media nu mai
mic dect 5) ordonat descresctor dup medii.
11. Se numesc numere bine ordonate acele care au cifrele n ordine strict cresctoare sau strict
descresctoare. Scriei un program care citete dintr-un fiier numere de 4 cifre i creaz alt
fiier unde nscrie numerele bine ordonate.
12. Fiierul text BAC.TXT conine numele, prenumele, clasa i media obinut la bacalaureat
ale fiecrui elev. Clasele sunt 12A, 12B, 12C. Scriei un program care afieaz media obinut
pentru fiecare clas (se consider numai elevii care au media mai mare ca 5).
ntrebri de control:
1. Ce este un fiier de date?
2. Ce este un flux de date?
3. Care este legtura dintre un fiier de date i un flux de date?
4. Ce este un flux text?
5. Ce este un flux binar?
6. Care este deosebirea dintre un flux text i un flux binar?
7. Cum se asociaz un flux de date la un fiier de date?
8. Ce este un fiier cu acces secvenial la date?
9. Ce este un fiier cu acces direct la date?
10. Care dintre urmtoarele afirmaii este adevrat?
a. ntr-un fiier text se pot scrie numai litere,
b.nu se poate terge o linie dintr-un fiier text,
c. fiierele text permit numai acces secvenial,
d.fiierele text nu pot fi modificate.
11. Ce se ntmpl la deschiderea cu modul w sau a a unui fiier inexistent?
12. Ce se ntmpl la deschiderea cu modul w a unui fiier existent?
13. Ce se ntmpl la deschiderea cu modul a a unui fiier existent?
14. Ce se ntmpl la deschiderea cu modul r a unui fiier inexistent?
15. Ce se ntmpl la deschiderea cu modul de citire i scriere a unui fiier inexistent?
16. Ce se ntmpl la deschiderea cu modul de citire i scriere a unui fiier existent?
17. Care moduri de deschidere a unui fiier duc la tergerea lui?
76

18. Funcia fseek(nume_p, nr, origine)


a. precizeaz poziia indicatorului de fiier
b.deplaseaz indicatorul de poziie cu nr octei fa de poziia curent
c. deplaseaz indicatorul de poziie cu nr octei fa de nceputul de fiier
d.deplaseaz indicatorul de poziie cu nr octei fa de origine.
19. Funcia void rewind(FILE *f);
a. terge coninutul fiierului
b.mut indicatorul de fiier la nceputul su
c. recitete coninutul fiierului
d.marcheaz sfritul de fiier.
20. Secvena:
FILE *f;
f = fopen ( a.txt, r );
fseek ( f, 0L, SEEK_END );
long l = ftell ( f );

a) calculeaz n l lungimea fiierului


b) calculeaz n l numrul de linii
c) calculeaz n l numrul de caractere diferite de cele albe
d) este eronat
21. Cnd se nchide un fiier?
a. la apelul funciei close
b.la apelul funciei freopen
c. la terminarea blocului n care a fost declarat
d.la apelul funciei fclose
22. Care sunt pointerii predefinii spre fiierele I/O standard?
23. Secvena
FILE *f = fopen ( a.txt, w);
int n; scanf ( %i, &n);
while ( n ) { if ( !feof ( f )) fprintf(f,%i,n ); scanf (%i,&n); }
fclose ( f );

a. scrie un numr n fiier


b.scrie n fiier numerele introduse pn la 0,
c. afieaz numerele nenule din fiier,
d.verific dac un numr se gsete n fiier.

77

Bibliografie
1. Herbert Shildt. C manual complet. Editura Teora, Bucure;ti, 1998
2. Liviu Negrescu. C i C++ pentru nceptori. Editura Microinformatica, Cluj-Napoca, 1995.
3. Vasile Petrovici, Florin Goicea. Programarea n limbajul C. Editura Tehnic. Bucureti, 1993.
4. Ana ntuneric, Cristina Sichim. Informatic. Editura Polirom, Bucureti, 2003.
5. Bogdan Ptru. Aplicaii n C i C++. Editura Teora, Bucureti, 1998.
6. . . DiaSoft, 2002.
7. . . , . . . . , 1999
8. . . , . . , . . , . . .
. , , 1988.

78

S-ar putea să vă placă și